diff --git a/configure.ac b/configure.ac index b92d9fc5b9..bc51a0d32b 100644 --- a/configure.ac +++ b/configure.ac @@ -167,7 +167,6 @@ AC_CONFIG_FILES([ icons/tango/scalable/Makefile ctags/Makefile scintilla/Makefile - scintilla/include/Makefile src/Makefile src/tagmanager/Makefile plugins/Makefile diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 77e803cf1c..44cf3ff9ee 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -74,6 +74,7 @@ AM_CPPFLAGS += \ -DGTK \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/tagmanager \ + -I$(top_srcdir)/scintilla/lexilla/include \ -I$(top_srcdir)/scintilla/include \ $(GTK_CFLAGS) \ $(PLUGIN_CFLAGS) diff --git a/scintilla/License.txt b/scintilla/License.txt index 47c7926558..e93ac62f2d 100644 --- a/scintilla/License.txt +++ b/scintilla/License.txt @@ -1,6 +1,6 @@ -License for Scintilla and SciTE +License for Lexilla, Scintilla, and SciTE -Copyright 1998-2003 by Neil Hodgson +Copyright 1998-2021 by Neil Hodgson All Rights Reserved diff --git a/scintilla/Makefile.am b/scintilla/Makefile.am index e59703f35e..5fcd74a60b 100644 --- a/scintilla/Makefile.am +++ b/scintilla/Makefile.am @@ -1,171 +1,194 @@ +noinst_LTLIBRARIES = libscintilla.la liblexilla.la -SUBDIRS = include +AM_CXXFLAGS = -DNDEBUG -DGTK -DSCI_LEXER -DNO_CXX11_REGEX -std=c++17 +AM_CPPFLAGS = @GTK_CFLAGS@ @LIBGEANY_CFLAGS@ -noinst_LTLIBRARIES=libscintilla.la +scintilla_includedir = $(includedir)/geany/scintilla/ +scintilla_include_HEADERS = \ +include/Scintilla.h \ +include/Scintilla.iface \ +include/ScintillaWidget.h \ +include/Sci_Position.h -AM_CXXFLAGS = -DNDEBUG -DGTK -DSCI_LEXER -DNO_CXX11_REGEX +LEXER_SRCS = \ +lexilla/lexers/LexAbaqus.cxx \ +lexilla/lexers/LexAda.cxx \ +lexilla/lexers/LexAsm.cxx \ +lexilla/lexers/LexBash.cxx \ +lexilla/lexers/LexBasic.cxx \ +lexilla/lexers/LexBatch.cxx \ +lexilla/lexers/LexCOBOL.cxx \ +lexilla/lexers/LexCPP.cxx \ +lexilla/lexers/LexCSS.cxx \ +lexilla/lexers/LexCaml.cxx \ +lexilla/lexers/LexCmake.cxx \ +lexilla/lexers/LexCoffeeScript.cxx \ +lexilla/lexers/LexD.cxx \ +lexilla/lexers/LexDiff.cxx \ +lexilla/lexers/LexErlang.cxx \ +lexilla/lexers/LexForth.cxx \ +lexilla/lexers/LexFortran.cxx \ +lexilla/lexers/LexHTML.cxx \ +lexilla/lexers/LexHaskell.cxx \ +lexilla/lexers/LexJulia.cxx \ +lexilla/lexers/LexLaTeX.cxx \ +lexilla/lexers/LexLisp.cxx \ +lexilla/lexers/LexLua.cxx \ +lexilla/lexers/LexMake.cxx \ +lexilla/lexers/LexMarkdown.cxx \ +lexilla/lexers/LexMatlab.cxx \ +lexilla/lexers/LexNsis.cxx \ +lexilla/lexers/LexNull.cxx \ +lexilla/lexers/LexPascal.cxx \ +lexilla/lexers/LexPerl.cxx \ +lexilla/lexers/LexPowerShell.cxx \ +lexilla/lexers/LexProps.cxx \ +lexilla/lexers/LexPython.cxx \ +lexilla/lexers/LexPO.cxx \ +lexilla/lexers/LexR.cxx \ +lexilla/lexers/LexRuby.cxx \ +lexilla/lexers/LexRust.cxx \ +lexilla/lexers/LexSmalltalk.cxx \ +lexilla/lexers/LexSQL.cxx \ +lexilla/lexers/LexTCL.cxx \ +lexilla/lexers/LexTxt2tags.cxx \ +lexilla/lexers/LexVHDL.cxx \ +lexilla/lexers/LexVerilog.cxx \ +lexilla/lexers/LexYAML.cxx -LEXER_SRCS= \ -lexers/LexAbaqus.cxx \ -lexers/LexAda.cxx \ -lexers/LexAsm.cxx \ -lexers/LexBash.cxx \ -lexers/LexBasic.cxx \ -lexers/LexBatch.cxx \ -lexers/LexCOBOL.cxx \ -lexers/LexCPP.cxx \ -lexers/LexCSS.cxx \ -lexers/LexCaml.cxx \ -lexers/LexCmake.cxx \ -lexers/LexCoffeeScript.cxx \ -lexers/LexD.cxx \ -lexers/LexDiff.cxx \ -lexers/LexErlang.cxx \ -lexers/LexForth.cxx \ -lexers/LexFortran.cxx \ -lexers/LexHTML.cxx \ -lexers/LexHaskell.cxx \ -lexers/LexJulia.cxx \ -lexers/LexLaTeX.cxx \ -lexers/LexLisp.cxx \ -lexers/LexLua.cxx \ -lexers/LexMake.cxx \ -lexers/LexMarkdown.cxx \ -lexers/LexMatlab.cxx \ -lexers/LexNsis.cxx \ -lexers/LexNull.cxx \ -lexers/LexPascal.cxx \ -lexers/LexPerl.cxx \ -lexers/LexPowerShell.cxx \ -lexers/LexProps.cxx \ -lexers/LexPython.cxx \ -lexers/LexPO.cxx \ -lexers/LexR.cxx \ -lexers/LexRuby.cxx \ -lexers/LexRust.cxx \ -lexers/LexSmalltalk.cxx \ -lexers/LexSQL.cxx \ -lexers/LexTCL.cxx \ -lexers/LexTxt2tags.cxx \ -lexers/LexVHDL.cxx \ -lexers/LexVerilog.cxx \ -lexers/LexYAML.cxx +LEXLIB_SRCS = \ +lexilla/include/LexicalStyles.iface \ +lexilla/include/Lexilla.h \ +lexilla/include/SciLexer.h \ +lexilla/lexlib/Accessor.cxx \ +lexilla/lexlib/Accessor.h \ +lexilla/lexlib/CatalogueModules.h \ +lexilla/lexlib/CharacterCategory.cxx \ +lexilla/lexlib/CharacterCategory.h \ +lexilla/lexlib/CharacterSet.cxx \ +lexilla/lexlib/CharacterSet.h \ +lexilla/lexlib/DefaultLexer.cxx \ +lexilla/lexlib/DefaultLexer.h \ +lexilla/lexlib/LexAccessor.cxx \ +lexilla/lexlib/LexAccessor.h \ +lexilla/lexlib/LexerBase.cxx \ +lexilla/lexlib/LexerBase.h \ +lexilla/lexlib/LexerModule.cxx \ +lexilla/lexlib/LexerModule.h \ +lexilla/lexlib/LexerNoExceptions.cxx \ +lexilla/lexlib/LexerNoExceptions.h \ +lexilla/lexlib/LexerSimple.cxx \ +lexilla/lexlib/LexerSimple.h \ +lexilla/lexlib/OptionSet.h \ +lexilla/lexlib/PropSetSimple.cxx \ +lexilla/lexlib/PropSetSimple.h \ +lexilla/lexlib/SparseState.h \ +lexilla/lexlib/StringCopy.h \ +lexilla/lexlib/StyleContext.cxx \ +lexilla/lexlib/StyleContext.h \ +lexilla/lexlib/SubStyles.h \ +lexilla/lexlib/WordList.cxx \ +lexilla/lexlib/WordList.h \ +lexilla/src/Lexilla.cxx -SRCS= \ -gtk/Converter.h \ -gtk/PlatGTK.cxx \ -gtk/ScintillaGTK.cxx \ -gtk/ScintillaGTK.h \ -gtk/ScintillaGTKAccessible.cxx \ -gtk/ScintillaGTKAccessible.h \ -gtk/scintilla-marshal.c \ -gtk/scintilla-marshal.h \ -lexlib/Accessor.cxx \ -lexlib/Accessor.h \ -lexlib/CatalogueModules.h \ -lexlib/CharacterCategory.cxx \ -lexlib/CharacterCategory.h \ -lexlib/CharacterSet.cxx \ -lexlib/CharacterSet.h \ -lexlib/DefaultLexer.cxx \ -lexlib/DefaultLexer.h \ -lexlib/LexAccessor.h \ -lexlib/LexerBase.cxx \ -lexlib/LexerBase.h \ -lexlib/LexerModule.cxx \ -lexlib/LexerModule.h \ -lexlib/LexerNoExceptions.cxx \ -lexlib/LexerNoExceptions.h \ -lexlib/LexerSimple.cxx \ -lexlib/LexerSimple.h \ -lexlib/OptionSet.h \ -lexlib/PropSetSimple.cxx \ -lexlib/PropSetSimple.h \ -lexlib/SparseState.h \ -lexlib/StringCopy.h \ -lexlib/StyleContext.cxx \ -lexlib/StyleContext.h \ -lexlib/SubStyles.h \ -lexlib/WordList.cxx \ -lexlib/WordList.h \ -src/AutoComplete.cxx \ -src/AutoComplete.h \ -src/CallTip.cxx \ -src/CallTip.h \ -src/CaseConvert.cxx \ -src/CaseConvert.h \ -src/CaseFolder.cxx \ -src/CaseFolder.h \ -src/Catalogue.cxx \ -src/Catalogue.h \ -src/CellBuffer.cxx \ -src/CellBuffer.h \ -src/CharClassify.cxx \ -src/CharClassify.h \ -src/ContractionState.cxx \ -src/ContractionState.h \ -src/DBCS.cxx \ -src/DBCS.h \ -src/Decoration.cxx \ -src/Decoration.h \ -src/Document.cxx \ -src/Document.h \ -src/Editor.cxx \ -src/Editor.h \ -src/EditModel.cxx \ -src/EditModel.h \ -src/EditView.cxx \ -src/EditView.h \ -src/ElapsedPeriod.h \ -src/ExternalLexer.cxx \ -src/ExternalLexer.h \ -src/FontQuality.h \ -src/Indicator.cxx \ -src/Indicator.h \ -src/IntegerRectangle.h \ -src/KeyMap.cxx \ -src/KeyMap.h \ -src/LineMarker.cxx \ -src/LineMarker.h \ -src/MarginView.cxx \ -src/MarginView.h \ -src/Partitioning.h \ -src/PerLine.cxx \ -src/PerLine.h \ -src/Position.h \ -src/PositionCache.cxx \ -src/PositionCache.h \ -src/RESearch.cxx \ -src/RESearch.h \ -src/RunStyles.cxx \ -src/RunStyles.h \ -src/SVector.h \ -src/ScintillaBase.cxx \ -src/ScintillaBase.h \ -src/Selection.cxx \ -src/Selection.h \ -src/SparseVector.h \ -src/SplitVector.h \ -src/Style.cxx \ -src/Style.h \ -src/UniConversion.cxx \ -src/UniConversion.h \ -src/UnicodeFromUTF8.h \ -src/UniqueString.cxx \ -src/UniqueString.h \ -src/ViewStyle.cxx \ -src/ViewStyle.h \ -src/XPM.cxx \ -src/XPM.h \ -$(LEXER_SRCS) +SRCS = \ +include/ILexer.h \ +include/ILoader.h \ +include/ScintillaCall.h \ +include/ScintillaMessages.h \ +include/ScintillaStructures.h \ +include/ScintillaTypes.h \ +include/ScintillaWidget.h \ +gtk/Converter.h \ +gtk/PlatGTK.cxx \ +gtk/ScintillaGTK.cxx \ +gtk/ScintillaGTK.h \ +gtk/ScintillaGTKAccessible.cxx \ +gtk/ScintillaGTKAccessible.h \ +gtk/scintilla-marshal.c \ +gtk/scintilla-marshal.h \ +src/AutoComplete.cxx \ +src/AutoComplete.h \ +src/CallTip.cxx \ +src/CallTip.h \ +src/CaseConvert.cxx \ +src/CaseConvert.h \ +src/CaseFolder.cxx \ +src/CaseFolder.h \ +src/CellBuffer.cxx \ +src/CellBuffer.h \ +src/CharacterCategoryMap.cxx \ +src/CharacterCategoryMap.h \ +src/CharacterType.cxx \ +src/CharacterType.h \ +src/CharClassify.cxx \ +src/CharClassify.h \ +src/ContractionState.cxx \ +src/ContractionState.h \ +src/DBCS.cxx \ +src/DBCS.h \ +src/Debugging.h \ +src/Decoration.cxx \ +src/Decoration.h \ +src/Document.cxx \ +src/Document.h \ +src/EditModel.cxx \ +src/EditModel.h \ +src/Editor.cxx \ +src/Editor.h \ +src/EditView.cxx \ +src/EditView.h \ +src/ElapsedPeriod.h \ +src/FontQuality.h \ +src/Geometry.cxx \ +src/Geometry.h \ +src/Indicator.cxx \ +src/Indicator.h \ +src/KeyMap.cxx \ +src/KeyMap.h \ +src/LineMarker.cxx \ +src/LineMarker.h \ +src/MarginView.cxx \ +src/MarginView.h \ +src/Partitioning.h \ +src/PerLine.cxx \ +src/PerLine.h \ +src/Platform.h \ +src/PositionCache.cxx \ +src/PositionCache.h \ +src/Position.h \ +src/RESearch.cxx \ +src/RESearch.h \ +src/RunStyles.cxx \ +src/RunStyles.h \ +src/ScintillaBase.cxx \ +src/ScintillaBase.h \ +src/Selection.cxx \ +src/Selection.h \ +src/SparseVector.h \ +src/SplitVector.h \ +src/Style.cxx \ +src/Style.h \ +src/UniConversion.cxx \ +src/UniConversion.h \ +src/UniqueString.cxx \ +src/UniqueString.h \ +src/ViewStyle.cxx \ +src/ViewStyle.h \ +src/XPM.cxx \ +src/XPM.h -libscintilla_la_SOURCES = $(SRCS) +liblexilla_la_CPPFLAGS = $(AM_CPPFLAGS) +liblexilla_la_CPPFLAGS += -I$(srcdir)/lexilla/include -I$(srcdir)/lexilla/lexlib -I$(srcdir)/include +liblexilla_la_SOURCES = $(LEXLIB_SRCS) $(LEXER_SRCS) -AM_CPPFLAGS = -I$(top_srcdir) -I$(srcdir)/include -I$(srcdir)/src -I$(srcdir)/lexlib \ - @GTK_CFLAGS@ @LIBGEANY_CFLAGS@ +libscintilla_la_CPPFLAGS = $(AM_CPPFLAGS) +libscintilla_la_CPPFLAGS += -I$(srcdir)/src -I$(srcdir)/include -I$(srcdir)/lexilla/include +libscintilla_la_SOURCES = $(SRCS) marshallers: gtk/scintilla-marshal.list glib-genmarshal --prefix scintilla_marshal gtk/scintilla-marshal.list --header > gtk/scintilla-marshal.h glib-genmarshal --prefix scintilla_marshal gtk/scintilla-marshal.list --body > gtk/scintilla-marshal.c -EXTRA_DIST=gtk/scintilla-marshal.list License.txt README version.txt +EXTRA_DIST = gtk/scintilla-marshal.list License.txt README version.txt +EXTRA_DIST += lexilla/License.txt lexilla/version.txt diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index b999feeee0..7a53bc28ef 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -10,8 +10,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -22,12 +24,15 @@ #include #include +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" + +#include "Debugging.h" +#include "Geometry.h" #include "Platform.h" #include "Scintilla.h" #include "ScintillaWidget.h" -#include "StringCopy.h" -#include "IntegerRectangle.h" #include "XPM.h" #include "UniConversion.h" @@ -39,11 +44,14 @@ #endif using namespace Scintilla; +using namespace Scintilla::Internal; namespace { constexpr double kPi = 3.14159265358979323846; +constexpr double degrees = kPi / 180.0; + // The Pango version guard for pango_units_from_double and pango_units_to_double // is more complex than simply implementing these here. @@ -55,9 +63,19 @@ constexpr float floatFromPangoUnits(int pu) noexcept { return static_cast(pu) / PANGO_SCALE; } -cairo_surface_t *CreateSimilarSurface(GdkWindow *window, cairo_content_t content, int width, int height) noexcept { - return gdk_window_create_similar_surface(window, content, width, height); -} +struct IntegerRectangle { + int left; + int top; + int right; + int bottom; + + explicit IntegerRectangle(PRectangle rc) noexcept : + left(static_cast(rc.left)), top(static_cast(rc.top)), + right(static_cast(rc.right)), bottom(static_cast(rc.bottom)) { + } + int Width() const noexcept { return right - left; } + int Height() const noexcept { return bottom - top; } +}; GdkWindow *WindowFromWidget(GtkWidget *w) noexcept { return gtk_widget_get_window(w); @@ -67,19 +85,30 @@ GtkWidget *PWidget(WindowID wid) noexcept { return static_cast(wid); } -enum encodingType { singleByte, UTF8, dbcs }; +enum class EncodingType { singleByte, utf8, dbcs }; // Holds a PangoFontDescription*. -class FontHandle { +class FontHandle : public Font { public: - PangoFontDescription *pfd; - int characterSet; - FontHandle() noexcept : pfd(nullptr), characterSet(-1) { + PangoFontDescription *pfd = nullptr; + CharacterSet characterSet; + FontHandle() noexcept : pfd(nullptr), characterSet(CharacterSet::Ansi) { } - FontHandle(PangoFontDescription *pfd_, int characterSet_) noexcept { + FontHandle(PangoFontDescription *pfd_, CharacterSet characterSet_) noexcept { pfd = pfd_; characterSet = characterSet_; } + FontHandle(const FontParameters &fp) { + pfd = pango_font_description_new(); + if (pfd) { + pango_font_description_set_family(pfd, + (fp.faceName[0] == '!') ? fp.faceName + 1 : fp.faceName); + pango_font_description_set_size(pfd, pangoUnitsFromDouble(fp.size)); + pango_font_description_set_weight(pfd, static_cast(fp.weight)); + pango_font_description_set_style(pfd, fp.italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL); + } + characterSet = fp.characterSet; + } // Deleted so FontHandle objects can not be copied. FontHandle(const FontHandle &) = delete; FontHandle(FontHandle &&) = delete; @@ -90,45 +119,19 @@ class FontHandle { pango_font_description_free(pfd); pfd = nullptr; } - static FontHandle *CreateNewFont(const FontParameters &fp); }; -FontHandle *FontHandle::CreateNewFont(const FontParameters &fp) { - PangoFontDescription *pfd = pango_font_description_new(); - if (pfd) { - pango_font_description_set_family(pfd, - (fp.faceName[0] == '!') ? fp.faceName+1 : fp.faceName); - pango_font_description_set_size(pfd, pangoUnitsFromDouble(fp.size)); - pango_font_description_set_weight(pfd, static_cast(fp.weight)); - pango_font_description_set_style(pfd, fp.italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL); - return new FontHandle(pfd, fp.characterSet); - } - - return nullptr; -} - // X has a 16 bit coordinate space, so stop drawing here to avoid wrapping constexpr int maxCoordinate = 32000; -FontHandle *PFont(const Font &f) noexcept { - return static_cast(f.GetID()); +const FontHandle *PFont(const Font *f) noexcept { + return dynamic_cast(f); } } -Font::Font() noexcept : fid(nullptr) {} - -Font::~Font() {} - -void Font::Create(const FontParameters &fp) { - Release(); - fid = FontHandle::CreateNewFont(fp); -} - -void Font::Release() { - if (fid) - delete static_cast(fid); - fid = nullptr; +std::shared_ptr Font::Allocate(const FontParameters &fp) { + return std::make_shared(fp); } // Required on OS X @@ -136,20 +139,23 @@ namespace Scintilla { // SurfaceID is a cairo_t* class SurfaceImpl : public Surface { - encodingType et; - cairo_t *context; - cairo_surface_t *psurf; - int x; - int y; - bool inited; - bool createdGC; - PangoContext *pcontext; - PangoLayout *layout; + SurfaceMode mode; + EncodingType et= EncodingType::singleByte; + WindowID widSave = nullptr; + cairo_t *context = nullptr; + cairo_surface_t *psurf = nullptr; + bool inited = false; + bool createdGC = false; + PangoContext *pcontext = nullptr; + PangoLayout *layout = nullptr; Converter conv; - int characterSet; - void SetConverter(int characterSet_); + CharacterSet characterSet = static_cast(-1); + void PenColourAlpha(ColourRGBA fore) noexcept; + void SetConverter(CharacterSet characterSet_); + void CairoRectangle(PRectangle rc) noexcept; public: SurfaceImpl() noexcept; + SurfaceImpl(cairo_t *context_, int width, int height, SurfaceMode mode_, WindowID wid) noexcept; // Deleted so SurfaceImpl objects can not be copied. SurfaceImpl(const SurfaceImpl&) = delete; SurfaceImpl(SurfaceImpl&&) = delete; @@ -159,111 +165,164 @@ class SurfaceImpl : public Surface { void Init(WindowID wid) override; void Init(SurfaceID sid, WindowID wid) override; - void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override; + std::unique_ptr AllocatePixMap(int width, int height) override; + + void SetMode(SurfaceMode mode_) override; void Clear() noexcept; - void Release() override; + void Release() noexcept override; + int SupportsFeature(Supports feature) noexcept override; bool Initialised() override; - void PenColour(ColourDesired fore) override; int LogPixelsY() override; + int PixelDivisions() override; int DeviceHeightFont(int points) override; - void MoveTo(int x_, int y_) override; - void LineTo(int x_, int y_) override; - void Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back) override; - void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) override; - void FillRectangle(PRectangle rc, ColourDesired back) override; + void LineDraw(Point start, Point end, Stroke stroke) override; + void PolyLine(const Point *pts, size_t npts, Stroke stroke) override; + void Polygon(const Point *pts, size_t npts, FillStroke fillStroke) override; + void RectangleDraw(PRectangle rc, FillStroke fillStroke) override; + void RectangleFrame(PRectangle rc, Stroke stroke) override; + void FillRectangle(PRectangle rc, Fill fill) override; + void FillRectangleAligned(PRectangle rc, Fill fill) override; void FillRectangle(PRectangle rc, Surface &surfacePattern) override; - void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) override; - void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, - ColourDesired outline, int alphaOutline, int flags) override; + void RoundedRectangle(PRectangle rc, FillStroke fillStroke) override; + void AlphaRectangle(PRectangle rc, XYPOSITION cornerSize, FillStroke fillStroke) override; void GradientRectangle(PRectangle rc, const std::vector &stops, GradientOptions options) override; void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) override; - void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override; + void Ellipse(PRectangle rc, FillStroke fillStroke) override; + void Stadium(PRectangle rc, FillStroke fillStroke, Ends ends) override; void Copy(PRectangle rc, Point from, Surface &surfaceSource) override; - void DrawTextBase(PRectangle rc, const Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); - void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override; - void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) override; - void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) override; - void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) override; - XYPOSITION WidthText(Font &font_, const char *s, int len) override; - XYPOSITION Ascent(Font &font_) override; - XYPOSITION Descent(Font &font_) override; - XYPOSITION InternalLeading(Font &font_) override; - XYPOSITION Height(Font &font_) override; - XYPOSITION AverageCharWidth(Font &font_) override; + std::unique_ptr Layout(const IScreenLine *screenLine) override; + + void DrawTextBase(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore); + void DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) override; + void DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) override; + void DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore) override; + void MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) override; + XYPOSITION WidthText(const Font *font_, std::string_view text) override; + + void DrawTextBaseUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore); + void DrawTextNoClipUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) override; + void DrawTextClippedUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) override; + void DrawTextTransparentUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore) override; + void MeasureWidthsUTF8(const Font *font_, std::string_view text, XYPOSITION *positions) override; + XYPOSITION WidthTextUTF8(const Font *font_, std::string_view text) override; + + XYPOSITION Ascent(const Font *font_) override; + XYPOSITION Descent(const Font *font_) override; + XYPOSITION InternalLeading(const Font *font_) override; + XYPOSITION Height(const Font *font_) override; + XYPOSITION AverageCharWidth(const Font *font_) override; void SetClip(PRectangle rc) override; + void PopClip() override; void FlushCachedState() override; + void FlushDrawing() override; +}; - void SetUnicodeMode(bool unicodeMode_) override; - void SetDBCSMode(int codePage) override; +const Supports SupportsGTK[] = { + Supports::LineDrawsFinal, + Supports::FractionalStrokeWidth, + Supports::TranslucentStroke, + Supports::PixelModification, }; + } -const char *CharacterSetID(int characterSet) noexcept { +const char *CharacterSetID(CharacterSet characterSet) noexcept { switch (characterSet) { - case SC_CHARSET_ANSI: + case CharacterSet::Ansi: return ""; - case SC_CHARSET_DEFAULT: + case CharacterSet::Default: return "ISO-8859-1"; - case SC_CHARSET_BALTIC: + case CharacterSet::Baltic: return "ISO-8859-13"; - case SC_CHARSET_CHINESEBIG5: + case CharacterSet::ChineseBig5: return "BIG-5"; - case SC_CHARSET_EASTEUROPE: + case CharacterSet::EastEurope: return "ISO-8859-2"; - case SC_CHARSET_GB2312: + case CharacterSet::GB2312: return "CP936"; - case SC_CHARSET_GREEK: + case CharacterSet::Greek: return "ISO-8859-7"; - case SC_CHARSET_HANGUL: + case CharacterSet::Hangul: return "CP949"; - case SC_CHARSET_MAC: + case CharacterSet::Mac: return "MACINTOSH"; - case SC_CHARSET_OEM: + case CharacterSet::Oem: return "ASCII"; - case SC_CHARSET_RUSSIAN: + case CharacterSet::Russian: return "KOI8-R"; - case SC_CHARSET_OEM866: + case CharacterSet::Oem866: return "CP866"; - case SC_CHARSET_CYRILLIC: + case CharacterSet::Cyrillic: return "CP1251"; - case SC_CHARSET_SHIFTJIS: + case CharacterSet::ShiftJis: return "SHIFT-JIS"; - case SC_CHARSET_SYMBOL: + case CharacterSet::Symbol: return ""; - case SC_CHARSET_TURKISH: + case CharacterSet::Turkish: return "ISO-8859-9"; - case SC_CHARSET_JOHAB: + case CharacterSet::Johab: return "CP1361"; - case SC_CHARSET_HEBREW: + case CharacterSet::Hebrew: return "ISO-8859-8"; - case SC_CHARSET_ARABIC: + case CharacterSet::Arabic: return "ISO-8859-6"; - case SC_CHARSET_VIETNAMESE: + case CharacterSet::Vietnamese: return ""; - case SC_CHARSET_THAI: + case CharacterSet::Thai: return "ISO-8859-11"; - case SC_CHARSET_8859_15: + case CharacterSet::Iso8859_15: return "ISO-8859-15"; default: return ""; } } -void SurfaceImpl::SetConverter(int characterSet_) { +void SurfaceImpl::PenColourAlpha(ColourRGBA fore) noexcept { + if (context) { + cairo_set_source_rgba(context, + fore.GetRedComponent(), + fore.GetGreenComponent(), + fore.GetBlueComponent(), + fore.GetAlphaComponent()); + } +} + +void SurfaceImpl::SetConverter(CharacterSet characterSet_) { if (characterSet != characterSet_) { characterSet = characterSet_; conv.Open("UTF-8", CharacterSetID(characterSet), false); } } -SurfaceImpl::SurfaceImpl() noexcept : et(singleByte), -context(nullptr), -psurf(nullptr), -x(0), y(0), inited(false), createdGC(false), -pcontext(nullptr), layout(nullptr), characterSet(-1) { +void SurfaceImpl::CairoRectangle(PRectangle rc) noexcept { + cairo_rectangle(context, rc.left, rc.top, rc.Width(), rc.Height()); +} + +SurfaceImpl::SurfaceImpl() noexcept { +} + +SurfaceImpl::SurfaceImpl(cairo_t *context_, int width, int height, SurfaceMode mode_, WindowID wid) noexcept { + if (height > 0 && width > 0) { + cairo_surface_t *psurfContext = cairo_get_target(context_); + psurf = cairo_surface_create_similar( + psurfContext, + CAIRO_CONTENT_COLOR_ALPHA, width, height); + context = cairo_create(psurf); + pcontext = gtk_widget_create_pango_context(PWidget(wid)); + PLATFORM_ASSERT(pcontext); + layout = pango_layout_new(pcontext); + PLATFORM_ASSERT(layout); + cairo_rectangle(context, 0, 0, width, height); + cairo_set_source_rgb(context, 1.0, 0, 0); + cairo_fill(context); + cairo_set_line_width(context, 1); + createdGC = true; + inited = true; + mode = mode_; + } } SurfaceImpl::~SurfaceImpl() { @@ -271,7 +330,7 @@ SurfaceImpl::~SurfaceImpl() { } void SurfaceImpl::Clear() noexcept { - et = singleByte; + et = EncodingType::singleByte; if (createdGC) { createdGC = false; cairo_destroy(context); @@ -287,14 +346,12 @@ void SurfaceImpl::Clear() noexcept { g_object_unref(pcontext); pcontext = nullptr; conv.Close(); - characterSet = -1; - x = 0; - y = 0; + characterSet = static_cast(-1); inited = false; createdGC = false; } -void SurfaceImpl::Release() { +void SurfaceImpl::Release() noexcept { Clear(); } @@ -319,6 +376,7 @@ bool SurfaceImpl::Initialised() { } void SurfaceImpl::Init(WindowID wid) { + widSave = wid; Release(); PLATFORM_ASSERT(wid); // if we are only created from a window ID, we can't perform drawing @@ -333,6 +391,7 @@ void SurfaceImpl::Init(WindowID wid) { } void SurfaceImpl::Init(SurfaceID sid, WindowID wid) { + widSave = wid; PLATFORM_ASSERT(sid); Release(); PLATFORM_ASSERT(wid); @@ -346,137 +405,115 @@ void SurfaceImpl::Init(SurfaceID sid, WindowID wid) { inited = true; } -void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID wid) { - PLATFORM_ASSERT(surface_); - Release(); - SurfaceImpl *surfImpl = dynamic_cast(surface_); - PLATFORM_ASSERT(surfImpl); - PLATFORM_ASSERT(wid); - context = cairo_reference(surfImpl->context); - pcontext = gtk_widget_create_pango_context(PWidget(wid)); - // update the Pango context in case surface_ isn't the widget's surface - pango_cairo_update_context(context, pcontext); - PLATFORM_ASSERT(pcontext); - layout = pango_layout_new(pcontext); - PLATFORM_ASSERT(layout); - if (height > 0 && width > 0) - psurf = CreateSimilarSurface( - WindowFromWidget(PWidget(wid)), - CAIRO_CONTENT_COLOR_ALPHA, width, height); - cairo_destroy(context); - context = cairo_create(psurf); - cairo_rectangle(context, 0, 0, width, height); - cairo_set_source_rgb(context, 1.0, 0, 0); - cairo_fill(context); - // This produces sharp drawing more similar to GDK: - //cairo_set_antialias(context, CAIRO_ANTIALIAS_NONE); - cairo_set_line_width(context, 1); - createdGC = true; - inited = true; - et = surfImpl->et; +std::unique_ptr SurfaceImpl::AllocatePixMap(int width, int height) { + // widSave must be alive now so safe for creating a PangoContext + return std::make_unique(context, width, height, mode, widSave); } -void SurfaceImpl::PenColour(ColourDesired fore) { - if (context) { - const ColourDesired cdFore(fore.AsInteger()); - cairo_set_source_rgb(context, - cdFore.GetRed() / 255.0, - cdFore.GetGreen() / 255.0, - cdFore.GetBlue() / 255.0); +void SurfaceImpl::SetMode(SurfaceMode mode_) { + mode = mode_; + if (mode.codePage == SC_CP_UTF8) { + et = EncodingType::utf8; + } else if (mode.codePage) { + et = EncodingType::dbcs; + } else { + et = EncodingType::singleByte; + } +} + +int SurfaceImpl::SupportsFeature(Supports feature) noexcept { + for (const Supports f : SupportsGTK) { + if (f == feature) + return 1; } + return 0; } int SurfaceImpl::LogPixelsY() { return 72; } +int SurfaceImpl::PixelDivisions() { + // GTK uses device pixels. + return 1; +} + int SurfaceImpl::DeviceHeightFont(int points) { const int logPix = LogPixelsY(); return (points * logPix + logPix / 2) / 72; } -void SurfaceImpl::MoveTo(int x_, int y_) { - x = x_; - y = y_; -} - -static int Delta(int difference) noexcept { - if (difference < 0) - return -1; - else if (difference > 0) - return 1; - else - return 0; +void SurfaceImpl::LineDraw(Point start, Point end, Stroke stroke) { + PLATFORM_ASSERT(context); + if (!context) + return; + PenColourAlpha(stroke.colour); + cairo_set_line_width(context, stroke.width); + cairo_move_to(context, start.x, start.y); + cairo_line_to(context, end.x, end.y); + cairo_stroke(context); } -void SurfaceImpl::LineTo(int x_, int y_) { - // cairo_line_to draws the end position, unlike Win32 or GDK with GDK_CAP_NOT_LAST. - // For simple cases, move back one pixel from end. - if (context) { - const int xDiff = x_ - x; - const int xDelta = Delta(xDiff); - const int yDiff = y_ - y; - const int yDelta = Delta(yDiff); - if ((xDiff == 0) || (yDiff == 0)) { - // Horizontal or vertical lines can be more precisely drawn as a filled rectangle - const int xEnd = x_ - xDelta; - const int left = std::min(x, xEnd); - const int width = std::abs(x - xEnd) + 1; - const int yEnd = y_ - yDelta; - const int top = std::min(y, yEnd); - const int height = std::abs(y - yEnd) + 1; - cairo_rectangle(context, left, top, width, height); - cairo_fill(context); - } else if ((std::abs(xDiff) == std::abs(yDiff))) { - // 45 degree slope - cairo_move_to(context, x + 0.5, y + 0.5); - cairo_line_to(context, x_ + 0.5 - xDelta, y_ + 0.5 - yDelta); - } else { - // Line has a different slope so difficult to avoid last pixel - cairo_move_to(context, x + 0.5, y + 0.5); - cairo_line_to(context, x_ + 0.5, y_ + 0.5); - } - cairo_stroke(context); +void SurfaceImpl::PolyLine(const Point *pts, size_t npts, Stroke stroke) { + // TODO: set line joins and caps + PLATFORM_ASSERT(context && npts > 1); + if (!context) + return; + PenColourAlpha(stroke.colour); + cairo_set_line_width(context, stroke.width); + cairo_move_to(context, pts[0].x, pts[0].y); + for (size_t i = 1; i < npts; i++) { + cairo_line_to(context, pts[i].x, pts[i].y); } - x = x_; - y = y_; + cairo_stroke(context); } -void SurfaceImpl::Polygon(Point *pts, size_t npts, ColourDesired fore, - ColourDesired back) { +void SurfaceImpl::Polygon(const Point *pts, size_t npts, FillStroke fillStroke) { PLATFORM_ASSERT(context); - PenColour(back); - cairo_move_to(context, pts[0].x + 0.5, pts[0].y + 0.5); + PenColourAlpha(fillStroke.fill.colour); + cairo_move_to(context, pts[0].x, pts[0].y); for (size_t i = 1; i < npts; i++) { - cairo_line_to(context, pts[i].x + 0.5, pts[i].y + 0.5); + cairo_line_to(context, pts[i].x, pts[i].y); } cairo_close_path(context); cairo_fill_preserve(context); - PenColour(fore); + PenColourAlpha(fillStroke.stroke.colour); + cairo_set_line_width(context, fillStroke.stroke.width); cairo_stroke(context); } -void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { +void SurfaceImpl::RectangleDraw(PRectangle rc, FillStroke fillStroke) { if (context) { - cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, - rc.Width() - 1, rc.Height() - 1); - PenColour(back); + CairoRectangle(rc.Inset(fillStroke.stroke.width / 2)); + PenColourAlpha(fillStroke.fill.colour); cairo_fill_preserve(context); - PenColour(fore); + PenColourAlpha(fillStroke.stroke.colour); + cairo_set_line_width(context, fillStroke.stroke.width); + cairo_stroke(context); + } +} + +void SurfaceImpl::RectangleFrame(PRectangle rc, Stroke stroke) { + if (context) { + CairoRectangle(rc.Inset(stroke.width / 2)); + PenColourAlpha(stroke.colour); + cairo_set_line_width(context, stroke.width); cairo_stroke(context); } } -void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { - PenColour(back); +void SurfaceImpl::FillRectangle(PRectangle rc, Fill fill) { + PenColourAlpha(fill.colour); if (context && (rc.left < maxCoordinate)) { // Protect against out of range - rc.left = Sci::round(rc.left); - rc.right = Sci::round(rc.right); - cairo_rectangle(context, rc.left, rc.top, rc.Width(), rc.Height()); + CairoRectangle(rc); cairo_fill(context); } } +void SurfaceImpl::FillRectangleAligned(PRectangle rc, Fill fill) { + FillRectangle(PixelAlign(rc, 1), fill); +} + void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { SurfaceImpl &surfi = dynamic_cast(surfacePattern); if (context && surfi.psurf) { @@ -488,28 +525,26 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { } } -void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) { +void SurfaceImpl::RoundedRectangle(PRectangle rc, FillStroke fillStroke) { if (((rc.right - rc.left) > 4) && ((rc.bottom - rc.top) > 4)) { // Approximate a round rect with some cut off corners Point pts[] = { - Point(rc.left + 2, rc.top), - Point(rc.right - 2, rc.top), - Point(rc.right, rc.top + 2), - Point(rc.right, rc.bottom - 2), - Point(rc.right - 2, rc.bottom), - Point(rc.left + 2, rc.bottom), - Point(rc.left, rc.bottom - 2), - Point(rc.left, rc.top + 2), - }; - Polygon(pts, Sci::size(pts), fore, back); + Point(rc.left + 2, rc.top), + Point(rc.right - 2, rc.top), + Point(rc.right, rc.top + 2), + Point(rc.right, rc.bottom - 2), + Point(rc.right - 2, rc.bottom), + Point(rc.left + 2, rc.bottom), + Point(rc.left, rc.bottom - 2), + Point(rc.left, rc.top + 2), + }; + Polygon(pts, std::size(pts), fillStroke); } else { - RectangleDraw(rc, fore, back); + RectangleDraw(rc, fillStroke); } } static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, double radius) noexcept { - constexpr double degrees = kPi / 180.0; - cairo_new_sub_path(context); cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees); cairo_arc(context, left + width - radius, top + height - radius, radius, 0 * degrees, 90 * degrees); @@ -518,31 +553,27 @@ static void PathRoundRectangle(cairo_t *context, double left, double top, double cairo_close_path(context); } -void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, - ColourDesired outline, int alphaOutline, int /*flags*/) { +void SurfaceImpl::AlphaRectangle(PRectangle rc, XYPOSITION cornerSize, FillStroke fillStroke) { if (context && rc.Width() > 0) { - const ColourDesired cdFill(fill.AsInteger()); - cairo_set_source_rgba(context, - cdFill.GetRed() / 255.0, - cdFill.GetGreen() / 255.0, - cdFill.GetBlue() / 255.0, - alphaFill / 255.0); + const float halfStroke = fillStroke.stroke.width / 2.0f; + const float doubleStroke = fillStroke.stroke.width * 2.0f; + PenColourAlpha(fillStroke.fill.colour); if (cornerSize > 0) - PathRoundRectangle(context, rc.left + 1.0, rc.top + 1.0, rc.Width() - 2.0, rc.Height() - 2.0, cornerSize); + PathRoundRectangle(context, rc.left + fillStroke.stroke.width, rc.top + fillStroke.stroke.width, + rc.Width() - doubleStroke, rc.Height() - doubleStroke, cornerSize); else - cairo_rectangle(context, rc.left + 1.0, rc.top + 1.0, rc.Width() - 2.0, rc.Height() - 2.0); + cairo_rectangle(context, rc.left + fillStroke.stroke.width, rc.top + fillStroke.stroke.width, + rc.Width() - doubleStroke, rc.Height() - doubleStroke); cairo_fill(context); - const ColourDesired cdOutline(outline.AsInteger()); - cairo_set_source_rgba(context, - cdOutline.GetRed() / 255.0, - cdOutline.GetGreen() / 255.0, - cdOutline.GetBlue() / 255.0, - alphaOutline / 255.0); + PenColourAlpha(fillStroke.stroke.colour); if (cornerSize > 0) - PathRoundRectangle(context, rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1, cornerSize); + PathRoundRectangle(context, rc.left + halfStroke, rc.top + halfStroke, + rc.Width() - fillStroke.stroke.width, rc.Height() - fillStroke.stroke.width, cornerSize); else - cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1); + cairo_rectangle(context, rc.left + halfStroke, rc.top + halfStroke, + rc.Width() - fillStroke.stroke.width, rc.Height() - fillStroke.stroke.width); + cairo_set_line_width(context, fillStroke.stroke.width); cairo_stroke(context); } } @@ -561,10 +592,10 @@ void SurfaceImpl::GradientRectangle(PRectangle rc, const std::vector } for (const ColourStop &stop : stops) { cairo_pattern_add_color_stop_rgba(pattern, stop.position, - stop.colour.GetRedComponent(), - stop.colour.GetGreenComponent(), - stop.colour.GetBlueComponent(), - stop.colour.GetAlphaComponent()); + stop.colour.GetRedComponent(), + stop.colour.GetGreenComponent(), + stop.colour.GetBlueComponent(), + stop.colour.GetAlphaComponent()); } cairo_rectangle(context, rc.left, rc.top, rc.Width(), rc.Height()); cairo_set_source(context, pattern); @@ -599,13 +630,72 @@ void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsi cairo_surface_destroy(psurfImage); } -void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) { +void SurfaceImpl::Ellipse(PRectangle rc, FillStroke fillStroke) { PLATFORM_ASSERT(context); - PenColour(back); + PenColourAlpha(fillStroke.fill.colour); cairo_arc(context, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2, - std::min(rc.Width(), rc.Height()) / 2, 0, 2*kPi); + (std::min(rc.Width(), rc.Height()) - fillStroke.stroke.width) / 2, 0, 2*kPi); + cairo_fill_preserve(context); + PenColourAlpha(fillStroke.stroke.colour); + cairo_set_line_width(context, fillStroke.stroke.width); + cairo_stroke(context); +} + +void SurfaceImpl::Stadium(PRectangle rc, FillStroke fillStroke, Ends ends) { + const XYPOSITION midLine = rc.Centre().y; + const XYPOSITION halfStroke = fillStroke.stroke.width / 2.0f; + const XYPOSITION radius = rc.Height() / 2.0f - halfStroke; + PRectangle rcInner = rc; + rcInner.left += radius; + rcInner.right -= radius; + + cairo_new_sub_path(context); + + const Ends leftSide = static_cast(static_cast(ends) & 0xf); + const Ends rightSide = static_cast(static_cast(ends) & 0xf0); + switch (leftSide) { + case Ends::leftFlat: + cairo_move_to(context, rc.left + halfStroke, rc.top + halfStroke); + cairo_line_to(context, rc.left + halfStroke, rc.bottom - halfStroke); + break; + case Ends::leftAngle: + cairo_move_to(context, rcInner.left + halfStroke, rc.top + halfStroke); + cairo_line_to(context, rc.left + halfStroke, rc.Centre().y); + cairo_line_to(context, rcInner.left + halfStroke, rc.bottom - halfStroke); + break; + case Ends::semiCircles: + default: + cairo_move_to(context, rcInner.left + halfStroke, rc.top + halfStroke); + cairo_arc_negative(context, rcInner.left + halfStroke, midLine, radius, + 270 * degrees, 90 * degrees); + break; + } + + switch (rightSide) { + case Ends::rightFlat: + cairo_line_to(context, rc.right - halfStroke, rc.bottom - halfStroke); + cairo_line_to(context, rc.right - halfStroke, rc.top + halfStroke); + break; + case Ends::rightAngle: + cairo_line_to(context, rcInner.right - halfStroke, rc.bottom - halfStroke); + cairo_line_to(context, rc.right - halfStroke, rc.Centre().y); + cairo_line_to(context, rcInner.right - halfStroke, rc.top + halfStroke); + break; + case Ends::semiCircles: + default: + cairo_line_to(context, rcInner.right - halfStroke, rc.bottom - halfStroke); + cairo_arc_negative(context, rcInner.right - halfStroke, midLine, radius, + 90 * degrees, 270 * degrees); + break; + } + + // Close the path to enclose it for stroking and for filling, then draw it + cairo_close_path(context); + PenColourAlpha(fillStroke.fill.colour); cairo_fill_preserve(context); - PenColour(fore); + + PenColourAlpha(fillStroke.stroke.colour); + cairo_set_line_width(context, fillStroke.stroke.width); cairo_stroke(context); } @@ -615,17 +705,21 @@ void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) { if (canDraw) { PLATFORM_ASSERT(context); cairo_set_source_surface(context, surfi.psurf, - rc.left - from.x, rc.top - from.y); + rc.left - from.x, rc.top - from.y); cairo_rectangle(context, rc.left, rc.top, rc.Width(), rc.Height()); cairo_fill(context); } } -std::string UTF8FromLatin1(const char *s, int len) { - std::string utfForm(len*2 + 1, '\0'); +std::unique_ptr SurfaceImpl::Layout(const IScreenLine *) { + return {}; +} + +std::string UTF8FromLatin1(std::string_view text) { + std::string utfForm(text.length()*2 + 1, '\0'); size_t lenU = 0; - for (int i=0; i(s[i]); + for (const char ch : text) { + const unsigned char uch = ch; if (uch < 0x80) { utfForm[lenU++] = uch; } else { @@ -639,14 +733,14 @@ std::string UTF8FromLatin1(const char *s, int len) { namespace { -std::string UTF8FromIconv(const Converter &conv, const char *s, int len) { +std::string UTF8FromIconv(const Converter &conv, std::string_view text) { if (conv) { - std::string utfForm(len*3+1, '\0'); - char *pin = const_cast(s); - gsize inLeft = len; + std::string utfForm(text.length()*3+1, '\0'); + char *pin = const_cast(text.data()); + gsize inLeft = text.length(); char *putf = &utfForm[0]; char *pout = putf; - gsize outLeft = len*3+1; + gsize outLeft = text.length()*3+1; const gsize conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); if (conversions != sizeFailure) { *pout = '\0'; @@ -676,20 +770,20 @@ size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t len) n } -void SurfaceImpl::DrawTextBase(PRectangle rc, const Font &font_, XYPOSITION ybase, const char *s, int len, - ColourDesired fore) { - PenColour(fore); +void SurfaceImpl::DrawTextBase(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourRGBA fore) { if (context) { + PenColourAlpha(fore); const XYPOSITION xText = rc.left; if (PFont(font_)->pfd) { std::string utfForm; - if (et == UTF8) { - pango_layout_set_text(layout, s, len); + if (et == EncodingType::utf8) { + pango_layout_set_text(layout, text.data(), text.length()); } else { SetConverter(PFont(font_)->characterSet); - utfForm = UTF8FromIconv(conv, s, len); + utfForm = UTF8FromIconv(conv, text); if (utfForm.empty()) { // iconv failed so treat as Latin1 - utfForm = UTF8FromLatin1(s, len); + utfForm = UTF8FromLatin1(text); } pango_layout_set_text(layout, utfForm.c_str(), utfForm.length()); } @@ -702,25 +796,25 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, const Font &font_, XYPOSITION ybas } } -void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, - ColourDesired fore, ColourDesired back) { - FillRectangle(rc, back); - DrawTextBase(rc, font_, ybase, s, len, fore); +void SurfaceImpl::DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourRGBA fore, ColourRGBA back) { + FillRectangleAligned(rc, back); + DrawTextBase(rc, font_, ybase, text, fore); } // On GTK+, exactly same as DrawTextNoClip -void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, - ColourDesired fore, ColourDesired back) { - FillRectangle(rc, back); - DrawTextBase(rc, font_, ybase, s, len, fore); +void SurfaceImpl::DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourRGBA fore, ColourRGBA back) { + FillRectangleAligned(rc, back); + DrawTextBase(rc, font_, ybase, text, fore); } -void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, - ColourDesired fore) { +void SurfaceImpl::DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourRGBA fore) { // Avoid drawing spaces in transparent mode - for (int i=0; ipfd) { - pango_layout_set_font_description(layout, PFont(font_)->pfd); - if (et == UTF8) { - // Simple and direct as UTF-8 is native Pango encoding - int i = 0; - pango_layout_set_text(layout, s, len); - ClusterIterator iti(layout, lenPositions); - while (!iti.finished) { - iti.Next(); - const int places = iti.curIndex - i; - while (i < iti.curIndex) { - // Evenly distribute space among bytes of this cluster. - // Would be better to find number of characters and then - // divide evenly between characters with each byte of a character - // being at the same position. - positions[i] = iti.position - (iti.curIndex - 1 - i) * iti.distance / places; - i++; - } - } - PLATFORM_ASSERT(i == lenPositions); - } else { - int positionsCalculated = 0; - if (et == dbcs) { - SetConverter(PFont(font_)->characterSet); - std::string utfForm = UTF8FromIconv(conv, s, len); - if (!utfForm.empty()) { - // Convert to UTF-8 so can ask Pango for widths, then - // Loop through UTF-8 and DBCS forms, taking account of different - // character byte lengths. - Converter convMeasure("UCS-2", CharacterSetID(characterSet), false); - pango_layout_set_text(layout, utfForm.c_str(), strlen(utfForm.c_str())); - int i = 0; - int clusterStart = 0; - ClusterIterator iti(layout, strlen(utfForm.c_str())); - while (!iti.finished) { - iti.Next(); - const int clusterEnd = iti.curIndex; - const int places = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart); - int place = 1; - while (clusterStart < clusterEnd) { - size_t lenChar = MultiByteLenFromIconv(convMeasure, s+i, len-i); - while (lenChar--) { - positions[i++] = iti.position - (places - place) * iti.distance / places; - positionsCalculated++; - } - clusterStart += UTF8BytesOfLead[static_cast(utfForm[clusterStart])]; - place++; - } - } - PLATFORM_ASSERT(i == lenPositions); - } +void SurfaceImpl::MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) { + if (PFont(font_)->pfd) { + pango_layout_set_font_description(layout, PFont(font_)->pfd); + if (et == EncodingType::utf8) { + // Simple and direct as UTF-8 is native Pango encoding + int i = 0; + pango_layout_set_text(layout, text.data(), text.length()); + ClusterIterator iti(layout, text.length()); + while (!iti.finished) { + iti.Next(); + const int places = iti.curIndex - i; + while (i < iti.curIndex) { + // Evenly distribute space among bytes of this cluster. + // Would be better to find number of characters and then + // divide evenly between characters with each byte of a character + // being at the same position. + positions[i] = iti.position - (iti.curIndex - 1 - i) * iti.distance / places; + i++; } - if (positionsCalculated < 1) { - // Either 8-bit or DBCS conversion failed so treat as 8-bit. - SetConverter(PFont(font_)->characterSet); - const bool rtlCheck = PFont(font_)->characterSet == SC_CHARSET_HEBREW || - PFont(font_)->characterSet == SC_CHARSET_ARABIC; - std::string utfForm = UTF8FromIconv(conv, s, len); - if (utfForm.empty()) { - utfForm = UTF8FromLatin1(s, len); - } - pango_layout_set_text(layout, utfForm.c_str(), utfForm.length()); + } + PLATFORM_ASSERT(static_cast(i) == text.length()); + } else { + int positionsCalculated = 0; + if (et == EncodingType::dbcs) { + SetConverter(PFont(font_)->characterSet); + std::string utfForm = UTF8FromIconv(conv, text); + if (!utfForm.empty()) { + // Convert to UTF-8 so can ask Pango for widths, then + // Loop through UTF-8 and DBCS forms, taking account of different + // character byte lengths. + Converter convMeasure("UCS-2", CharacterSetID(characterSet), false); + pango_layout_set_text(layout, utfForm.c_str(), strlen(utfForm.c_str())); int i = 0; int clusterStart = 0; - // Each 8-bit input character may take 1 or 2 bytes in UTF-8 - // and groups of up to 3 may be represented as ligatures. - ClusterIterator iti(layout, utfForm.length()); + ClusterIterator iti(layout, strlen(utfForm.c_str())); while (!iti.finished) { iti.Next(); const int clusterEnd = iti.curIndex; - const int ligatureLength = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart); - if (rtlCheck && ((clusterEnd <= clusterStart) || (ligatureLength == 0) || (ligatureLength > 3))) { - // Something has gone wrong: exit quickly but pretend all the characters are equally spaced: - int widthLayout = 0; - pango_layout_get_size(layout, &widthLayout, nullptr); - const XYPOSITION widthTotal = floatFromPangoUnits(widthLayout); - for (int bytePos=0; bytePos(utfForm[clusterStart])]; + place++; } - PLATFORM_ASSERT(ligatureLength > 0 && ligatureLength <= 3); - for (int charInLig=0; charInLig(i) == text.length()); + } + } + if (positionsCalculated < 1) { + const size_t lenPositions = text.length(); + // Either 8-bit or DBCS conversion failed so treat as 8-bit. + SetConverter(PFont(font_)->characterSet); + const bool rtlCheck = PFont(font_)->characterSet == CharacterSet::Hebrew || + PFont(font_)->characterSet == CharacterSet::Arabic; + std::string utfForm = UTF8FromIconv(conv, text); + if (utfForm.empty()) { + utfForm = UTF8FromLatin1(text); + } + pango_layout_set_text(layout, utfForm.c_str(), utfForm.length()); + size_t i = 0; + int clusterStart = 0; + // Each 8-bit input character may take 1 or 2 bytes in UTF-8 + // and groups of up to 3 may be represented as ligatures. + ClusterIterator iti(layout, utfForm.length()); + while (!iti.finished) { + iti.Next(); + const int clusterEnd = iti.curIndex; + const int ligatureLength = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart); + if (rtlCheck && ((clusterEnd <= clusterStart) || (ligatureLength == 0) || (ligatureLength > 3))) { + // Something has gone wrong: exit quickly but pretend all the characters are equally spaced: + int widthLayout = 0; + pango_layout_get_size(layout, &widthLayout, nullptr); + const XYPOSITION widthTotal = floatFromPangoUnits(widthLayout); + for (size_t bytePos=0; bytePos 0 && ligatureLength <= 3); + for (int charInLig=0; charInLigpfd) { + std::string utfForm; + pango_layout_set_font_description(layout, PFont(font_)->pfd); + if (et == EncodingType::utf8) { + pango_layout_set_text(layout, text.data(), text.length()); + } else { + SetConverter(PFont(font_)->characterSet); + utfForm = UTF8FromIconv(conv, text); + if (utfForm.empty()) { // iconv failed so treat as Latin1 + utfForm = UTF8FromLatin1(text); + } + pango_layout_set_text(layout, utfForm.c_str(), utfForm.length()); + } + PangoLayoutLine *pangoLine = pango_layout_get_line_readonly(layout, 0); + PangoRectangle pos {}; + pango_layout_line_get_extents(pangoLine, nullptr, &pos); + return floatFromPangoUnits(pos.width); + } + return 1; +} + +void SurfaceImpl::DrawTextBaseUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourRGBA fore) { + if (context) { + PenColourAlpha(fore); + const XYPOSITION xText = rc.left; if (PFont(font_)->pfd) { - std::string utfForm; + pango_layout_set_text(layout, text.data(), text.length()); pango_layout_set_font_description(layout, PFont(font_)->pfd); - if (et == UTF8) { - pango_layout_set_text(layout, s, len); - } else { - SetConverter(PFont(font_)->characterSet); - utfForm = UTF8FromIconv(conv, s, len); - if (utfForm.empty()) { // iconv failed so treat as Latin1 - utfForm = UTF8FromLatin1(s, len); - } - pango_layout_set_text(layout, utfForm.c_str(), utfForm.length()); + pango_cairo_update_layout(context, layout); + PangoLayoutLine *pll = pango_layout_get_line_readonly(layout, 0); + cairo_move_to(context, xText, ybase); + pango_cairo_show_layout_line(context, pll); + } + } +} + +void SurfaceImpl::DrawTextNoClipUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourRGBA fore, ColourRGBA back) { + FillRectangleAligned(rc, back); + DrawTextBaseUTF8(rc, font_, ybase, text, fore); +} + +// On GTK+, exactly same as DrawTextNoClip +void SurfaceImpl::DrawTextClippedUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourRGBA fore, ColourRGBA back) { + FillRectangleAligned(rc, back); + DrawTextBaseUTF8(rc, font_, ybase, text, fore); +} + +void SurfaceImpl::DrawTextTransparentUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, + ColourRGBA fore) { + // Avoid drawing spaces in transparent mode + for (size_t i = 0; i < text.length(); i++) { + if (text[i] != ' ') { + DrawTextBaseUTF8(rc, font_, ybase, text, fore); + return; + } + } +} + +void SurfaceImpl::MeasureWidthsUTF8(const Font *font_, std::string_view text, XYPOSITION *positions) { + if (PFont(font_)->pfd) { + pango_layout_set_font_description(layout, PFont(font_)->pfd); + // Simple and direct as UTF-8 is native Pango encoding + int i = 0; + pango_layout_set_text(layout, text.data(), text.length()); + ClusterIterator iti(layout, text.length()); + while (!iti.finished) { + iti.Next(); + const int places = iti.curIndex - i; + while (i < iti.curIndex) { + // Evenly distribute space among bytes of this cluster. + // Would be better to find number of characters and then + // divide evenly between characters with each byte of a character + // being at the same position. + positions[i] = iti.position - (iti.curIndex - 1 - i) * iti.distance / places; + i++; } - PangoLayoutLine *pangoLine = pango_layout_get_line_readonly(layout, 0); - PangoRectangle pos {}; - pango_layout_line_get_extents(pangoLine, nullptr, &pos); - return floatFromPangoUnits(pos.width); } - return 1; + PLATFORM_ASSERT(static_cast(i) == text.length()); } else { - return 1; + // No font so return an ascending range of values + for (size_t i = 0; i < text.length(); i++) { + positions[i] = i + 1; + } + } +} + +XYPOSITION SurfaceImpl::WidthTextUTF8(const Font *font_, std::string_view text) { + if (PFont(font_)->pfd) { + pango_layout_set_font_description(layout, PFont(font_)->pfd); + pango_layout_set_text(layout, text.data(), text.length()); + PangoLayoutLine *pangoLine = pango_layout_get_line_readonly(layout, 0); + PangoRectangle pos{}; + pango_layout_line_get_extents(pangoLine, nullptr, &pos); + return floatFromPangoUnits(pos.width); } + return 1; } // Ascent and descent determined by Pango font metrics. -XYPOSITION SurfaceImpl::Ascent(Font &font_) { - if (!(font_.GetID())) - return 1; +XYPOSITION SurfaceImpl::Ascent(const Font *font_) { XYPOSITION ascent = 0; if (PFont(font_)->pfd) { PangoFontMetrics *metrics = pango_context_get_metrics(pcontext, - PFont(font_)->pfd, pango_context_get_language(pcontext)); - ascent = Sci::round(floatFromPangoUnits( - pango_font_metrics_get_ascent(metrics))); + PFont(font_)->pfd, pango_context_get_language(pcontext)); + ascent = std::round(floatFromPangoUnits( + pango_font_metrics_get_ascent(metrics))); pango_font_metrics_unref(metrics); } if (ascent == 0) { @@ -917,57 +1083,54 @@ XYPOSITION SurfaceImpl::Ascent(Font &font_) { return ascent; } -XYPOSITION SurfaceImpl::Descent(Font &font_) { - if (!(font_.GetID())) - return 1; +XYPOSITION SurfaceImpl::Descent(const Font *font_) { if (PFont(font_)->pfd) { PangoFontMetrics *metrics = pango_context_get_metrics(pcontext, - PFont(font_)->pfd, pango_context_get_language(pcontext)); - const XYPOSITION descent = Sci::round(floatFromPangoUnits( - pango_font_metrics_get_descent(metrics))); + PFont(font_)->pfd, pango_context_get_language(pcontext)); + const XYPOSITION descent = std::round(floatFromPangoUnits( + pango_font_metrics_get_descent(metrics))); pango_font_metrics_unref(metrics); return descent; } return 0; } -XYPOSITION SurfaceImpl::InternalLeading(Font &) { +XYPOSITION SurfaceImpl::InternalLeading(const Font *) { return 0; } -XYPOSITION SurfaceImpl::Height(Font &font_) { +XYPOSITION SurfaceImpl::Height(const Font *font_) { return Ascent(font_) + Descent(font_); } -XYPOSITION SurfaceImpl::AverageCharWidth(Font &font_) { - return WidthText(font_, "n", 1); +XYPOSITION SurfaceImpl::AverageCharWidth(const Font *font_) { + return WidthText(font_, "n"); } void SurfaceImpl::SetClip(PRectangle rc) { PLATFORM_ASSERT(context); - cairo_rectangle(context, rc.left, rc.top, rc.Width(), rc.Height()); + cairo_save(context); + CairoRectangle(rc); cairo_clip(context); } -void SurfaceImpl::FlushCachedState() {} - -void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { - if (unicodeMode_) - et = UTF8; +void SurfaceImpl::PopClip() { + PLATFORM_ASSERT(context); + cairo_restore(context); } -void SurfaceImpl::SetDBCSMode(int codePage) { - if (codePage && (codePage != SC_CP_UTF8)) - et = dbcs; +void SurfaceImpl::FlushCachedState() {} + +void SurfaceImpl::FlushDrawing() { } -Surface *Surface::Allocate(int) { - return new SurfaceImpl(); +std::unique_ptr Surface::Allocate(Technology) { + return std::make_unique(); } -Window::~Window() {} +Window::~Window() noexcept {} -void Window::Destroy() { +void Window::Destroy() noexcept { if (wid) { ListBox *listbox = dynamic_cast(this); if (listbox) { @@ -1001,7 +1164,7 @@ PRectangle Window::GetPosition() const { } void Window::SetPosition(PRectangle rc) { - GtkAllocation alloc; + GtkAllocation alloc {}; alloc.x = static_cast(rc.left); alloc.y = static_cast(rc.top); alloc.width = static_cast(rc.Width()); @@ -1076,15 +1239,11 @@ void Window::InvalidateRectangle(PRectangle rc) { if (wid) { const IntegerRectangle irc(rc); gtk_widget_queue_draw_area(PWidget(wid), - irc.left, irc.top, - irc.Width(), irc.Height()); + irc.left, irc.top, + irc.Width(), irc.Height()); } } -void Window::SetFont(Font &) { - // Can not be done generically but only needed for ListBox -} - void Window::SetCursor(Cursor curs) { // We don't set the cursor to same value numerous times under gtk because // it stores the cursor in the window once it's set @@ -1096,27 +1255,27 @@ void Window::SetCursor(Cursor curs) { GdkCursor *gdkCurs; switch (curs) { - case cursorText: + case Cursor::text: gdkCurs = gdk_cursor_new_for_display(pdisplay, GDK_XTERM); break; - case cursorArrow: + case Cursor::arrow: gdkCurs = gdk_cursor_new_for_display(pdisplay, GDK_LEFT_PTR); break; - case cursorUp: + case Cursor::up: gdkCurs = gdk_cursor_new_for_display(pdisplay, GDK_CENTER_PTR); break; - case cursorWait: + case Cursor::wait: gdkCurs = gdk_cursor_new_for_display(pdisplay, GDK_WATCH); break; - case cursorHand: + case Cursor::hand: gdkCurs = gdk_cursor_new_for_display(pdisplay, GDK_HAND2); break; - case cursorReverseArrow: + case Cursor::reverseArrow: gdkCurs = gdk_cursor_new_for_display(pdisplay, GDK_RIGHT_PTR); break; default: gdkCurs = gdk_cursor_new_for_display(pdisplay, GDK_LEFT_PTR); - cursorLast = cursorArrow; + cursorLast = Cursor::arrow; break; } @@ -1141,12 +1300,12 @@ PRectangle Window::GetMonitorRect(Point pt) { #if GTK_CHECK_VERSION(3,22,0) GdkDisplay *pdisplay = gtk_widget_get_display(PWidget(wid)); GdkMonitor *monitor = gdk_display_get_monitor_at_point(pdisplay, - pt.x + x_offset, pt.y + y_offset); + pt.x + x_offset, pt.y + y_offset); gdk_monitor_get_geometry(monitor, &rect); #else GdkScreen *screen = gtk_widget_get_screen(PWidget(wid)); const gint monitor_num = gdk_screen_get_monitor_at_point(screen, - pt.x + x_offset, pt.y + y_offset); + pt.x + x_offset, pt.y + y_offset); gdk_screen_get_monitor_geometry(screen, monitor_num, &rect); #endif rect.x -= x_offset; @@ -1171,7 +1330,7 @@ static void list_image_free(gpointer, gpointer value, gpointer) noexcept { ListBox::ListBox() noexcept { } -ListBox::~ListBox() { +ListBox::~ListBox() noexcept { } enum { @@ -1213,7 +1372,7 @@ class ListBoxX : public ListBox { ListBoxX(ListBoxX&&) = delete; ListBoxX&operator=(const ListBoxX&) = delete; ListBoxX&operator=(ListBoxX&&) = delete; - ~ListBoxX() override { + ~ListBoxX() noexcept override { if (pixhash) { g_hash_table_foreach((GHashTable *) pixhash, list_image_free, nullptr); g_hash_table_destroy((GHashTable *) pixhash); @@ -1229,32 +1388,32 @@ class ListBoxX : public ListBox { } #endif } - void SetFont(Font &font) override; - void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_, int technology_) override; + void SetFont(const Font *font) override; + void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_, Technology technology_) override; void SetAverageCharWidth(int width) override; void SetVisibleRows(int rows) override; int GetVisibleRows() const override; int GetRowHeight(); PRectangle GetDesiredRect() override; int CaretFromEdge() override; - void Clear() override; + void Clear() noexcept override; void Append(char *s, int type = -1) override; int Length() override; void Select(int n) override; int GetSelection() override; int Find(const char *prefix) override; - void GetValue(int n, char *value, int len) override; - void RegisterRGBA(int type, RGBAImage *image); + std::string GetValue(int n) override; + void RegisterRGBA(int type, std::unique_ptr image); void RegisterImage(int type, const char *xpm_data) override; void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) override; void ClearRegisteredImages() override; void SetDelegate(IListBoxDelegate *lbDelegate) override; void SetList(const char *listText, char separator, char typesep) override; + void SetOptions(ListOptions options_) override; }; -ListBox *ListBox::Allocate() { - ListBoxX *lb = new ListBoxX(); - return lb; +std::unique_ptr ListBox::Allocate() { + return std::make_unique(); } static int treeViewGetRowHeight(GtkTreeView *view) { @@ -1273,8 +1432,8 @@ static int treeViewGetRowHeight(GtkTreeView *view) { GtkTreeViewColumn *column = gtk_tree_view_get_column(view, 0); gtk_tree_view_column_cell_get_size(column, nullptr, nullptr, nullptr, nullptr, &row_height); gtk_widget_style_get(GTK_WIDGET(view), - "vertical-separator", &vertical_separator, - "expander-size", &expander_size, nullptr); + "vertical-separator", &vertical_separator, + "expander-size", &expander_size, nullptr); row_height += vertical_separator; row_height = std::max(row_height, expander_size); return row_height; @@ -1415,7 +1574,7 @@ static void StyleSet(GtkWidget *w, GtkStyle *, void *) { #endif } -void ListBoxX::Create(Window &parent, int, Point, int, bool, int) { +void ListBoxX::Create(Window &parent, int, Point, int, bool, Technology) { if (widCached != nullptr) { wid = widCached; return; @@ -1438,7 +1597,7 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, int) { scroller = g_object_new(small_scroller_get_type(), nullptr); gtk_container_set_border_width(GTK_CONTAINER(scroller), 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(frame), PWidget(scroller)); gtk_widget_show(PWidget(scroller)); @@ -1453,7 +1612,7 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, int) { GtkStyleContext *styleContext = gtk_widget_get_style_context(GTK_WIDGET(list)); if (styleContext) { gtk_style_context_add_provider(styleContext, GTK_STYLE_PROVIDER(cssProvider), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } #endif @@ -1472,13 +1631,13 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, int) { gtk_cell_renderer_set_fixed_size(pixbuf_renderer, 0, -1); gtk_tree_view_column_pack_start(column, pixbuf_renderer, FALSE); gtk_tree_view_column_add_attribute(column, pixbuf_renderer, - "pixbuf", PIXBUF_COLUMN); + "pixbuf", PIXBUF_COLUMN); renderer = gtk_cell_renderer_text_new(); gtk_cell_renderer_text_set_fixed_height_from_font(GTK_CELL_RENDERER_TEXT(renderer), 1); gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_add_attribute(column, renderer, - "text", TEXT_COLUMN); + "text", TEXT_COLUMN); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); if (g_object_class_find_property(G_OBJECT_GET_CLASS(list), "fixed-height-mode")) @@ -1488,16 +1647,16 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, int) { gtk_container_add(GTK_CONTAINER(PWidget(scroller)), widget); gtk_widget_show(widget); g_signal_connect(G_OBJECT(widget), "button_press_event", - G_CALLBACK(ButtonPress), this); + G_CALLBACK(ButtonPress), this); g_signal_connect(G_OBJECT(widget), "button_release_event", - G_CALLBACK(ButtonRelease), this); + G_CALLBACK(ButtonRelease), this); GtkWidget *top = gtk_widget_get_toplevel(static_cast(parent.GetID())); gtk_window_set_transient_for(GTK_WINDOW(static_cast(wid)), - GTK_WINDOW(top)); + GTK_WINDOW(top)); } -void ListBoxX::SetFont(Font &font) { +void ListBoxX::SetFont(const Font *font) { // Only do for Pango font as there have been crashes for GDK fonts if (Created() && PFont(font)->pfd) { // Current font is Pango font @@ -1513,7 +1672,7 @@ void ListBoxX::SetFont(Font &font) { // need to use the "px" unit. Normally we only get fonts in points here, so // don't bother to handle the case the font is actually in pixels on < 3.21.0. if (gtk_check_version(3, 21, 0) != nullptr || // on < 3.21.0 - pango_font_description_get_size_is_absolute(pfd)) { + pango_font_description_get_size_is_absolute(pfd)) { ssFontSetting << "px; "; } else { ssFontSetting << "pt; "; @@ -1521,7 +1680,7 @@ void ListBoxX::SetFont(Font &font) { ssFontSetting << "font-weight:"<< pango_font_description_get_weight(pfd) << "; "; ssFontSetting << "}"; gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(cssProvider), - ssFontSetting.str().c_str(), -1, nullptr); + ssFontSetting.str().c_str(), -1, nullptr); } #else gtk_widget_modify_font(PWidget(list), PFont(font)->pfd); @@ -1597,14 +1756,14 @@ PRectangle ListBoxX::GetDesiredRect() { # endif height = (rows * row_height - + padding.top + padding.bottom - + border.top + border.bottom - + border_border.top + border_border.bottom - + 2 * gtk_container_get_border_width(GTK_CONTAINER(PWidget(list)))); + + padding.top + padding.bottom + + border.top + border.bottom + + border_border.top + border_border.bottom + + 2 * gtk_container_get_border_width(GTK_CONTAINER(PWidget(list)))); #else height = (rows * row_height - + 2 * (PWidget(frame)->style->ythickness - + GTK_CONTAINER(PWidget(list))->border_width)); + + 2 * (PWidget(frame)->style->ythickness + + GTK_CONTAINER(PWidget(list))->border_width)); #endif rc.bottom = height; @@ -1615,16 +1774,16 @@ PRectangle ListBoxX::GetDesiredRect() { // Add horizontal padding and borders int horizontal_separator=0; gtk_widget_style_get(PWidget(list), - "horizontal-separator", &horizontal_separator, nullptr); + "horizontal-separator", &horizontal_separator, nullptr); rc.right += horizontal_separator; #if GTK_CHECK_VERSION(3,0,0) rc.right += (padding.left + padding.right - + border.left + border.right - + border_border.left + border_border.right - + 2 * gtk_container_get_border_width(GTK_CONTAINER(PWidget(list)))); + + border.left + border.right + + border_border.left + border_border.right + + 2 * gtk_container_get_border_width(GTK_CONTAINER(PWidget(list)))); #else rc.right += 2 * (PWidget(frame)->style->xthickness - + GTK_CONTAINER(PWidget(list))->border_width); + + GTK_CONTAINER(PWidget(list))->border_width); #endif if (Length() > rows) { // Add the width of the scrollbar @@ -1644,31 +1803,31 @@ PRectangle ListBoxX::GetDesiredRect() { int ListBoxX::CaretFromEdge() { gint renderer_width, renderer_height; gtk_cell_renderer_get_fixed_size(pixbuf_renderer, &renderer_width, - &renderer_height); + &renderer_height); return 4 + renderer_width; } -void ListBoxX::Clear() { +void ListBoxX::Clear() noexcept { GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); gtk_list_store_clear(GTK_LIST_STORE(model)); maxItemCharacters = 0; } -static void init_pixmap(ListImage *list_image) { +static void init_pixmap(ListImage *list_image) noexcept { if (list_image->rgba_data) { // Drop any existing pixmap/bitmap as data may have changed if (list_image->pixbuf) g_object_unref(list_image->pixbuf); list_image->pixbuf = gdk_pixbuf_new_from_data(list_image->rgba_data->Pixels(), - GDK_COLORSPACE_RGB, - TRUE, - 8, - list_image->rgba_data->GetWidth(), - list_image->rgba_data->GetHeight(), - list_image->rgba_data->GetWidth() * 4, - nullptr, - nullptr); + GDK_COLORSPACE_RGB, + TRUE, + 8, + list_image->rgba_data->GetWidth(), + list_image->rgba_data->GetHeight(), + list_image->rgba_data->GetWidth() * 4, + nullptr, + nullptr); } } @@ -1689,23 +1848,23 @@ void ListBoxX::Append(char *s, int type) { init_pixmap(list_image); if (list_image->pixbuf) { gtk_list_store_set(GTK_LIST_STORE(store), &iter, - PIXBUF_COLUMN, list_image->pixbuf, - TEXT_COLUMN, s, -1); + PIXBUF_COLUMN, list_image->pixbuf, + TEXT_COLUMN, s, -1); const gint pixbuf_width = gdk_pixbuf_get_width(list_image->pixbuf); gint renderer_height, renderer_width; gtk_cell_renderer_get_fixed_size(pixbuf_renderer, - &renderer_width, &renderer_height); + &renderer_width, &renderer_height); if (pixbuf_width > renderer_width) gtk_cell_renderer_set_fixed_size(pixbuf_renderer, - pixbuf_width, -1); + pixbuf_width, -1); } else { gtk_list_store_set(GTK_LIST_STORE(store), &iter, - TEXT_COLUMN, s, -1); + TEXT_COLUMN, s, -1); } } else { - gtk_list_store_set(GTK_LIST_STORE(store), &iter, - TEXT_COLUMN, s, -1); + gtk_list_store_set(GTK_LIST_STORE(store), &iter, + TEXT_COLUMN, s, -1); } const size_t len = strlen(s); if (maxItemCharacters < len) @@ -1715,7 +1874,7 @@ void ListBoxX::Append(char *s, int type) { int ListBoxX::Length() { if (wid) return gtk_tree_model_iter_n_children(gtk_tree_view_get_model - (GTK_TREE_VIEW(list)), nullptr); + (GTK_TREE_VIEW(list)), nullptr); return 0; } @@ -1744,7 +1903,7 @@ void ListBoxX::Select(int n) { gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list)); #endif gfloat value = (static_cast(n) / total) * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj)) - + gtk_adjustment_get_lower(adj) - gtk_adjustment_get_page_size(adj) / 2; + + gtk_adjustment_get_lower(adj) - gtk_adjustment_get_page_size(adj) / 2; // Get cell height const int row_height = GetRowHeight(); @@ -1759,7 +1918,7 @@ void ListBoxX::Select(int n) { // Clamp it. value = (value < 0)? 0 : value; value = (value > (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)))? - (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)) : value; + (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)) : value; // Set it. gtk_adjustment_set_value(adj, value); @@ -1810,7 +1969,7 @@ int ListBoxX::Find(const char *prefix) { return -1; } -void ListBoxX::GetValue(int n, char *value, int len) { +std::string ListBoxX::GetValue(int n) { char *text = nullptr; GtkTreeIter iter {}; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); @@ -1818,12 +1977,12 @@ void ListBoxX::GetValue(int n, char *value, int len) { if (valid) { gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1); } - if (text && len > 0) { - g_strlcpy(value, text, len); - } else { - value[0] = '\0'; + std::string value; + if (text) { + value = text; } g_free(text); + return value; } // g_return_if_fail causes unnecessary compiler warning in release compile. @@ -1831,8 +1990,9 @@ void ListBoxX::GetValue(int n, char *value, int len) { #pragma warning(disable: 4127) #endif -void ListBoxX::RegisterRGBA(int type, RGBAImage *image) { - images.Add(type, image); +void ListBoxX::RegisterRGBA(int type, std::unique_ptr image) { + images.AddImage(type, std::move(image)); + const RGBAImage * const observe = images.Get(type); if (!pixhash) { pixhash = g_hash_table_new(g_direct_hash, g_direct_equal); @@ -1844,23 +2004,23 @@ void ListBoxX::RegisterRGBA(int type, RGBAImage *image) { if (list_image->pixbuf) g_object_unref(list_image->pixbuf); list_image->pixbuf = nullptr; - list_image->rgba_data = image; + list_image->rgba_data = observe; } else { list_image = g_new0(ListImage, 1); - list_image->rgba_data = image; + list_image->rgba_data = observe; g_hash_table_insert((GHashTable *) pixhash, GINT_TO_POINTER(type), - (gpointer) list_image); + (gpointer) list_image); } } void ListBoxX::RegisterImage(int type, const char *xpm_data) { g_return_if_fail(xpm_data); XPM xpmImage(xpm_data); - RegisterRGBA(type, new RGBAImage(xpmImage)); + RegisterRGBA(type, std::make_unique(xpmImage)); } void ListBoxX::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) { - RegisterRGBA(type, new RGBAImage(width, height, 1.0, pixelsImage)); + RegisterRGBA(type, std::make_unique(width, height, 1.0f, pixelsImage)); } void ListBoxX::ClearRegisteredImages() { @@ -1897,6 +2057,9 @@ void ListBoxX::SetList(const char *listText, char separator, char typesep) { } } +void ListBoxX::SetOptions(ListOptions) { +} + Menu::Menu() noexcept : mid(nullptr) {} void Menu::CreatePopUp() { @@ -1905,7 +2068,7 @@ void Menu::CreatePopUp() { g_object_ref_sink(G_OBJECT(mid)); } -void Menu::Destroy() { +void Menu::Destroy() noexcept { if (mid) g_object_unref(G_OBJECT(mid)); mid = nullptr; @@ -1919,7 +2082,7 @@ static void MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer u } #endif -void Menu::Show(Point pt, Window &w) { +void Menu::Show(Point pt, const Window &w) { GtkMenu *widget = static_cast(mid); gtk_widget_show_all(GTK_WIDGET(widget)); #if GTK_CHECK_VERSION(3,22,0) @@ -1940,57 +2103,17 @@ void Menu::Show(Point pt, Window &w) { pt.y = rcMonitor.y + rcMonitor.height - requisition.height; } gtk_menu_popup(widget, nullptr, nullptr, MenuPositionFunc, - GINT_TO_POINTER((static_cast(pt.y) << 16) | static_cast(pt.x)), 0, - gtk_get_current_event_time()); + GINT_TO_POINTER((static_cast(pt.y) << 16) | static_cast(pt.x)), 0, + gtk_get_current_event_time()); #endif } -class DynamicLibraryImpl : public DynamicLibrary { -protected: - GModule *m; -public: - explicit DynamicLibraryImpl(const char *modulePath) noexcept { - m = g_module_open(modulePath, G_MODULE_BIND_LAZY); - } - // Deleted so DynamicLibraryImpl objects can not be copied. - DynamicLibraryImpl(const DynamicLibraryImpl&) = delete; - DynamicLibraryImpl(DynamicLibraryImpl&&) = delete; - DynamicLibraryImpl&operator=(const DynamicLibraryImpl&) = delete; - DynamicLibraryImpl&operator=(DynamicLibraryImpl&&) = delete; - ~DynamicLibraryImpl() override { - if (m != nullptr) - g_module_close(m); - } - - // Use g_module_symbol to get a pointer to the relevant function. - Function FindFunction(const char *name) override { - if (m != nullptr) { - gpointer fn_address = nullptr; - const gboolean status = g_module_symbol(m, name, &fn_address); - if (status) - return static_cast(fn_address); - else - return nullptr; - } else { - return nullptr; - } - } - - bool IsValid() override { - return m != nullptr; - } -}; - -DynamicLibrary *DynamicLibrary::Load(const char *modulePath) { - return static_cast(new DynamicLibraryImpl(modulePath)); -} - -ColourDesired Platform::Chrome() { - return ColourDesired(0xe0, 0xe0, 0xe0); +ColourRGBA Platform::Chrome() { + return ColourRGBA(0xe0, 0xe0, 0xe0); } -ColourDesired Platform::ChromeHighlight() { - return ColourDesired(0xff, 0xff, 0xff); +ColourRGBA Platform::ChromeHighlight() { + return ColourRGBA(0xff, 0xff, 0xff); } const char *Platform::DefaultFont() { @@ -2013,14 +2136,14 @@ unsigned int Platform::DoubleClickTime() { return 500; // Half a second } -void Platform::DebugDisplay(const char *s) { +void Platform::DebugDisplay(const char *s) noexcept { fprintf(stderr, "%s", s); } //#define TRACE #ifdef TRACE -void Platform::DebugPrintf(const char *format, ...) { +void Platform::DebugPrintf(const char *format, ...) noexcept { char buffer[2000]; va_list pArguments; va_start(pArguments, format); @@ -2029,20 +2152,20 @@ void Platform::DebugPrintf(const char *format, ...) { Platform::DebugDisplay(buffer); } #else -void Platform::DebugPrintf(const char *, ...) {} +void Platform::DebugPrintf(const char *, ...) noexcept {} #endif // Not supported for GTK+ static bool assertionPopUps = true; -bool Platform::ShowAssertionPopUps(bool assertionPopUps_) { +bool Platform::ShowAssertionPopUps(bool assertionPopUps_) noexcept { const bool ret = assertionPopUps; assertionPopUps = assertionPopUps_; return ret; } -void Platform::Assert(const char *c, const char *file, int line) { +void Platform::Assert(const char *c, const char *file, int line) noexcept { char buffer[2000]; g_snprintf(buffer, sizeof(buffer), "Assertion [%s] failed at %s %d\r\n", c, file, line); Platform::DebugDisplay(buffer); diff --git a/scintilla/gtk/ScintillaGTK.cxx b/scintilla/gtk/ScintillaGTK.cxx index 659eb76356..c42af8f573 100644 --- a/scintilla/gtk/ScintillaGTK.cxx +++ b/scintilla/gtk/ScintillaGTK.cxx @@ -14,8 +14,11 @@ #include #include #include +#include #include #include +#include +#include #include #include @@ -35,14 +38,19 @@ #include #endif -#include "Platform.h" - +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" +#include "ScintillaStructures.h" #include "ILoader.h" #include "ILexer.h" + +#include "Debugging.h" +#include "Geometry.h" +#include "Platform.h" + #include "Scintilla.h" #include "ScintillaWidget.h" -#include "StringCopy.h" -#include "CharacterCategory.h" +#include "CharacterCategoryMap.h" #include "Position.h" #include "UniqueString.h" #include "SplitVector.h" @@ -85,25 +93,15 @@ #define SC_INDICATOR_CONVERTED INDICATOR_IME+2 #define SC_INDICATOR_UNKNOWN INDICATOR_IME_MAX -static GdkWindow *WindowFromWidget(GtkWidget *w) noexcept { - return gtk_widget_get_window(w); -} - -#ifdef _MSC_VER -// Constant conditional expressions are because of GTK+ headers -#pragma warning(disable: 4127) -// Ignore unreferenced local functions in GTK+ headers -#pragma warning(disable: 4505) -#endif - using namespace Scintilla; +using namespace Scintilla::Internal; -static GdkWindow *PWindow(const Window &w) noexcept { - GtkWidget *widget = static_cast(w.GetID()); - return gtk_widget_get_window(widget); -} +// From PlatGTK.cxx +extern std::string UTF8FromLatin1(std::string_view text); +extern void Platform_Initialise(); +extern void Platform_Finalise(); -extern std::string UTF8FromLatin1(const char *s, int len); +namespace { enum { COMMAND_SIGNAL, @@ -111,7 +109,7 @@ enum { LAST_SIGNAL }; -static gint scintilla_signals[LAST_SIGNAL] = { 0 }; +gint scintilla_signals[LAST_SIGNAL] = { 0 }; enum { TARGET_STRING, @@ -121,31 +119,88 @@ enum { TARGET_URI }; -GdkAtom ScintillaGTK::atomUTF8 = nullptr; -GdkAtom ScintillaGTK::atomUTF8Mime = nullptr; -GdkAtom ScintillaGTK::atomString = nullptr; -GdkAtom ScintillaGTK::atomUriList = nullptr; -GdkAtom ScintillaGTK::atomDROPFILES_DND = nullptr; - -static const GtkTargetEntry clipboardCopyTargets[] = { +const GtkTargetEntry clipboardCopyTargets[] = { { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING }, { (gchar *) "STRING", 0, TARGET_STRING }, }; -static constexpr gint nClipboardCopyTargets = ELEMENTS(clipboardCopyTargets); +constexpr gint nClipboardCopyTargets = static_cast(std::size(clipboardCopyTargets)); -static const GtkTargetEntry clipboardPasteTargets[] = { +const GtkTargetEntry clipboardPasteTargets[] = { { (gchar *) "text/uri-list", 0, TARGET_URI }, { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING }, { (gchar *) "STRING", 0, TARGET_STRING }, }; -static constexpr gint nClipboardPasteTargets = ELEMENTS(clipboardPasteTargets); +constexpr gint nClipboardPasteTargets = static_cast(std::size(clipboardPasteTargets)); -static const GdkDragAction actionCopyOrMove = static_cast(GDK_ACTION_COPY | GDK_ACTION_MOVE); +const GdkDragAction actionCopyOrMove = static_cast(GDK_ACTION_COPY | GDK_ACTION_MOVE); + +GdkWindow *WindowFromWidget(GtkWidget *w) noexcept { + return gtk_widget_get_window(w); +} -static GtkWidget *PWidget(const Window &w) noexcept { +GtkWidget *PWidget(const Window &w) noexcept { return static_cast(w.GetID()); } +GdkWindow *PWindow(const Window &w) noexcept { + GtkWidget *widget = static_cast(w.GetID()); + return gtk_widget_get_window(widget); +} + +void UnRefCursor(GdkCursor *cursor) noexcept { +#if GTK_CHECK_VERSION(3,0,0) + g_object_unref(cursor); +#else + gdk_cursor_unref(cursor); +#endif +} + +void MapWidget(GtkWidget *widget) noexcept { + if (widget && + gtk_widget_get_visible(GTK_WIDGET(widget)) && + !IS_WIDGET_MAPPED(widget)) { + gtk_widget_map(widget); + } +} + +const guchar *DataOfGSD(GtkSelectionData *sd) noexcept { + return gtk_selection_data_get_data(sd); +} + +gint LengthOfGSD(GtkSelectionData *sd) noexcept { + return gtk_selection_data_get_length(sd); +} + +GdkAtom TypeOfGSD(GtkSelectionData *sd) noexcept { + return gtk_selection_data_get_data_type(sd); +} + +GdkAtom SelectionOfGSD(GtkSelectionData *sd) noexcept { + return gtk_selection_data_get_selection(sd); +} + +} + +FontOptions::FontOptions(GtkWidget *widget) noexcept { + PangoContext *pcontext = gtk_widget_create_pango_context(widget); + PLATFORM_ASSERT(pcontext); + const cairo_font_options_t *options = pango_cairo_context_get_font_options(pcontext); + // options is owned by the PangoContext so must not be freed. + if (options) { + // options is NULL on Win32 + antialias = cairo_font_options_get_antialias(options); + order = cairo_font_options_get_subpixel_order(options); + hint = cairo_font_options_get_hint_style(options); + } + g_object_unref(pcontext); +} + +bool FontOptions::operator==(const FontOptions &other) const noexcept { + return antialias == other.antialias && + order == other.order && + hint == other.hint; +} + ScintillaGTK *ScintillaGTK::FromWidget(GtkWidget *widget) noexcept { ScintillaObject *scio = SCINTILLA(widget); return static_cast(scio->pscin); @@ -182,7 +237,7 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) : // There does not seem to be a real standard for indicating that the clipboard // contains a rectangular selection, so copy Developer Studio. cfColumnSelect = static_cast( - ::RegisterClipboardFormat("MSDEVColumnSelect")); + ::RegisterClipboardFormatW(L"MSDEVColumnSelect")); // Get intellimouse parameters when running on win32; otherwise use // reasonable default @@ -193,6 +248,7 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) : #else linesPerScroll = 4; #endif + primarySelection = false; Init(); } @@ -206,21 +262,14 @@ ScintillaGTK::~ScintillaGTK() { gdk_event_free(evbtn); evbtn = nullptr; } + ClearPrimarySelection(); wPreedit.Destroy(); } -static void UnRefCursor(GdkCursor *cursor) noexcept { -#if GTK_CHECK_VERSION(3,0,0) - g_object_unref(cursor); -#else - gdk_cursor_unref(cursor); -#endif -} - void ScintillaGTK::RealizeThis(GtkWidget *widget) { //Platform::DebugPrintf("ScintillaGTK::realize this\n"); gtk_widget_set_realized(widget, TRUE); - GdkWindowAttr attrs; + GdkWindowAttr attrs {}; attrs.window_type = GDK_WINDOW_CHILD; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); @@ -292,12 +341,6 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { cursor = gdk_cursor_new_for_display(pdisplay, GDK_LEFT_PTR); gdk_window_set_cursor(PWindow(scrollbarh), cursor); UnRefCursor(cursor); - - wSelection = gtk_invisible_new(); - g_signal_connect(PWidget(wSelection), "selection_get", G_CALLBACK(PrimarySelection), (gpointer) this); - g_signal_connect(PWidget(wSelection), "selection_clear_event", G_CALLBACK(PrimaryClear), (gpointer) this); - gtk_selection_add_targets(PWidget(wSelection), GDK_SELECTION_PRIMARY, - clipboardCopyTargets, nClipboardCopyTargets); } void ScintillaGTK::Realize(GtkWidget *widget) { @@ -307,9 +350,6 @@ void ScintillaGTK::Realize(GtkWidget *widget) { void ScintillaGTK::UnRealizeThis(GtkWidget *widget) { try { - gtk_selection_clear_targets(PWidget(wSelection), GDK_SELECTION_PRIMARY); - wSelection.Destroy(); - if (IS_WIDGET_MAPPED(widget)) { gtk_widget_unmap(widget); } @@ -328,7 +368,7 @@ void ScintillaGTK::UnRealizeThis(GtkWidget *widget) { Finalise(); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } @@ -337,14 +377,6 @@ void ScintillaGTK::UnRealize(GtkWidget *widget) { sciThis->UnRealizeThis(widget); } -static void MapWidget(GtkWidget *widget) noexcept { - if (widget && - gtk_widget_get_visible(GTK_WIDGET(widget)) && - !IS_WIDGET_MAPPED(widget)) { - gtk_widget_map(widget); - } -} - void ScintillaGTK::MapThis() { try { //Platform::DebugPrintf("ScintillaGTK::map this\n"); @@ -352,13 +384,13 @@ void ScintillaGTK::MapThis() { MapWidget(PWidget(wText)); MapWidget(PWidget(scrollbarh)); MapWidget(PWidget(scrollbarv)); - wMain.SetCursor(Window::cursorArrow); - scrollbarv.SetCursor(Window::cursorArrow); - scrollbarh.SetCursor(Window::cursorArrow); + wMain.SetCursor(Window::Cursor::arrow); + scrollbarv.SetCursor(Window::Cursor::arrow); + scrollbarh.SetCursor(Window::Cursor::arrow); ChangeSize(); gdk_window_show(PWindow(wMain)); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } @@ -371,7 +403,7 @@ void ScintillaGTK::UnMapThis() { try { //Platform::DebugPrintf("ScintillaGTK::unmap this\n"); gtk_widget_set_mapped(PWidget(wMain), FALSE); - DropGraphics(false); + DropGraphics(); gdk_window_hide(PWindow(wMain)); gtk_widget_unmap(PWidget(wText)); if (PWidget(scrollbarh)) @@ -379,7 +411,7 @@ void ScintillaGTK::UnMapThis() { if (PWidget(scrollbarv)) gtk_widget_unmap(PWidget(scrollbarv)); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } @@ -396,12 +428,12 @@ void ScintillaGTK::ForAll(GtkCallback callback, gpointer callback_data) { if (PWidget(scrollbarh)) (*callback)(PWidget(scrollbarh), callback_data); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { - ScintillaGTK *sciThis = FromWidget((GtkWidget *)container); + ScintillaGTK *sciThis = FromWidget(GTK_WIDGET(container)); if (callback && include_internals) { sciThis->ForAll(callback, callback_data); @@ -423,7 +455,7 @@ class PreEditString { explicit PreEditString(GtkIMContext *im_context) noexcept { gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos); validUTF8 = g_utf8_validate(str, strlen(str), nullptr); - uniStr = g_utf8_to_ucs4_fast(str, strlen(str), &uniStrLen); + uniStr = g_utf8_to_ucs4_fast(str, static_cast(strlen(str)), &uniStrLen); pscript = g_unichar_get_script(uniStr[0]); } // Deleted so PreEditString objects can not be copied. @@ -462,7 +494,7 @@ gint ScintillaGTK::FocusInThis(GtkWidget *) { } } } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return FALSE; } @@ -482,7 +514,7 @@ gint ScintillaGTK::FocusOutThis(GtkWidget *) { gtk_im_context_focus_out(im_context); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return FALSE; } @@ -536,7 +568,7 @@ void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) { sciThis->Resize(allocation->width, allocation->height); } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } } @@ -655,19 +687,21 @@ void ScintillaGTK::Init() { caret.period = 0; } - for (TickReason tr = tickCaret; tr <= tickDwell; tr = static_cast(tr + 1)) { - timers[tr].reason = tr; + for (size_t tr = static_cast(TickReason::caret); tr <= static_cast(TickReason::dwell); tr++) { + timers[tr].reason = static_cast(tr); timers[tr].scintilla = this; } - vs.indicators[SC_INDICATOR_UNKNOWN] = Indicator(INDIC_HIDDEN, ColourDesired(0, 0, 0xff)); - vs.indicators[SC_INDICATOR_INPUT] = Indicator(INDIC_DOTS, ColourDesired(0, 0, 0xff)); - vs.indicators[SC_INDICATOR_CONVERTED] = Indicator(INDIC_COMPOSITIONTHICK, ColourDesired(0, 0, 0xff)); - vs.indicators[SC_INDICATOR_TARGET] = Indicator(INDIC_STRAIGHTBOX, ColourDesired(0, 0, 0xff)); + vs.indicators[SC_INDICATOR_UNKNOWN] = Indicator(IndicatorStyle::Hidden, ColourRGBA(0, 0, 0xff)); + vs.indicators[SC_INDICATOR_INPUT] = Indicator(IndicatorStyle::Dots, ColourRGBA(0, 0, 0xff)); + vs.indicators[SC_INDICATOR_CONVERTED] = Indicator(IndicatorStyle::CompositionThick, ColourRGBA(0, 0, 0xff)); + vs.indicators[SC_INDICATOR_TARGET] = Indicator(IndicatorStyle::StraightBox, ColourRGBA(0, 0, 0xff)); + + fontOptionsPrevious = FontOptions(PWidget(wText)); } void ScintillaGTK::Finalise() { - for (TickReason tr = tickCaret; tr <= tickDwell; tr = static_cast(tr + 1)) { - FineTickerCancel(tr); + for (size_t tr = static_cast(TickReason::caret); tr <= static_cast(TickReason::dwell); tr++) { + FineTickerCancel(static_cast(tr)); } if (accessible) { gtk_accessible_set_widget(GTK_ACCESSIBLE(accessible), nullptr); @@ -679,14 +713,14 @@ void ScintillaGTK::Finalise() { } bool ScintillaGTK::AbandonPaint() { - if ((paintState == painting) && !paintingAllText) { + if ((paintState == PaintState::painting) && !paintingAllText) { repaintFullWindow = true; } return false; } void ScintillaGTK::DisplayCursor(Window::Cursor c) { - if (cursorMode == SC_CURSORNORMAL) + if (cursorMode == CursorShape::Normal) wText.SetCursor(c); else wText.SetCursor(static_cast(cursorMode)); @@ -694,13 +728,14 @@ void ScintillaGTK::DisplayCursor(Window::Cursor c) { bool ScintillaGTK::DragThreshold(Point ptStart, Point ptNow) { return gtk_drag_check_threshold(GTK_WIDGET(PWidget(wMain)), - ptStart.x, ptStart.y, ptNow.x, ptNow.y); + static_cast(ptStart.x), static_cast(ptStart.y), + static_cast(ptNow.x), static_cast(ptNow.y)); } void ScintillaGTK::StartDrag() { PLATFORM_ASSERT(evbtn); dragWasDropped = false; - inDragDrop = ddDragging; + inDragDrop = DragDrop::dragging; GtkTargetList *tl = gtk_target_list_new(clipboardCopyTargets, nClipboardCopyTargets); #if GTK_CHECK_VERSION(3,10,0) gtk_drag_begin_with_coordinates(GTK_WIDGET(PWidget(wMain)), @@ -718,7 +753,8 @@ void ScintillaGTK::StartDrag() { #endif } -namespace Scintilla { +namespace Scintilla::Internal { + std::string ConvertText(const char *s, size_t len, const char *charSetDest, const char *charSetSource, bool transliterations, bool silent) { // s is not const because of different versions of iconv disagreeing about const @@ -737,7 +773,7 @@ std::string ConvertText(const char *s, size_t len, const char *charSetDest, if (!silent) { if (len == 1) fprintf(stderr, "iconv %s->%s failed for %0x '%s'\n", - charSetSource, charSetDest, (unsigned char)(*s), s); + charSetSource, charSetDest, static_cast(*s), s); else fprintf(stderr, "iconv %s->%s failed for %s\n", charSetSource, charSetDest, s); @@ -819,35 +855,56 @@ bool ScintillaGTK::ValidCodePage(int codePage) const { || codePage == 1361; } -sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { +std::string ScintillaGTK::UTF8FromEncoded(std::string_view encoded) const { + if (IsUnicodeMode()) { + return std::string(encoded); + } else { + const char *charSetBuffer = CharacterSetID(); + return ConvertText(encoded.data(), encoded.length(), "UTF-8", charSetBuffer, true); + } +} + +std::string ScintillaGTK::EncodedFromUTF8(std::string_view utf8) const { + if (IsUnicodeMode()) { + return std::string(utf8); + } else { + const char *charSetBuffer = CharacterSetID(); + return ConvertText(utf8.data(), utf8.length(), charSetBuffer, "UTF-8", true); + } +} + +sptr_t ScintillaGTK::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { try { switch (iMessage) { - case SCI_GRABFOCUS: + case Message::GrabFocus: gtk_widget_grab_focus(PWidget(wMain)); break; - case SCI_GETDIRECTFUNCTION: + case Message::GetDirectFunction: return reinterpret_cast(DirectFunction); - case SCI_GETDIRECTPOINTER: + case Message::GetDirectStatusFunction: + return reinterpret_cast(DirectStatusFunction); + + case Message::GetDirectPointer: return reinterpret_cast(this); - case SCI_TARGETASUTF8: + case Message::TargetAsUTF8: return TargetAsUTF8(CharPtrFromSPtr(lParam)); - case SCI_ENCODEDFROMUTF8: + case Message::EncodedFromUTF8: return EncodedFromUTF8(ConstCharPtrFromUPtr(wParam), CharPtrFromSPtr(lParam)); - case SCI_SETRECTANGULARSELECTIONMODIFIER: - rectangularSelectionModifier = wParam; + case Message::SetRectangularSelectionModifier: + rectangularSelectionModifier = static_cast(wParam); break; - case SCI_GETRECTANGULARSELECTIONMODIFIER: + case Message::GetRectangularSelectionModifier: return rectangularSelectionModifier; - case SCI_SETREADONLY: { + case Message::SetReadOnly: { const sptr_t ret = ScintillaBase::WndProc(iMessage, wParam, lParam); if (accessible) { ScintillaGTKAccessible *sciAccessible = ScintillaGTKAccessible::FromAccessible(accessible); @@ -858,11 +915,11 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam return ret; } - case SCI_GETACCESSIBILITY: + case Message::GetAccessibility: return accessibilityEnabled; - case SCI_SETACCESSIBILITY: - accessibilityEnabled = wParam; + case Message::SetAccessibility: + accessibilityEnabled = static_cast(wParam); if (accessible) { ScintillaGTKAccessible *sciAccessible = ScintillaGTKAccessible::FromAccessible(accessible); if (sciAccessible) { @@ -875,30 +932,32 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam return ScintillaBase::WndProc(iMessage, wParam, lParam); } } catch (std::bad_alloc &) { - errorStatus = SC_STATUS_BADALLOC; + errorStatus = Status::BadAlloc; } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return 0; } -sptr_t ScintillaGTK::DefWndProc(unsigned int, uptr_t, sptr_t) { +sptr_t ScintillaGTK::DefWndProc(Message, uptr_t, sptr_t) { return 0; } bool ScintillaGTK::FineTickerRunning(TickReason reason) { - return timers[reason].timer != 0; + return timers[static_cast(reason)].timer != 0; } void ScintillaGTK::FineTickerStart(TickReason reason, int millis, int /* tolerance */) { FineTickerCancel(reason); - timers[reason].timer = gdk_threads_add_timeout(millis, TimeOut, &timers[reason]); + const size_t reasonIndex = static_cast(reason); + timers[reasonIndex].timer = gdk_threads_add_timeout(millis, TimeOut, &timers[reasonIndex]); } void ScintillaGTK::FineTickerCancel(TickReason reason) { - if (timers[reason].timer) { - g_source_remove(timers[reason].timer); - timers[reason].timer = 0; + const size_t reasonIndex = static_cast(reason); + if (timers[reasonIndex].timer) { + g_source_remove(timers[reasonIndex].timer); + timers[reasonIndex].timer = 0; } } @@ -937,8 +996,10 @@ bool ScintillaGTK::HaveMouseCapture() { #if GTK_CHECK_VERSION(3,0,0) +namespace { + // Is crcTest completely in crcContainer? -static bool CRectContains(const cairo_rectangle_t &crcContainer, const cairo_rectangle_t &crcTest) { +bool CRectContains(const cairo_rectangle_t &crcContainer, const cairo_rectangle_t &crcTest) { return (crcTest.x >= crcContainer.x) && ((crcTest.x + crcTest.width) <= (crcContainer.x + crcContainer.width)) && (crcTest.y >= crcContainer.y) && ((crcTest.y + crcTest.height) <= (crcContainer.y + crcContainer.height)); @@ -946,7 +1007,7 @@ static bool CRectContains(const cairo_rectangle_t &crcContainer, const cairo_rec // Is crcTest completely in crcListContainer? // May incorrectly return false if complex shape -static bool CRectListContains(const cairo_rectangle_list_t *crcListContainer, const cairo_rectangle_t &crcTest) { +bool CRectListContains(const cairo_rectangle_list_t *crcListContainer, const cairo_rectangle_t &crcTest) { for (int r=0; rnum_rectangles; r++) { if (CRectContains(crcListContainer->rectangles[r], crcTest)) return true; @@ -954,13 +1015,15 @@ static bool CRectListContains(const cairo_rectangle_list_t *crcListContainer, co return false; } +} + #endif bool ScintillaGTK::PaintContains(PRectangle rc) { // This allows optimization when a rectangle is completely in the update region. // It is OK to return false when too difficult to determine as that just performs extra drawing bool contains = true; - if (paintState == painting) { + if (paintState == PaintState::painting) { if (!rcPaint.Contains(rc)) { contains = false; } else if (rgnUpdate) { @@ -1013,8 +1076,8 @@ void ScintillaGTK::ScrollText(Sci::Line linesToMove) { #else GtkWidget *wi = PWidget(wText); if (IS_WIDGET_REALIZED(wi)) { - const int diff = vs.lineHeight * -linesToMove; - gdk_window_scroll(WindowFromWidget(wi), 0, -diff); + const Sci::Line diff = vs.lineHeight * -linesToMove; + gdk_window_scroll(WindowFromWidget(wi), 0, static_cast(-diff)); gdk_window_process_updates(WindowFromWidget(wi), FALSE); } #endif @@ -1022,7 +1085,7 @@ void ScintillaGTK::ScrollText(Sci::Line linesToMove) { void ScintillaGTK::SetVerticalScrollPos() { DwellEnd(true); - gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmentv), topLine); + gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmentv), static_cast(topLine)); } void ScintillaGTK::SetHorizontalScrollPos() { @@ -1032,13 +1095,13 @@ void ScintillaGTK::SetHorizontalScrollPos() { bool ScintillaGTK::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) { bool modified = false; - const int pageScroll = LinesToScroll(); + const int pageScroll = static_cast(LinesToScroll()); if (gtk_adjustment_get_upper(adjustmentv) != (nMax + 1) || gtk_adjustment_get_page_size(adjustmentv) != nPage || gtk_adjustment_get_page_increment(adjustmentv) != pageScroll) { - gtk_adjustment_set_upper(adjustmentv, nMax + 1); - gtk_adjustment_set_page_size(adjustmentv, nPage); + gtk_adjustment_set_upper(adjustmentv, nMax + 1.0); + gtk_adjustment_set_page_size(adjustmentv, static_cast(nPage)); gtk_adjustment_set_page_increment(adjustmentv, pageScroll); #if !GTK_CHECK_VERSION(3,18,0) gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv)); @@ -1052,7 +1115,7 @@ bool ScintillaGTK::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) { horizEndPreferred = 0; const unsigned int pageWidth = static_cast(rcText.Width()); const unsigned int pageIncrement = pageWidth / 3; - const unsigned int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth; + const unsigned int charWidth = static_cast(vs.styles[STYLE_DEFAULT].aveCharWidth); if (gtk_adjustment_get_upper(adjustmenth) != horizEndPreferred || gtk_adjustment_get_page_size(adjustmenth) != pageWidth || gtk_adjustment_get_page_increment(adjustmenth) != pageIncrement || @@ -1066,7 +1129,7 @@ bool ScintillaGTK::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) { #endif modified = true; } - if (modified && (paintState == painting)) { + if (modified && (paintState == PaintState::painting)) { repaintFullWindow = true; } @@ -1091,31 +1154,31 @@ void ScintillaGTK::NotifyFocus(bool focus) { Editor::NotifyFocus(focus); } -void ScintillaGTK::NotifyParent(SCNotification scn) { +void ScintillaGTK::NotifyParent(NotificationData scn) { scn.nmhdr.hwndFrom = PWidget(wMain); scn.nmhdr.idFrom = GetCtrlID(); g_signal_emit(G_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL], 0, GetCtrlID(), &scn); } -void ScintillaGTK::NotifyKey(int key, int modifiers) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_KEY; - scn.ch = key; +void ScintillaGTK::NotifyKey(Keys key, KeyMod modifiers) { + NotificationData scn = {}; + scn.nmhdr.code = Notification::Key; + scn.ch = static_cast(key); scn.modifiers = modifiers; NotifyParent(scn); } void ScintillaGTK::NotifyURIDropped(const char *list) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_URIDROPPED; + NotificationData scn = {}; + scn.nmhdr.code = Notification::URIDropped; scn.text = list; NotifyParent(scn); } -const char *CharacterSetID(int characterSet); +const char *CharacterSetID(CharacterSet characterSet); const char *ScintillaGTK::CharacterSetID() const { return ::CharacterSetID(vs.styles[STYLE_DEFAULT].characterSet); @@ -1124,7 +1187,7 @@ const char *ScintillaGTK::CharacterSetID() const { class CaseFolderDBCS : public CaseFolderTable { const char *charSet; public: - explicit CaseFolderDBCS(const char *charSet_) : charSet(charSet_) { + explicit CaseFolderDBCS(const char *charSet_) noexcept : charSet(charSet_) { StandardASCII(); } size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) override { @@ -1153,14 +1216,14 @@ class CaseFolderDBCS : public CaseFolderTable { } }; -CaseFolder *ScintillaGTK::CaseFolderForEncoding() { +std::unique_ptr ScintillaGTK::CaseFolderForEncoding() { if (pdoc->dbcsCodePage == SC_CP_UTF8) { - return new CaseFolderUnicode(); + return std::make_unique(); } else { const char *charSetBuffer = CharacterSetID(); if (charSetBuffer) { if (pdoc->dbcsCodePage == 0) { - CaseFolderTable *pcf = new CaseFolderTable(); + std::unique_ptr pcf = std::make_unique(); pcf->StandardASCII(); // Only for single byte encodings for (int i=0x80; i<0x100; i++) { @@ -1183,7 +1246,7 @@ CaseFolder *ScintillaGTK::CaseFolderForEncoding() { } return pcf; } else { - return new CaseFolderDBCS(charSetBuffer); + return std::make_unique(charSetBuffer); } } return nullptr; @@ -1194,7 +1257,7 @@ namespace { struct CaseMapper { gchar *mapped; // Must be freed with g_free - CaseMapper(const std::string &sUTF8, bool toUpperCase) { + CaseMapper(const std::string &sUTF8, bool toUpperCase) noexcept { if (toUpperCase) { mapped = g_utf8_strup(sUTF8.c_str(), sUTF8.length()); } else { @@ -1206,21 +1269,21 @@ struct CaseMapper { CaseMapper(CaseMapper&&) = delete; CaseMapper&operator=(const CaseMapper&) = delete; CaseMapper&operator=(CaseMapper&&) = delete; - ~CaseMapper() { + ~CaseMapper() noexcept { g_free(mapped); } }; } -std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) { - if ((s.size() == 0) || (caseMapping == cmSame)) +std::string ScintillaGTK::CaseMapString(const std::string &s, CaseMapping caseMapping) { + if ((s.size() == 0) || (caseMapping == CaseMapping::same)) return s; if (IsUnicodeMode()) { std::string retMapped(s.length() * maxExpansionCaseConversion, 0); const size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), - (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); + (caseMapping == CaseMapping::upper) ? CaseConversion::upper : CaseConversion::lower); retMapped.resize(lenMapped); return retMapped; } @@ -1228,18 +1291,18 @@ std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) { const char *charSetBuffer = CharacterSetID(); if (!*charSetBuffer) { - CaseMapper mapper(s, caseMapping == cmUpper); + CaseMapper mapper(s, caseMapping == CaseMapping::upper); return std::string(mapper.mapped, strlen(mapper.mapped)); } else { // Change text to UTF-8 std::string sUTF8 = ConvertText(s.c_str(), s.length(), "UTF-8", charSetBuffer, false); - CaseMapper mapper(sUTF8, caseMapping == cmUpper); + CaseMapper mapper(sUTF8, caseMapping == CaseMapping::upper); return ConvertText(mapper.mapped, strlen(mapper.mapped), charSetBuffer, "UTF-8", false); } } -int ScintillaGTK::KeyDefault(int key, int modifiers) { +int ScintillaGTK::KeyDefault(Keys key, KeyMod modifiers) { // Pass up to container in case it is an accelerator NotifyKey(key, modifiers); return 0; @@ -1283,7 +1346,7 @@ class SelectionReceiver : GObjectWatcher { sci(sci_) { } - static void ClipboardReceived(GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data) { + static void ClipboardReceived(GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data) noexcept { SelectionReceiver *self = static_cast(data); if (self->sci) { self->sci->ReceivedClipboard(clipboard, selection_data); @@ -1355,26 +1418,66 @@ void ScintillaGTK::AddToPopUp(const char *label, int cmd, bool enabled) { } bool ScintillaGTK::OwnPrimarySelection() { - return (wSelection.Created() && - (gdk_selection_owner_get(GDK_SELECTION_PRIMARY) == PWindow(wSelection)) && - (PWindow(wSelection) != nullptr)); + return primarySelection; +} + +void ScintillaGTK::ClearPrimarySelection() { + if (primarySelection) { + inClearSelection++; + // Calls PrimaryClearSelection: primarySelection -> false + gtk_clipboard_clear(gtk_clipboard_get(GDK_SELECTION_PRIMARY)); + inClearSelection--; + } +} + +void ScintillaGTK::PrimaryGetSelectionThis(GtkClipboard *clip, GtkSelectionData *selection_data, guint info) { + try { + if (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY) { + if (primary.Empty()) { + CopySelectionRange(&primary); + } + GetSelection(selection_data, info, &primary); + } + } catch (...) { + errorStatus = Status::Failure; + } +} + +void ScintillaGTK::PrimaryGetSelection(GtkClipboard *clip, GtkSelectionData *selection_data, guint info, gpointer pSci) { + static_cast(pSci)->PrimaryGetSelectionThis(clip, selection_data, info); +} + +void ScintillaGTK::PrimaryClearSelectionThis(GtkClipboard *clip) { + try { + primarySelection = false; + primary.Clear(); + if (!inClearSelection) { + // Called because of another application or window claiming primary selection + // so redraw to show selection in secondary colour. + Redraw(); + } + } catch (...) { + errorStatus = Status::Failure; + } +} + +void ScintillaGTK::PrimaryClearSelection(GtkClipboard *clip, gpointer pSci) { + static_cast(pSci)->PrimaryClearSelectionThis(clip); } void ScintillaGTK::ClaimSelection() { // X Windows has a 'primary selection' as well as the clipboard. // Whenever the user selects some text, we become the primary selection - if (!sel.Empty() && wSelection.Created() && IS_WIDGET_REALIZED(GTK_WIDGET(PWidget(wSelection)))) { - primarySelection = true; - gtk_selection_owner_set(GTK_WIDGET(PWidget(wSelection)), - GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); - primary.Clear(); - } else if (OwnPrimarySelection()) { - primarySelection = true; - if (primary.Empty()) - gtk_selection_owner_set(nullptr, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); - } else { - primarySelection = false; - primary.Clear(); + ClearPrimarySelection(); + if (!sel.Empty()) { + if (gtk_clipboard_set_with_data( + gtk_clipboard_get(GDK_SELECTION_PRIMARY), + clipboardCopyTargets, nClipboardCopyTargets, + PrimaryGetSelection, + PrimaryClearSelection, + this)) { + primarySelection = true; + } } } @@ -1382,11 +1485,6 @@ bool ScintillaGTK::IsStringAtom(GdkAtom type) { return (type == GDK_TARGET_STRING) || (type == atomUTF8) || (type == atomUTF8Mime); } -static const guchar *DataOfGSD(GtkSelectionData *sd) noexcept { return gtk_selection_data_get_data(sd); } -static gint LengthOfGSD(GtkSelectionData *sd) noexcept { return gtk_selection_data_get_length(sd); } -static GdkAtom TypeOfGSD(GtkSelectionData *sd) noexcept { return gtk_selection_data_get_data_type(sd); } -static GdkAtom SelectionOfGSD(GtkSelectionData *sd) noexcept { return gtk_selection_data_get_selection(sd); } - // Detect rectangular text, convert line ends to current mode, convert from or to UTF-8 void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText) { const char *data = reinterpret_cast(DataOfGSD(selectionData)); @@ -1420,8 +1518,8 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio if (selectionTypeData == GDK_TARGET_STRING) { if (IsUnicodeMode()) { // Unknown encoding so assume in Latin1 - dest = UTF8FromLatin1(dest.c_str(), dest.length()); - selText.Copy(dest, SC_CP_UTF8, 0, isRectangular, false); + dest = UTF8FromLatin1(dest); + selText.Copy(dest, CpUtf8, CharacterSet::Ansi, isRectangular, false); } else { // Assume buffer is in same encoding as selection selText.Copy(dest, pdoc->dbcsCodePage, @@ -1435,7 +1533,7 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio selText.Copy(dest, pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, isRectangular, false); } else { - selText.Copy(dest, SC_CP_UTF8, 0, isRectangular, false); + selText.Copy(dest, CpUtf8, CharacterSet::Ansi, isRectangular, false); } } } @@ -1449,11 +1547,11 @@ void ScintillaGTK::InsertSelection(GtkClipboard *clipBoard, GtkSelectionData *se UndoGroup ug(pdoc); if (selection == GDK_SELECTION_CLIPBOARD) { - ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH); + ClearSelection(multiPasteMode == MultiPaste::Each); } InsertPasteShape(selText.Data(), selText.Length(), - selText.rectangular ? pasteRectangular : pasteStream); + selText.rectangular ? PasteShape::rectangular : PasteShape::stream); EnsureCaretVisible(); } else { GdkAtom target = gtk_selection_data_get_target(selectionData); @@ -1476,7 +1574,7 @@ void ScintillaGTK::ReceivedClipboard(GtkClipboard *clipBoard, GtkSelectionData * try { InsertSelection(clipBoard, selection_data); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } @@ -1496,7 +1594,7 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) { // else fprintf(stderr, "Target non string %d %d\n", (int)(selection_data->type), // (int)(atomUTF8)); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } @@ -1528,9 +1626,9 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se // from code below std::unique_ptr newline_normalized; { - std::string tmpstr = Document::TransformLineEnds(text->Data(), text->Length(), SC_EOL_LF); + std::string tmpstr = Document::TransformLineEnds(text->Data(), text->Length(), EndOfLine::Lf); newline_normalized.reset(new SelectionText()); - newline_normalized->Copy(tmpstr, SC_CP_UTF8, 0, text->rectangular, false); + newline_normalized->Copy(tmpstr, CpUtf8, CharacterSet::Ansi, text->rectangular, false); text = newline_normalized.get(); } #endif @@ -1541,8 +1639,8 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se const char *charSet = ::CharacterSetID(text->characterSet); if (*charSet) { std::string tmputf = ConvertText(text->Data(), text->Length(), "UTF-8", charSet, false); - converted = Sci::make_unique(); - converted->Copy(tmputf, SC_CP_UTF8, 0, text->rectangular, false); + converted = std::make_unique(); + converted->Copy(tmputf, CpUtf8, CharacterSet::Ansi, text->rectangular, false); text = converted.get(); } } @@ -1555,7 +1653,7 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se // The #if is here because on Windows cfColumnSelect clip entry is used // instead as standard indicator of rectangularness (so no need to kludge) const char *textData = text->Data(); - int len = text->Length(); + gint len = static_cast(text->Length()); #if PLAT_GTK_WIN32 == 0 if (text->rectangular) len++; @@ -1603,31 +1701,10 @@ void ScintillaGTK::UnclaimSelection(GdkEventSelection *selection_event) { } } } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } -void ScintillaGTK::PrimarySelection(GtkWidget *, GtkSelectionData *selection_data, guint info, guint, ScintillaGTK *sciThis) { - try { - if (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY) { - if (sciThis->primary.Empty()) { - sciThis->CopySelectionRange(&sciThis->primary); - } - sciThis->GetSelection(selection_data, info, &sciThis->primary); - } - } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; - } -} - -gboolean ScintillaGTK::PrimaryClear(GtkWidget *widget, GdkEventSelection *event, ScintillaGTK *sciThis) { - sciThis->UnclaimSelection(event); - if (GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event) { - return GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event(widget, event); - } - return TRUE; -} - void ScintillaGTK::Resize(int width, int height) { //Platform::DebugPrintf("Resize %d %d\n", width, height); //printf("Resize %d %d\n", width, height); @@ -1811,16 +1888,16 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { if (ctrl) SetAdjustmentValue(adjustmenth, xOffset - 6); else - SetAdjustmentValue(adjustmentv, topLine - 3); + SetAdjustmentValue(adjustmentv, static_cast(topLine) - 3); } else if (event->button == 5) { // Wheel scrolling down (only GTK 1.x does it this way) if (ctrl) SetAdjustmentValue(adjustmenth, xOffset + 6); else - SetAdjustmentValue(adjustmentv, topLine + 3); + SetAdjustmentValue(adjustmentv, static_cast(topLine) + 3); } } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return TRUE; } @@ -1846,14 +1923,14 @@ gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) { // If mouse released on scroll bar then the position is relative to the // scrollbar, not the drawing window so just repeat the most recent point. pt = sciThis->ptMouseLast; - const int modifiers = ModifierFlags( + const KeyMod modifiers = ModifierFlags( (event->state & GDK_SHIFT_MASK) != 0, (event->state & GDK_CONTROL_MASK) != 0, (event->state & modifierTranslated(sciThis->rectangularSelectionModifier)) != 0); sciThis->ButtonUpWithModifiers(pt, event->time, modifiers); } } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } return FALSE; } @@ -1942,9 +2019,9 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) { // Text font size zoom } else if (event->state & GDK_CONTROL_MASK) { if (cLineScroll < 0) { - sciThis->KeyCommand(SCI_ZOOMIN); + sciThis->KeyCommand(Message::ZoomIn); } else { - sciThis->KeyCommand(SCI_ZOOMOUT); + sciThis->KeyCommand(Message::ZoomOut); } // Regular scrolling @@ -1953,7 +2030,7 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) { } return TRUE; } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } return FALSE; } @@ -1982,19 +2059,21 @@ gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) { //Platform::DebugPrintf("Move %x %x %d %c %d %d\n", // sciThis,event->window,event->time,event->is_hint? 'h' :'.', x, y); const Point pt(static_cast(x), static_cast(y)); - const int modifiers = ModifierFlags( + const KeyMod modifiers = ModifierFlags( (event->state & GDK_SHIFT_MASK) != 0, (event->state & GDK_CONTROL_MASK) != 0, (event->state & modifierTranslated(sciThis->rectangularSelectionModifier)) != 0); sciThis->ButtonMoveWithModifiers(pt, event->time, modifiers); } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } return FALSE; } +namespace { + // Map the keypad keys to their equivalent functions -static int KeyTranslate(int keyIn) noexcept { +int KeyTranslate(int keyIn) noexcept { switch (keyIn) { #if GTK_CHECK_VERSION(3,0,0) case GDK_KEY_ISO_Left_Tab: @@ -2136,6 +2215,8 @@ static int KeyTranslate(int keyIn) noexcept { } } +} + gboolean ScintillaGTK::KeyThis(GdkEventKey *event) { try { //fprintf(stderr, "SC-key: %d %x [%s]\n", @@ -2172,20 +2253,20 @@ gboolean ScintillaGTK::KeyThis(GdkEventKey *event) { const bool meta = ctrl; ctrl = (event->state & GDK_META_MASK) != 0; #endif - const bool added = KeyDownWithModifiers(key, ModifierFlags(shift, ctrl, alt, meta, super), &consumed) != 0; + const bool added = KeyDownWithModifiers(static_cast(key), ModifierFlags(shift, ctrl, alt, meta, super), &consumed) != 0; if (!consumed) consumed = added; //fprintf(stderr, "SK-key: %d %x %x\n",event->keyval, event->state, consumed); if (event->keyval == 0xffffff && event->length > 0) { ClearSelection(); - const int lengthInserted = pdoc->InsertString(CurrentPosition(), event->string, strlen(event->string)); + const Sci::Position lengthInserted = pdoc->InsertString(CurrentPosition(), event->string, strlen(event->string)); if (lengthInserted > 0) { MovePositionTo(CurrentPosition() + lengthInserted); } } return consumed; } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return FALSE; } @@ -2217,7 +2298,7 @@ gboolean ScintillaGTK::DrawPreeditThis(GtkWidget *, cairo_t *cr) { g_object_unref(layout); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return TRUE; } @@ -2234,13 +2315,13 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *) { PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), pes.str); pango_layout_set_attributes(layout, pes.attrs); - cairo_t *context = gdk_cairo_create(reinterpret_cast(WindowFromWidget(widget))); + cairo_t *context = gdk_cairo_create(WindowFromWidget(widget)); cairo_move_to(context, 0, 0); pango_cairo_show_layout(context, layout); cairo_destroy(context); g_object_unref(layout); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return TRUE; } @@ -2258,7 +2339,7 @@ bool ScintillaGTK::KoreanIME() { return lastNonCommonScript == G_UNICODE_SCRIPT_HANGUL; } -void ScintillaGTK::MoveImeCarets(int pos) { +void ScintillaGTK::MoveImeCarets(Sci::Position pos) { // Move carets relatively by bytes for (size_t r=0; r MapImeIndicators(PangoAttrList *attrs, const char *u8Str) { +namespace { + +std::vector MapImeIndicators(PangoAttrList *attrs, const char *u8Str) { // Map input style to scintilla ime indicator. // Attrs position points between UTF-8 bytes. // Indicator index to be returned is character based though. @@ -2292,11 +2375,12 @@ static std::vector MapImeIndicators(PangoAttrList *attrs, const char *u8Str PangoAttrIterator *iterunderline = pango_attr_list_get_iterator(attrs); if (iterunderline) { do { - PangoAttribute *attrunderline = pango_attr_iterator_get(iterunderline, PANGO_ATTR_UNDERLINE); + const PangoAttribute *attrunderline = pango_attr_iterator_get(iterunderline, PANGO_ATTR_UNDERLINE); if (attrunderline) { const glong start = g_utf8_strlen(u8Str, attrunderline->start_index); const glong end = g_utf8_strlen(u8Str, attrunderline->end_index); - const PangoUnderline uline = (PangoUnderline)((PangoAttrInt *)attrunderline)->value; + const int ulinevalue = reinterpret_cast(attrunderline)->value; + const PangoUnderline uline = static_cast(ulinevalue); for (glong i=start; i < end; ++i) { switch (uline) { case PANGO_UNDERLINE_NONE: @@ -2308,6 +2392,7 @@ static std::vector MapImeIndicators(PangoAttrList *attrs, const char *u8Str case PANGO_UNDERLINE_DOUBLE: case PANGO_UNDERLINE_LOW: case PANGO_UNDERLINE_ERROR: + default: break; } } @@ -2333,6 +2418,8 @@ static std::vector MapImeIndicators(PangoAttrList *attrs, const char *u8Str return indicator; } +} + void ScintillaGTK::SetCandidateWindowPos() { // Composition box accompanies candidate box. const Point pt = PointMainCaret(); @@ -2356,7 +2443,7 @@ void ScintillaGTK::CommitThis(char *commitStr) { const char *charSetSource = CharacterSetID(); glong uniStrLen = 0; - gunichar *uniStr = g_utf8_to_ucs4_fast(commitStr, strlen(commitStr), &uniStrLen); + gunichar *uniStr = g_utf8_to_ucs4_fast(commitStr, static_cast(strlen(commitStr)), &uniStrLen); for (glong i = 0; i < uniStrLen; i++) { gchar u8Char[UTF8MaxBytes+2] = {0}; const gint u8CharLen = g_unichar_to_utf8(uniStr[i], u8Char); @@ -2364,12 +2451,12 @@ void ScintillaGTK::CommitThis(char *commitStr) { if (!IsUnicodeMode()) docChar = ConvertText(u8Char, u8CharLen, charSetSource, "UTF-8", true); - InsertCharacter(docChar.c_str(), docChar.size(), CharacterSource::directInput); + InsertCharacter(docChar, CharacterSource::DirectInput); } g_free(uniStr); ShowCaretAtCurrentPosition(); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } @@ -2405,8 +2492,7 @@ void ScintillaGTK::PreeditChangedInlineThis() { return; } - if (preeditStr.uniStrLen == 0 || preeditStr.uniStrLen > maxLenInputIME) { - //fprintf(stderr, "Do not allow over 200 chars: %i\n", preeditStr.uniStrLen); + if (preeditStr.uniStrLen == 0) { ShowCaretAtCurrentPosition(); return; } @@ -2427,14 +2513,14 @@ void ScintillaGTK::PreeditChangedInlineThis() { if (!IsUnicodeMode()) docChar = ConvertText(u8Char, u8CharLen, charSetSource, "UTF-8", true); - InsertCharacter(docChar.c_str(), docChar.size(), CharacterSource::tentativeInput); + InsertCharacter(docChar, CharacterSource::TentativeInput); DrawImeIndicator(indicator[i], docChar.size()); } // Move caret to ime cursor position. const int imeEndToImeCaretU32 = preeditStr.cursor_pos - preeditStr.uniStrLen; - const int imeCaretPosDoc = pdoc->GetRelativePosition(CurrentPosition(), imeEndToImeCaretU32); + const Sci::Position imeCaretPosDoc = pdoc->GetRelativePosition(CurrentPosition(), imeEndToImeCaretU32); MoveImeCarets(- CurrentPosition() + imeCaretPosDoc); @@ -2451,7 +2537,7 @@ void ScintillaGTK::PreeditChangedInlineThis() { EnsureCaretVisible(); ShowCaretAtCurrentPosition(); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } @@ -2477,7 +2563,7 @@ void ScintillaGTK::PreeditChangedWindowedThis() { if (pt.y < 0) pt.y = 0; - gtk_window_move(GTK_WINDOW(PWidget(wPreedit)), x + pt.x, y + pt.y); + gtk_window_move(GTK_WINDOW(PWidget(wPreedit)), x + static_cast(pt.x), y + static_cast(pt.y)); gtk_window_resize(GTK_WINDOW(PWidget(wPreedit)), w, h); gtk_widget_show(PWidget(wPreedit)); gtk_widget_queue_draw_area(PWidget(wPreeditDraw), 0, 0, w, h); @@ -2485,12 +2571,12 @@ void ScintillaGTK::PreeditChangedWindowedThis() { gtk_widget_hide(PWidget(wPreedit)); } } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } } void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) { - if ((sciThis->imeInteraction == imeInline) || (sciThis->KoreanIME())) { + if ((sciThis->imeInteraction == IMEInteraction::Inline) || (sciThis->KoreanIME())) { sciThis->PreeditChangedInlineThis(); } else { sciThis->PreeditChangedWindowedThis(); @@ -2556,11 +2642,22 @@ void ScintillaGTK::Destroy(GObject *object) { } } +void ScintillaGTK::CheckForFontOptionChange() { + const FontOptions fontOptionsNow(PWidget(wText)); + if (!(fontOptionsNow == fontOptionsPrevious)) { + // Clear position caches + InvalidateStyleData(); + } + fontOptionsPrevious = fontOptionsNow; +} + #if GTK_CHECK_VERSION(3,0,0) gboolean ScintillaGTK::DrawTextThis(cairo_t *cr) { try { - paintState = painting; + CheckForFontOptionChange(); + + paintState = PaintState::painting; repaintFullWindow = false; rcPaint = GetClientRectangle(); @@ -2582,24 +2679,24 @@ gboolean ScintillaGTK::DrawTextThis(cairo_t *cr) { rcPaint.bottom = y2; PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); - std::unique_ptr surfaceWindow(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); + std::unique_ptr surfaceWindow(Surface::Allocate(Technology::Default)); surfaceWindow->Init(cr, PWidget(wText)); Paint(surfaceWindow.get(), rcPaint); surfaceWindow->Release(); - if ((paintState == paintAbandoned) || repaintFullWindow) { + if ((paintState == PaintState::abandoned) || repaintFullWindow) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); } - paintState = notPainting; + paintState = PaintState::notPainting; repaintFullWindow = false; if (rgnUpdate) { cairo_rectangle_list_destroy(rgnUpdate); } rgnUpdate = 0; - paintState = notPainting; + paintState = PaintState::notPainting; } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return FALSE; @@ -2644,7 +2741,7 @@ gboolean ScintillaGTK::DrawThis(cairo_t *cr) { } #endif } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return FALSE; } @@ -2658,7 +2755,9 @@ gboolean ScintillaGTK::DrawMain(GtkWidget *widget, cairo_t *cr) { gboolean ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) { try { - paintState = painting; + CheckForFontOptionChange(); + + paintState = PaintState::painting; rcPaint = PRectangle::FromInts( ose->area.x, @@ -2670,17 +2769,17 @@ gboolean ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *os rgnUpdate = gdk_region_copy(ose->region); const PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); - std::unique_ptr surfaceWindow(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); + std::unique_ptr surfaceWindow(Surface::Allocate(Technology::Default)); cairo_t *cr = gdk_cairo_create(PWindow(wText)); surfaceWindow->Init(cr, PWidget(wText)); Paint(surfaceWindow.get(), rcPaint); surfaceWindow->Release(); cairo_destroy(cr); - if ((paintState == paintAbandoned) || repaintFullWindow) { + if ((paintState == PaintState::abandoned) || repaintFullWindow) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); } - paintState = notPainting; + paintState = PaintState::notPainting; repaintFullWindow = false; if (rgnUpdate) { @@ -2688,7 +2787,7 @@ gboolean ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *os } rgnUpdate = nullptr; } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return FALSE; @@ -2717,7 +2816,7 @@ gboolean ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) { GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), ose); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return FALSE; } @@ -2728,7 +2827,7 @@ void ScintillaGTK::ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) { try { sciThis->ScrollTo(static_cast(gtk_adjustment_get_value(adj)), false); } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } } @@ -2736,7 +2835,7 @@ void ScintillaGTK::ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) { try { sciThis->HorizontalScrollTo(static_cast(gtk_adjustment_get_value(adj))); } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } } @@ -2759,7 +2858,7 @@ void ScintillaGTK::SelectionGet(GtkWidget *widget, sciThis->GetSelection(selection_data, info, &sciThis->primary); } } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } } @@ -2781,7 +2880,7 @@ gboolean ScintillaGTK::DragMotionThis(GdkDragContext *context, GdkDragAction preferredAction = gdk_drag_context_get_suggested_action(context); const GdkDragAction actions = gdk_drag_context_get_actions(context); const SelectionPosition pos = SPositionFromLocation(npt); - if ((inDragDrop == ddDragging) && (PositionInSelection(pos.Position()))) { + if ((inDragDrop == DragDrop::dragging) && (PositionInSelection(pos.Position()))) { // Avoid dragging selection onto itself as that produces a move // with no real effect but which creates undo actions. preferredAction = static_cast(0); @@ -2790,7 +2889,7 @@ gboolean ScintillaGTK::DragMotionThis(GdkDragContext *context, } gdk_drag_status(context, preferredAction, dragtime); } catch (...) { - errorStatus = SC_STATUS_FAILURE; + errorStatus = Status::Failure; } return FALSE; } @@ -2807,7 +2906,7 @@ void ScintillaGTK::DragLeave(GtkWidget *widget, GdkDragContext * /*context*/, gu sciThis->SetDragPosition(SelectionPosition(Sci::invalidPosition)); //Platform::DebugPrintf("DragLeave %x\n", sciThis); } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } } @@ -2819,9 +2918,9 @@ void ScintillaGTK::DragEnd(GtkWidget *widget, GdkDragContext * /*context*/) { sciThis->SetEmptySelection(sciThis->posDrag); sciThis->SetDragPosition(SelectionPosition(Sci::invalidPosition)); //Platform::DebugPrintf("DragEnd %x %d\n", sciThis, sciThis->dragWasDropped); - sciThis->inDragDrop = ddNone; + sciThis->inDragDrop = DragDrop::none; } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } } @@ -2832,7 +2931,7 @@ gboolean ScintillaGTK::Drop(GtkWidget *widget, GdkDragContext * /*context*/, //Platform::DebugPrintf("Drop %x\n", sciThis); sciThis->SetDragPosition(SelectionPosition(Sci::invalidPosition)); } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } return FALSE; } @@ -2844,7 +2943,7 @@ void ScintillaGTK::DragDataReceived(GtkWidget *widget, GdkDragContext * /*contex sciThis->ReceivedDrop(selection_data); sciThis->SetDragPosition(SelectionPosition(Sci::invalidPosition)); } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } } @@ -2871,7 +2970,7 @@ void ScintillaGTK::DragDataGet(GtkWidget *widget, GdkDragContext *context, } sciThis->SetDragPosition(SelectionPosition(Sci::invalidPosition)); } catch (...) { - sciThis->errorStatus = SC_STATUS_FAILURE; + sciThis->errorStatus = Status::Failure; } } @@ -2907,7 +3006,7 @@ void ScintillaGTK::IdleWork() { styleIdleID = 0; } -void ScintillaGTK::QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo) { +void ScintillaGTK::QueueIdleWork(WorkItems items, Sci::Position upTo) { Editor::QueueIdleWork(items, upTo); if (!styleIdleID) { // Only allow one style needed to be queued @@ -2922,7 +3021,9 @@ void ScintillaGTK::SetDocPointer(Document *document) { sciAccessible = ScintillaGTKAccessible::FromAccessible(accessible); if (sciAccessible && pdoc) { oldDoc = pdoc; - oldDoc->AddRef(); + if (oldDoc) { + oldDoc->AddRef(); + } } } @@ -2962,10 +3063,9 @@ gboolean ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, Scintil gboolean ScintillaGTK::DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip) { try { - std::unique_ptr surfaceWindow(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); + std::unique_ptr surfaceWindow(Surface::Allocate(Technology::Default)); surfaceWindow->Init(cr, widget); - surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ctip->codePage); - surfaceWindow->SetDBCSMode(ctip->codePage); + surfaceWindow->SetMode(SurfaceMode(ctip->codePage, false)); ctip->PaintCT(surfaceWindow.get()); surfaceWindow->Release(); } catch (...) { @@ -2978,11 +3078,10 @@ gboolean ScintillaGTK::DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip) { gboolean ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip *ctip) { try { - std::unique_ptr surfaceWindow(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); + std::unique_ptr surfaceWindow(Surface::Allocate(Technology::Default)); cairo_t *cr = gdk_cairo_create(WindowFromWidget(widget)); surfaceWindow->Init(cr, widget); - surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ctip->codePage); - surfaceWindow->SetDBCSMode(ctip->codePage); + surfaceWindow->SetMode(SurfaceMode(ctip->codePage, false)); ctip->PaintCT(surfaceWindow.get()); surfaceWindow->Release(); cairo_destroy(cr); @@ -3004,14 +3103,23 @@ AtkObject *ScintillaGTK::GetAccessible(GtkWidget *widget) { sptr_t ScintillaGTK::DirectFunction( sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { - return reinterpret_cast(ptr)->WndProc(iMessage, wParam, lParam); + ScintillaGTK *sci = reinterpret_cast(ptr); + return sci->WndProc(static_cast(iMessage), wParam, lParam); +} + +sptr_t ScintillaGTK::DirectStatusFunction( + sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam, int *pStatus) { + ScintillaGTK *sci = reinterpret_cast(ptr); + const sptr_t returnValue = sci->WndProc(static_cast(iMessage), wParam, lParam); + *pStatus = static_cast(sci->errorStatus); + return returnValue; } /* legacy name for scintilla_object_send_message */ GEANY_API_SYMBOL sptr_t scintilla_send_message(ScintillaObject *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { ScintillaGTK *psci = static_cast(sci->pscin); - return psci->WndProc(iMessage, wParam, lParam); + return psci->WndProc(static_cast(iMessage), wParam, lParam); } GEANY_API_SYMBOL @@ -3022,9 +3130,6 @@ gintptr scintilla_object_send_message(ScintillaObject *sci, unsigned int iMessag static void scintilla_class_init(ScintillaClass *klass); static void scintilla_init(ScintillaObject *sci); -extern void Platform_Initialise(); -extern void Platform_Finalise(); - /* legacy name for scintilla_object_get_type */ GEANY_API_SYMBOL GType scintilla_get_type() { @@ -3122,7 +3227,7 @@ static void scintilla_class_init(ScintillaClass *klass) { GtkWidgetClass *widget_class = (GtkWidgetClass *) klass; GtkContainerClass *container_class = (GtkContainerClass *) klass; - const GSignalFlags sigflags = GSignalFlags(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST); + const GSignalFlags sigflags = static_cast(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST); scintilla_signals[COMMAND_SIGNAL] = g_signal_new( "command", G_TYPE_FROM_CLASS(object_class), @@ -3177,7 +3282,7 @@ GtkWidget *scintilla_object_new() { void scintilla_set_id(ScintillaObject *sci, uptr_t id) { ScintillaGTK *psci = static_cast(sci->pscin); - psci->ctrlID = id; + psci->ctrlID = static_cast(id); } void scintilla_release_resources(void) { diff --git a/scintilla/gtk/ScintillaGTK.h b/scintilla/gtk/ScintillaGTK.h index e8c61f85f0..2db733c87d 100644 --- a/scintilla/gtk/ScintillaGTK.h +++ b/scintilla/gtk/ScintillaGTK.h @@ -6,12 +6,21 @@ #ifndef SCINTILLAGTK_H #define SCINTILLAGTK_H -namespace Scintilla { +namespace Scintilla::Internal { class ScintillaGTKAccessible; #define OBJECT_CLASS GObjectClass +struct FontOptions { + cairo_antialias_t antialias {}; + cairo_subpixel_order_t order {}; + cairo_hint_style_t hint {}; + FontOptions() noexcept = default; + explicit FontOptions(GtkWidget *widget) noexcept; + bool operator==(const FontOptions &other) const noexcept; +}; + class ScintillaGTK : public ScintillaBase { friend class ScintillaGTKAccessible; @@ -21,7 +30,6 @@ class ScintillaGTK : public ScintillaBase { Window scrollbarh; GtkAdjustment *adjustmentv; GtkAdjustment *adjustmenth; - Window wSelection; int verticalScrollBarWidth; int horizontalScrollBarHeight; @@ -36,12 +44,13 @@ class ScintillaGTK : public ScintillaBase { GtkWidgetClass *parentClass; - static GdkAtom atomUTF8; - static GdkAtom atomUTF8Mime; - static GdkAtom atomString; - static GdkAtom atomUriList; - static GdkAtom atomDROPFILES_DND; + static inline GdkAtom atomUTF8 {}; + static inline GdkAtom atomUTF8Mime {}; + static inline GdkAtom atomString {}; + static inline GdkAtom atomUriList {}; + static inline GdkAtom atomDROPFILES_DND {}; GdkAtom atomSought; + size_t inClearSelection = 0; #if PLAT_GTK_WIN32 CLIPFORMAT cfColumnSelect; @@ -69,6 +78,7 @@ class ScintillaGTK : public ScintillaBase { bool repaintFullWindow; guint styleIdleID; + FontOptions fontOptionsPrevious; int accessibilityEnabled; AtkObject *accessible; @@ -92,17 +102,19 @@ class ScintillaGTK : public ScintillaBase { Sci::Position TargetAsUTF8(char *text) const; Sci::Position EncodedFromUTF8(const char *utf8, char *encoded) const; bool ValidCodePage(int codePage) const override; + std::string UTF8FromEncoded(std::string_view encoded) const override; + std::string EncodedFromUTF8(std::string_view utf8) const override; public: // Public for scintilla_send_message - sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) override; + sptr_t WndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) override; private: - sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) override; + sptr_t DefWndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) override; struct TimeThunk { TickReason reason; ScintillaGTK *scintilla; guint timer; - TimeThunk() noexcept : reason(tickCaret), scintilla(nullptr), timer(0) {} + TimeThunk() noexcept : reason(TickReason::caret), scintilla(nullptr), timer(0) {} }; - TimeThunk timers[tickDwell+1]; + TimeThunk timers[static_cast(TickReason::dwell)+1]; bool FineTickerRunning(TickReason reason) override; void FineTickerStart(TickReason reason, int millis, int tolerance) override; void FineTickerCancel(TickReason reason) override; @@ -119,13 +131,13 @@ class ScintillaGTK : public ScintillaBase { void ReconfigureScrollBars() override; void NotifyChange() override; void NotifyFocus(bool focus) override; - void NotifyParent(SCNotification scn) override; - void NotifyKey(int key, int modifiers); + void NotifyParent(Scintilla::NotificationData scn) override; + void NotifyKey(Scintilla::Keys key, Scintilla::KeyMod modifiers); void NotifyURIDropped(const char *list); const char *CharacterSetID() const; - CaseFolder *CaseFolderForEncoding() override; - std::string CaseMapString(const std::string &s, int caseMapping) override; - int KeyDefault(int key, int modifiers) override; + std::unique_ptr CaseFolderForEncoding() override; + std::string CaseMapString(const std::string &s, CaseMapping caseMapping) override; + int KeyDefault(Scintilla::Keys key, Scintilla::KeyMod modifiers) override; void CopyToClipboard(const SelectionText &selectedText) override; void Copy() override; void RequestSelection(GdkAtom atomSelection); @@ -148,9 +160,13 @@ class ScintillaGTK : public ScintillaBase { static void ClipboardGetSelection(GtkClipboard *clip, GtkSelectionData *selection_data, guint info, void *data); static void ClipboardClearSelection(GtkClipboard *clip, void *data); + void ClearPrimarySelection(); + void PrimaryGetSelectionThis(GtkClipboard *clip, GtkSelectionData *selection_data, guint info); + static void PrimaryGetSelection(GtkClipboard *clip, GtkSelectionData *selection_data, guint info, gpointer pSci); + void PrimaryClearSelectionThis(GtkClipboard *clip); + static void PrimaryClearSelection(GtkClipboard *clip, gpointer pSci); + void UnclaimSelection(GdkEventSelection *selection_event); - static void PrimarySelection(GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time_stamp, ScintillaGTK *sciThis); - static gboolean PrimaryClear(GtkWidget *widget, GdkEventSelection *event, ScintillaGTK *sciThis); void Resize(int width, int height); // Callback functions @@ -172,6 +188,7 @@ class ScintillaGTK : public ScintillaBase { static void GetPreferredHeight(GtkWidget *widget, gint *minimalHeight, gint *naturalHeight); #endif static void SizeAllocate(GtkWidget *widget, GtkAllocation *allocation); + void CheckForFontOptionChange(); #if GTK_CHECK_VERSION(3,0,0) gboolean DrawTextThis(cairo_t *cr); static gboolean DrawText(GtkWidget *widget, cairo_t *cr, ScintillaGTK *sciThis); @@ -212,8 +229,8 @@ class ScintillaGTK : public ScintillaBase { void PreeditChangedInlineThis(); void PreeditChangedWindowedThis(); static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis); - void MoveImeCarets(int pos); - void DrawImeIndicator(int indicator, int len); + void MoveImeCarets(Sci::Position pos); + void DrawImeIndicator(int indicator, Sci::Position len); void SetCandidateWindowPos(); static void StyleSetText(GtkWidget *widget, GtkStyle *previous, void *); @@ -241,7 +258,7 @@ class ScintillaGTK : public ScintillaBase { static gboolean IdleCallback(gpointer pSci); static gboolean StyleIdle(gpointer pSci); void IdleWork() override; - void QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo) override; + void QueueIdleWork(WorkItems items, Sci::Position upTo) override; void SetDocPointer(Document *document) override; static void PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis); @@ -254,6 +271,8 @@ class ScintillaGTK : public ScintillaBase { static sptr_t DirectFunction(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam); + static sptr_t DirectStatusFunction(sptr_t ptr, + unsigned int iMessage, uptr_t wParam, sptr_t lParam, int *pStatus); }; // helper class to watch a GObject lifetime and get notified when it dies diff --git a/scintilla/gtk/ScintillaGTKAccessible.cxx b/scintilla/gtk/ScintillaGTKAccessible.cxx index 90b41ebc6c..bff9a45720 100644 --- a/scintilla/gtk/ScintillaGTKAccessible.cxx +++ b/scintilla/gtk/ScintillaGTKAccessible.cxx @@ -59,8 +59,11 @@ #include #include #include +#include #include #include +#include +#include #include #include @@ -86,14 +89,19 @@ #endif // ScintillaGTK.h and stuff it needs -#include "Platform.h" - +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" +#include "ScintillaStructures.h" #include "ILoader.h" #include "ILexer.h" + +#include "Debugging.h" +#include "Geometry.h" +#include "Platform.h" + #include "Scintilla.h" #include "ScintillaWidget.h" -#include "StringCopy.h" -#include "CharacterCategory.h" +#include "CharacterCategoryMap.h" #include "Position.h" #include "UniqueString.h" #include "SplitVector.h" @@ -126,6 +134,7 @@ #include "ScintillaGTKAccessible.h" using namespace Scintilla; +using namespace Scintilla::Internal; struct ScintillaObjectAccessiblePrivate { ScintillaGTKAccessible *pscin; @@ -219,30 +228,30 @@ gchar *ScintillaGTKAccessible::GetTextAfterOffset(int charOffset, break; case ATK_TEXT_BOUNDARY_WORD_START: - startByte = sci->WndProc(SCI_WORDENDPOSITION, byteOffset, 1); - startByte = sci->WndProc(SCI_WORDENDPOSITION, startByte, 0); - endByte = sci->WndProc(SCI_WORDENDPOSITION, startByte, 1); - endByte = sci->WndProc(SCI_WORDENDPOSITION, endByte, 0); + startByte = sci->WndProc(Message::WordEndPosition, byteOffset, 1); + startByte = sci->WndProc(Message::WordEndPosition, startByte, 0); + endByte = sci->WndProc(Message::WordEndPosition, startByte, 1); + endByte = sci->WndProc(Message::WordEndPosition, endByte, 0); break; case ATK_TEXT_BOUNDARY_WORD_END: - startByte = sci->WndProc(SCI_WORDENDPOSITION, byteOffset, 0); - startByte = sci->WndProc(SCI_WORDENDPOSITION, startByte, 1); - endByte = sci->WndProc(SCI_WORDENDPOSITION, startByte, 0); - endByte = sci->WndProc(SCI_WORDENDPOSITION, endByte, 1); + startByte = sci->WndProc(Message::WordEndPosition, byteOffset, 0); + startByte = sci->WndProc(Message::WordEndPosition, startByte, 1); + endByte = sci->WndProc(Message::WordEndPosition, startByte, 0); + endByte = sci->WndProc(Message::WordEndPosition, endByte, 1); break; case ATK_TEXT_BOUNDARY_LINE_START: { - int line = sci->WndProc(SCI_LINEFROMPOSITION, byteOffset, 0); - startByte = sci->WndProc(SCI_POSITIONFROMLINE, line + 1, 0); - endByte = sci->WndProc(SCI_POSITIONFROMLINE, line + 2, 0); + int line = sci->WndProc(Message::LineFromPosition, byteOffset, 0); + startByte = sci->WndProc(Message::PositionFromLine, line + 1, 0); + endByte = sci->WndProc(Message::PositionFromLine, line + 2, 0); break; } case ATK_TEXT_BOUNDARY_LINE_END: { - int line = sci->WndProc(SCI_LINEFROMPOSITION, byteOffset, 0); - startByte = sci->WndProc(SCI_GETLINEENDPOSITION, line, 0); - endByte = sci->WndProc(SCI_GETLINEENDPOSITION, line + 1, 0); + int line = sci->WndProc(Message::LineFromPosition, byteOffset, 0); + startByte = sci->WndProc(Message::GetLineEndPosition, line, 0); + endByte = sci->WndProc(Message::GetLineEndPosition, line + 1, 0); break; } @@ -269,24 +278,24 @@ gchar *ScintillaGTKAccessible::GetTextBeforeOffset(int charOffset, break; case ATK_TEXT_BOUNDARY_WORD_START: - endByte = sci->WndProc(SCI_WORDSTARTPOSITION, byteOffset, 0); - endByte = sci->WndProc(SCI_WORDSTARTPOSITION, endByte, 1); - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, endByte, 0); - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, startByte, 1); + endByte = sci->WndProc(Message::WordStartPosition, byteOffset, 0); + endByte = sci->WndProc(Message::WordStartPosition, endByte, 1); + startByte = sci->WndProc(Message::WordStartPosition, endByte, 0); + startByte = sci->WndProc(Message::WordStartPosition, startByte, 1); break; case ATK_TEXT_BOUNDARY_WORD_END: - endByte = sci->WndProc(SCI_WORDSTARTPOSITION, byteOffset, 1); - endByte = sci->WndProc(SCI_WORDSTARTPOSITION, endByte, 0); - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, endByte, 1); - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, startByte, 0); + endByte = sci->WndProc(Message::WordStartPosition, byteOffset, 1); + endByte = sci->WndProc(Message::WordStartPosition, endByte, 0); + startByte = sci->WndProc(Message::WordStartPosition, endByte, 1); + startByte = sci->WndProc(Message::WordStartPosition, startByte, 0); break; case ATK_TEXT_BOUNDARY_LINE_START: { - int line = sci->WndProc(SCI_LINEFROMPOSITION, byteOffset, 0); - endByte = sci->WndProc(SCI_POSITIONFROMLINE, line, 0); + int line = sci->WndProc(Message::LineFromPosition, byteOffset, 0); + endByte = sci->WndProc(Message::PositionFromLine, line, 0); if (line > 0) { - startByte = sci->WndProc(SCI_POSITIONFROMLINE, line - 1, 0); + startByte = sci->WndProc(Message::PositionFromLine, line - 1, 0); } else { startByte = endByte; } @@ -294,14 +303,14 @@ gchar *ScintillaGTKAccessible::GetTextBeforeOffset(int charOffset, } case ATK_TEXT_BOUNDARY_LINE_END: { - int line = sci->WndProc(SCI_LINEFROMPOSITION, byteOffset, 0); + int line = sci->WndProc(Message::LineFromPosition, byteOffset, 0); if (line > 0) { - endByte = sci->WndProc(SCI_GETLINEENDPOSITION, line - 1, 0); + endByte = sci->WndProc(Message::GetLineEndPosition, line - 1, 0); } else { endByte = 0; } if (line > 1) { - startByte = sci->WndProc(SCI_GETLINEENDPOSITION, line - 2, 0); + startByte = sci->WndProc(Message::GetLineEndPosition, line - 2, 0); } else { startByte = endByte; } @@ -327,46 +336,46 @@ gchar *ScintillaGTKAccessible::GetTextAtOffset(int charOffset, switch (boundaryType) { case ATK_TEXT_BOUNDARY_CHAR: startByte = byteOffset; - endByte = sci->WndProc(SCI_POSITIONAFTER, byteOffset, 0); + endByte = sci->WndProc(Message::PositionAfter, byteOffset, 0); break; case ATK_TEXT_BOUNDARY_WORD_START: - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, byteOffset, 1); - endByte = sci->WndProc(SCI_WORDENDPOSITION, byteOffset, 1); - if (! sci->WndProc(SCI_ISRANGEWORD, startByte, endByte)) { + startByte = sci->WndProc(Message::WordStartPosition, byteOffset, 1); + endByte = sci->WndProc(Message::WordEndPosition, byteOffset, 1); + if (! sci->WndProc(Message::IsRangeWord, startByte, endByte)) { // if the cursor was not on a word, forward back - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, startByte, 0); - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, startByte, 1); + startByte = sci->WndProc(Message::WordStartPosition, startByte, 0); + startByte = sci->WndProc(Message::WordStartPosition, startByte, 1); } - endByte = sci->WndProc(SCI_WORDENDPOSITION, endByte, 0); + endByte = sci->WndProc(Message::WordEndPosition, endByte, 0); break; case ATK_TEXT_BOUNDARY_WORD_END: - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, byteOffset, 1); - endByte = sci->WndProc(SCI_WORDENDPOSITION, byteOffset, 1); - if (! sci->WndProc(SCI_ISRANGEWORD, startByte, endByte)) { + startByte = sci->WndProc(Message::WordStartPosition, byteOffset, 1); + endByte = sci->WndProc(Message::WordEndPosition, byteOffset, 1); + if (! sci->WndProc(Message::IsRangeWord, startByte, endByte)) { // if the cursor was not on a word, forward back - endByte = sci->WndProc(SCI_WORDENDPOSITION, endByte, 0); - endByte = sci->WndProc(SCI_WORDENDPOSITION, endByte, 1); + endByte = sci->WndProc(Message::WordEndPosition, endByte, 0); + endByte = sci->WndProc(Message::WordEndPosition, endByte, 1); } - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, startByte, 0); + startByte = sci->WndProc(Message::WordStartPosition, startByte, 0); break; case ATK_TEXT_BOUNDARY_LINE_START: { - int line = sci->WndProc(SCI_LINEFROMPOSITION, byteOffset, 0); - startByte = sci->WndProc(SCI_POSITIONFROMLINE, line, 0); - endByte = sci->WndProc(SCI_POSITIONFROMLINE, line + 1, 0); + int line = sci->WndProc(Message::LineFromPosition, byteOffset, 0); + startByte = sci->WndProc(Message::PositionFromLine, line, 0); + endByte = sci->WndProc(Message::PositionFromLine, line + 1, 0); break; } case ATK_TEXT_BOUNDARY_LINE_END: { - int line = sci->WndProc(SCI_LINEFROMPOSITION, byteOffset, 0); + int line = sci->WndProc(Message::LineFromPosition, byteOffset, 0); if (line > 0) { - startByte = sci->WndProc(SCI_GETLINEENDPOSITION, line - 1, 0); + startByte = sci->WndProc(Message::GetLineEndPosition, line - 1, 0); } else { startByte = 0; } - endByte = sci->WndProc(SCI_GETLINEENDPOSITION, line, 0); + endByte = sci->WndProc(Message::GetLineEndPosition, line, 0); break; } @@ -390,16 +399,16 @@ gchar *ScintillaGTKAccessible::GetStringAtOffset(int charOffset, switch (granularity) { case ATK_TEXT_GRANULARITY_CHAR: startByte = byteOffset; - endByte = sci->WndProc(SCI_POSITIONAFTER, byteOffset, 0); + endByte = sci->WndProc(Message::PositionAfter, byteOffset, 0); break; case ATK_TEXT_GRANULARITY_WORD: - startByte = sci->WndProc(SCI_WORDSTARTPOSITION, byteOffset, 1); - endByte = sci->WndProc(SCI_WORDENDPOSITION, byteOffset, 1); + startByte = sci->WndProc(Message::WordStartPosition, byteOffset, 1); + endByte = sci->WndProc(Message::WordEndPosition, byteOffset, 1); break; case ATK_TEXT_GRANULARITY_LINE: { - gint line = sci->WndProc(SCI_LINEFROMPOSITION, byteOffset, 0); - startByte = sci->WndProc(SCI_POSITIONFROMLINE, line, 0); - endByte = sci->WndProc(SCI_GETLINEENDPOSITION, line, 0); + gint line = sci->WndProc(Message::LineFromPosition, byteOffset, 0); + startByte = sci->WndProc(Message::PositionFromLine, line, 0); + endByte = sci->WndProc(Message::GetLineEndPosition, line, 0); break; } default: @@ -429,11 +438,11 @@ gint ScintillaGTKAccessible::GetCharacterCount() { } gint ScintillaGTKAccessible::GetCaretOffset() { - return CharacterOffsetFromByteOffset(sci->WndProc(SCI_GETCURRENTPOS, 0, 0)); + return CharacterOffsetFromByteOffset(sci->WndProc(Message::GetCurrentPos, 0, 0)); } gboolean ScintillaGTKAccessible::SetCaretOffset(int charOffset) { - sci->WndProc(SCI_GOTOPOS, ByteOffsetFromCharacterOffset(charOffset), 0); + sci->WndProc(Message::GotoPos, ByteOffsetFromCharacterOffset(charOffset), 0); return TRUE; } @@ -457,7 +466,7 @@ gint ScintillaGTKAccessible::GetOffsetAtPoint(gint x, gint y, AtkCoordType coord } // FIXME: should we handle scrolling? - return CharacterOffsetFromByteOffset(sci->WndProc(SCI_CHARPOSITIONFROMPOINTCLOSE, x, y)); + return CharacterOffsetFromByteOffset(sci->WndProc(Message::CharPositionFromPointClose, x, y)); } void ScintillaGTKAccessible::GetCharacterExtents(int charOffset, @@ -467,14 +476,14 @@ void ScintillaGTKAccessible::GetCharacterExtents(int charOffset, Sci::Position byteOffset = ByteOffsetFromCharacterOffset(charOffset); // FIXME: should we handle scrolling? - *x = sci->WndProc(SCI_POINTXFROMPOSITION, 0, byteOffset); - *y = sci->WndProc(SCI_POINTYFROMPOSITION, 0, byteOffset); + *x = sci->WndProc(Message::PointXFromPosition, 0, byteOffset); + *y = sci->WndProc(Message::PointYFromPosition, 0, byteOffset); - int line = sci->WndProc(SCI_LINEFROMPOSITION, byteOffset, 0); - *height = sci->WndProc(SCI_TEXTHEIGHT, line, 0); + int line = sci->WndProc(Message::LineFromPosition, byteOffset, 0); + *height = sci->WndProc(Message::TextHeight, line, 0); int nextByteOffset = PositionAfter(byteOffset); - int next_x = sci->WndProc(SCI_POINTXFROMPOSITION, 0, nextByteOffset); + int next_x = sci->WndProc(Message::PointXFromPosition, 0, nextByteOffset); if (next_x > *x) { *width = next_x - *x; } else if (nextByteOffset > byteOffset) { @@ -520,7 +529,7 @@ static AtkAttributeSet *AddTextIntAttribute(AtkAttributeSet *attributes, AtkText return AddTextAttribute(attributes, attr, g_strdup(atk_text_attribute_get_value(attr, i))); } -static AtkAttributeSet *AddTextColorAttribute(AtkAttributeSet *attributes, AtkTextAttribute attr, const ColourDesired &colour) { +static AtkAttributeSet *AddTextColorAttribute(AtkAttributeSet *attributes, AtkTextAttribute attr, ColourRGBA colour) { return AddTextAttribute(attributes, attr, g_strdup_printf("%u,%u,%u", colour.GetRed() * 257, colour.GetGreen() * 257, colour.GetBlue() * 257)); } @@ -534,7 +543,7 @@ AtkAttributeSet *ScintillaGTKAccessible::GetAttributesForStyle(unsigned int styl attr_set = AddTextAttribute(attr_set, ATK_TEXT_ATTR_FAMILY_NAME, g_strdup(style.fontName)); attr_set = AddTextAttribute(attr_set, ATK_TEXT_ATTR_SIZE, g_strdup_printf("%d", style.size / SC_FONT_SIZE_MULTIPLIER)); - attr_set = AddTextIntAttribute(attr_set, ATK_TEXT_ATTR_WEIGHT, CLAMP(style.weight, 100, 1000)); + attr_set = AddTextIntAttribute(attr_set, ATK_TEXT_ATTR_WEIGHT, CLAMP(static_cast(style.weight), 100, 1000)); attr_set = AddTextIntAttribute(attr_set, ATK_TEXT_ATTR_STYLE, style.italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL); attr_set = AddTextIntAttribute(attr_set, ATK_TEXT_ATTR_UNDERLINE, style.underline ? PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE); attr_set = AddTextColorAttribute(attr_set, ATK_TEXT_ATTR_FG_COLOR, style.fore); @@ -550,7 +559,7 @@ AtkAttributeSet *ScintillaGTKAccessible::GetRunAttributes(int charOffset, int *s Sci::Position byteOffset; if (charOffset == -1) { - byteOffset = sci->WndProc(SCI_GETCURRENTPOS, 0, 0); + byteOffset = sci->WndProc(Message::GetCurrentPos, 0, 0); } else { byteOffset = ByteOffsetFromCharacterOffset(charOffset); } @@ -597,9 +606,9 @@ gboolean ScintillaGTKAccessible::AddSelection(int startChar, int endChar) { ByteRangeFromCharacterRange(startChar, endChar, startByte, endByte); // use WndProc() to set the selections so it notifies as needed if (n_selections > 1 || ! sci->sel.Empty()) { - sci->WndProc(SCI_ADDSELECTION, startByte, endByte); + sci->WndProc(Message::AddSelection, startByte, endByte); } else { - sci->WndProc(SCI_SETSELECTION, startByte, endByte); + sci->WndProc(Message::SetSelection, startByte, endByte); } return TRUE; @@ -611,11 +620,11 @@ gboolean ScintillaGTKAccessible::RemoveSelection(gint selection_num) { return FALSE; if (n_selections > 1) { - sci->WndProc(SCI_DROPSELECTIONN, selection_num, 0); + sci->WndProc(Message::DropSelectionN, selection_num, 0); } else if (sci->sel.Empty()) { return FALSE; } else { - sci->WndProc(SCI_CLEARSELECTIONS, 0, 0); + sci->WndProc(Message::ClearSelections, 0, 0); } return TRUE; @@ -628,8 +637,8 @@ gboolean ScintillaGTKAccessible::SetSelection(gint selection_num, int startChar, Sci::Position startByte, endByte; ByteRangeFromCharacterRange(startChar, endChar, startByte, endByte); - sci->WndProc(SCI_SETSELECTIONNSTART, selection_num, startByte); - sci->WndProc(SCI_SETSELECTIONNEND, selection_num, endByte); + sci->WndProc(Message::SetSelectionNStart, selection_num, startByte); + sci->WndProc(Message::SetSelectionNEnd, selection_num, endByte); return TRUE; } @@ -662,7 +671,7 @@ void ScintillaGTKAccessible::AtkTextIface::init(::AtkTextIface *iface) { void ScintillaGTKAccessible::SetTextContents(const gchar *contents) { // FIXME: it's probably useless to check for READONLY here, SETTEXT probably does it just fine? if (! sci->pdoc->IsReadOnly()) { - sci->WndProc(SCI_SETTEXT, 0, (sptr_t) contents); + sci->WndProc(Message::SetText, 0, (sptr_t) contents); } } @@ -793,7 +802,7 @@ bool ScintillaGTKAccessible::Enabled() const { // Callbacks void ScintillaGTKAccessible::UpdateCursor() { - Sci::Position pos = sci->WndProc(SCI_GETCURRENTPOS, 0, 0); + Sci::Position pos = sci->WndProc(Message::GetCurrentPos, 0, 0); if (old_pos != pos) { int charPosition = CharacterOffsetFromByteOffset(pos); g_signal_emit_by_name(accessible, "text-caret-moved", charPosition); @@ -863,39 +872,41 @@ void ScintillaGTKAccessible::NotifyReadOnly() { void ScintillaGTKAccessible::SetAccessibility(bool enabled) { // Called by ScintillaGTK when application has enabled or disabled accessibility if (enabled) - sci->pdoc->AllocateLineCharacterIndex(SC_LINECHARACTERINDEX_UTF32); + sci->pdoc->AllocateLineCharacterIndex(LineCharacterIndexType::Utf32); else - sci->pdoc->ReleaseLineCharacterIndex(SC_LINECHARACTERINDEX_UTF32); + sci->pdoc->ReleaseLineCharacterIndex(LineCharacterIndexType::Utf32); } -void ScintillaGTKAccessible::Notify(GtkWidget *, gint, SCNotification *nt) { +void ScintillaGTKAccessible::Notify(GtkWidget *, gint, NotificationData *nt) { if (!Enabled()) return; switch (nt->nmhdr.code) { - case SCN_MODIFIED: { - if (nt->modificationType & SC_MOD_INSERTTEXT) { + case Notification::Modified: { + if (FlagSet(nt->modificationType, ModificationFlags::InsertText)) { int startChar = CharacterOffsetFromByteOffset(nt->position); int lengthChar = sci->pdoc->CountCharacters(nt->position, nt->position + nt->length); g_signal_emit_by_name(accessible, "text-changed::insert", startChar, lengthChar); UpdateCursor(); } - if (nt->modificationType & SC_MOD_BEFOREDELETE) { + if (FlagSet(nt->modificationType, ModificationFlags::BeforeDelete)) { int startChar = CharacterOffsetFromByteOffset(nt->position); int lengthChar = sci->pdoc->CountCharacters(nt->position, nt->position + nt->length); g_signal_emit_by_name(accessible, "text-changed::delete", startChar, lengthChar); } - if (nt->modificationType & SC_MOD_DELETETEXT) { + if (FlagSet(nt->modificationType, ModificationFlags::DeleteText)) { UpdateCursor(); } - if (nt->modificationType & SC_MOD_CHANGESTYLE) { + if (FlagSet(nt->modificationType, ModificationFlags::ChangeStyle)) { g_signal_emit_by_name(accessible, "text-attributes-changed"); } } break; - case SCN_UPDATEUI: { - if (nt->updated & SC_UPDATE_SELECTION) { + case Notification::UpdateUI: { + if (FlagSet(nt->updated, Update::Selection)) { UpdateCursor(); } } break; + default: + break; } } @@ -1004,7 +1015,7 @@ static gpointer scintilla_object_accessible_parent_class = nullptr; // @p parent_type is only required on GTK 3.2 to 3.6, and only on the first call static GType scintilla_object_accessible_get_type(GType parent_type G_GNUC_UNUSED) { - static volatile gsize type_id_result = 0; + static gsize type_id_result = 0; if (g_once_init_enter(&type_id_result)) { GTypeInfo tinfo = { @@ -1095,7 +1106,7 @@ AtkObject *ScintillaGTKAccessible::WidgetGetAccessibleImpl(GtkWidget *widget, At #if HAVE_GTK_A11Y_H // just instantiate the accessible *cache = scintilla_object_accessible_new(0, G_OBJECT(widget)); #elif HAVE_GTK_FACTORY // register in the factory and let GTK instantiate - static volatile gsize registered = 0; + static gsize registered = 0; if (g_once_init_enter(®istered)) { // Figure out whether accessibility is enabled by looking at the type of the accessible @@ -1141,7 +1152,7 @@ static AtkStateSet *scintilla_object_accessible_ref_state_set(AtkObject *accessi if (widget == nullptr) { atk_state_set_add_state(state_set, ATK_STATE_DEFUNCT); } else { - if (! scintilla_send_message(SCINTILLA_OBJECT(widget), SCI_GETREADONLY, 0, 0)) + if (! scintilla_send_message(SCINTILLA_OBJECT(widget), static_cast(Message::GetReadOnly), 0, 0)) atk_state_set_add_state(state_set, ATK_STATE_EDITABLE); #if ATK_CHECK_VERSION(2, 16, 0) else diff --git a/scintilla/gtk/ScintillaGTKAccessible.h b/scintilla/gtk/ScintillaGTKAccessible.h index 2168d034c9..169dd507a9 100644 --- a/scintilla/gtk/ScintillaGTKAccessible.h +++ b/scintilla/gtk/ScintillaGTKAccessible.h @@ -6,7 +6,7 @@ #ifndef SCINTILLAGTKACCESSIBLE_H #define SCINTILLAGTKACCESSIBLE_H -namespace Scintilla { +namespace Scintilla::Internal { #ifndef ATK_CHECK_VERSION # define ATK_CHECK_VERSION(x, y, z) 0 @@ -24,25 +24,25 @@ class ScintillaGTKAccessible { bool Enabled() const; void UpdateCursor(); - void Notify(GtkWidget *widget, gint code, SCNotification *nt); - static void SciNotify(GtkWidget *widget, gint code, SCNotification *nt, gpointer data) { + void Notify(GtkWidget *widget, gint code, Scintilla::NotificationData *nt); + static void SciNotify(GtkWidget *widget, gint code, Scintilla::NotificationData *nt, gpointer data) { try { static_cast(data)->Notify(widget, code, nt); } catch (...) {} } Sci::Position ByteOffsetFromCharacterOffset(Sci::Position startByte, int characterOffset) { - if (!(sci->pdoc->LineCharacterIndex() & SC_LINECHARACTERINDEX_UTF32)) { + if (!FlagSet(sci->pdoc->LineCharacterIndex(), Scintilla::LineCharacterIndexType::Utf32)) { return startByte + characterOffset; } if (characterOffset > 0) { // Try and reduce the range by reverse-looking into the character offset cache Sci::Line lineStart = sci->pdoc->LineFromPosition(startByte); - Sci::Position posStart = sci->pdoc->IndexLineStart(lineStart, SC_LINECHARACTERINDEX_UTF32); - Sci::Line line = sci->pdoc->LineFromPositionIndex(posStart + characterOffset, SC_LINECHARACTERINDEX_UTF32); + Sci::Position posStart = sci->pdoc->IndexLineStart(lineStart, Scintilla::LineCharacterIndexType::Utf32); + Sci::Line line = sci->pdoc->LineFromPositionIndex(posStart + characterOffset, Scintilla::LineCharacterIndexType::Utf32); if (line != lineStart) { startByte += sci->pdoc->LineStart(line) - sci->pdoc->LineStart(lineStart); - characterOffset -= sci->pdoc->IndexLineStart(line, SC_LINECHARACTERINDEX_UTF32) - posStart; + characterOffset -= sci->pdoc->IndexLineStart(line, Scintilla::LineCharacterIndexType::Utf32) - posStart; } } Sci::Position pos = sci->pdoc->GetRelativePosition(startByte, characterOffset); @@ -62,12 +62,12 @@ class ScintillaGTKAccessible { } Sci::Position CharacterOffsetFromByteOffset(Sci::Position byteOffset) { - if (!(sci->pdoc->LineCharacterIndex() & SC_LINECHARACTERINDEX_UTF32)) { + if (!FlagSet(sci->pdoc->LineCharacterIndex(), Scintilla::LineCharacterIndexType::Utf32)) { return byteOffset; } const Sci::Line line = sci->pdoc->LineFromPosition(byteOffset); const Sci::Position lineStart = sci->pdoc->LineStart(line); - return sci->pdoc->IndexLineStart(line, SC_LINECHARACTERINDEX_UTF32) + sci->pdoc->CountCharacters(lineStart, byteOffset); + return sci->pdoc->IndexLineStart(line, Scintilla::LineCharacterIndexType::Utf32) + sci->pdoc->CountCharacters(lineStart, byteOffset); } void CharacterRangeFromByteRange(Sci::Position startByte, Sci::Position endByte, int *startChar, int *endChar) { diff --git a/scintilla/include/Compat.h b/scintilla/include/Compat.h deleted file mode 100644 index b6d41e5918..0000000000 --- a/scintilla/include/Compat.h +++ /dev/null @@ -1,70 +0,0 @@ -// c++11 compatibility with some c++14 features and higher. -// This helps minimize changes from the default branch. - -#ifndef COMPAT_H -#define COMPAT_H - -#ifdef __cplusplus - -#include -#include -#include -#include -#include - -namespace Sci { - -// std::clamp -template -inline constexpr T clamp(T val, T minVal, T maxVal) { - return (val > maxVal) ? maxVal : ((val < minVal) ? minVal : val); -} - -// std::round (not present on older MacOSX SDKs) -template -T round(T arg) { - return ::round(arg); -} - -// std::lround (not present on older MacOSX SDKs) -template -long lround(T arg) { - return ::lround(arg); -} - -// std::make_unique -template struct _Unique_if { - typedef std::unique_ptr _Single_object; -}; -template struct _Unique_if { - typedef std::unique_ptr _Unknown_bound; -}; -template struct _Unique_if { - typedef void _Known_bound; -}; -template - typename _Unique_if::_Single_object - make_unique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); - } -template - typename _Unique_if::_Unknown_bound - make_unique(size_t n) { - typedef typename std::remove_extent::type U; - return std::unique_ptr(new U[n]()); - } -template - typename _Unique_if::_Known_bound - make_unique(Args&&...) = delete; - -// std::size -template -constexpr size_t size(const T (&)[N]) noexcept { - return N; -} - -} - -#endif - -#endif diff --git a/scintilla/include/ILexer.h b/scintilla/include/ILexer.h index f7f188972f..bc9ee1ab54 100644 --- a/scintilla/include/ILexer.h +++ b/scintilla/include/ILexer.h @@ -12,7 +12,7 @@ namespace Scintilla { -enum { dvOriginal=0, dvLineEnd=1 }; +enum { dvRelease4=2 }; class IDocument { public: @@ -27,7 +27,7 @@ class IDocument { virtual int SCI_METHOD SetLevel(Sci_Position line, int level) = 0; virtual int SCI_METHOD GetLineState(Sci_Position line) const = 0; virtual int SCI_METHOD SetLineState(Sci_Position line, int state) = 0; - virtual void SCI_METHOD StartStyling(Sci_Position position, char mask) = 0; + virtual void SCI_METHOD StartStyling(Sci_Position position) = 0; virtual bool SCI_METHOD SetStyleFor(Sci_Position length, char style) = 0; virtual bool SCI_METHOD SetStyles(Sci_Position length, const char *styles) = 0; virtual void SCI_METHOD DecorationSetCurrentIndicator(int indicator) = 0; @@ -37,18 +37,14 @@ class IDocument { virtual bool SCI_METHOD IsDBCSLeadByte(char ch) const = 0; virtual const char * SCI_METHOD BufferPointer() = 0; virtual int SCI_METHOD GetLineIndentation(Sci_Position line) = 0; -}; - -class IDocumentWithLineEnd : public IDocument { -public: virtual Sci_Position SCI_METHOD LineEnd(Sci_Position line) const = 0; virtual Sci_Position SCI_METHOD GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const = 0; virtual int SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const = 0; }; -enum { lvOriginal=0, lvSubStyles=1, lvMetaData=2, lvIdentity=3 }; +enum { lvRelease4=2, lvRelease5=3 }; -class ILexer { +class ILexer4 { public: virtual int SCI_METHOD Version() const = 0; virtual void SCI_METHOD Release() = 0; @@ -61,10 +57,6 @@ class ILexer { virtual void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) = 0; virtual void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) = 0; virtual void * SCI_METHOD PrivateCall(int operation, void *pointer) = 0; -}; - -class ILexerWithSubStyles : public ILexer { -public: virtual int SCI_METHOD LineEndTypesSupported() = 0; virtual int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) = 0; virtual int SCI_METHOD SubStylesStart(int styleBase) = 0; @@ -75,17 +67,13 @@ class ILexerWithSubStyles : public ILexer { virtual void SCI_METHOD SetIdentifiers(int style, const char *identifiers) = 0; virtual int SCI_METHOD DistanceToSecondaryStyles() = 0; virtual const char * SCI_METHOD GetSubStyleBases() = 0; -}; - -class ILexerWithMetaData : public ILexerWithSubStyles { -public: virtual int SCI_METHOD NamedStyles() = 0; virtual const char * SCI_METHOD NameOfStyle(int style) = 0; virtual const char * SCI_METHOD TagsOfStyle(int style) = 0; virtual const char * SCI_METHOD DescriptionOfStyle(int style) = 0; }; -class ILexerWithIdentity : public ILexerWithMetaData { +class ILexer5 : public ILexer4 { public: virtual const char * SCI_METHOD GetName() = 0; virtual int SCI_METHOD GetIdentifier() = 0; diff --git a/scintilla/include/ILoader.h b/scintilla/include/ILoader.h index e989de8736..2fa69f527f 100644 --- a/scintilla/include/ILoader.h +++ b/scintilla/include/ILoader.h @@ -10,6 +10,8 @@ #include "Sci_Position.h" +namespace Scintilla { + class ILoader { public: virtual int SCI_METHOD Release() = 0; @@ -18,4 +20,6 @@ class ILoader { virtual void * SCI_METHOD ConvertToDocument() = 0; }; +} + #endif diff --git a/scintilla/include/Makefile.am b/scintilla/include/Makefile.am deleted file mode 100644 index 9fa85d7c2a..0000000000 --- a/scintilla/include/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -## Process this file with automake to produce Makefile.in - -noinst_HEADERS = \ - ILexer.h \ - ILoader.h \ - Platform.h - -scintilla_includedir = $(includedir)/geany/scintilla/ -scintilla_include_HEADERS = \ - Compat.h \ - SciLexer.h \ - Scintilla.h \ - Scintilla.iface \ - ScintillaWidget.h \ - Sci_Position.h diff --git a/scintilla/include/Platform.h b/scintilla/include/Platform.h deleted file mode 100644 index b5e2109b4d..0000000000 --- a/scintilla/include/Platform.h +++ /dev/null @@ -1,549 +0,0 @@ -// Scintilla source code edit control -/** @file Platform.h - ** Interface to platform facilities. Also includes some basic utilities. - ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows. - **/ -// Copyright 1998-2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef PLATFORM_H -#define PLATFORM_H - -// PLAT_GTK = GTK+ on Linux or Win32 -// PLAT_GTK_WIN32 is defined additionally when running PLAT_GTK under Win32 -// PLAT_WIN = Win32 API on Win32 OS -// PLAT_WX is wxWindows on any supported platform -// PLAT_TK = Tcl/TK on Linux or Win32 - -#define PLAT_GTK 0 -#define PLAT_GTK_WIN32 0 -#define PLAT_GTK_MACOSX 0 -#define PLAT_MACOSX 0 -#define PLAT_WIN 0 -#define PLAT_WX 0 -#define PLAT_QT 0 -#define PLAT_FOX 0 -#define PLAT_CURSES 0 -#define PLAT_TK 0 -#define PLAT_HAIKU 0 - -#if defined(FOX) -#undef PLAT_FOX -#define PLAT_FOX 1 - -#elif defined(__WX__) -#undef PLAT_WX -#define PLAT_WX 1 - -#elif defined(CURSES) -#undef PLAT_CURSES -#define PLAT_CURSES 1 - -#elif defined(__HAIKU__) -#undef PLAT_HAIKU -#define PLAT_HAIKU 1 - -#elif defined(SCINTILLA_QT) -#undef PLAT_QT -#define PLAT_QT 1 - -#elif defined(TK) -#undef PLAT_TK -#define PLAT_TK 1 - -#elif defined(GTK) -#undef PLAT_GTK -#define PLAT_GTK 1 - -#if defined(__WIN32__) || defined(_MSC_VER) -#undef PLAT_GTK_WIN32 -#define PLAT_GTK_WIN32 1 -#endif - -#if defined(__APPLE__) -#undef PLAT_GTK_MACOSX -#define PLAT_GTK_MACOSX 1 -#endif - -#elif defined(__APPLE__) - -#undef PLAT_MACOSX -#define PLAT_MACOSX 1 - -#else -#undef PLAT_WIN -#define PLAT_WIN 1 - -#endif - -namespace Scintilla { - -typedef float XYPOSITION; -typedef double XYACCUMULATOR; - -// Underlying the implementation of the platform classes are platform specific types. -// Sometimes these need to be passed around by client code so they are defined here - -typedef void *FontID; -typedef void *SurfaceID; -typedef void *WindowID; -typedef void *MenuID; -typedef void *TickerID; -typedef void *Function; -typedef void *IdlerID; - -/** - * A geometric point class. - * Point is similar to the Win32 POINT and GTK+ GdkPoint types. - */ -class Point { -public: - XYPOSITION x; - XYPOSITION y; - - constexpr explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) noexcept : x(x_), y(y_) { - } - - static constexpr Point FromInts(int x_, int y_) noexcept { - return Point(static_cast(x_), static_cast(y_)); - } - - constexpr bool operator!=(Point other) const noexcept { - return (x != other.x) || (y != other.y); - } - - constexpr Point operator+(Point other) const noexcept { - return Point(x + other.x, y + other.y); - } - - constexpr Point operator-(Point other) const noexcept { - return Point(x - other.x, y - other.y); - } - - // Other automatically defined methods (assignment, copy constructor, destructor) are fine -}; - -/** - * A geometric rectangle class. - * PRectangle is similar to Win32 RECT. - * PRectangles contain their top and left sides, but not their right and bottom sides. - */ -class PRectangle { -public: - XYPOSITION left; - XYPOSITION top; - XYPOSITION right; - XYPOSITION bottom; - - constexpr explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) noexcept : - left(left_), top(top_), right(right_), bottom(bottom_) { - } - - static constexpr PRectangle FromInts(int left_, int top_, int right_, int bottom_) noexcept { - return PRectangle(static_cast(left_), static_cast(top_), - static_cast(right_), static_cast(bottom_)); - } - - // Other automatically defined methods (assignment, copy constructor, destructor) are fine - - constexpr bool operator==(const PRectangle &rc) const noexcept { - return (rc.left == left) && (rc.right == right) && - (rc.top == top) && (rc.bottom == bottom); - } - constexpr bool Contains(Point pt) const noexcept { - return (pt.x >= left) && (pt.x <= right) && - (pt.y >= top) && (pt.y <= bottom); - } - constexpr bool ContainsWholePixel(Point pt) const noexcept { - // Does the rectangle contain all of the pixel to left/below the point - return (pt.x >= left) && ((pt.x+1) <= right) && - (pt.y >= top) && ((pt.y+1) <= bottom); - } - constexpr bool Contains(PRectangle rc) const noexcept { - return (rc.left >= left) && (rc.right <= right) && - (rc.top >= top) && (rc.bottom <= bottom); - } - constexpr bool Intersects(PRectangle other) const noexcept { - return (right > other.left) && (left < other.right) && - (bottom > other.top) && (top < other.bottom); - } - void Move(XYPOSITION xDelta, XYPOSITION yDelta) noexcept { - left += xDelta; - top += yDelta; - right += xDelta; - bottom += yDelta; - } - constexpr XYPOSITION Width() const noexcept { return right - left; } - constexpr XYPOSITION Height() const noexcept { return bottom - top; } - constexpr bool Empty() const noexcept { - return (Height() <= 0) || (Width() <= 0); - } -}; - -/** - * Holds an RGB colour with 8 bits for each component. - */ -constexpr const float componentMaximum = 255.0f; -class ColourDesired { - int co; -public: - constexpr explicit ColourDesired(int co_=0) noexcept : co(co_) { - } - - constexpr ColourDesired(unsigned int red, unsigned int green, unsigned int blue) noexcept : - co(red | (green << 8) | (blue << 16)) { - } - - constexpr bool operator==(const ColourDesired &other) const noexcept { - return co == other.co; - } - - constexpr int AsInteger() const noexcept { - return co; - } - - // Red, green and blue values as bytes 0..255 - constexpr unsigned char GetRed() const noexcept { - return co & 0xff; - } - constexpr unsigned char GetGreen() const noexcept { - return (co >> 8) & 0xff; - } - constexpr unsigned char GetBlue() const noexcept { - return (co >> 16) & 0xff; - } - - // Red, green and blue values as float 0..1.0 - constexpr float GetRedComponent() const noexcept { - return GetRed() / componentMaximum; - } - constexpr float GetGreenComponent() const noexcept { - return GetGreen() / componentMaximum; - } - constexpr float GetBlueComponent() const noexcept { - return GetBlue() / componentMaximum; - } -}; - -/** -* Holds an RGBA colour. -*/ -class ColourAlpha : public ColourDesired { -public: - constexpr explicit ColourAlpha(int co_ = 0) noexcept : ColourDesired(co_) { - } - - constexpr ColourAlpha(unsigned int red, unsigned int green, unsigned int blue) noexcept : - ColourDesired(red | (green << 8) | (blue << 16)) { - } - - constexpr ColourAlpha(unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha) noexcept : - ColourDesired(red | (green << 8) | (blue << 16) | (alpha << 24)) { - } - - constexpr ColourAlpha(ColourDesired cd, unsigned int alpha) noexcept : - ColourDesired(cd.AsInteger() | (alpha << 24)) { - } - - constexpr ColourDesired GetColour() const noexcept { - return ColourDesired(AsInteger() & 0xffffff); - } - - constexpr unsigned char GetAlpha() const noexcept { - return (AsInteger() >> 24) & 0xff; - } - - constexpr float GetAlphaComponent() const noexcept { - return GetAlpha() / componentMaximum; - } - - ColourAlpha MixedWith(ColourAlpha other) const noexcept { - const unsigned int red = (GetRed() + other.GetRed()) / 2; - const unsigned int green = (GetGreen() + other.GetGreen()) / 2; - const unsigned int blue = (GetBlue() + other.GetBlue()) / 2; - const unsigned int alpha = (GetAlpha() + other.GetAlpha()) / 2; - return ColourAlpha(red, green, blue, alpha); - } -}; - -/** -* Holds an element of a gradient with an RGBA colour and a relative position. -*/ -class ColourStop { -public: - float position; - ColourAlpha colour; - ColourStop(float position_, ColourAlpha colour_) noexcept : - position(position_), colour(colour_) { - } -}; - -/** - * Font management. - */ - -struct FontParameters { - const char *faceName; - float size; - int weight; - bool italic; - int extraFontFlag; - int technology; - int characterSet; - - FontParameters( - const char *faceName_, - float size_=10, - int weight_=400, - bool italic_=false, - int extraFontFlag_=0, - int technology_=0, - int characterSet_=0) noexcept : - - faceName(faceName_), - size(size_), - weight(weight_), - italic(italic_), - extraFontFlag(extraFontFlag_), - technology(technology_), - characterSet(characterSet_) - { - } - -}; - -class Font { -protected: - FontID fid; -public: - Font() noexcept; - // Deleted so Font objects can not be copied - Font(const Font &) = delete; - Font(Font &&) = delete; - Font &operator=(const Font &) = delete; - Font &operator=(Font &&) = delete; - virtual ~Font(); - - virtual void Create(const FontParameters &fp); - virtual void Release(); - - FontID GetID() const noexcept { return fid; } - // Alias another font - caller guarantees not to Release - void SetID(FontID fid_) noexcept { fid = fid_; } - friend class Surface; - friend class SurfaceImpl; -}; - -/** - * A surface abstracts a place to draw. - */ -class Surface { -public: - Surface() noexcept = default; - Surface(const Surface &) = delete; - Surface(Surface &&) = delete; - Surface &operator=(const Surface &) = delete; - Surface &operator=(Surface &&) = delete; - virtual ~Surface() {} - static Surface *Allocate(int technology); - - virtual void Init(WindowID wid)=0; - virtual void Init(SurfaceID sid, WindowID wid)=0; - virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; - - virtual void Release()=0; - virtual bool Initialised()=0; - virtual void PenColour(ColourDesired fore)=0; - virtual int LogPixelsY()=0; - virtual int DeviceHeightFont(int points)=0; - virtual void MoveTo(int x_, int y_)=0; - virtual void LineTo(int x_, int y_)=0; - virtual void Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back)=0; - virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back)=0; - virtual void FillRectangle(PRectangle rc, ColourDesired back)=0; - virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; - virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back)=0; - virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, - ColourDesired outline, int alphaOutline, int flags)=0; - enum class GradientOptions { leftToRight, topToBottom }; - virtual void GradientRectangle(PRectangle rc, const std::vector &stops, GradientOptions options)=0; - virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0; - virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0; - virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; - - virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) = 0; - virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) = 0; - virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) = 0; - virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) = 0; - virtual XYPOSITION WidthText(Font &font_, const char *s, int len) = 0; - virtual XYPOSITION Ascent(Font &font_)=0; - virtual XYPOSITION Descent(Font &font_)=0; - virtual XYPOSITION InternalLeading(Font &font_)=0; - virtual XYPOSITION Height(Font &font_)=0; - virtual XYPOSITION AverageCharWidth(Font &font_)=0; - - virtual void SetClip(PRectangle rc)=0; - virtual void FlushCachedState()=0; - - virtual void SetUnicodeMode(bool unicodeMode_)=0; - virtual void SetDBCSMode(int codePage)=0; -}; - -/** - * Class to hide the details of window manipulation. - * Does not own the window which will normally have a longer life than this object. - */ -class Window { -protected: - WindowID wid; -public: - Window() noexcept : wid(nullptr), cursorLast(cursorInvalid) { - } - Window(const Window &source) = delete; - Window(Window &&) = delete; - Window &operator=(WindowID wid_) noexcept { - wid = wid_; - cursorLast = cursorInvalid; - return *this; - } - Window &operator=(const Window &) = delete; - Window &operator=(Window &&) = delete; - virtual ~Window(); - WindowID GetID() const noexcept { return wid; } - bool Created() const noexcept { return wid != nullptr; } - void Destroy(); - PRectangle GetPosition() const; - void SetPosition(PRectangle rc); - void SetPositionRelative(PRectangle rc, const Window *relativeTo); - PRectangle GetClientPosition() const; - void Show(bool show=true); - void InvalidateAll(); - void InvalidateRectangle(PRectangle rc); - virtual void SetFont(Font &font); - enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand }; - void SetCursor(Cursor curs); - PRectangle GetMonitorRect(Point pt); -private: - Cursor cursorLast; -}; - -/** - * Listbox management. - */ - -// ScintillaBase implements IListBoxDelegate to receive ListBoxEvents from a ListBox - -struct ListBoxEvent { - enum class EventType { selectionChange, doubleClick } event; - ListBoxEvent(EventType event_) noexcept : event(event_) { - } -}; - -class IListBoxDelegate { -public: - virtual void ListNotify(ListBoxEvent *plbe)=0; -}; - -class ListBox : public Window { -public: - ListBox() noexcept; - ~ListBox() override; - static ListBox *Allocate(); - - void SetFont(Font &font) override =0; - virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, int technology_)=0; - virtual void SetAverageCharWidth(int width)=0; - virtual void SetVisibleRows(int rows)=0; - virtual int GetVisibleRows() const=0; - virtual PRectangle GetDesiredRect()=0; - virtual int CaretFromEdge()=0; - virtual void Clear()=0; - virtual void Append(char *s, int type = -1)=0; - virtual int Length()=0; - virtual void Select(int n)=0; - virtual int GetSelection()=0; - virtual int Find(const char *prefix)=0; - virtual void GetValue(int n, char *value, int len)=0; - virtual void RegisterImage(int type, const char *xpm_data)=0; - virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0; - virtual void ClearRegisteredImages()=0; - virtual void SetDelegate(IListBoxDelegate *lbDelegate)=0; - virtual void SetList(const char* list, char separator, char typesep)=0; -}; - -/** - * Menu management. - */ -class Menu { - MenuID mid; -public: - Menu() noexcept; - MenuID GetID() const noexcept { return mid; } - void CreatePopUp(); - void Destroy(); - void Show(Point pt, Window &w); -}; - -/** - * Dynamic Library (DLL/SO/...) loading - */ -class DynamicLibrary { -public: - virtual ~DynamicLibrary() = default; - - /// @return Pointer to function "name", or NULL on failure. - virtual Function FindFunction(const char *name) = 0; - - /// @return true if the library was loaded successfully. - virtual bool IsValid() = 0; - - /// @return An instance of a DynamicLibrary subclass with "modulePath" loaded. - static DynamicLibrary *Load(const char *modulePath); -}; - -#if defined(__clang__) -# if __has_feature(attribute_analyzer_noreturn) -# define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) -# else -# define CLANG_ANALYZER_NORETURN -# endif -#else -# define CLANG_ANALYZER_NORETURN -#endif - -/** - * Platform class used to retrieve system wide parameters such as double click speed - * and chrome colour. Not a creatable object, more of a module with several functions. - */ -class Platform { -public: - Platform() = default; - Platform(const Platform &) = delete; - Platform(Platform &&) = delete; - Platform &operator=(const Platform &) = delete; - Platform &operator=(Platform &&) = delete; - ~Platform() = default; - static ColourDesired Chrome(); - static ColourDesired ChromeHighlight(); - static const char *DefaultFont(); - static int DefaultFontSize(); - static unsigned int DoubleClickTime(); - static void DebugDisplay(const char *s); - static constexpr long LongFromTwoShorts(short a,short b) noexcept { - return (a) | ((b) << 16); - } - - static void DebugPrintf(const char *format, ...); - static bool ShowAssertionPopUps(bool assertionPopUps_); - static void Assert(const char *c, const char *file, int line) CLANG_ANALYZER_NORETURN; -}; - -#ifdef NDEBUG -#define PLATFORM_ASSERT(c) ((void)0) -#else -#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__)) -#endif - -} - -#endif diff --git a/scintilla/include/Scintilla.h b/scintilla/include/Scintilla.h index 6f59d4e278..97fbd3be01 100644 --- a/scintilla/include/Scintilla.h +++ b/scintilla/include/Scintilla.h @@ -20,7 +20,6 @@ extern "C" { int Scintilla_RegisterClasses(void *hInstance); int Scintilla_ReleaseResources(void); #endif -int Scintilla_LinkLexers(void); #ifdef __cplusplus } @@ -37,6 +36,7 @@ typedef intptr_t sptr_t; #include "Sci_Position.h" typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam); +typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam, int *pStatus); #ifndef SCI_DISABLE_AUTOGENERATED @@ -104,6 +104,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_GETNEXTTABSTOP 2677 #define SC_CP_UTF8 65001 #define SCI_SETCODEPAGE 2037 +#define SCI_SETFONTLOCALE 2760 +#define SCI_GETFONTLOCALE 2761 #define SC_IME_WINDOWED 0 #define SC_IME_INLINE 1 #define SCI_GETIMEINTERACTION 2678 @@ -162,6 +164,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_MARKERSETFORE 2041 #define SCI_MARKERSETBACK 2042 #define SCI_MARKERSETBACKSELECTED 2292 +#define SCI_MARKERSETFORETRANSLUCENT 2294 +#define SCI_MARKERSETBACKTRANSLUCENT 2295 +#define SCI_MARKERSETBACKSELECTEDTRANSLUCENT 2296 +#define SCI_MARKERSETSTROKEWIDTH 2297 #define SCI_MARKERENABLEHIGHLIGHT 2293 #define SCI_MARKERADD 2043 #define SCI_MARKERDELETE 2044 @@ -172,6 +178,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_MARKERDEFINEPIXMAP 2049 #define SCI_MARKERADDSET 2466 #define SCI_MARKERSETALPHA 2476 +#define SCI_MARKERGETLAYER 2734 +#define SCI_MARKERSETLAYER 2735 #define SC_MAX_MARGIN 4 #define SC_MARGIN_SYMBOL 0 #define SC_MARGIN_NUMBER 1 @@ -264,12 +272,44 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_STYLEGETWEIGHT 2064 #define SCI_STYLESETCHARACTERSET 2066 #define SCI_STYLESETHOTSPOT 2409 +#define SC_ELEMENT_LIST 0 +#define SC_ELEMENT_LIST_BACK 1 +#define SC_ELEMENT_LIST_SELECTED 2 +#define SC_ELEMENT_LIST_SELECTED_BACK 3 +#define SC_ELEMENT_SELECTION_TEXT 10 +#define SC_ELEMENT_SELECTION_BACK 11 +#define SC_ELEMENT_SELECTION_ADDITIONAL_TEXT 12 +#define SC_ELEMENT_SELECTION_ADDITIONAL_BACK 13 +#define SC_ELEMENT_SELECTION_SECONDARY_TEXT 14 +#define SC_ELEMENT_SELECTION_SECONDARY_BACK 15 +#define SC_ELEMENT_SELECTION_INACTIVE_TEXT 16 +#define SC_ELEMENT_SELECTION_INACTIVE_BACK 17 +#define SC_ELEMENT_CARET 40 +#define SC_ELEMENT_CARET_ADDITIONAL 41 +#define SC_ELEMENT_CARET_LINE_BACK 50 +#define SC_ELEMENT_WHITE_SPACE 60 +#define SC_ELEMENT_WHITE_SPACE_BACK 61 +#define SC_ELEMENT_HOT_SPOT_ACTIVE 70 +#define SC_ELEMENT_HOT_SPOT_ACTIVE_BACK 71 +#define SCI_SETELEMENTCOLOUR 2753 +#define SCI_GETELEMENTCOLOUR 2754 +#define SCI_RESETELEMENTCOLOUR 2755 +#define SCI_GETELEMENTISSET 2756 +#define SCI_GETELEMENTALLOWSTRANSLUCENT 2757 +#define SCI_GETELEMENTBASECOLOUR 2758 #define SCI_SETSELFORE 2067 #define SCI_SETSELBACK 2068 #define SCI_GETSELALPHA 2477 #define SCI_SETSELALPHA 2478 #define SCI_GETSELEOLFILLED 2479 #define SCI_SETSELEOLFILLED 2480 +#define SC_LAYER_BASE 0 +#define SC_LAYER_UNDER_TEXT 1 +#define SC_LAYER_OVER_TEXT 2 +#define SCI_GETSELECTIONLAYER 2762 +#define SCI_SETSELECTIONLAYER 2763 +#define SCI_GETCARETLINELAYER 2764 +#define SCI_SETCARETLINELAYER 2765 #define SCI_SETCARETFORE 2069 #define SCI_ASSIGNCMDKEY 2070 #define SCI_CLEARCMDKEY 2071 @@ -326,9 +366,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_INDICGETHOVERFORE 2683 #define SC_INDICVALUEBIT 0x1000000 #define SC_INDICVALUEMASK 0xFFFFFF +#define SC_INDICFLAG_NONE 0 #define SC_INDICFLAG_VALUEFORE 1 #define SCI_INDICSETFLAGS 2684 #define SCI_INDICGETFLAGS 2685 +#define SCI_INDICSETSTROKEWIDTH 2751 +#define SCI_INDICGETSTROKEWIDTH 2752 #define SCI_SETWHITESPACEFORE 2084 #define SCI_SETWHITESPACEBACK 2085 #define SCI_SETWHITESPACESIZE 2086 @@ -362,6 +405,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_USERLISTSHOW 2117 #define SCI_AUTOCSETAUTOHIDE 2118 #define SCI_AUTOCGETAUTOHIDE 2119 +#define SC_AUTOCOMPLETE_NORMAL 0 +#define SC_AUTOCOMPLETE_FIXED_SIZE 1 +#define SCI_AUTOCSETOPTIONS 2638 +#define SCI_AUTOCGETOPTIONS 2639 #define SCI_AUTOCSETDROPRESTOFWORD 2270 #define SCI_AUTOCGETDROPRESTOFWORD 2271 #define SCI_REGISTERIMAGE 2405 @@ -424,6 +471,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_GETFIRSTVISIBLELINE 2152 #define SCI_GETLINE 2153 #define SCI_GETLINECOUNT 2154 +#define SCI_ALLOCATELINES 2089 #define SCI_SETMARGINLEFT 2155 #define SCI_GETMARGINLEFT 2156 #define SCI_SETMARGINRIGHT 2157 @@ -455,6 +503,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_GETTEXT 2182 #define SCI_GETTEXTLENGTH 2183 #define SCI_GETDIRECTFUNCTION 2184 +#define SCI_GETDIRECTSTATUSFUNCTION 2772 #define SCI_GETDIRECTPOINTER 2185 #define SCI_SETOVERTYPE 2186 #define SCI_GETOVERTYPE 2187 @@ -491,6 +540,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_VISIBLEFROMDOCLINE 2220 #define SCI_DOCLINEFROMVISIBLE 2221 #define SCI_WRAPCOUNT 2235 +#define SC_FOLDLEVELNONE 0x0 #define SC_FOLDLEVELBASE 0x400 #define SC_FOLDLEVELWHITEFLAG 0x1000 #define SC_FOLDLEVELHEADERFLAG 0x2000 @@ -522,11 +572,13 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_EXPANDCHILDREN 2239 #define SCI_FOLDALL 2662 #define SCI_ENSUREVISIBLE 2232 +#define SC_AUTOMATICFOLD_NONE 0x0000 #define SC_AUTOMATICFOLD_SHOW 0x0001 #define SC_AUTOMATICFOLD_CLICK 0x0002 #define SC_AUTOMATICFOLD_CHANGE 0x0004 #define SCI_SETAUTOMATICFOLD 2663 #define SCI_GETAUTOMATICFOLD 2664 +#define SC_FOLDFLAG_NONE 0x0000 #define SC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002 #define SC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004 #define SC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008 @@ -593,8 +645,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETVSCROLLBAR 2280 #define SCI_GETVSCROLLBAR 2281 #define SCI_APPENDTEXT 2282 -#define SCI_GETTWOPHASEDRAW 2283 -#define SCI_SETTWOPHASEDRAW 2284 #define SC_PHASES_ONE 0 #define SC_PHASES_TWO 1 #define SC_PHASES_MULTIPLE 2 @@ -842,6 +892,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_TOGGLECARETSTICKY 2459 #define SCI_SETPASTECONVERTENDINGS 2467 #define SCI_GETPASTECONVERTENDINGS 2468 +#define SCI_REPLACERECTANGULAR 2771 #define SCI_SELECTIONDUPLICATE 2469 #define SCI_SETCARETLINEBACKALPHA 2470 #define SCI_GETCARETLINEBACKALPHA 2471 @@ -1009,28 +1060,56 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETREPRESENTATION 2665 #define SCI_GETREPRESENTATION 2666 #define SCI_CLEARREPRESENTATION 2667 +#define SCI_CLEARALLREPRESENTATIONS 2770 +#define SC_REPRESENTATION_PLAIN 0 +#define SC_REPRESENTATION_BLOB 1 +#define SC_REPRESENTATION_COLOUR 0x10 +#define SCI_SETREPRESENTATIONAPPEARANCE 2766 +#define SCI_GETREPRESENTATIONAPPEARANCE 2767 +#define SCI_SETREPRESENTATIONCOLOUR 2768 +#define SCI_GETREPRESENTATIONCOLOUR 2769 #define SCI_EOLANNOTATIONSETTEXT 2740 #define SCI_EOLANNOTATIONGETTEXT 2741 #define SCI_EOLANNOTATIONSETSTYLE 2742 #define SCI_EOLANNOTATIONGETSTYLE 2743 #define SCI_EOLANNOTATIONCLEARALL 2744 -#define EOLANNOTATION_HIDDEN 0 -#define EOLANNOTATION_STANDARD 1 -#define EOLANNOTATION_BOXED 2 +#define EOLANNOTATION_HIDDEN 0x0 +#define EOLANNOTATION_STANDARD 0x1 +#define EOLANNOTATION_BOXED 0x2 +#define EOLANNOTATION_STADIUM 0x100 +#define EOLANNOTATION_FLAT_CIRCLE 0x101 +#define EOLANNOTATION_ANGLE_CIRCLE 0x102 +#define EOLANNOTATION_CIRCLE_FLAT 0x110 +#define EOLANNOTATION_FLATS 0x111 +#define EOLANNOTATION_ANGLE_FLAT 0x112 +#define EOLANNOTATION_CIRCLE_ANGLE 0x120 +#define EOLANNOTATION_FLAT_ANGLE 0x121 +#define EOLANNOTATION_ANGLES 0x122 #define SCI_EOLANNOTATIONSETVISIBLE 2745 #define SCI_EOLANNOTATIONGETVISIBLE 2746 #define SCI_EOLANNOTATIONSETSTYLEOFFSET 2747 #define SCI_EOLANNOTATIONGETSTYLEOFFSET 2748 +#define SC_SUPPORTS_LINE_DRAWS_FINAL 0 +#define SC_SUPPORTS_PIXEL_DIVISIONS 1 +#define SC_SUPPORTS_FRACTIONAL_STROKE_WIDTH 2 +#define SC_SUPPORTS_TRANSLUCENT_STROKE 3 +#define SC_SUPPORTS_PIXEL_MODIFICATION 4 +#define SCI_SUPPORTSFEATURE 2750 +#define SC_LINECHARACTERINDEX_NONE 0 +#define SC_LINECHARACTERINDEX_UTF32 1 +#define SC_LINECHARACTERINDEX_UTF16 2 +#define SCI_GETLINECHARACTERINDEX 2710 +#define SCI_ALLOCATELINECHARACTERINDEX 2711 +#define SCI_RELEASELINECHARACTERINDEX 2712 +#define SCI_LINEFROMINDEXPOSITION 2713 +#define SCI_INDEXPOSITIONFROMLINE 2714 #define SCI_STARTRECORD 3001 #define SCI_STOPRECORD 3002 -#define SCI_SETLEXER 4001 #define SCI_GETLEXER 4002 #define SCI_COLOURISE 4003 #define SCI_SETPROPERTY 4004 #define KEYWORDSET_MAX 8 #define SCI_SETKEYWORDS 4005 -#define SCI_SETLEXERLANGUAGE 4006 -#define SCI_LOADLEXERLIBRARY 4007 #define SCI_GETPROPERTY 4008 #define SCI_GETPROPERTYEXPANDED 4009 #define SCI_GETPROPERTYINT 4010 @@ -1057,6 +1136,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_NAMEOFSTYLE 4030 #define SCI_TAGSOFSTYLE 4031 #define SCI_DESCRIPTIONOFSTYLE 4032 +#define SCI_SETILEXER 4033 #define SC_MOD_NONE 0x0 #define SC_MOD_INSERTTEXT 0x1 #define SC_MOD_DELETETEXT 0x2 @@ -1082,6 +1162,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_MOD_CHANGETABSTOPS 0x200000 #define SC_MOD_CHANGEEOLANNOTATION 0x400000 #define SC_MODEVENTMASKALL 0x7FFFFF +#define SC_UPDATE_NONE 0x0 #define SC_UPDATE_CONTENT 0x1 #define SC_UPDATE_SELECTION 0x2 #define SC_UPDATE_V_SCROLL 0x4 @@ -1156,14 +1237,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCN_MARGINRIGHTCLICK 2031 #define SCN_AUTOCSELECTIONCHANGE 2032 #ifndef SCI_DISABLE_PROVISIONAL -#define SC_LINECHARACTERINDEX_NONE 0 -#define SC_LINECHARACTERINDEX_UTF32 1 -#define SC_LINECHARACTERINDEX_UTF16 2 -#define SCI_GETLINECHARACTERINDEX 2710 -#define SCI_ALLOCATELINECHARACTERINDEX 2711 -#define SCI_RELEASELINECHARACTERINDEX 2712 -#define SCI_LINEFROMINDEXPOSITION 2713 -#define SCI_INDEXPOSITIONFROMLINE 2714 +#define SC_BIDIRECTIONAL_DISABLED 0 +#define SC_BIDIRECTIONAL_L2R 1 +#define SC_BIDIRECTIONAL_R2L 2 +#define SCI_GETBIDIRECTIONAL 2708 +#define SCI_SETBIDIRECTIONAL 2709 #endif /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ @@ -1270,6 +1348,9 @@ struct SCNotification { #define SCI_SETKEYSUNICODE 2521 #define SCI_GETKEYSUNICODE 2522 +#define SCI_GETTWOPHASEDRAW 2283 +#define SCI_SETTWOPHASEDRAW 2284 + #define CharacterRange Sci_CharacterRange #define TextRange Sci_TextRange #define TextToFind Sci_TextToFind @@ -1287,6 +1368,4 @@ struct SCNotification { #endif -#include "Compat.h" - #endif diff --git a/scintilla/include/Scintilla.iface b/scintilla/include/Scintilla.iface index 4b40127baa..cc7dedf363 100644 --- a/scintilla/include/Scintilla.iface +++ b/scintilla/include/Scintilla.iface @@ -53,7 +53,8 @@ ## bool -> integer, 1=true, 0=false ## position -> intptr_t position in a document ## line -> intptr_t line in a document -## colour -> colour integer containing red, green and blue bytes. +## colour -> colour integer containing red, green, and blue bytes with red as least-significant and blue as most. +## colouralpha -> colour integer containing red, green, blue, and alpha bytes with red as least-significant and alpha as most. ## string -> pointer to const character ## stringresult -> pointer to character, NULL-> return size of result ## cells -> pointer to array of cells, each cell containing a style byte and character byte @@ -281,6 +282,12 @@ val SC_CP_UTF8=65001 # The SC_CP_UTF8 value can be used to enter Unicode mode. set void SetCodePage=2037(int codePage,) +# Set the locale for displaying text. +set void SetFontLocale=2760(, string localeName) + +# Get the locale for displaying text. +get int GetFontLocale=2761(, stringresult localeName) + enu IMEInteraction=SC_IME_ val SC_IME_WINDOWED=0 val SC_IME_INLINE=1 @@ -403,6 +410,18 @@ set void MarkerSetBack=2042(int markerNumber, colour back) # Set the background colour used for a particular marker number when its folding block is selected. set void MarkerSetBackSelected=2292(int markerNumber, colour back) +# Set the foreground colour used for a particular marker number. +set void MarkerSetForeTranslucent=2294(int markerNumber, colouralpha fore) + +# Set the background colour used for a particular marker number. +set void MarkerSetBackTranslucent=2295(int markerNumber, colouralpha back) + +# Set the background colour used for a particular marker number when its folding block is selected. +set void MarkerSetBackSelectedTranslucent=2296(int markerNumber, colouralpha back) + +# Set the width of strokes used in .01 pixels so 50 = 1/2 pixel width. +set void MarkerSetStrokeWidth=2297(int markerNumber, int hundredths) + # Enable/disable highlight for current folding block (smallest one that contains the caret) fun void MarkerEnableHighlight=2293(bool enabled,) @@ -434,6 +453,12 @@ fun void MarkerAddSet=2466(line line, int markerSet) # Set the alpha used for a marker that is drawn in the text area, not the margin. set void MarkerSetAlpha=2476(int markerNumber, Alpha alpha) +# Get the layer used for a marker that is drawn in the text area, not the margin. +get Layer MarkerGetLayer=2734(int markerNumber,) + +# Set the layer used for a marker that is drawn in the text area, not the margin. +set void MarkerSetLayer=2735(int markerNumber, Layer layer) + val SC_MAX_MARGIN=4 enu MarginType=SC_MARGIN_ @@ -652,6 +677,47 @@ set void StyleSetCharacterSet=2066(int style, CharacterSet characterSet) # Set a style to be a hotspot or not. set void StyleSetHotSpot=2409(int style, bool hotspot) +enu Element=SC_ELEMENT_ +val SC_ELEMENT_LIST=0 +val SC_ELEMENT_LIST_BACK=1 +val SC_ELEMENT_LIST_SELECTED=2 +val SC_ELEMENT_LIST_SELECTED_BACK=3 +val SC_ELEMENT_SELECTION_TEXT=10 +val SC_ELEMENT_SELECTION_BACK=11 +val SC_ELEMENT_SELECTION_ADDITIONAL_TEXT=12 +val SC_ELEMENT_SELECTION_ADDITIONAL_BACK=13 +val SC_ELEMENT_SELECTION_SECONDARY_TEXT=14 +val SC_ELEMENT_SELECTION_SECONDARY_BACK=15 +val SC_ELEMENT_SELECTION_INACTIVE_TEXT=16 +val SC_ELEMENT_SELECTION_INACTIVE_BACK=17 +val SC_ELEMENT_CARET=40 +val SC_ELEMENT_CARET_ADDITIONAL=41 +val SC_ELEMENT_CARET_LINE_BACK=50 +val SC_ELEMENT_WHITE_SPACE=60 +val SC_ELEMENT_WHITE_SPACE_BACK=61 +val SC_ELEMENT_HOT_SPOT_ACTIVE=70 +val SC_ELEMENT_HOT_SPOT_ACTIVE_BACK=71 + +# Set the colour of an element. Translucency (alpha) may or may not be significant +# and this may depend on the platform. The alpha byte should commonly be 0xff for opaque. +set void SetElementColour=2753(Element element, colouralpha colourElement) + +# Get the colour of an element. +get colouralpha GetElementColour=2754(Element element,) + +# Use the default or platform-defined colour for an element. +fun void ResetElementColour=2755(Element element,) + +# Get whether an element has been set by SetElementColour. +# When false, a platform-defined or default colour is used. +get bool GetElementIsSet=2756(Element element,) + +# Get whether an element supports translucency. +get bool GetElementAllowsTranslucent=2757(Element element,) + +# Get the colour of an element. +get colouralpha GetElementBaseColour=2758(Element element,) + # Set the foreground colour of the main and additional selections and whether to use this setting. fun void SetSelFore=2067(bool useSetting, colour fore) @@ -670,6 +736,23 @@ get bool GetSelEOLFilled=2479(,) # Set the selection to have its end of line filled or not. set void SetSelEOLFilled=2480(bool filled,) +enu Layer=SC_LAYER_ +val SC_LAYER_BASE=0 +val SC_LAYER_UNDER_TEXT=1 +val SC_LAYER_OVER_TEXT=2 + +# Get the layer for drawing selections +get Layer GetSelectionLayer=2762(,) + +# Set the layer for drawing selections: either opaquely on base layer or translucently over text +set void SetSelectionLayer=2763(Layer layer,) + +# Get the layer of the background of the line containing the caret. +get Layer GetCaretLineLayer=2764(,) + +# Set the layer of the background of the line containing the caret. +set void SetCaretLineLayer=2765(Layer layer,) + # Set the foreground colour of the caret. set void SetCaretFore=2069(colour fore,) @@ -802,6 +885,7 @@ val SC_INDICVALUEBIT=0x1000000 val SC_INDICVALUEMASK=0xFFFFFF enu IndicFlag=SC_INDICFLAG_ +val SC_INDICFLAG_NONE=0 val SC_INDICFLAG_VALUEFORE=1 ali SC_INDICFLAG_VALUEFORE=VALUE_FORE @@ -812,6 +896,12 @@ set void IndicSetFlags=2684(int indicator, IndicFlag flags) # Retrieve the attributes of an indicator. get IndicFlag IndicGetFlags=2685(int indicator,) +# Set the stroke width of an indicator in hundredths of a pixel. +set void IndicSetStrokeWidth=2751(int indicator, int hundredths) + +# Retrieve the stroke width of an indicator. +get int IndicGetStrokeWidth=2752(int indicator,) + # Set the foreground colour of all whitespace and whether to use this setting. fun void SetWhitespaceFore=2084(bool useSetting, colour fore) @@ -919,6 +1009,18 @@ set void AutoCSetAutoHide=2118(bool autoHide,) # Retrieve whether or not autocompletion is hidden automatically when nothing matches. get bool AutoCGetAutoHide=2119(,) +# Define option flags for autocompletion lists +enu AutoCompleteOption=SC_AUTOCOMPLETE_ +val SC_AUTOCOMPLETE_NORMAL=0 +# Win32 specific: +val SC_AUTOCOMPLETE_FIXED_SIZE=1 + +# Set autocompletion options. +set void AutoCSetOptions=2638(AutoCompleteOption options,) + +# Retrieve autocompletion options. +get AutoCompleteOption AutoCGetOptions=2639(,) + # Set whether or not autocompletion deletes any word characters # after the inserted text upon completion. set void AutoCSetDropRestOfWord=2270(bool dropRestOfWord,) @@ -1106,6 +1208,9 @@ fun position GetLine=2153(line line, stringresult text) # Returns the number of lines in the document. There is always at least one. get line GetLineCount=2154(,) +# Enlarge the number of lines allocated. +set void AllocateLines=2089(line lines,) + # Sets the size in pixels of the left margin. set void SetMarginLeft=2155(, int pixelWidth) @@ -1206,6 +1311,9 @@ get position GetTextLength=2183(,) # Retrieve a pointer to a function that processes messages for this Scintilla. get pointer GetDirectFunction=2184(,) +# Retrieve a pointer to a function that processes messages for this Scintilla and returns status. +get pointer GetDirectStatusFunction=2772(,) + # Retrieve a pointer value to use as the first argument when calling # the function returned by GetDirectFunction. get pointer GetDirectPointer=2185(,) @@ -1327,6 +1435,7 @@ fun line DocLineFromVisible=2221(line displayLine,) fun line WrapCount=2235(line docLine,) enu FoldLevel=SC_FOLDLEVEL +val SC_FOLDLEVELNONE=0x0 val SC_FOLDLEVELBASE=0x400 val SC_FOLDLEVELWHITEFLAG=0x1000 val SC_FOLDLEVELHEADERFLAG=0x2000 @@ -1412,6 +1521,7 @@ fun void FoldAll=2662(FoldAction action,) fun void EnsureVisible=2232(line line,) enu AutomaticFold=SC_AUTOMATICFOLD_ +val SC_AUTOMATICFOLD_NONE=0x0000 val SC_AUTOMATICFOLD_SHOW=0x0001 val SC_AUTOMATICFOLD_CLICK=0x0002 val SC_AUTOMATICFOLD_CHANGE=0x0004 @@ -1423,6 +1533,7 @@ set void SetAutomaticFold=2663(AutomaticFold automaticFold,) get AutomaticFold GetAutomaticFold=2664(,) enu FoldFlag=SC_FOLDFLAG_ +val SC_FOLDFLAG_NONE=0x0000 val SC_FOLDFLAG_LINEBEFORE_EXPANDED=0x0002 val SC_FOLDFLAG_LINEBEFORE_CONTRACTED=0x0004 val SC_FOLDFLAG_LINEAFTER_EXPANDED=0x0008 @@ -1595,13 +1706,6 @@ get bool GetVScrollBar=2281(,) # Append a string to the end of the document without changing the selection. fun void AppendText=2282(position length, string text) -# Is drawing done in two phases with backgrounds drawn before foregrounds? -get bool GetTwoPhaseDraw=2283(,) - -# In twoPhaseDraw mode, drawing is performed in two phases, first the background -# and then the foreground. This avoids chopping off characters that overlap the next run. -set void SetTwoPhaseDraw=2284(bool twoPhase,) - enu PhasesDraw=SC_PHASES_ val SC_PHASES_ONE=0 val SC_PHASES_TWO=1 @@ -2353,6 +2457,9 @@ set void SetPasteConvertEndings=2467(bool convert,) # Get convert-on-paste setting get bool GetPasteConvertEndings=2468(,) +# Replace the selection with text like a rectangular paste. +fun void ReplaceRectangular=2771(position length, string text) + # Duplicate the selection. If selection empty duplicate the line containing the caret. fun void SelectionDuplicate=2469(,) @@ -2843,13 +2950,34 @@ get LineEndType GetLineEndTypesActive=2658(,) # Set the way a character is drawn. set void SetRepresentation=2665(string encodedCharacter, string representation) -# Set the way a character is drawn. +# Get the way a character is drawn. # Result is NUL-terminated. get int GetRepresentation=2666(string encodedCharacter, stringresult representation) # Remove a character representation. fun void ClearRepresentation=2667(string encodedCharacter,) +# Clear representations to default. +fun void ClearAllRepresentations=2770(,) + +# Can draw representations in various ways +enu RepresentationAppearance=SC_REPRESENTATION +val SC_REPRESENTATION_PLAIN=0 +val SC_REPRESENTATION_BLOB=1 +val SC_REPRESENTATION_COLOUR=0x10 + +# Set the appearance of a representation. +set void SetRepresentationAppearance=2766(string encodedCharacter, RepresentationAppearance appearance) + +# Get the appearance of a representation. +get RepresentationAppearance GetRepresentationAppearance=2767(string encodedCharacter,) + +# Set the colour of a representation. +set void SetRepresentationColour=2768(string encodedCharacter, colouralpha colour) + +# Get the colour of a representation. +get colouralpha GetRepresentationColour=2769(string encodedCharacter,) + # Set the end of line annotation text for a line set void EOLAnnotationSetText=2740(line line, string text) @@ -2866,9 +2994,18 @@ get int EOLAnnotationGetStyle=2743(line line,) fun void EOLAnnotationClearAll=2744(,) enu EOLAnnotationVisible=EOLANNOTATION_ -val EOLANNOTATION_HIDDEN=0 -val EOLANNOTATION_STANDARD=1 -val EOLANNOTATION_BOXED=2 +val EOLANNOTATION_HIDDEN=0x0 +val EOLANNOTATION_STANDARD=0x1 +val EOLANNOTATION_BOXED=0x2 +val EOLANNOTATION_STADIUM=0x100 +val EOLANNOTATION_FLAT_CIRCLE=0x101 +val EOLANNOTATION_ANGLE_CIRCLE=0x102 +val EOLANNOTATION_CIRCLE_FLAT=0x110 +val EOLANNOTATION_FLATS=0x111 +val EOLANNOTATION_ANGLE_FLAT=0x112 +val EOLANNOTATION_CIRCLE_ANGLE=0x120 +val EOLANNOTATION_FLAT_ANGLE=0x121 +val EOLANNOTATION_ANGLES=0x122 # Set the visibility for the end of line annotations for a view set void EOLAnnotationSetVisible=2745(EOLAnnotationVisible visible,) @@ -2882,15 +3019,42 @@ set void EOLAnnotationSetStyleOffset=2747(int style,) # Get the start of the range of style numbers used for end of line annotations get int EOLAnnotationGetStyleOffset=2748(,) +enu Supports=SC_SUPPORTS_ +val SC_SUPPORTS_LINE_DRAWS_FINAL=0 +val SC_SUPPORTS_PIXEL_DIVISIONS=1 +val SC_SUPPORTS_FRACTIONAL_STROKE_WIDTH=2 +val SC_SUPPORTS_TRANSLUCENT_STROKE=3 +val SC_SUPPORTS_PIXEL_MODIFICATION=4 + +# Get whether a feature is supported +get bool SupportsFeature=2750(Supports feature,) + +enu LineCharacterIndexType=SC_LINECHARACTERINDEX_ +val SC_LINECHARACTERINDEX_NONE=0 +val SC_LINECHARACTERINDEX_UTF32=1 +val SC_LINECHARACTERINDEX_UTF16=2 + +# Retrieve line character index state. +get LineCharacterIndexType GetLineCharacterIndex=2710(,) + +# Request line character index be created or its use count increased. +fun void AllocateLineCharacterIndex=2711(LineCharacterIndexType lineCharacterIndex,) + +# Decrease use count of line character index and remove if 0. +fun void ReleaseLineCharacterIndex=2712(LineCharacterIndexType lineCharacterIndex,) + +# Retrieve the document line containing a position measured in index units. +fun line LineFromIndexPosition=2713(position pos, LineCharacterIndexType lineCharacterIndex) + +# Retrieve the position measured in index units at the start of a document line. +fun position IndexPositionFromLine=2714(line line, LineCharacterIndexType lineCharacterIndex) + # Start notifying the container of all key presses and commands. fun void StartRecord=3001(,) # Stop notifying the container of all key presses and commands. fun void StopRecord=3002(,) -# Set the lexing language of the document. -set void SetLexer=4001(int lexer,) - # Retrieve the lexing language of the document. get int GetLexer=4002(,) @@ -2906,12 +3070,6 @@ val KEYWORDSET_MAX=8 # Set up the key words used by the lexer. set void SetKeyWords=4005(int keyWordSet, string keyWords) -# Set the lexing language of the document based on string name. -set void SetLexerLanguage=4006(, string language) - -# Load a lexer library (dll / so). -fun void LoadLexerLibrary=4007(, string path) - # Retrieve a "property" value previously set with SetProperty. # Result is NUL-terminated. get int GetProperty=4008(string key, stringresult value) @@ -3001,6 +3159,9 @@ fun int TagsOfStyle=4031(int style, stringresult tags) # Result is NUL-terminated. fun int DescriptionOfStyle=4032(int style, stringresult description) +# Set the lexer from an ILexer*. +set void SetILexer=4033(, pointer ilexer) + # Notifications # Type of modification and the action which caused the modification. # These are defined as a bit mask to make it easy to specify which notifications are wanted. @@ -3054,6 +3215,7 @@ ali SC_MOD_CHANGEEOLANNOTATION=CHANGE_E_O_L_ANNOTATION ali SC_MODEVENTMASKALL=EVENT_MASK_ALL enu Update=SC_UPDATE_ +val SC_UPDATE_NONE=0x0 val SC_UPDATE_CONTENT=0x1 val SC_UPDATE_SELECTION=0x2 val SC_UPDATE_V_SCROLL=0x4 @@ -3063,6 +3225,7 @@ val SC_UPDATE_H_SCROLL=0x8 # and should have had exactly the same values as the EN_* constants. # Unfortunately the SETFOCUS and KILLFOCUS are flipped over from EN_* # As clients depend on these constants, this will not be changed. +enu FocusChange=SCEN_ val SCEN_CHANGE=768 val SCEN_SETFOCUS=512 val SCEN_KILLFOCUS=256 @@ -3122,2228 +3285,6 @@ val SC_CHARACTERSOURCE_TENTATIVE_INPUT=1 # IME (either inline or windowed mode) full composited string. val SC_CHARACTERSOURCE_IME_RESULT=2 -################################################ -# For SciLexer.h -enu Lexer=SCLEX_ -val SCLEX_CONTAINER=0 -val SCLEX_NULL=1 -val SCLEX_PYTHON=2 -val SCLEX_CPP=3 -val SCLEX_HTML=4 -val SCLEX_XML=5 -val SCLEX_PERL=6 -val SCLEX_SQL=7 -val SCLEX_VB=8 -val SCLEX_PROPERTIES=9 -val SCLEX_ERRORLIST=10 -val SCLEX_MAKEFILE=11 -val SCLEX_BATCH=12 -val SCLEX_XCODE=13 -val SCLEX_LATEX=14 -val SCLEX_LUA=15 -val SCLEX_DIFF=16 -val SCLEX_CONF=17 -val SCLEX_PASCAL=18 -val SCLEX_AVE=19 -val SCLEX_ADA=20 -val SCLEX_LISP=21 -val SCLEX_RUBY=22 -val SCLEX_EIFFEL=23 -val SCLEX_EIFFELKW=24 -val SCLEX_TCL=25 -val SCLEX_NNCRONTAB=26 -val SCLEX_BULLANT=27 -val SCLEX_VBSCRIPT=28 -val SCLEX_BAAN=31 -val SCLEX_MATLAB=32 -val SCLEX_SCRIPTOL=33 -val SCLEX_ASM=34 -val SCLEX_CPPNOCASE=35 -val SCLEX_FORTRAN=36 -val SCLEX_F77=37 -val SCLEX_CSS=38 -val SCLEX_POV=39 -val SCLEX_LOUT=40 -val SCLEX_ESCRIPT=41 -val SCLEX_PS=42 -val SCLEX_NSIS=43 -val SCLEX_MMIXAL=44 -val SCLEX_CLW=45 -val SCLEX_CLWNOCASE=46 -val SCLEX_LOT=47 -val SCLEX_YAML=48 -val SCLEX_TEX=49 -val SCLEX_METAPOST=50 -val SCLEX_POWERBASIC=51 -val SCLEX_FORTH=52 -val SCLEX_ERLANG=53 -val SCLEX_OCTAVE=54 -val SCLEX_MSSQL=55 -val SCLEX_VERILOG=56 -val SCLEX_KIX=57 -val SCLEX_GUI4CLI=58 -val SCLEX_SPECMAN=59 -val SCLEX_AU3=60 -val SCLEX_APDL=61 -val SCLEX_BASH=62 -val SCLEX_ASN1=63 -val SCLEX_VHDL=64 -val SCLEX_CAML=65 -val SCLEX_BLITZBASIC=66 -val SCLEX_PUREBASIC=67 -val SCLEX_HASKELL=68 -val SCLEX_PHPSCRIPT=69 -val SCLEX_TADS3=70 -val SCLEX_REBOL=71 -val SCLEX_SMALLTALK=72 -val SCLEX_FLAGSHIP=73 -val SCLEX_CSOUND=74 -val SCLEX_FREEBASIC=75 -val SCLEX_INNOSETUP=76 -val SCLEX_OPAL=77 -val SCLEX_SPICE=78 -val SCLEX_D=79 -val SCLEX_CMAKE=80 -val SCLEX_GAP=81 -val SCLEX_PLM=82 -val SCLEX_PROGRESS=83 -val SCLEX_ABAQUS=84 -val SCLEX_ASYMPTOTE=85 -val SCLEX_R=86 -val SCLEX_MAGIK=87 -val SCLEX_POWERSHELL=88 -val SCLEX_MYSQL=89 -val SCLEX_PO=90 -val SCLEX_TAL=91 -val SCLEX_COBOL=92 -val SCLEX_TACL=93 -val SCLEX_SORCUS=94 -val SCLEX_POWERPRO=95 -val SCLEX_NIMROD=96 -val SCLEX_SML=97 -val SCLEX_MARKDOWN=98 -val SCLEX_TXT2TAGS=99 -val SCLEX_A68K=100 -val SCLEX_MODULA=101 -val SCLEX_COFFEESCRIPT=102 -val SCLEX_TCMD=103 -val SCLEX_AVS=104 -val SCLEX_ECL=105 -val SCLEX_OSCRIPT=106 -val SCLEX_VISUALPROLOG=107 -val SCLEX_LITERATEHASKELL=108 -val SCLEX_STTXT=109 -val SCLEX_KVIRC=110 -val SCLEX_RUST=111 -val SCLEX_DMAP=112 -val SCLEX_AS=113 -val SCLEX_DMIS=114 -val SCLEX_REGISTRY=115 -val SCLEX_BIBTEX=116 -val SCLEX_SREC=117 -val SCLEX_IHEX=118 -val SCLEX_TEHEX=119 -val SCLEX_JSON=120 -val SCLEX_EDIFACT=121 -val SCLEX_INDENT=122 -val SCLEX_MAXIMA=123 -val SCLEX_STATA=124 -val SCLEX_SAS=125 -val SCLEX_NIM=126 -val SCLEX_CIL=127 -val SCLEX_X12=128 -val SCLEX_DATAFLEX=129 -val SCLEX_HOLLYWOOD=130 -val SCLEX_RAKU=131 -val SCLEX_JULIA=133 -val SCLEX_LPEG=999 - -# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a -# value assigned in sequence from SCLEX_AUTOMATIC+1. -val SCLEX_AUTOMATIC=1000 -# Lexical states for SCLEX_PYTHON -lex Python=SCLEX_PYTHON SCE_P_ -lex Nimrod=SCLEX_NIMROD SCE_P_ -val SCE_P_DEFAULT=0 -val SCE_P_COMMENTLINE=1 -val SCE_P_NUMBER=2 -val SCE_P_STRING=3 -val SCE_P_CHARACTER=4 -val SCE_P_WORD=5 -val SCE_P_TRIPLE=6 -val SCE_P_TRIPLEDOUBLE=7 -val SCE_P_CLASSNAME=8 -val SCE_P_DEFNAME=9 -val SCE_P_OPERATOR=10 -val SCE_P_IDENTIFIER=11 -val SCE_P_COMMENTBLOCK=12 -val SCE_P_STRINGEOL=13 -val SCE_P_WORD2=14 -val SCE_P_DECORATOR=15 -val SCE_P_FSTRING=16 -val SCE_P_FCHARACTER=17 -val SCE_P_FTRIPLE=18 -val SCE_P_FTRIPLEDOUBLE=19 -# Lexical states for SCLEX_CPP -# Lexical states for SCLEX_BULLANT -# Lexical states for SCLEX_COBOL -# Lexical states for SCLEX_TACL -# Lexical states for SCLEX_TAL -lex Cpp=SCLEX_CPP SCE_C_ -lex BullAnt=SCLEX_BULLANT SCE_C_ -lex COBOL=SCLEX_COBOL SCE_C_ -lex TACL=SCLEX_TACL SCE_C_ -lex TAL=SCLEX_TAL SCE_C_ -val SCE_C_DEFAULT=0 -val SCE_C_COMMENT=1 -val SCE_C_COMMENTLINE=2 -val SCE_C_COMMENTDOC=3 -val SCE_C_NUMBER=4 -val SCE_C_WORD=5 -val SCE_C_STRING=6 -val SCE_C_CHARACTER=7 -val SCE_C_UUID=8 -val SCE_C_PREPROCESSOR=9 -val SCE_C_OPERATOR=10 -val SCE_C_IDENTIFIER=11 -val SCE_C_STRINGEOL=12 -val SCE_C_VERBATIM=13 -val SCE_C_REGEX=14 -val SCE_C_COMMENTLINEDOC=15 -val SCE_C_WORD2=16 -val SCE_C_COMMENTDOCKEYWORD=17 -val SCE_C_COMMENTDOCKEYWORDERROR=18 -val SCE_C_GLOBALCLASS=19 -val SCE_C_STRINGRAW=20 -val SCE_C_TRIPLEVERBATIM=21 -val SCE_C_HASHQUOTEDSTRING=22 -val SCE_C_PREPROCESSORCOMMENT=23 -val SCE_C_PREPROCESSORCOMMENTDOC=24 -val SCE_C_USERLITERAL=25 -val SCE_C_TASKMARKER=26 -val SCE_C_ESCAPESEQUENCE=27 -# Lexical states for SCLEX_D -lex D=SCLEX_D SCE_D_ -val SCE_D_DEFAULT=0 -val SCE_D_COMMENT=1 -val SCE_D_COMMENTLINE=2 -val SCE_D_COMMENTDOC=3 -val SCE_D_COMMENTNESTED=4 -val SCE_D_NUMBER=5 -val SCE_D_WORD=6 -val SCE_D_WORD2=7 -val SCE_D_WORD3=8 -val SCE_D_TYPEDEF=9 -val SCE_D_STRING=10 -val SCE_D_STRINGEOL=11 -val SCE_D_CHARACTER=12 -val SCE_D_OPERATOR=13 -val SCE_D_IDENTIFIER=14 -val SCE_D_COMMENTLINEDOC=15 -val SCE_D_COMMENTDOCKEYWORD=16 -val SCE_D_COMMENTDOCKEYWORDERROR=17 -val SCE_D_STRINGB=18 -val SCE_D_STRINGR=19 -val SCE_D_WORD5=20 -val SCE_D_WORD6=21 -val SCE_D_WORD7=22 -# Lexical states for SCLEX_TCL -lex TCL=SCLEX_TCL SCE_TCL_ -val SCE_TCL_DEFAULT=0 -val SCE_TCL_COMMENT=1 -val SCE_TCL_COMMENTLINE=2 -val SCE_TCL_NUMBER=3 -val SCE_TCL_WORD_IN_QUOTE=4 -val SCE_TCL_IN_QUOTE=5 -val SCE_TCL_OPERATOR=6 -val SCE_TCL_IDENTIFIER=7 -val SCE_TCL_SUBSTITUTION=8 -val SCE_TCL_SUB_BRACE=9 -val SCE_TCL_MODIFIER=10 -val SCE_TCL_EXPAND=11 -val SCE_TCL_WORD=12 -val SCE_TCL_WORD2=13 -val SCE_TCL_WORD3=14 -val SCE_TCL_WORD4=15 -val SCE_TCL_WORD5=16 -val SCE_TCL_WORD6=17 -val SCE_TCL_WORD7=18 -val SCE_TCL_WORD8=19 -val SCE_TCL_COMMENT_BOX=20 -val SCE_TCL_BLOCK_COMMENT=21 -# Lexical states for SCLEX_HTML, SCLEX_XML -lex HTML=SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ -lex XML=SCLEX_XML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ -val SCE_H_DEFAULT=0 -val SCE_H_TAG=1 -val SCE_H_TAGUNKNOWN=2 -val SCE_H_ATTRIBUTE=3 -val SCE_H_ATTRIBUTEUNKNOWN=4 -val SCE_H_NUMBER=5 -val SCE_H_DOUBLESTRING=6 -val SCE_H_SINGLESTRING=7 -val SCE_H_OTHER=8 -val SCE_H_COMMENT=9 -val SCE_H_ENTITY=10 -# XML and ASP -val SCE_H_TAGEND=11 -val SCE_H_XMLSTART=12 -val SCE_H_XMLEND=13 -val SCE_H_SCRIPT=14 -val SCE_H_ASP=15 -val SCE_H_ASPAT=16 -val SCE_H_CDATA=17 -val SCE_H_QUESTION=18 -# More HTML -val SCE_H_VALUE=19 -# X-Code -val SCE_H_XCCOMMENT=20 -# SGML -val SCE_H_SGML_DEFAULT=21 -val SCE_H_SGML_COMMAND=22 -val SCE_H_SGML_1ST_PARAM=23 -val SCE_H_SGML_DOUBLESTRING=24 -val SCE_H_SGML_SIMPLESTRING=25 -val SCE_H_SGML_ERROR=26 -val SCE_H_SGML_SPECIAL=27 -val SCE_H_SGML_ENTITY=28 -val SCE_H_SGML_COMMENT=29 -val SCE_H_SGML_1ST_PARAM_COMMENT=30 -val SCE_H_SGML_BLOCK_DEFAULT=31 -# Embedded Javascript -val SCE_HJ_START=40 -val SCE_HJ_DEFAULT=41 -val SCE_HJ_COMMENT=42 -val SCE_HJ_COMMENTLINE=43 -val SCE_HJ_COMMENTDOC=44 -val SCE_HJ_NUMBER=45 -val SCE_HJ_WORD=46 -val SCE_HJ_KEYWORD=47 -val SCE_HJ_DOUBLESTRING=48 -val SCE_HJ_SINGLESTRING=49 -val SCE_HJ_SYMBOLS=50 -val SCE_HJ_STRINGEOL=51 -val SCE_HJ_REGEX=52 -# ASP Javascript -val SCE_HJA_START=55 -val SCE_HJA_DEFAULT=56 -val SCE_HJA_COMMENT=57 -val SCE_HJA_COMMENTLINE=58 -val SCE_HJA_COMMENTDOC=59 -val SCE_HJA_NUMBER=60 -val SCE_HJA_WORD=61 -val SCE_HJA_KEYWORD=62 -val SCE_HJA_DOUBLESTRING=63 -val SCE_HJA_SINGLESTRING=64 -val SCE_HJA_SYMBOLS=65 -val SCE_HJA_STRINGEOL=66 -val SCE_HJA_REGEX=67 -# Embedded VBScript -val SCE_HB_START=70 -val SCE_HB_DEFAULT=71 -val SCE_HB_COMMENTLINE=72 -val SCE_HB_NUMBER=73 -val SCE_HB_WORD=74 -val SCE_HB_STRING=75 -val SCE_HB_IDENTIFIER=76 -val SCE_HB_STRINGEOL=77 -# ASP VBScript -val SCE_HBA_START=80 -val SCE_HBA_DEFAULT=81 -val SCE_HBA_COMMENTLINE=82 -val SCE_HBA_NUMBER=83 -val SCE_HBA_WORD=84 -val SCE_HBA_STRING=85 -val SCE_HBA_IDENTIFIER=86 -val SCE_HBA_STRINGEOL=87 -# Embedded Python -val SCE_HP_START=90 -val SCE_HP_DEFAULT=91 -val SCE_HP_COMMENTLINE=92 -val SCE_HP_NUMBER=93 -val SCE_HP_STRING=94 -val SCE_HP_CHARACTER=95 -val SCE_HP_WORD=96 -val SCE_HP_TRIPLE=97 -val SCE_HP_TRIPLEDOUBLE=98 -val SCE_HP_CLASSNAME=99 -val SCE_HP_DEFNAME=100 -val SCE_HP_OPERATOR=101 -val SCE_HP_IDENTIFIER=102 -# PHP -val SCE_HPHP_COMPLEX_VARIABLE=104 -# ASP Python -val SCE_HPA_START=105 -val SCE_HPA_DEFAULT=106 -val SCE_HPA_COMMENTLINE=107 -val SCE_HPA_NUMBER=108 -val SCE_HPA_STRING=109 -val SCE_HPA_CHARACTER=110 -val SCE_HPA_WORD=111 -val SCE_HPA_TRIPLE=112 -val SCE_HPA_TRIPLEDOUBLE=113 -val SCE_HPA_CLASSNAME=114 -val SCE_HPA_DEFNAME=115 -val SCE_HPA_OPERATOR=116 -val SCE_HPA_IDENTIFIER=117 -# PHP -val SCE_HPHP_DEFAULT=118 -val SCE_HPHP_HSTRING=119 -val SCE_HPHP_SIMPLESTRING=120 -val SCE_HPHP_WORD=121 -val SCE_HPHP_NUMBER=122 -val SCE_HPHP_VARIABLE=123 -val SCE_HPHP_COMMENT=124 -val SCE_HPHP_COMMENTLINE=125 -val SCE_HPHP_HSTRING_VARIABLE=126 -val SCE_HPHP_OPERATOR=127 -# Lexical states for SCLEX_PERL -lex Perl=SCLEX_PERL SCE_PL_ -val SCE_PL_DEFAULT=0 -val SCE_PL_ERROR=1 -val SCE_PL_COMMENTLINE=2 -val SCE_PL_POD=3 -val SCE_PL_NUMBER=4 -val SCE_PL_WORD=5 -val SCE_PL_STRING=6 -val SCE_PL_CHARACTER=7 -val SCE_PL_PUNCTUATION=8 -val SCE_PL_PREPROCESSOR=9 -val SCE_PL_OPERATOR=10 -val SCE_PL_IDENTIFIER=11 -val SCE_PL_SCALAR=12 -val SCE_PL_ARRAY=13 -val SCE_PL_HASH=14 -val SCE_PL_SYMBOLTABLE=15 -val SCE_PL_VARIABLE_INDEXER=16 -val SCE_PL_REGEX=17 -val SCE_PL_REGSUBST=18 -val SCE_PL_LONGQUOTE=19 -val SCE_PL_BACKTICKS=20 -val SCE_PL_DATASECTION=21 -val SCE_PL_HERE_DELIM=22 -val SCE_PL_HERE_Q=23 -val SCE_PL_HERE_QQ=24 -val SCE_PL_HERE_QX=25 -val SCE_PL_STRING_Q=26 -val SCE_PL_STRING_QQ=27 -val SCE_PL_STRING_QX=28 -val SCE_PL_STRING_QR=29 -val SCE_PL_STRING_QW=30 -val SCE_PL_POD_VERB=31 -val SCE_PL_SUB_PROTOTYPE=40 -val SCE_PL_FORMAT_IDENT=41 -val SCE_PL_FORMAT=42 -val SCE_PL_STRING_VAR=43 -val SCE_PL_XLAT=44 -val SCE_PL_REGEX_VAR=54 -val SCE_PL_REGSUBST_VAR=55 -val SCE_PL_BACKTICKS_VAR=57 -val SCE_PL_HERE_QQ_VAR=61 -val SCE_PL_HERE_QX_VAR=62 -val SCE_PL_STRING_QQ_VAR=64 -val SCE_PL_STRING_QX_VAR=65 -val SCE_PL_STRING_QR_VAR=66 -# Lexical states for SCLEX_RUBY -lex Ruby=SCLEX_RUBY SCE_RB_ -val SCE_RB_DEFAULT=0 -val SCE_RB_ERROR=1 -val SCE_RB_COMMENTLINE=2 -val SCE_RB_POD=3 -val SCE_RB_NUMBER=4 -val SCE_RB_WORD=5 -val SCE_RB_STRING=6 -val SCE_RB_CHARACTER=7 -val SCE_RB_CLASSNAME=8 -val SCE_RB_DEFNAME=9 -val SCE_RB_OPERATOR=10 -val SCE_RB_IDENTIFIER=11 -val SCE_RB_REGEX=12 -val SCE_RB_GLOBAL=13 -val SCE_RB_SYMBOL=14 -val SCE_RB_MODULE_NAME=15 -val SCE_RB_INSTANCE_VAR=16 -val SCE_RB_CLASS_VAR=17 -val SCE_RB_BACKTICKS=18 -val SCE_RB_DATASECTION=19 -val SCE_RB_HERE_DELIM=20 -val SCE_RB_HERE_Q=21 -val SCE_RB_HERE_QQ=22 -val SCE_RB_HERE_QX=23 -val SCE_RB_STRING_Q=24 -val SCE_RB_STRING_QQ=25 -val SCE_RB_STRING_QX=26 -val SCE_RB_STRING_QR=27 -val SCE_RB_STRING_QW=28 -val SCE_RB_WORD_DEMOTED=29 -val SCE_RB_STDIN=30 -val SCE_RB_STDOUT=31 -val SCE_RB_STDERR=40 -val SCE_RB_UPPER_BOUND=41 -# Lexical states for SCLEX_VB, SCLEX_VBSCRIPT, SCLEX_POWERBASIC, SCLEX_BLITZBASIC, SCLEX_PUREBASIC, SCLEX_FREEBASIC -lex VB=SCLEX_VB SCE_B_ -lex VBScript=SCLEX_VBSCRIPT SCE_B_ -lex PowerBasic=SCLEX_POWERBASIC SCE_B_ -lex BlitzBasic=SCLEX_BLITZBASIC SCE_B_ -lex PureBasic=SCLEX_PUREBASIC SCE_B_ -lex FreeBasic=SCLEX_FREEBASIC SCE_B_ -val SCE_B_DEFAULT=0 -val SCE_B_COMMENT=1 -val SCE_B_NUMBER=2 -val SCE_B_KEYWORD=3 -val SCE_B_STRING=4 -val SCE_B_PREPROCESSOR=5 -val SCE_B_OPERATOR=6 -val SCE_B_IDENTIFIER=7 -val SCE_B_DATE=8 -val SCE_B_STRINGEOL=9 -val SCE_B_KEYWORD2=10 -val SCE_B_KEYWORD3=11 -val SCE_B_KEYWORD4=12 -val SCE_B_CONSTANT=13 -val SCE_B_ASM=14 -val SCE_B_LABEL=15 -val SCE_B_ERROR=16 -val SCE_B_HEXNUMBER=17 -val SCE_B_BINNUMBER=18 -val SCE_B_COMMENTBLOCK=19 -val SCE_B_DOCLINE=20 -val SCE_B_DOCBLOCK=21 -val SCE_B_DOCKEYWORD=22 -# Lexical states for SCLEX_PROPERTIES -lex Properties=SCLEX_PROPERTIES SCE_PROPS_ -val SCE_PROPS_DEFAULT=0 -val SCE_PROPS_COMMENT=1 -val SCE_PROPS_SECTION=2 -val SCE_PROPS_ASSIGNMENT=3 -val SCE_PROPS_DEFVAL=4 -val SCE_PROPS_KEY=5 -# Lexical states for SCLEX_LATEX -lex LaTeX=SCLEX_LATEX SCE_L_ -val SCE_L_DEFAULT=0 -val SCE_L_COMMAND=1 -val SCE_L_TAG=2 -val SCE_L_MATH=3 -val SCE_L_COMMENT=4 -val SCE_L_TAG2=5 -val SCE_L_MATH2=6 -val SCE_L_COMMENT2=7 -val SCE_L_VERBATIM=8 -val SCE_L_SHORTCMD=9 -val SCE_L_SPECIAL=10 -val SCE_L_CMDOPT=11 -val SCE_L_ERROR=12 -# Lexical states for SCLEX_LUA -lex Lua=SCLEX_LUA SCE_LUA_ -val SCE_LUA_DEFAULT=0 -val SCE_LUA_COMMENT=1 -val SCE_LUA_COMMENTLINE=2 -val SCE_LUA_COMMENTDOC=3 -val SCE_LUA_NUMBER=4 -val SCE_LUA_WORD=5 -val SCE_LUA_STRING=6 -val SCE_LUA_CHARACTER=7 -val SCE_LUA_LITERALSTRING=8 -val SCE_LUA_PREPROCESSOR=9 -val SCE_LUA_OPERATOR=10 -val SCE_LUA_IDENTIFIER=11 -val SCE_LUA_STRINGEOL=12 -val SCE_LUA_WORD2=13 -val SCE_LUA_WORD3=14 -val SCE_LUA_WORD4=15 -val SCE_LUA_WORD5=16 -val SCE_LUA_WORD6=17 -val SCE_LUA_WORD7=18 -val SCE_LUA_WORD8=19 -val SCE_LUA_LABEL=20 -# Lexical states for SCLEX_ERRORLIST -lex ErrorList=SCLEX_ERRORLIST SCE_ERR_ -val SCE_ERR_DEFAULT=0 -val SCE_ERR_PYTHON=1 -val SCE_ERR_GCC=2 -val SCE_ERR_MS=3 -val SCE_ERR_CMD=4 -val SCE_ERR_BORLAND=5 -val SCE_ERR_PERL=6 -val SCE_ERR_NET=7 -val SCE_ERR_LUA=8 -val SCE_ERR_CTAG=9 -val SCE_ERR_DIFF_CHANGED=10 -val SCE_ERR_DIFF_ADDITION=11 -val SCE_ERR_DIFF_DELETION=12 -val SCE_ERR_DIFF_MESSAGE=13 -val SCE_ERR_PHP=14 -val SCE_ERR_ELF=15 -val SCE_ERR_IFC=16 -val SCE_ERR_IFORT=17 -val SCE_ERR_ABSF=18 -val SCE_ERR_TIDY=19 -val SCE_ERR_JAVA_STACK=20 -val SCE_ERR_VALUE=21 -val SCE_ERR_GCC_INCLUDED_FROM=22 -val SCE_ERR_ESCSEQ=23 -val SCE_ERR_ESCSEQ_UNKNOWN=24 -val SCE_ERR_GCC_EXCERPT=25 -val SCE_ERR_ES_BLACK=40 -val SCE_ERR_ES_RED=41 -val SCE_ERR_ES_GREEN=42 -val SCE_ERR_ES_BROWN=43 -val SCE_ERR_ES_BLUE=44 -val SCE_ERR_ES_MAGENTA=45 -val SCE_ERR_ES_CYAN=46 -val SCE_ERR_ES_GRAY=47 -val SCE_ERR_ES_DARK_GRAY=48 -val SCE_ERR_ES_BRIGHT_RED=49 -val SCE_ERR_ES_BRIGHT_GREEN=50 -val SCE_ERR_ES_YELLOW=51 -val SCE_ERR_ES_BRIGHT_BLUE=52 -val SCE_ERR_ES_BRIGHT_MAGENTA=53 -val SCE_ERR_ES_BRIGHT_CYAN=54 -val SCE_ERR_ES_WHITE=55 -# Lexical states for SCLEX_BATCH -lex Batch=SCLEX_BATCH SCE_BAT_ -val SCE_BAT_DEFAULT=0 -val SCE_BAT_COMMENT=1 -val SCE_BAT_WORD=2 -val SCE_BAT_LABEL=3 -val SCE_BAT_HIDE=4 -val SCE_BAT_COMMAND=5 -val SCE_BAT_IDENTIFIER=6 -val SCE_BAT_OPERATOR=7 -# Lexical states for SCLEX_TCMD -lex TCMD=SCLEX_TCMD SCE_TCMD_ -val SCE_TCMD_DEFAULT=0 -val SCE_TCMD_COMMENT=1 -val SCE_TCMD_WORD=2 -val SCE_TCMD_LABEL=3 -val SCE_TCMD_HIDE=4 -val SCE_TCMD_COMMAND=5 -val SCE_TCMD_IDENTIFIER=6 -val SCE_TCMD_OPERATOR=7 -val SCE_TCMD_ENVIRONMENT=8 -val SCE_TCMD_EXPANSION=9 -val SCE_TCMD_CLABEL=10 -# Lexical states for SCLEX_MAKEFILE -lex MakeFile=SCLEX_MAKEFILE SCE_MAKE_ -val SCE_MAKE_DEFAULT=0 -val SCE_MAKE_COMMENT=1 -val SCE_MAKE_PREPROCESSOR=2 -val SCE_MAKE_IDENTIFIER=3 -val SCE_MAKE_OPERATOR=4 -val SCE_MAKE_TARGET=5 -val SCE_MAKE_IDEOL=9 -# Lexical states for SCLEX_DIFF -lex Diff=SCLEX_DIFF SCE_DIFF_ -val SCE_DIFF_DEFAULT=0 -val SCE_DIFF_COMMENT=1 -val SCE_DIFF_COMMAND=2 -val SCE_DIFF_HEADER=3 -val SCE_DIFF_POSITION=4 -val SCE_DIFF_DELETED=5 -val SCE_DIFF_ADDED=6 -val SCE_DIFF_CHANGED=7 -val SCE_DIFF_PATCH_ADD=8 -val SCE_DIFF_PATCH_DELETE=9 -val SCE_DIFF_REMOVED_PATCH_ADD=10 -val SCE_DIFF_REMOVED_PATCH_DELETE=11 -# Lexical states for SCLEX_CONF (Apache Configuration Files Lexer) -lex Conf=SCLEX_CONF SCE_CONF_ -val SCE_CONF_DEFAULT=0 -val SCE_CONF_COMMENT=1 -val SCE_CONF_NUMBER=2 -val SCE_CONF_IDENTIFIER=3 -val SCE_CONF_EXTENSION=4 -val SCE_CONF_PARAMETER=5 -val SCE_CONF_STRING=6 -val SCE_CONF_OPERATOR=7 -val SCE_CONF_IP=8 -val SCE_CONF_DIRECTIVE=9 -# Lexical states for SCLEX_AVE, Avenue -lex Avenue=SCLEX_AVE SCE_AVE_ -val SCE_AVE_DEFAULT=0 -val SCE_AVE_COMMENT=1 -val SCE_AVE_NUMBER=2 -val SCE_AVE_WORD=3 -val SCE_AVE_STRING=6 -val SCE_AVE_ENUM=7 -val SCE_AVE_STRINGEOL=8 -val SCE_AVE_IDENTIFIER=9 -val SCE_AVE_OPERATOR=10 -val SCE_AVE_WORD1=11 -val SCE_AVE_WORD2=12 -val SCE_AVE_WORD3=13 -val SCE_AVE_WORD4=14 -val SCE_AVE_WORD5=15 -val SCE_AVE_WORD6=16 -# Lexical states for SCLEX_ADA -lex Ada=SCLEX_ADA SCE_ADA_ -val SCE_ADA_DEFAULT=0 -val SCE_ADA_WORD=1 -val SCE_ADA_IDENTIFIER=2 -val SCE_ADA_NUMBER=3 -val SCE_ADA_DELIMITER=4 -val SCE_ADA_CHARACTER=5 -val SCE_ADA_CHARACTEREOL=6 -val SCE_ADA_STRING=7 -val SCE_ADA_STRINGEOL=8 -val SCE_ADA_LABEL=9 -val SCE_ADA_COMMENTLINE=10 -val SCE_ADA_ILLEGAL=11 -# Lexical states for SCLEX_BAAN -lex Baan=SCLEX_BAAN SCE_BAAN_ -val SCE_BAAN_DEFAULT=0 -val SCE_BAAN_COMMENT=1 -val SCE_BAAN_COMMENTDOC=2 -val SCE_BAAN_NUMBER=3 -val SCE_BAAN_WORD=4 -val SCE_BAAN_STRING=5 -val SCE_BAAN_PREPROCESSOR=6 -val SCE_BAAN_OPERATOR=7 -val SCE_BAAN_IDENTIFIER=8 -val SCE_BAAN_STRINGEOL=9 -val SCE_BAAN_WORD2=10 -val SCE_BAAN_WORD3=11 -val SCE_BAAN_WORD4=12 -val SCE_BAAN_WORD5=13 -val SCE_BAAN_WORD6=14 -val SCE_BAAN_WORD7=15 -val SCE_BAAN_WORD8=16 -val SCE_BAAN_WORD9=17 -val SCE_BAAN_TABLEDEF=18 -val SCE_BAAN_TABLESQL=19 -val SCE_BAAN_FUNCTION=20 -val SCE_BAAN_DOMDEF=21 -val SCE_BAAN_FUNCDEF=22 -val SCE_BAAN_OBJECTDEF=23 -val SCE_BAAN_DEFINEDEF=24 -# Lexical states for SCLEX_LISP -lex Lisp=SCLEX_LISP SCE_LISP_ -val SCE_LISP_DEFAULT=0 -val SCE_LISP_COMMENT=1 -val SCE_LISP_NUMBER=2 -val SCE_LISP_KEYWORD=3 -val SCE_LISP_KEYWORD_KW=4 -val SCE_LISP_SYMBOL=5 -val SCE_LISP_STRING=6 -val SCE_LISP_STRINGEOL=8 -val SCE_LISP_IDENTIFIER=9 -val SCE_LISP_OPERATOR=10 -val SCE_LISP_SPECIAL=11 -val SCE_LISP_MULTI_COMMENT=12 -# Lexical states for SCLEX_EIFFEL and SCLEX_EIFFELKW -lex Eiffel=SCLEX_EIFFEL SCE_EIFFEL_ -lex EiffelKW=SCLEX_EIFFELKW SCE_EIFFEL_ -val SCE_EIFFEL_DEFAULT=0 -val SCE_EIFFEL_COMMENTLINE=1 -val SCE_EIFFEL_NUMBER=2 -val SCE_EIFFEL_WORD=3 -val SCE_EIFFEL_STRING=4 -val SCE_EIFFEL_CHARACTER=5 -val SCE_EIFFEL_OPERATOR=6 -val SCE_EIFFEL_IDENTIFIER=7 -val SCE_EIFFEL_STRINGEOL=8 -# Lexical states for SCLEX_NNCRONTAB (nnCron crontab Lexer) -lex NNCronTab=SCLEX_NNCRONTAB SCE_NNCRONTAB_ -val SCE_NNCRONTAB_DEFAULT=0 -val SCE_NNCRONTAB_COMMENT=1 -val SCE_NNCRONTAB_TASK=2 -val SCE_NNCRONTAB_SECTION=3 -val SCE_NNCRONTAB_KEYWORD=4 -val SCE_NNCRONTAB_MODIFIER=5 -val SCE_NNCRONTAB_ASTERISK=6 -val SCE_NNCRONTAB_NUMBER=7 -val SCE_NNCRONTAB_STRING=8 -val SCE_NNCRONTAB_ENVIRONMENT=9 -val SCE_NNCRONTAB_IDENTIFIER=10 -# Lexical states for SCLEX_FORTH (Forth Lexer) -lex Forth=SCLEX_FORTH SCE_FORTH_ -val SCE_FORTH_DEFAULT=0 -val SCE_FORTH_COMMENT=1 -val SCE_FORTH_COMMENT_ML=2 -val SCE_FORTH_IDENTIFIER=3 -val SCE_FORTH_CONTROL=4 -val SCE_FORTH_KEYWORD=5 -val SCE_FORTH_DEFWORD=6 -val SCE_FORTH_PREWORD1=7 -val SCE_FORTH_PREWORD2=8 -val SCE_FORTH_NUMBER=9 -val SCE_FORTH_STRING=10 -val SCE_FORTH_LOCALE=11 -# Lexical states for SCLEX_MATLAB -lex MatLab=SCLEX_MATLAB SCE_MATLAB_ -val SCE_MATLAB_DEFAULT=0 -val SCE_MATLAB_COMMENT=1 -val SCE_MATLAB_COMMAND=2 -val SCE_MATLAB_NUMBER=3 -val SCE_MATLAB_KEYWORD=4 -# single quoted string -val SCE_MATLAB_STRING=5 -val SCE_MATLAB_OPERATOR=6 -val SCE_MATLAB_IDENTIFIER=7 -val SCE_MATLAB_DOUBLEQUOTESTRING=8 -# Lexical states for SCLEX_MAXIMA -lex Maxima=SCLEX_MAXIMA SCE_MAXIMA_ -val SCE_MAXIMA_OPERATOR=0 -val SCE_MAXIMA_COMMANDENDING=1 -val SCE_MAXIMA_COMMENT=2 -val SCE_MAXIMA_NUMBER=3 -val SCE_MAXIMA_STRING=4 -val SCE_MAXIMA_COMMAND=5 -val SCE_MAXIMA_VARIABLE=6 -val SCE_MAXIMA_UNKNOWN=7 -# Lexical states for SCLEX_SCRIPTOL -lex Sol=SCLEX_SCRIPTOL SCE_SCRIPTOL_ -val SCE_SCRIPTOL_DEFAULT=0 -val SCE_SCRIPTOL_WHITE=1 -val SCE_SCRIPTOL_COMMENTLINE=2 -val SCE_SCRIPTOL_PERSISTENT=3 -val SCE_SCRIPTOL_CSTYLE=4 -val SCE_SCRIPTOL_COMMENTBLOCK=5 -val SCE_SCRIPTOL_NUMBER=6 -val SCE_SCRIPTOL_STRING=7 -val SCE_SCRIPTOL_CHARACTER=8 -val SCE_SCRIPTOL_STRINGEOL=9 -val SCE_SCRIPTOL_KEYWORD=10 -val SCE_SCRIPTOL_OPERATOR=11 -val SCE_SCRIPTOL_IDENTIFIER=12 -val SCE_SCRIPTOL_TRIPLE=13 -val SCE_SCRIPTOL_CLASSNAME=14 -val SCE_SCRIPTOL_PREPROCESSOR=15 -# Lexical states for SCLEX_ASM, SCLEX_AS -lex Asm=SCLEX_ASM SCE_ASM_ -lex As=SCLEX_AS SCE_ASM_ -val SCE_ASM_DEFAULT=0 -val SCE_ASM_COMMENT=1 -val SCE_ASM_NUMBER=2 -val SCE_ASM_STRING=3 -val SCE_ASM_OPERATOR=4 -val SCE_ASM_IDENTIFIER=5 -val SCE_ASM_CPUINSTRUCTION=6 -val SCE_ASM_MATHINSTRUCTION=7 -val SCE_ASM_REGISTER=8 -val SCE_ASM_DIRECTIVE=9 -val SCE_ASM_DIRECTIVEOPERAND=10 -val SCE_ASM_COMMENTBLOCK=11 -val SCE_ASM_CHARACTER=12 -val SCE_ASM_STRINGEOL=13 -val SCE_ASM_EXTINSTRUCTION=14 -val SCE_ASM_COMMENTDIRECTIVE=15 -# Lexical states for SCLEX_FORTRAN -lex Fortran=SCLEX_FORTRAN SCE_F_ -lex F77=SCLEX_F77 SCE_F_ -val SCE_F_DEFAULT=0 -val SCE_F_COMMENT=1 -val SCE_F_NUMBER=2 -val SCE_F_STRING1=3 -val SCE_F_STRING2=4 -val SCE_F_STRINGEOL=5 -val SCE_F_OPERATOR=6 -val SCE_F_IDENTIFIER=7 -val SCE_F_WORD=8 -val SCE_F_WORD2=9 -val SCE_F_WORD3=10 -val SCE_F_PREPROCESSOR=11 -val SCE_F_OPERATOR2=12 -val SCE_F_LABEL=13 -val SCE_F_CONTINUATION=14 -# Lexical states for SCLEX_CSS -lex CSS=SCLEX_CSS SCE_CSS_ -val SCE_CSS_DEFAULT=0 -val SCE_CSS_TAG=1 -val SCE_CSS_CLASS=2 -val SCE_CSS_PSEUDOCLASS=3 -val SCE_CSS_UNKNOWN_PSEUDOCLASS=4 -val SCE_CSS_OPERATOR=5 -val SCE_CSS_IDENTIFIER=6 -val SCE_CSS_UNKNOWN_IDENTIFIER=7 -val SCE_CSS_VALUE=8 -val SCE_CSS_COMMENT=9 -val SCE_CSS_ID=10 -val SCE_CSS_IMPORTANT=11 -val SCE_CSS_DIRECTIVE=12 -val SCE_CSS_DOUBLESTRING=13 -val SCE_CSS_SINGLESTRING=14 -val SCE_CSS_IDENTIFIER2=15 -val SCE_CSS_ATTRIBUTE=16 -val SCE_CSS_IDENTIFIER3=17 -val SCE_CSS_PSEUDOELEMENT=18 -val SCE_CSS_EXTENDED_IDENTIFIER=19 -val SCE_CSS_EXTENDED_PSEUDOCLASS=20 -val SCE_CSS_EXTENDED_PSEUDOELEMENT=21 -val SCE_CSS_MEDIA=22 -val SCE_CSS_VARIABLE=23 -# Lexical states for SCLEX_POV -lex POV=SCLEX_POV SCE_POV_ -val SCE_POV_DEFAULT=0 -val SCE_POV_COMMENT=1 -val SCE_POV_COMMENTLINE=2 -val SCE_POV_NUMBER=3 -val SCE_POV_OPERATOR=4 -val SCE_POV_IDENTIFIER=5 -val SCE_POV_STRING=6 -val SCE_POV_STRINGEOL=7 -val SCE_POV_DIRECTIVE=8 -val SCE_POV_BADDIRECTIVE=9 -val SCE_POV_WORD2=10 -val SCE_POV_WORD3=11 -val SCE_POV_WORD4=12 -val SCE_POV_WORD5=13 -val SCE_POV_WORD6=14 -val SCE_POV_WORD7=15 -val SCE_POV_WORD8=16 -# Lexical states for SCLEX_LOUT -lex LOUT=SCLEX_LOUT SCE_LOUT_ -val SCE_LOUT_DEFAULT=0 -val SCE_LOUT_COMMENT=1 -val SCE_LOUT_NUMBER=2 -val SCE_LOUT_WORD=3 -val SCE_LOUT_WORD2=4 -val SCE_LOUT_WORD3=5 -val SCE_LOUT_WORD4=6 -val SCE_LOUT_STRING=7 -val SCE_LOUT_OPERATOR=8 -val SCE_LOUT_IDENTIFIER=9 -val SCE_LOUT_STRINGEOL=10 -# Lexical states for SCLEX_ESCRIPT -lex ESCRIPT=SCLEX_ESCRIPT SCE_ESCRIPT_ -val SCE_ESCRIPT_DEFAULT=0 -val SCE_ESCRIPT_COMMENT=1 -val SCE_ESCRIPT_COMMENTLINE=2 -val SCE_ESCRIPT_COMMENTDOC=3 -val SCE_ESCRIPT_NUMBER=4 -val SCE_ESCRIPT_WORD=5 -val SCE_ESCRIPT_STRING=6 -val SCE_ESCRIPT_OPERATOR=7 -val SCE_ESCRIPT_IDENTIFIER=8 -val SCE_ESCRIPT_BRACE=9 -val SCE_ESCRIPT_WORD2=10 -val SCE_ESCRIPT_WORD3=11 -# Lexical states for SCLEX_PS -lex PS=SCLEX_PS SCE_PS_ -val SCE_PS_DEFAULT=0 -val SCE_PS_COMMENT=1 -val SCE_PS_DSC_COMMENT=2 -val SCE_PS_DSC_VALUE=3 -val SCE_PS_NUMBER=4 -val SCE_PS_NAME=5 -val SCE_PS_KEYWORD=6 -val SCE_PS_LITERAL=7 -val SCE_PS_IMMEVAL=8 -val SCE_PS_PAREN_ARRAY=9 -val SCE_PS_PAREN_DICT=10 -val SCE_PS_PAREN_PROC=11 -val SCE_PS_TEXT=12 -val SCE_PS_HEXSTRING=13 -val SCE_PS_BASE85STRING=14 -val SCE_PS_BADSTRINGCHAR=15 -# Lexical states for SCLEX_NSIS -lex NSIS=SCLEX_NSIS SCE_NSIS_ -val SCE_NSIS_DEFAULT=0 -val SCE_NSIS_COMMENT=1 -val SCE_NSIS_STRINGDQ=2 -val SCE_NSIS_STRINGLQ=3 -val SCE_NSIS_STRINGRQ=4 -val SCE_NSIS_FUNCTION=5 -val SCE_NSIS_VARIABLE=6 -val SCE_NSIS_LABEL=7 -val SCE_NSIS_USERDEFINED=8 -val SCE_NSIS_SECTIONDEF=9 -val SCE_NSIS_SUBSECTIONDEF=10 -val SCE_NSIS_IFDEFINEDEF=11 -val SCE_NSIS_MACRODEF=12 -val SCE_NSIS_STRINGVAR=13 -val SCE_NSIS_NUMBER=14 -val SCE_NSIS_SECTIONGROUP=15 -val SCE_NSIS_PAGEEX=16 -val SCE_NSIS_FUNCTIONDEF=17 -val SCE_NSIS_COMMENTBOX=18 -# Lexical states for SCLEX_MMIXAL -lex MMIXAL=SCLEX_MMIXAL SCE_MMIXAL_ -val SCE_MMIXAL_LEADWS=0 -val SCE_MMIXAL_COMMENT=1 -val SCE_MMIXAL_LABEL=2 -val SCE_MMIXAL_OPCODE=3 -val SCE_MMIXAL_OPCODE_PRE=4 -val SCE_MMIXAL_OPCODE_VALID=5 -val SCE_MMIXAL_OPCODE_UNKNOWN=6 -val SCE_MMIXAL_OPCODE_POST=7 -val SCE_MMIXAL_OPERANDS=8 -val SCE_MMIXAL_NUMBER=9 -val SCE_MMIXAL_REF=10 -val SCE_MMIXAL_CHAR=11 -val SCE_MMIXAL_STRING=12 -val SCE_MMIXAL_REGISTER=13 -val SCE_MMIXAL_HEX=14 -val SCE_MMIXAL_OPERATOR=15 -val SCE_MMIXAL_SYMBOL=16 -val SCE_MMIXAL_INCLUDE=17 -# Lexical states for SCLEX_CLW -lex Clarion=SCLEX_CLW SCE_CLW_ -val SCE_CLW_DEFAULT=0 -val SCE_CLW_LABEL=1 -val SCE_CLW_COMMENT=2 -val SCE_CLW_STRING=3 -val SCE_CLW_USER_IDENTIFIER=4 -val SCE_CLW_INTEGER_CONSTANT=5 -val SCE_CLW_REAL_CONSTANT=6 -val SCE_CLW_PICTURE_STRING=7 -val SCE_CLW_KEYWORD=8 -val SCE_CLW_COMPILER_DIRECTIVE=9 -val SCE_CLW_RUNTIME_EXPRESSIONS=10 -val SCE_CLW_BUILTIN_PROCEDURES_FUNCTION=11 -val SCE_CLW_STRUCTURE_DATA_TYPE=12 -val SCE_CLW_ATTRIBUTE=13 -val SCE_CLW_STANDARD_EQUATE=14 -val SCE_CLW_ERROR=15 -val SCE_CLW_DEPRECATED=16 -# Lexical states for SCLEX_LOT -lex LOT=SCLEX_LOT SCE_LOT_ -val SCE_LOT_DEFAULT=0 -val SCE_LOT_HEADER=1 -val SCE_LOT_BREAK=2 -val SCE_LOT_SET=3 -val SCE_LOT_PASS=4 -val SCE_LOT_FAIL=5 -val SCE_LOT_ABORT=6 -# Lexical states for SCLEX_YAML -lex YAML=SCLEX_YAML SCE_YAML_ -val SCE_YAML_DEFAULT=0 -val SCE_YAML_COMMENT=1 -val SCE_YAML_IDENTIFIER=2 -val SCE_YAML_KEYWORD=3 -val SCE_YAML_NUMBER=4 -val SCE_YAML_REFERENCE=5 -val SCE_YAML_DOCUMENT=6 -val SCE_YAML_TEXT=7 -val SCE_YAML_ERROR=8 -val SCE_YAML_OPERATOR=9 -# Lexical states for SCLEX_TEX -lex TeX=SCLEX_TEX SCE_TEX_ -val SCE_TEX_DEFAULT=0 -val SCE_TEX_SPECIAL=1 -val SCE_TEX_GROUP=2 -val SCE_TEX_SYMBOL=3 -val SCE_TEX_COMMAND=4 -val SCE_TEX_TEXT=5 -lex Metapost=SCLEX_METAPOST SCE_METAPOST_ -val SCE_METAPOST_DEFAULT=0 -val SCE_METAPOST_SPECIAL=1 -val SCE_METAPOST_GROUP=2 -val SCE_METAPOST_SYMBOL=3 -val SCE_METAPOST_COMMAND=4 -val SCE_METAPOST_TEXT=5 -val SCE_METAPOST_EXTRA=6 -# Lexical states for SCLEX_ERLANG -lex Erlang=SCLEX_ERLANG SCE_ERLANG_ -val SCE_ERLANG_DEFAULT=0 -val SCE_ERLANG_COMMENT=1 -val SCE_ERLANG_VARIABLE=2 -val SCE_ERLANG_NUMBER=3 -val SCE_ERLANG_KEYWORD=4 -val SCE_ERLANG_STRING=5 -val SCE_ERLANG_OPERATOR=6 -val SCE_ERLANG_ATOM=7 -val SCE_ERLANG_FUNCTION_NAME=8 -val SCE_ERLANG_CHARACTER=9 -val SCE_ERLANG_MACRO=10 -val SCE_ERLANG_RECORD=11 -val SCE_ERLANG_PREPROC=12 -val SCE_ERLANG_NODE_NAME=13 -val SCE_ERLANG_COMMENT_FUNCTION=14 -val SCE_ERLANG_COMMENT_MODULE=15 -val SCE_ERLANG_COMMENT_DOC=16 -val SCE_ERLANG_COMMENT_DOC_MACRO=17 -val SCE_ERLANG_ATOM_QUOTED=18 -val SCE_ERLANG_MACRO_QUOTED=19 -val SCE_ERLANG_RECORD_QUOTED=20 -val SCE_ERLANG_NODE_NAME_QUOTED=21 -val SCE_ERLANG_BIFS=22 -val SCE_ERLANG_MODULES=23 -val SCE_ERLANG_MODULES_ATT=24 -val SCE_ERLANG_UNKNOWN=31 -# Lexical states for SCLEX_OCTAVE are identical to MatLab -lex Octave=SCLEX_OCTAVE SCE_MATLAB_ -# Lexical states for SCLEX_JULIA -lex Julia=SCLEX_JULIA SCE_JULIA_ -val SCE_JULIA_DEFAULT=0 -val SCE_JULIA_COMMENT=1 -val SCE_JULIA_NUMBER=2 -val SCE_JULIA_KEYWORD1=3 -val SCE_JULIA_KEYWORD2=4 -val SCE_JULIA_KEYWORD3=5 -val SCE_JULIA_CHAR=6 -val SCE_JULIA_OPERATOR=7 -val SCE_JULIA_BRACKET=8 -val SCE_JULIA_IDENTIFIER=9 -val SCE_JULIA_STRING=10 -val SCE_JULIA_SYMBOL=11 -val SCE_JULIA_MACRO=12 -val SCE_JULIA_STRINGINTERP=13 -val SCE_JULIA_DOCSTRING=14 -val SCE_JULIA_STRINGLITERAL=15 -val SCE_JULIA_COMMAND=16 -val SCE_JULIA_COMMANDLITERAL=17 -val SCE_JULIA_TYPEANNOT=18 -val SCE_JULIA_LEXERROR=19 -val SCE_JULIA_KEYWORD4=20 -val SCE_JULIA_TYPEOPERATOR=21 -# Lexical states for SCLEX_MSSQL -lex MSSQL=SCLEX_MSSQL SCE_MSSQL_ -val SCE_MSSQL_DEFAULT=0 -val SCE_MSSQL_COMMENT=1 -val SCE_MSSQL_LINE_COMMENT=2 -val SCE_MSSQL_NUMBER=3 -val SCE_MSSQL_STRING=4 -val SCE_MSSQL_OPERATOR=5 -val SCE_MSSQL_IDENTIFIER=6 -val SCE_MSSQL_VARIABLE=7 -val SCE_MSSQL_COLUMN_NAME=8 -val SCE_MSSQL_STATEMENT=9 -val SCE_MSSQL_DATATYPE=10 -val SCE_MSSQL_SYSTABLE=11 -val SCE_MSSQL_GLOBAL_VARIABLE=12 -val SCE_MSSQL_FUNCTION=13 -val SCE_MSSQL_STORED_PROCEDURE=14 -val SCE_MSSQL_DEFAULT_PREF_DATATYPE=15 -val SCE_MSSQL_COLUMN_NAME_2=16 -# Lexical states for SCLEX_VERILOG -lex Verilog=SCLEX_VERILOG SCE_V_ -val SCE_V_DEFAULT=0 -val SCE_V_COMMENT=1 -val SCE_V_COMMENTLINE=2 -val SCE_V_COMMENTLINEBANG=3 -val SCE_V_NUMBER=4 -val SCE_V_WORD=5 -val SCE_V_STRING=6 -val SCE_V_WORD2=7 -val SCE_V_WORD3=8 -val SCE_V_PREPROCESSOR=9 -val SCE_V_OPERATOR=10 -val SCE_V_IDENTIFIER=11 -val SCE_V_STRINGEOL=12 -val SCE_V_USER=19 -val SCE_V_COMMENT_WORD=20 -val SCE_V_INPUT=21 -val SCE_V_OUTPUT=22 -val SCE_V_INOUT=23 -val SCE_V_PORT_CONNECT=24 -# Lexical states for SCLEX_KIX -lex Kix=SCLEX_KIX SCE_KIX_ -val SCE_KIX_DEFAULT=0 -val SCE_KIX_COMMENT=1 -val SCE_KIX_STRING1=2 -val SCE_KIX_STRING2=3 -val SCE_KIX_NUMBER=4 -val SCE_KIX_VAR=5 -val SCE_KIX_MACRO=6 -val SCE_KIX_KEYWORD=7 -val SCE_KIX_FUNCTIONS=8 -val SCE_KIX_OPERATOR=9 -val SCE_KIX_COMMENTSTREAM=10 -val SCE_KIX_IDENTIFIER=31 -# Lexical states for SCLEX_GUI4CLI -lex Gui4Cli=SCLEX_GUI4CLI SCE_GC_ -val SCE_GC_DEFAULT=0 -val SCE_GC_COMMENTLINE=1 -val SCE_GC_COMMENTBLOCK=2 -val SCE_GC_GLOBAL=3 -val SCE_GC_EVENT=4 -val SCE_GC_ATTRIBUTE=5 -val SCE_GC_CONTROL=6 -val SCE_GC_COMMAND=7 -val SCE_GC_STRING=8 -val SCE_GC_OPERATOR=9 -# Lexical states for SCLEX_SPECMAN -lex Specman=SCLEX_SPECMAN SCE_SN_ -val SCE_SN_DEFAULT=0 -val SCE_SN_CODE=1 -val SCE_SN_COMMENTLINE=2 -val SCE_SN_COMMENTLINEBANG=3 -val SCE_SN_NUMBER=4 -val SCE_SN_WORD=5 -val SCE_SN_STRING=6 -val SCE_SN_WORD2=7 -val SCE_SN_WORD3=8 -val SCE_SN_PREPROCESSOR=9 -val SCE_SN_OPERATOR=10 -val SCE_SN_IDENTIFIER=11 -val SCE_SN_STRINGEOL=12 -val SCE_SN_REGEXTAG=13 -val SCE_SN_SIGNAL=14 -val SCE_SN_USER=19 -# Lexical states for SCLEX_AU3 -lex Au3=SCLEX_AU3 SCE_AU3_ -val SCE_AU3_DEFAULT=0 -val SCE_AU3_COMMENT=1 -val SCE_AU3_COMMENTBLOCK=2 -val SCE_AU3_NUMBER=3 -val SCE_AU3_FUNCTION=4 -val SCE_AU3_KEYWORD=5 -val SCE_AU3_MACRO=6 -val SCE_AU3_STRING=7 -val SCE_AU3_OPERATOR=8 -val SCE_AU3_VARIABLE=9 -val SCE_AU3_SENT=10 -val SCE_AU3_PREPROCESSOR=11 -val SCE_AU3_SPECIAL=12 -val SCE_AU3_EXPAND=13 -val SCE_AU3_COMOBJ=14 -val SCE_AU3_UDF=15 -# Lexical states for SCLEX_APDL -lex APDL=SCLEX_APDL SCE_APDL_ -val SCE_APDL_DEFAULT=0 -val SCE_APDL_COMMENT=1 -val SCE_APDL_COMMENTBLOCK=2 -val SCE_APDL_NUMBER=3 -val SCE_APDL_STRING=4 -val SCE_APDL_OPERATOR=5 -val SCE_APDL_WORD=6 -val SCE_APDL_PROCESSOR=7 -val SCE_APDL_COMMAND=8 -val SCE_APDL_SLASHCOMMAND=9 -val SCE_APDL_STARCOMMAND=10 -val SCE_APDL_ARGUMENT=11 -val SCE_APDL_FUNCTION=12 -# Lexical states for SCLEX_BASH -lex Bash=SCLEX_BASH SCE_SH_ -val SCE_SH_DEFAULT=0 -val SCE_SH_ERROR=1 -val SCE_SH_COMMENTLINE=2 -val SCE_SH_NUMBER=3 -val SCE_SH_WORD=4 -val SCE_SH_STRING=5 -val SCE_SH_CHARACTER=6 -val SCE_SH_OPERATOR=7 -val SCE_SH_IDENTIFIER=8 -val SCE_SH_SCALAR=9 -val SCE_SH_PARAM=10 -val SCE_SH_BACKTICKS=11 -val SCE_SH_HERE_DELIM=12 -val SCE_SH_HERE_Q=13 -# Lexical states for SCLEX_ASN1 -lex Asn1=SCLEX_ASN1 SCE_ASN1_ -val SCE_ASN1_DEFAULT=0 -val SCE_ASN1_COMMENT=1 -val SCE_ASN1_IDENTIFIER=2 -val SCE_ASN1_STRING=3 -val SCE_ASN1_OID=4 -val SCE_ASN1_SCALAR=5 -val SCE_ASN1_KEYWORD=6 -val SCE_ASN1_ATTRIBUTE=7 -val SCE_ASN1_DESCRIPTOR=8 -val SCE_ASN1_TYPE=9 -val SCE_ASN1_OPERATOR=10 -# Lexical states for SCLEX_VHDL -lex VHDL=SCLEX_VHDL SCE_VHDL_ -val SCE_VHDL_DEFAULT=0 -val SCE_VHDL_COMMENT=1 -val SCE_VHDL_COMMENTLINEBANG=2 -val SCE_VHDL_NUMBER=3 -val SCE_VHDL_STRING=4 -val SCE_VHDL_OPERATOR=5 -val SCE_VHDL_IDENTIFIER=6 -val SCE_VHDL_STRINGEOL=7 -val SCE_VHDL_KEYWORD=8 -val SCE_VHDL_STDOPERATOR=9 -val SCE_VHDL_ATTRIBUTE=10 -val SCE_VHDL_STDFUNCTION=11 -val SCE_VHDL_STDPACKAGE=12 -val SCE_VHDL_STDTYPE=13 -val SCE_VHDL_USERWORD=14 -val SCE_VHDL_BLOCK_COMMENT=15 -# Lexical states for SCLEX_CAML -lex Caml=SCLEX_CAML SCE_CAML_ -val SCE_CAML_DEFAULT=0 -val SCE_CAML_IDENTIFIER=1 -val SCE_CAML_TAGNAME=2 -val SCE_CAML_KEYWORD=3 -val SCE_CAML_KEYWORD2=4 -val SCE_CAML_KEYWORD3=5 -val SCE_CAML_LINENUM=6 -val SCE_CAML_OPERATOR=7 -val SCE_CAML_NUMBER=8 -val SCE_CAML_CHAR=9 -val SCE_CAML_WHITE=10 -val SCE_CAML_STRING=11 -val SCE_CAML_COMMENT=12 -val SCE_CAML_COMMENT1=13 -val SCE_CAML_COMMENT2=14 -val SCE_CAML_COMMENT3=15 -# Lexical states for SCLEX_HASKELL -lex Haskell=SCLEX_HASKELL SCE_HA_ -val SCE_HA_DEFAULT=0 -val SCE_HA_IDENTIFIER=1 -val SCE_HA_KEYWORD=2 -val SCE_HA_NUMBER=3 -val SCE_HA_STRING=4 -val SCE_HA_CHARACTER=5 -val SCE_HA_CLASS=6 -val SCE_HA_MODULE=7 -val SCE_HA_CAPITAL=8 -val SCE_HA_DATA=9 -val SCE_HA_IMPORT=10 -val SCE_HA_OPERATOR=11 -val SCE_HA_INSTANCE=12 -val SCE_HA_COMMENTLINE=13 -val SCE_HA_COMMENTBLOCK=14 -val SCE_HA_COMMENTBLOCK2=15 -val SCE_HA_COMMENTBLOCK3=16 -val SCE_HA_PRAGMA=17 -val SCE_HA_PREPROCESSOR=18 -val SCE_HA_STRINGEOL=19 -val SCE_HA_RESERVED_OPERATOR=20 -val SCE_HA_LITERATE_COMMENT=21 -val SCE_HA_LITERATE_CODEDELIM=22 -# Lexical states of SCLEX_TADS3 -lex TADS3=SCLEX_TADS3 SCE_T3_ -val SCE_T3_DEFAULT=0 -val SCE_T3_X_DEFAULT=1 -val SCE_T3_PREPROCESSOR=2 -val SCE_T3_BLOCK_COMMENT=3 -val SCE_T3_LINE_COMMENT=4 -val SCE_T3_OPERATOR=5 -val SCE_T3_KEYWORD=6 -val SCE_T3_NUMBER=7 -val SCE_T3_IDENTIFIER=8 -val SCE_T3_S_STRING=9 -val SCE_T3_D_STRING=10 -val SCE_T3_X_STRING=11 -val SCE_T3_LIB_DIRECTIVE=12 -val SCE_T3_MSG_PARAM=13 -val SCE_T3_HTML_TAG=14 -val SCE_T3_HTML_DEFAULT=15 -val SCE_T3_HTML_STRING=16 -val SCE_T3_USER1=17 -val SCE_T3_USER2=18 -val SCE_T3_USER3=19 -val SCE_T3_BRACE=20 -# Lexical states for SCLEX_REBOL -lex Rebol=SCLEX_REBOL SCE_REBOL_ -val SCE_REBOL_DEFAULT=0 -val SCE_REBOL_COMMENTLINE=1 -val SCE_REBOL_COMMENTBLOCK=2 -val SCE_REBOL_PREFACE=3 -val SCE_REBOL_OPERATOR=4 -val SCE_REBOL_CHARACTER=5 -val SCE_REBOL_QUOTEDSTRING=6 -val SCE_REBOL_BRACEDSTRING=7 -val SCE_REBOL_NUMBER=8 -val SCE_REBOL_PAIR=9 -val SCE_REBOL_TUPLE=10 -val SCE_REBOL_BINARY=11 -val SCE_REBOL_MONEY=12 -val SCE_REBOL_ISSUE=13 -val SCE_REBOL_TAG=14 -val SCE_REBOL_FILE=15 -val SCE_REBOL_EMAIL=16 -val SCE_REBOL_URL=17 -val SCE_REBOL_DATE=18 -val SCE_REBOL_TIME=19 -val SCE_REBOL_IDENTIFIER=20 -val SCE_REBOL_WORD=21 -val SCE_REBOL_WORD2=22 -val SCE_REBOL_WORD3=23 -val SCE_REBOL_WORD4=24 -val SCE_REBOL_WORD5=25 -val SCE_REBOL_WORD6=26 -val SCE_REBOL_WORD7=27 -val SCE_REBOL_WORD8=28 -# Lexical states for SCLEX_SQL -lex SQL=SCLEX_SQL SCE_SQL_ -val SCE_SQL_DEFAULT=0 -val SCE_SQL_COMMENT=1 -val SCE_SQL_COMMENTLINE=2 -val SCE_SQL_COMMENTDOC=3 -val SCE_SQL_NUMBER=4 -val SCE_SQL_WORD=5 -val SCE_SQL_STRING=6 -val SCE_SQL_CHARACTER=7 -val SCE_SQL_SQLPLUS=8 -val SCE_SQL_SQLPLUS_PROMPT=9 -val SCE_SQL_OPERATOR=10 -val SCE_SQL_IDENTIFIER=11 -val SCE_SQL_SQLPLUS_COMMENT=13 -val SCE_SQL_COMMENTLINEDOC=15 -val SCE_SQL_WORD2=16 -val SCE_SQL_COMMENTDOCKEYWORD=17 -val SCE_SQL_COMMENTDOCKEYWORDERROR=18 -val SCE_SQL_USER1=19 -val SCE_SQL_USER2=20 -val SCE_SQL_USER3=21 -val SCE_SQL_USER4=22 -val SCE_SQL_QUOTEDIDENTIFIER=23 -val SCE_SQL_QOPERATOR=24 -# Lexical states for SCLEX_SMALLTALK -lex Smalltalk=SCLEX_SMALLTALK SCE_ST_ -val SCE_ST_DEFAULT=0 -val SCE_ST_STRING=1 -val SCE_ST_NUMBER=2 -val SCE_ST_COMMENT=3 -val SCE_ST_SYMBOL=4 -val SCE_ST_BINARY=5 -val SCE_ST_BOOL=6 -val SCE_ST_SELF=7 -val SCE_ST_SUPER=8 -val SCE_ST_NIL=9 -val SCE_ST_GLOBAL=10 -val SCE_ST_RETURN=11 -val SCE_ST_SPECIAL=12 -val SCE_ST_KWSEND=13 -val SCE_ST_ASSIGN=14 -val SCE_ST_CHARACTER=15 -val SCE_ST_SPEC_SEL=16 -# Lexical states for SCLEX_FLAGSHIP (clipper) -lex FlagShip=SCLEX_FLAGSHIP SCE_FS_ -val SCE_FS_DEFAULT=0 -val SCE_FS_COMMENT=1 -val SCE_FS_COMMENTLINE=2 -val SCE_FS_COMMENTDOC=3 -val SCE_FS_COMMENTLINEDOC=4 -val SCE_FS_COMMENTDOCKEYWORD=5 -val SCE_FS_COMMENTDOCKEYWORDERROR=6 -val SCE_FS_KEYWORD=7 -val SCE_FS_KEYWORD2=8 -val SCE_FS_KEYWORD3=9 -val SCE_FS_KEYWORD4=10 -val SCE_FS_NUMBER=11 -val SCE_FS_STRING=12 -val SCE_FS_PREPROCESSOR=13 -val SCE_FS_OPERATOR=14 -val SCE_FS_IDENTIFIER=15 -val SCE_FS_DATE=16 -val SCE_FS_STRINGEOL=17 -val SCE_FS_CONSTANT=18 -val SCE_FS_WORDOPERATOR=19 -val SCE_FS_DISABLEDCODE=20 -val SCE_FS_DEFAULT_C=21 -val SCE_FS_COMMENTDOC_C=22 -val SCE_FS_COMMENTLINEDOC_C=23 -val SCE_FS_KEYWORD_C=24 -val SCE_FS_KEYWORD2_C=25 -val SCE_FS_NUMBER_C=26 -val SCE_FS_STRING_C=27 -val SCE_FS_PREPROCESSOR_C=28 -val SCE_FS_OPERATOR_C=29 -val SCE_FS_IDENTIFIER_C=30 -val SCE_FS_STRINGEOL_C=31 -# Lexical states for SCLEX_CSOUND -lex Csound=SCLEX_CSOUND SCE_CSOUND_ -val SCE_CSOUND_DEFAULT=0 -val SCE_CSOUND_COMMENT=1 -val SCE_CSOUND_NUMBER=2 -val SCE_CSOUND_OPERATOR=3 -val SCE_CSOUND_INSTR=4 -val SCE_CSOUND_IDENTIFIER=5 -val SCE_CSOUND_OPCODE=6 -val SCE_CSOUND_HEADERSTMT=7 -val SCE_CSOUND_USERKEYWORD=8 -val SCE_CSOUND_COMMENTBLOCK=9 -val SCE_CSOUND_PARAM=10 -val SCE_CSOUND_ARATE_VAR=11 -val SCE_CSOUND_KRATE_VAR=12 -val SCE_CSOUND_IRATE_VAR=13 -val SCE_CSOUND_GLOBAL_VAR=14 -val SCE_CSOUND_STRINGEOL=15 -# Lexical states for SCLEX_INNOSETUP -lex Inno=SCLEX_INNOSETUP SCE_INNO_ -val SCE_INNO_DEFAULT=0 -val SCE_INNO_COMMENT=1 -val SCE_INNO_KEYWORD=2 -val SCE_INNO_PARAMETER=3 -val SCE_INNO_SECTION=4 -val SCE_INNO_PREPROC=5 -val SCE_INNO_INLINE_EXPANSION=6 -val SCE_INNO_COMMENT_PASCAL=7 -val SCE_INNO_KEYWORD_PASCAL=8 -val SCE_INNO_KEYWORD_USER=9 -val SCE_INNO_STRING_DOUBLE=10 -val SCE_INNO_STRING_SINGLE=11 -val SCE_INNO_IDENTIFIER=12 -# Lexical states for SCLEX_OPAL -lex Opal=SCLEX_OPAL SCE_OPAL_ -val SCE_OPAL_SPACE=0 -val SCE_OPAL_COMMENT_BLOCK=1 -val SCE_OPAL_COMMENT_LINE=2 -val SCE_OPAL_INTEGER=3 -val SCE_OPAL_KEYWORD=4 -val SCE_OPAL_SORT=5 -val SCE_OPAL_STRING=6 -val SCE_OPAL_PAR=7 -val SCE_OPAL_BOOL_CONST=8 -val SCE_OPAL_DEFAULT=32 -# Lexical states for SCLEX_SPICE -lex Spice=SCLEX_SPICE SCE_SPICE_ -val SCE_SPICE_DEFAULT=0 -val SCE_SPICE_IDENTIFIER=1 -val SCE_SPICE_KEYWORD=2 -val SCE_SPICE_KEYWORD2=3 -val SCE_SPICE_KEYWORD3=4 -val SCE_SPICE_NUMBER=5 -val SCE_SPICE_DELIMITER=6 -val SCE_SPICE_VALUE=7 -val SCE_SPICE_COMMENTLINE=8 -# Lexical states for SCLEX_CMAKE -lex CMAKE=SCLEX_CMAKE SCE_CMAKE_ -val SCE_CMAKE_DEFAULT=0 -val SCE_CMAKE_COMMENT=1 -val SCE_CMAKE_STRINGDQ=2 -val SCE_CMAKE_STRINGLQ=3 -val SCE_CMAKE_STRINGRQ=4 -val SCE_CMAKE_COMMANDS=5 -val SCE_CMAKE_PARAMETERS=6 -val SCE_CMAKE_VARIABLE=7 -val SCE_CMAKE_USERDEFINED=8 -val SCE_CMAKE_WHILEDEF=9 -val SCE_CMAKE_FOREACHDEF=10 -val SCE_CMAKE_IFDEFINEDEF=11 -val SCE_CMAKE_MACRODEF=12 -val SCE_CMAKE_STRINGVAR=13 -val SCE_CMAKE_NUMBER=14 -# Lexical states for SCLEX_GAP -lex Gap=SCLEX_GAP SCE_GAP_ -val SCE_GAP_DEFAULT=0 -val SCE_GAP_IDENTIFIER=1 -val SCE_GAP_KEYWORD=2 -val SCE_GAP_KEYWORD2=3 -val SCE_GAP_KEYWORD3=4 -val SCE_GAP_KEYWORD4=5 -val SCE_GAP_STRING=6 -val SCE_GAP_CHAR=7 -val SCE_GAP_OPERATOR=8 -val SCE_GAP_COMMENT=9 -val SCE_GAP_NUMBER=10 -val SCE_GAP_STRINGEOL=11 -# Lexical state for SCLEX_PLM -lex PLM=SCLEX_PLM SCE_PLM_ -val SCE_PLM_DEFAULT=0 -val SCE_PLM_COMMENT=1 -val SCE_PLM_STRING=2 -val SCE_PLM_NUMBER=3 -val SCE_PLM_IDENTIFIER=4 -val SCE_PLM_OPERATOR=5 -val SCE_PLM_CONTROL=6 -val SCE_PLM_KEYWORD=7 -# Lexical state for SCLEX_PROGRESS -lex Progress=SCLEX_PROGRESS SCE_ABL_ -val SCE_ABL_DEFAULT=0 -val SCE_ABL_NUMBER=1 -val SCE_ABL_WORD=2 -val SCE_ABL_STRING=3 -val SCE_ABL_CHARACTER=4 -val SCE_ABL_PREPROCESSOR=5 -val SCE_ABL_OPERATOR=6 -val SCE_ABL_IDENTIFIER=7 -val SCE_ABL_BLOCK=8 -val SCE_ABL_END=9 -val SCE_ABL_COMMENT=10 -val SCE_ABL_TASKMARKER=11 -val SCE_ABL_LINECOMMENT=12 -# Lexical states for SCLEX_ABAQUS -lex ABAQUS=SCLEX_ABAQUS SCE_ABAQUS_ -val SCE_ABAQUS_DEFAULT=0 -val SCE_ABAQUS_COMMENT=1 -val SCE_ABAQUS_COMMENTBLOCK=2 -val SCE_ABAQUS_NUMBER=3 -val SCE_ABAQUS_STRING=4 -val SCE_ABAQUS_OPERATOR=5 -val SCE_ABAQUS_WORD=6 -val SCE_ABAQUS_PROCESSOR=7 -val SCE_ABAQUS_COMMAND=8 -val SCE_ABAQUS_SLASHCOMMAND=9 -val SCE_ABAQUS_STARCOMMAND=10 -val SCE_ABAQUS_ARGUMENT=11 -val SCE_ABAQUS_FUNCTION=12 -# Lexical states for SCLEX_ASYMPTOTE -lex Asymptote=SCLEX_ASYMPTOTE SCE_ASY_ -val SCE_ASY_DEFAULT=0 -val SCE_ASY_COMMENT=1 -val SCE_ASY_COMMENTLINE=2 -val SCE_ASY_NUMBER=3 -val SCE_ASY_WORD=4 -val SCE_ASY_STRING=5 -val SCE_ASY_CHARACTER=6 -val SCE_ASY_OPERATOR=7 -val SCE_ASY_IDENTIFIER=8 -val SCE_ASY_STRINGEOL=9 -val SCE_ASY_COMMENTLINEDOC=10 -val SCE_ASY_WORD2=11 -# Lexical states for SCLEX_R -lex R=SCLEX_R SCE_R_ -val SCE_R_DEFAULT=0 -val SCE_R_COMMENT=1 -val SCE_R_KWORD=2 -val SCE_R_BASEKWORD=3 -val SCE_R_OTHERKWORD=4 -val SCE_R_NUMBER=5 -val SCE_R_STRING=6 -val SCE_R_STRING2=7 -val SCE_R_OPERATOR=8 -val SCE_R_IDENTIFIER=9 -val SCE_R_INFIX=10 -val SCE_R_INFIXEOL=11 -# Lexical state for SCLEX_MAGIK -lex MagikSF=SCLEX_MAGIK SCE_MAGIK_ -val SCE_MAGIK_DEFAULT=0 -val SCE_MAGIK_COMMENT=1 -val SCE_MAGIK_HYPER_COMMENT=16 -val SCE_MAGIK_STRING=2 -val SCE_MAGIK_CHARACTER=3 -val SCE_MAGIK_NUMBER=4 -val SCE_MAGIK_IDENTIFIER=5 -val SCE_MAGIK_OPERATOR=6 -val SCE_MAGIK_FLOW=7 -val SCE_MAGIK_CONTAINER=8 -val SCE_MAGIK_BRACKET_BLOCK=9 -val SCE_MAGIK_BRACE_BLOCK=10 -val SCE_MAGIK_SQBRACKET_BLOCK=11 -val SCE_MAGIK_UNKNOWN_KEYWORD=12 -val SCE_MAGIK_KEYWORD=13 -val SCE_MAGIK_PRAGMA=14 -val SCE_MAGIK_SYMBOL=15 -# Lexical state for SCLEX_POWERSHELL -lex PowerShell=SCLEX_POWERSHELL SCE_POWERSHELL_ -val SCE_POWERSHELL_DEFAULT=0 -val SCE_POWERSHELL_COMMENT=1 -val SCE_POWERSHELL_STRING=2 -val SCE_POWERSHELL_CHARACTER=3 -val SCE_POWERSHELL_NUMBER=4 -val SCE_POWERSHELL_VARIABLE=5 -val SCE_POWERSHELL_OPERATOR=6 -val SCE_POWERSHELL_IDENTIFIER=7 -val SCE_POWERSHELL_KEYWORD=8 -val SCE_POWERSHELL_CMDLET=9 -val SCE_POWERSHELL_ALIAS=10 -val SCE_POWERSHELL_FUNCTION=11 -val SCE_POWERSHELL_USER1=12 -val SCE_POWERSHELL_COMMENTSTREAM=13 -val SCE_POWERSHELL_HERE_STRING=14 -val SCE_POWERSHELL_HERE_CHARACTER=15 -val SCE_POWERSHELL_COMMENTDOCKEYWORD=16 -# Lexical state for SCLEX_MYSQL -lex MySQL=SCLEX_MYSQL SCE_MYSQL_ -val SCE_MYSQL_DEFAULT=0 -val SCE_MYSQL_COMMENT=1 -val SCE_MYSQL_COMMENTLINE=2 -val SCE_MYSQL_VARIABLE=3 -val SCE_MYSQL_SYSTEMVARIABLE=4 -val SCE_MYSQL_KNOWNSYSTEMVARIABLE=5 -val SCE_MYSQL_NUMBER=6 -val SCE_MYSQL_MAJORKEYWORD=7 -val SCE_MYSQL_KEYWORD=8 -val SCE_MYSQL_DATABASEOBJECT=9 -val SCE_MYSQL_PROCEDUREKEYWORD=10 -val SCE_MYSQL_STRING=11 -val SCE_MYSQL_SQSTRING=12 -val SCE_MYSQL_DQSTRING=13 -val SCE_MYSQL_OPERATOR=14 -val SCE_MYSQL_FUNCTION=15 -val SCE_MYSQL_IDENTIFIER=16 -val SCE_MYSQL_QUOTEDIDENTIFIER=17 -val SCE_MYSQL_USER1=18 -val SCE_MYSQL_USER2=19 -val SCE_MYSQL_USER3=20 -val SCE_MYSQL_HIDDENCOMMAND=21 -val SCE_MYSQL_PLACEHOLDER=22 -# Lexical state for SCLEX_PO -lex Po=SCLEX_PO SCE_PO_ -val SCE_PO_DEFAULT=0 -val SCE_PO_COMMENT=1 -val SCE_PO_MSGID=2 -val SCE_PO_MSGID_TEXT=3 -val SCE_PO_MSGSTR=4 -val SCE_PO_MSGSTR_TEXT=5 -val SCE_PO_MSGCTXT=6 -val SCE_PO_MSGCTXT_TEXT=7 -val SCE_PO_FUZZY=8 -val SCE_PO_PROGRAMMER_COMMENT=9 -val SCE_PO_REFERENCE=10 -val SCE_PO_FLAGS=11 -val SCE_PO_MSGID_TEXT_EOL=12 -val SCE_PO_MSGSTR_TEXT_EOL=13 -val SCE_PO_MSGCTXT_TEXT_EOL=14 -val SCE_PO_ERROR=15 -# Lexical states for SCLEX_PASCAL -lex Pascal=SCLEX_PASCAL SCE_PAS_ -val SCE_PAS_DEFAULT=0 -val SCE_PAS_IDENTIFIER=1 -val SCE_PAS_COMMENT=2 -val SCE_PAS_COMMENT2=3 -val SCE_PAS_COMMENTLINE=4 -val SCE_PAS_PREPROCESSOR=5 -val SCE_PAS_PREPROCESSOR2=6 -val SCE_PAS_NUMBER=7 -val SCE_PAS_HEXNUMBER=8 -val SCE_PAS_WORD=9 -val SCE_PAS_STRING=10 -val SCE_PAS_STRINGEOL=11 -val SCE_PAS_CHARACTER=12 -val SCE_PAS_OPERATOR=13 -val SCE_PAS_ASM=14 -# Lexical state for SCLEX_SORCUS -lex SORCUS=SCLEX_SORCUS SCE_SORCUS_ -val SCE_SORCUS_DEFAULT=0 -val SCE_SORCUS_COMMAND=1 -val SCE_SORCUS_PARAMETER=2 -val SCE_SORCUS_COMMENTLINE=3 -val SCE_SORCUS_STRING=4 -val SCE_SORCUS_STRINGEOL=5 -val SCE_SORCUS_IDENTIFIER=6 -val SCE_SORCUS_OPERATOR=7 -val SCE_SORCUS_NUMBER=8 -val SCE_SORCUS_CONSTANT=9 -# Lexical state for SCLEX_POWERPRO -lex PowerPro=SCLEX_POWERPRO SCE_POWERPRO_ -val SCE_POWERPRO_DEFAULT=0 -val SCE_POWERPRO_COMMENTBLOCK=1 -val SCE_POWERPRO_COMMENTLINE=2 -val SCE_POWERPRO_NUMBER=3 -val SCE_POWERPRO_WORD=4 -val SCE_POWERPRO_WORD2=5 -val SCE_POWERPRO_WORD3=6 -val SCE_POWERPRO_WORD4=7 -val SCE_POWERPRO_DOUBLEQUOTEDSTRING=8 -val SCE_POWERPRO_SINGLEQUOTEDSTRING=9 -val SCE_POWERPRO_LINECONTINUE=10 -val SCE_POWERPRO_OPERATOR=11 -val SCE_POWERPRO_IDENTIFIER=12 -val SCE_POWERPRO_STRINGEOL=13 -val SCE_POWERPRO_VERBATIM=14 -val SCE_POWERPRO_ALTQUOTE=15 -val SCE_POWERPRO_FUNCTION=16 -# Lexical states for SCLEX_SML -lex SML=SCLEX_SML SCE_SML_ -val SCE_SML_DEFAULT=0 -val SCE_SML_IDENTIFIER=1 -val SCE_SML_TAGNAME=2 -val SCE_SML_KEYWORD=3 -val SCE_SML_KEYWORD2=4 -val SCE_SML_KEYWORD3=5 -val SCE_SML_LINENUM=6 -val SCE_SML_OPERATOR=7 -val SCE_SML_NUMBER=8 -val SCE_SML_CHAR=9 -val SCE_SML_STRING=11 -val SCE_SML_COMMENT=12 -val SCE_SML_COMMENT1=13 -val SCE_SML_COMMENT2=14 -val SCE_SML_COMMENT3=15 -# Lexical state for SCLEX_MARKDOWN -lex Markdown=SCLEX_MARKDOWN SCE_MARKDOWN_ -val SCE_MARKDOWN_DEFAULT=0 -val SCE_MARKDOWN_LINE_BEGIN=1 -val SCE_MARKDOWN_STRONG1=2 -val SCE_MARKDOWN_STRONG2=3 -val SCE_MARKDOWN_EM1=4 -val SCE_MARKDOWN_EM2=5 -val SCE_MARKDOWN_HEADER1=6 -val SCE_MARKDOWN_HEADER2=7 -val SCE_MARKDOWN_HEADER3=8 -val SCE_MARKDOWN_HEADER4=9 -val SCE_MARKDOWN_HEADER5=10 -val SCE_MARKDOWN_HEADER6=11 -val SCE_MARKDOWN_PRECHAR=12 -val SCE_MARKDOWN_ULIST_ITEM=13 -val SCE_MARKDOWN_OLIST_ITEM=14 -val SCE_MARKDOWN_BLOCKQUOTE=15 -val SCE_MARKDOWN_STRIKEOUT=16 -val SCE_MARKDOWN_HRULE=17 -val SCE_MARKDOWN_LINK=18 -val SCE_MARKDOWN_CODE=19 -val SCE_MARKDOWN_CODE2=20 -val SCE_MARKDOWN_CODEBK=21 -# Lexical state for SCLEX_TXT2TAGS -lex Txt2tags=SCLEX_TXT2TAGS SCE_TXT2TAGS_ -val SCE_TXT2TAGS_DEFAULT=0 -val SCE_TXT2TAGS_LINE_BEGIN=1 -val SCE_TXT2TAGS_STRONG1=2 -val SCE_TXT2TAGS_STRONG2=3 -val SCE_TXT2TAGS_EM1=4 -val SCE_TXT2TAGS_EM2=5 -val SCE_TXT2TAGS_HEADER1=6 -val SCE_TXT2TAGS_HEADER2=7 -val SCE_TXT2TAGS_HEADER3=8 -val SCE_TXT2TAGS_HEADER4=9 -val SCE_TXT2TAGS_HEADER5=10 -val SCE_TXT2TAGS_HEADER6=11 -val SCE_TXT2TAGS_PRECHAR=12 -val SCE_TXT2TAGS_ULIST_ITEM=13 -val SCE_TXT2TAGS_OLIST_ITEM=14 -val SCE_TXT2TAGS_BLOCKQUOTE=15 -val SCE_TXT2TAGS_STRIKEOUT=16 -val SCE_TXT2TAGS_HRULE=17 -val SCE_TXT2TAGS_LINK=18 -val SCE_TXT2TAGS_CODE=19 -val SCE_TXT2TAGS_CODE2=20 -val SCE_TXT2TAGS_CODEBK=21 -val SCE_TXT2TAGS_COMMENT=22 -val SCE_TXT2TAGS_OPTION=23 -val SCE_TXT2TAGS_PREPROC=24 -val SCE_TXT2TAGS_POSTPROC=25 -# Lexical states for SCLEX_A68K -lex A68k=SCLEX_A68K SCE_A68K_ -val SCE_A68K_DEFAULT=0 -val SCE_A68K_COMMENT=1 -val SCE_A68K_NUMBER_DEC=2 -val SCE_A68K_NUMBER_BIN=3 -val SCE_A68K_NUMBER_HEX=4 -val SCE_A68K_STRING1=5 -val SCE_A68K_OPERATOR=6 -val SCE_A68K_CPUINSTRUCTION=7 -val SCE_A68K_EXTINSTRUCTION=8 -val SCE_A68K_REGISTER=9 -val SCE_A68K_DIRECTIVE=10 -val SCE_A68K_MACRO_ARG=11 -val SCE_A68K_LABEL=12 -val SCE_A68K_STRING2=13 -val SCE_A68K_IDENTIFIER=14 -val SCE_A68K_MACRO_DECLARATION=15 -val SCE_A68K_COMMENT_WORD=16 -val SCE_A68K_COMMENT_SPECIAL=17 -val SCE_A68K_COMMENT_DOXYGEN=18 -# Lexical states for SCLEX_MODULA -lex Modula=SCLEX_MODULA SCE_MODULA_ -val SCE_MODULA_DEFAULT=0 -val SCE_MODULA_COMMENT=1 -val SCE_MODULA_DOXYCOMM=2 -val SCE_MODULA_DOXYKEY=3 -val SCE_MODULA_KEYWORD=4 -val SCE_MODULA_RESERVED=5 -val SCE_MODULA_NUMBER=6 -val SCE_MODULA_BASENUM=7 -val SCE_MODULA_FLOAT=8 -val SCE_MODULA_STRING=9 -val SCE_MODULA_STRSPEC=10 -val SCE_MODULA_CHAR=11 -val SCE_MODULA_CHARSPEC=12 -val SCE_MODULA_PROC=13 -val SCE_MODULA_PRAGMA=14 -val SCE_MODULA_PRGKEY=15 -val SCE_MODULA_OPERATOR=16 -val SCE_MODULA_BADSTR=17 -# Lexical states for SCLEX_COFFEESCRIPT -lex CoffeeScript=SCLEX_COFFEESCRIPT SCE_COFFEESCRIPT_ -val SCE_COFFEESCRIPT_DEFAULT=0 -val SCE_COFFEESCRIPT_COMMENT=1 -val SCE_COFFEESCRIPT_COMMENTLINE=2 -val SCE_COFFEESCRIPT_COMMENTDOC=3 -val SCE_COFFEESCRIPT_NUMBER=4 -val SCE_COFFEESCRIPT_WORD=5 -val SCE_COFFEESCRIPT_STRING=6 -val SCE_COFFEESCRIPT_CHARACTER=7 -val SCE_COFFEESCRIPT_UUID=8 -val SCE_COFFEESCRIPT_PREPROCESSOR=9 -val SCE_COFFEESCRIPT_OPERATOR=10 -val SCE_COFFEESCRIPT_IDENTIFIER=11 -val SCE_COFFEESCRIPT_STRINGEOL=12 -val SCE_COFFEESCRIPT_VERBATIM=13 -val SCE_COFFEESCRIPT_REGEX=14 -val SCE_COFFEESCRIPT_COMMENTLINEDOC=15 -val SCE_COFFEESCRIPT_WORD2=16 -val SCE_COFFEESCRIPT_COMMENTDOCKEYWORD=17 -val SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR=18 -val SCE_COFFEESCRIPT_GLOBALCLASS=19 -val SCE_COFFEESCRIPT_STRINGRAW=20 -val SCE_COFFEESCRIPT_TRIPLEVERBATIM=21 -val SCE_COFFEESCRIPT_COMMENTBLOCK=22 -val SCE_COFFEESCRIPT_VERBOSE_REGEX=23 -val SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT=24 -val SCE_COFFEESCRIPT_INSTANCEPROPERTY=25 -# Lexical states for SCLEX_AVS -lex AVS=SCLEX_AVS SCE_AVS_ -val SCE_AVS_DEFAULT=0 -val SCE_AVS_COMMENTBLOCK=1 -val SCE_AVS_COMMENTBLOCKN=2 -val SCE_AVS_COMMENTLINE=3 -val SCE_AVS_NUMBER=4 -val SCE_AVS_OPERATOR=5 -val SCE_AVS_IDENTIFIER=6 -val SCE_AVS_STRING=7 -val SCE_AVS_TRIPLESTRING=8 -val SCE_AVS_KEYWORD=9 -val SCE_AVS_FILTER=10 -val SCE_AVS_PLUGIN=11 -val SCE_AVS_FUNCTION=12 -val SCE_AVS_CLIPPROP=13 -val SCE_AVS_USERDFN=14 -# Lexical states for SCLEX_ECL -lex ECL=SCLEX_ECL SCE_ECL_ -val SCE_ECL_DEFAULT=0 -val SCE_ECL_COMMENT=1 -val SCE_ECL_COMMENTLINE=2 -val SCE_ECL_NUMBER=3 -val SCE_ECL_STRING=4 -val SCE_ECL_WORD0=5 -val SCE_ECL_OPERATOR=6 -val SCE_ECL_CHARACTER=7 -val SCE_ECL_UUID=8 -val SCE_ECL_PREPROCESSOR=9 -val SCE_ECL_UNKNOWN=10 -val SCE_ECL_IDENTIFIER=11 -val SCE_ECL_STRINGEOL=12 -val SCE_ECL_VERBATIM=13 -val SCE_ECL_REGEX=14 -val SCE_ECL_COMMENTLINEDOC=15 -val SCE_ECL_WORD1=16 -val SCE_ECL_COMMENTDOCKEYWORD=17 -val SCE_ECL_COMMENTDOCKEYWORDERROR=18 -val SCE_ECL_WORD2=19 -val SCE_ECL_WORD3=20 -val SCE_ECL_WORD4=21 -val SCE_ECL_WORD5=22 -val SCE_ECL_COMMENTDOC=23 -val SCE_ECL_ADDED=24 -val SCE_ECL_DELETED=25 -val SCE_ECL_CHANGED=26 -val SCE_ECL_MOVED=27 -# Lexical states for SCLEX_OSCRIPT -lex OScript=SCLEX_OSCRIPT SCE_OSCRIPT_ -val SCE_OSCRIPT_DEFAULT=0 -val SCE_OSCRIPT_LINE_COMMENT=1 -val SCE_OSCRIPT_BLOCK_COMMENT=2 -val SCE_OSCRIPT_DOC_COMMENT=3 -val SCE_OSCRIPT_PREPROCESSOR=4 -val SCE_OSCRIPT_NUMBER=5 -val SCE_OSCRIPT_SINGLEQUOTE_STRING=6 -val SCE_OSCRIPT_DOUBLEQUOTE_STRING=7 -val SCE_OSCRIPT_CONSTANT=8 -val SCE_OSCRIPT_IDENTIFIER=9 -val SCE_OSCRIPT_GLOBAL=10 -val SCE_OSCRIPT_KEYWORD=11 -val SCE_OSCRIPT_OPERATOR=12 -val SCE_OSCRIPT_LABEL=13 -val SCE_OSCRIPT_TYPE=14 -val SCE_OSCRIPT_FUNCTION=15 -val SCE_OSCRIPT_OBJECT=16 -val SCE_OSCRIPT_PROPERTY=17 -val SCE_OSCRIPT_METHOD=18 -# Lexical states for SCLEX_VISUALPROLOG -lex VisualProlog=SCLEX_VISUALPROLOG SCE_VISUALPROLOG_ -val SCE_VISUALPROLOG_DEFAULT=0 -val SCE_VISUALPROLOG_KEY_MAJOR=1 -val SCE_VISUALPROLOG_KEY_MINOR=2 -val SCE_VISUALPROLOG_KEY_DIRECTIVE=3 -val SCE_VISUALPROLOG_COMMENT_BLOCK=4 -val SCE_VISUALPROLOG_COMMENT_LINE=5 -val SCE_VISUALPROLOG_COMMENT_KEY=6 -val SCE_VISUALPROLOG_COMMENT_KEY_ERROR=7 -val SCE_VISUALPROLOG_IDENTIFIER=8 -val SCE_VISUALPROLOG_VARIABLE=9 -val SCE_VISUALPROLOG_ANONYMOUS=10 -val SCE_VISUALPROLOG_NUMBER=11 -val SCE_VISUALPROLOG_OPERATOR=12 -val SCE_VISUALPROLOG_CHARACTER=13 -val SCE_VISUALPROLOG_CHARACTER_TOO_MANY=14 -val SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR=15 -val SCE_VISUALPROLOG_STRING=16 -val SCE_VISUALPROLOG_STRING_ESCAPE=17 -val SCE_VISUALPROLOG_STRING_ESCAPE_ERROR=18 -val SCE_VISUALPROLOG_STRING_EOL_OPEN=19 -val SCE_VISUALPROLOG_STRING_VERBATIM=20 -val SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL=21 -val SCE_VISUALPROLOG_STRING_VERBATIM_EOL=22 -# Lexical states for SCLEX_STTXT -lex StructuredText=SCLEX_STTXT SCE_STTXT_ -val SCE_STTXT_DEFAULT=0 -val SCE_STTXT_COMMENT=1 -val SCE_STTXT_COMMENTLINE=2 -val SCE_STTXT_KEYWORD=3 -val SCE_STTXT_TYPE=4 -val SCE_STTXT_FUNCTION=5 -val SCE_STTXT_FB=6 -val SCE_STTXT_NUMBER=7 -val SCE_STTXT_HEXNUMBER=8 -val SCE_STTXT_PRAGMA=9 -val SCE_STTXT_OPERATOR=10 -val SCE_STTXT_CHARACTER=11 -val SCE_STTXT_STRING1=12 -val SCE_STTXT_STRING2=13 -val SCE_STTXT_STRINGEOL=14 -val SCE_STTXT_IDENTIFIER=15 -val SCE_STTXT_DATETIME=16 -val SCE_STTXT_VARS=17 -val SCE_STTXT_PRAGMAS=18 -# Lexical states for SCLEX_KVIRC -lex KVIrc=SCLEX_KVIRC SCE_KVIRC_ -val SCE_KVIRC_DEFAULT=0 -val SCE_KVIRC_COMMENT=1 -val SCE_KVIRC_COMMENTBLOCK=2 -val SCE_KVIRC_STRING=3 -val SCE_KVIRC_WORD=4 -val SCE_KVIRC_KEYWORD=5 -val SCE_KVIRC_FUNCTION_KEYWORD=6 -val SCE_KVIRC_FUNCTION=7 -val SCE_KVIRC_VARIABLE=8 -val SCE_KVIRC_NUMBER=9 -val SCE_KVIRC_OPERATOR=10 -val SCE_KVIRC_STRING_FUNCTION=11 -val SCE_KVIRC_STRING_VARIABLE=12 -# Lexical states for SCLEX_RUST -lex Rust=SCLEX_RUST SCE_RUST_ -val SCE_RUST_DEFAULT=0 -val SCE_RUST_COMMENTBLOCK=1 -val SCE_RUST_COMMENTLINE=2 -val SCE_RUST_COMMENTBLOCKDOC=3 -val SCE_RUST_COMMENTLINEDOC=4 -val SCE_RUST_NUMBER=5 -val SCE_RUST_WORD=6 -val SCE_RUST_WORD2=7 -val SCE_RUST_WORD3=8 -val SCE_RUST_WORD4=9 -val SCE_RUST_WORD5=10 -val SCE_RUST_WORD6=11 -val SCE_RUST_WORD7=12 -val SCE_RUST_STRING=13 -val SCE_RUST_STRINGR=14 -val SCE_RUST_CHARACTER=15 -val SCE_RUST_OPERATOR=16 -val SCE_RUST_IDENTIFIER=17 -val SCE_RUST_LIFETIME=18 -val SCE_RUST_MACRO=19 -val SCE_RUST_LEXERROR=20 -val SCE_RUST_BYTESTRING=21 -val SCE_RUST_BYTESTRINGR=22 -val SCE_RUST_BYTECHARACTER=23 -# Lexical states for SCLEX_DMAP -lex DMAP=SCLEX_DMAP SCE_DMAP_ -val SCE_DMAP_DEFAULT=0 -val SCE_DMAP_COMMENT=1 -val SCE_DMAP_NUMBER=2 -val SCE_DMAP_STRING1=3 -val SCE_DMAP_STRING2=4 -val SCE_DMAP_STRINGEOL=5 -val SCE_DMAP_OPERATOR=6 -val SCE_DMAP_IDENTIFIER=7 -val SCE_DMAP_WORD=8 -val SCE_DMAP_WORD2=9 -val SCE_DMAP_WORD3=10 -# Lexical states for SCLEX_DMIS -lex DMIS=SCLEX_DMIS SCE_DMIS_ -val SCE_DMIS_DEFAULT=0 -val SCE_DMIS_COMMENT=1 -val SCE_DMIS_STRING=2 -val SCE_DMIS_NUMBER=3 -val SCE_DMIS_KEYWORD=4 -val SCE_DMIS_MAJORWORD=5 -val SCE_DMIS_MINORWORD=6 -val SCE_DMIS_UNSUPPORTED_MAJOR=7 -val SCE_DMIS_UNSUPPORTED_MINOR=8 -val SCE_DMIS_LABEL=9 -# Lexical states for SCLEX_REGISTRY -lex REG=SCLEX_REGISTRY SCE_REG_ -val SCE_REG_DEFAULT=0 -val SCE_REG_COMMENT=1 -val SCE_REG_VALUENAME=2 -val SCE_REG_STRING=3 -val SCE_REG_HEXDIGIT=4 -val SCE_REG_VALUETYPE=5 -val SCE_REG_ADDEDKEY=6 -val SCE_REG_DELETEDKEY=7 -val SCE_REG_ESCAPED=8 -val SCE_REG_KEYPATH_GUID=9 -val SCE_REG_STRING_GUID=10 -val SCE_REG_PARAMETER=11 -val SCE_REG_OPERATOR=12 -# Lexical state for SCLEX_BIBTEX -lex BibTeX=SCLEX_BIBTEX SCE_BIBTEX_ -val SCE_BIBTEX_DEFAULT=0 -val SCE_BIBTEX_ENTRY=1 -val SCE_BIBTEX_UNKNOWN_ENTRY=2 -val SCE_BIBTEX_KEY=3 -val SCE_BIBTEX_PARAMETER=4 -val SCE_BIBTEX_VALUE=5 -val SCE_BIBTEX_COMMENT=6 -# Lexical state for SCLEX_SREC -lex Srec=SCLEX_SREC SCE_HEX_ -val SCE_HEX_DEFAULT=0 -val SCE_HEX_RECSTART=1 -val SCE_HEX_RECTYPE=2 -val SCE_HEX_RECTYPE_UNKNOWN=3 -val SCE_HEX_BYTECOUNT=4 -val SCE_HEX_BYTECOUNT_WRONG=5 -val SCE_HEX_NOADDRESS=6 -val SCE_HEX_DATAADDRESS=7 -val SCE_HEX_RECCOUNT=8 -val SCE_HEX_STARTADDRESS=9 -val SCE_HEX_ADDRESSFIELD_UNKNOWN=10 -val SCE_HEX_EXTENDEDADDRESS=11 -val SCE_HEX_DATA_ODD=12 -val SCE_HEX_DATA_EVEN=13 -val SCE_HEX_DATA_UNKNOWN=14 -val SCE_HEX_DATA_EMPTY=15 -val SCE_HEX_CHECKSUM=16 -val SCE_HEX_CHECKSUM_WRONG=17 -val SCE_HEX_GARBAGE=18 -# Lexical state for SCLEX_IHEX (shared with Srec) -lex IHex=SCLEX_IHEX SCE_HEX_ -# Lexical state for SCLEX_TEHEX (shared with Srec) -lex TEHex=SCLEX_TEHEX SCE_HEX_ -# Lexical states for SCLEX_JSON -lex JSON=SCLEX_JSON SCE_JSON_ -val SCE_JSON_DEFAULT=0 -val SCE_JSON_NUMBER=1 -val SCE_JSON_STRING=2 -val SCE_JSON_STRINGEOL=3 -val SCE_JSON_PROPERTYNAME=4 -val SCE_JSON_ESCAPESEQUENCE=5 -val SCE_JSON_LINECOMMENT=6 -val SCE_JSON_BLOCKCOMMENT=7 -val SCE_JSON_OPERATOR=8 -val SCE_JSON_URI=9 -val SCE_JSON_COMPACTIRI=10 -val SCE_JSON_KEYWORD=11 -val SCE_JSON_LDKEYWORD=12 -val SCE_JSON_ERROR=13 -lex EDIFACT=SCLEX_EDIFACT SCE_EDI_ -val SCE_EDI_DEFAULT=0 -val SCE_EDI_SEGMENTSTART=1 -val SCE_EDI_SEGMENTEND=2 -val SCE_EDI_SEP_ELEMENT=3 -val SCE_EDI_SEP_COMPOSITE=4 -val SCE_EDI_SEP_RELEASE=5 -val SCE_EDI_UNA=6 -val SCE_EDI_UNH=7 -val SCE_EDI_BADSEGMENT=8 -# Lexical states for SCLEX_STATA -lex STATA=SCLEX_STATA SCE_STATA_ -val SCE_STATA_DEFAULT=0 -val SCE_STATA_COMMENT=1 -val SCE_STATA_COMMENTLINE=2 -val SCE_STATA_COMMENTBLOCK=3 -val SCE_STATA_NUMBER=4 -val SCE_STATA_OPERATOR=5 -val SCE_STATA_IDENTIFIER=6 -val SCE_STATA_STRING=7 -val SCE_STATA_TYPE=8 -val SCE_STATA_WORD=9 -val SCE_STATA_GLOBAL_MACRO=10 -val SCE_STATA_MACRO=11 -# Lexical states for SCLEX_SAS -lex SAS=SCLEX_SAS SCE_SAS_ -val SCE_SAS_DEFAULT=0 -val SCE_SAS_COMMENT=1 -val SCE_SAS_COMMENTLINE=2 -val SCE_SAS_COMMENTBLOCK=3 -val SCE_SAS_NUMBER=4 -val SCE_SAS_OPERATOR=5 -val SCE_SAS_IDENTIFIER=6 -val SCE_SAS_STRING=7 -val SCE_SAS_TYPE=8 -val SCE_SAS_WORD=9 -val SCE_SAS_GLOBAL_MACRO=10 -val SCE_SAS_MACRO=11 -val SCE_SAS_MACRO_KEYWORD=12 -val SCE_SAS_BLOCK_KEYWORD=13 -val SCE_SAS_MACRO_FUNCTION=14 -val SCE_SAS_STATEMENT=15 -# Lexical states for SCLEX_NIM -lex Nim=SCLEX_NIM SCE_NIM_ -val SCE_NIM_DEFAULT=0 -val SCE_NIM_COMMENT=1 -val SCE_NIM_COMMENTDOC=2 -val SCE_NIM_COMMENTLINE=3 -val SCE_NIM_COMMENTLINEDOC=4 -val SCE_NIM_NUMBER=5 -val SCE_NIM_STRING=6 -val SCE_NIM_CHARACTER=7 -val SCE_NIM_WORD=8 -val SCE_NIM_TRIPLE=9 -val SCE_NIM_TRIPLEDOUBLE=10 -val SCE_NIM_BACKTICKS=11 -val SCE_NIM_FUNCNAME=12 -val SCE_NIM_STRINGEOL=13 -val SCE_NIM_NUMERROR=14 -val SCE_NIM_OPERATOR=15 -val SCE_NIM_IDENTIFIER=16 -# Lexical states for SCLEX_CIL -lex CIL=SCLEX_CIL SCE_CIL_ -val SCE_CIL_DEFAULT=0 -val SCE_CIL_COMMENT=1 -val SCE_CIL_COMMENTLINE=2 -val SCE_CIL_WORD=3 -val SCE_CIL_WORD2=4 -val SCE_CIL_WORD3=5 -val SCE_CIL_STRING=6 -val SCE_CIL_LABEL=7 -val SCE_CIL_OPERATOR=8 -val SCE_CIL_IDENTIFIER=9 -val SCE_CIL_STRINGEOL=10 -# Lexical states for SCLEX_X12 -lex X12=SCLEX_X12 SCE_X12_ -val SCE_X12_DEFAULT=0 -val SCE_X12_BAD=1 -val SCE_X12_ENVELOPE=2 -val SCE_X12_FUNCTIONGROUP=3 -val SCE_X12_TRANSACTIONSET=4 -val SCE_X12_SEGMENTHEADER=5 -val SCE_X12_SEGMENTEND=6 -val SCE_X12_SEP_ELEMENT=7 -val SCE_X12_SEP_SUBELEMENT=8 -# Lexical states for SCLEX_DATAFLEX -lex Dataflex=SCLEX_DATAFLEX SCE_DF_ -val SCE_DF_DEFAULT=0 -val SCE_DF_IDENTIFIER=1 -val SCE_DF_METATAG=2 -val SCE_DF_IMAGE=3 -val SCE_DF_COMMENTLINE=4 -val SCE_DF_PREPROCESSOR=5 -val SCE_DF_PREPROCESSOR2=6 -val SCE_DF_NUMBER=7 -val SCE_DF_HEXNUMBER=8 -val SCE_DF_WORD=9 -val SCE_DF_STRING=10 -val SCE_DF_STRINGEOL=11 -val SCE_DF_SCOPEWORD=12 -val SCE_DF_OPERATOR=13 -val SCE_DF_ICODE=14 -# Lexical states for SCLEX_HOLLYWOOD -lex Hollywood=SCLEX_HOLLYWOOD SCE_HOLLYWOOD_ -val SCE_HOLLYWOOD_DEFAULT=0 -val SCE_HOLLYWOOD_COMMENT=1 -val SCE_HOLLYWOOD_COMMENTBLOCK=2 -val SCE_HOLLYWOOD_NUMBER=3 -val SCE_HOLLYWOOD_KEYWORD=4 -val SCE_HOLLYWOOD_STDAPI=5 -val SCE_HOLLYWOOD_PLUGINAPI=6 -val SCE_HOLLYWOOD_PLUGINMETHOD=7 -val SCE_HOLLYWOOD_STRING=8 -val SCE_HOLLYWOOD_STRINGBLOCK=9 -val SCE_HOLLYWOOD_PREPROCESSOR=10 -val SCE_HOLLYWOOD_OPERATOR=11 -val SCE_HOLLYWOOD_IDENTIFIER=12 -val SCE_HOLLYWOOD_CONSTANT=13 -val SCE_HOLLYWOOD_HEXNUMBER=14 -# Lexical states for SCLEX_RAKU -lex Raku=SCLEX_RAKU SCE_RAKU_ -val SCE_RAKU_DEFAULT=0 -val SCE_RAKU_ERROR=1 -val SCE_RAKU_COMMENTLINE=2 -val SCE_RAKU_COMMENTEMBED=3 -val SCE_RAKU_POD=4 -val SCE_RAKU_CHARACTER=5 -val SCE_RAKU_HEREDOC_Q=6 -val SCE_RAKU_HEREDOC_QQ=7 -val SCE_RAKU_STRING=8 -val SCE_RAKU_STRING_Q=9 -val SCE_RAKU_STRING_QQ=10 -val SCE_RAKU_STRING_Q_LANG=11 -val SCE_RAKU_STRING_VAR=12 -val SCE_RAKU_REGEX=13 -val SCE_RAKU_REGEX_VAR=14 -val SCE_RAKU_ADVERB=15 -val SCE_RAKU_NUMBER=16 -val SCE_RAKU_PREPROCESSOR=17 -val SCE_RAKU_OPERATOR=18 -val SCE_RAKU_WORD=19 -val SCE_RAKU_FUNCTION=20 -val SCE_RAKU_IDENTIFIER=21 -val SCE_RAKU_TYPEDEF=22 -val SCE_RAKU_MU=23 -val SCE_RAKU_POSITIONAL=24 -val SCE_RAKU_ASSOCIATIVE=25 -val SCE_RAKU_CALLABLE=26 -val SCE_RAKU_GRAMMAR=27 -val SCE_RAKU_CLASS=28 - # Events evt void StyleNeeded=2000(int position) @@ -5382,25 +3323,16 @@ evt void AutoCSelectionChange=2032(int listType, string text, int position) cat Provisional -enu LineCharacterIndexType=SC_LINECHARACTERINDEX_ -val SC_LINECHARACTERINDEX_NONE=0 -val SC_LINECHARACTERINDEX_UTF32=1 -val SC_LINECHARACTERINDEX_UTF16=2 - -# Retrieve line character index state. -get LineCharacterIndexType GetLineCharacterIndex=2710(,) - -# Request line character index be created or its use count increased. -fun void AllocateLineCharacterIndex=2711(LineCharacterIndexType lineCharacterIndex,) - -# Decrease use count of line character index and remove if 0. -fun void ReleaseLineCharacterIndex=2712(LineCharacterIndexType lineCharacterIndex,) +enu Bidirectional=SC_BIDIRECTIONAL_ +val SC_BIDIRECTIONAL_DISABLED=0 +val SC_BIDIRECTIONAL_L2R=1 +val SC_BIDIRECTIONAL_R2L=2 -# Retrieve the document line containing a position measured in index units. -fun line LineFromIndexPosition=2713(position pos, LineCharacterIndexType lineCharacterIndex) +# Retrieve bidirectional text display state. +get Bidirectional GetBidirectional=2708(,) -# Retrieve the position measured in index units at the start of a document line. -fun position IndexPositionFromLine=2714(line line, LineCharacterIndexType lineCharacterIndex) +# Set bidirectional text display state. +set void SetBidirectional=2709(Bidirectional bidirectional,) cat Deprecated @@ -5423,6 +3355,13 @@ set void SetKeysUnicode=2521(bool keysUnicode,) # Are keys always interpreted as Unicode? get bool GetKeysUnicode=2522(,) +# Is drawing done in two phases with backgrounds drawn before foregrounds? +get bool GetTwoPhaseDraw=2283(,) + +# In twoPhaseDraw mode, drawing is performed in two phases, first the background +# and then the foreground. This avoids chopping off characters that overlap the next run. +set void SetTwoPhaseDraw=2284(bool twoPhase,) + val INDIC0_MASK=0x20 val INDIC1_MASK=0x40 val INDIC2_MASK=0x80 diff --git a/scintilla/include/ScintillaCall.h b/scintilla/include/ScintillaCall.h new file mode 100644 index 0000000000..098b9ec1d6 --- /dev/null +++ b/scintilla/include/ScintillaCall.h @@ -0,0 +1,881 @@ +// SciTE - Scintilla based Text Editor +/** @file ScintillaCall.h + ** Interface to calling a Scintilla instance. + **/ +// Copyright 1998-2019 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +/* Most of this file is automatically generated from the Scintilla.iface interface definition + * file which contains any comments about the definitions. APIFacer.py does the generation. */ + +#ifndef SCINTILLACALL_H +#define SCINTILLACALL_H + +namespace Scintilla { + +enum class Message; // Declare in case ScintillaMessages.h not included + +using FunctionDirect = intptr_t(*)(intptr_t ptr, unsigned int iMessage, uintptr_t wParam, intptr_t lParam, int *pStatus); + +struct Failure { + Scintilla::Status status; + explicit Failure(Scintilla::Status status_) noexcept : status(status_) { + } +}; + +struct Span { + // An ordered range + // end may be less than start when, for example, searching backwards + Position start; + Position end; + explicit Span(Position position) noexcept : start(position), end(position) { + } + Span(Position start_, Position end_) noexcept : start(start_), end(end_) { + } + Position Length() const noexcept { + if (end > start) + return end - start; + else + return start - end; + } + bool operator==(const Span &other) const noexcept { + return (other.start == start) && (other.end == end); + } +}; + +class ScintillaCall { + FunctionDirect fn; + intptr_t ptr; + intptr_t CallPointer(Message msg, uintptr_t wParam, void *s); + intptr_t CallString(Message msg, uintptr_t wParam, const char *s); + std::string CallReturnString(Message msg, uintptr_t wParam); +public: + Scintilla::Status statusLastCall; + ScintillaCall() noexcept; + // All standard methods are fine + + void SetFnPtr(FunctionDirect fn_, intptr_t ptr_) noexcept; + bool IsValid() const noexcept; + intptr_t Call(Message msg, uintptr_t wParam=0, intptr_t lParam=0); + + // Common APIs made more structured and type-safe + Position LineStart(Line line); + Position LineEnd(Line line); + Span SelectionSpan(); + Span TargetSpan(); + void SetTarget(Span span); + void ColouriseAll(); + char CharacterAt(Position position); + int UnsignedStyleAt(Position position); + std::string StringOfSpan(Span span); + Position ReplaceTarget(std::string_view text); + Position ReplaceTargetRE(std::string_view text); + Position SearchInTarget(std::string_view text); + Span SpanSearchInTarget(std::string_view text); + + // Generated APIs +//++Autogenerated -- start of section automatically generated from Scintilla.iface +//**\(\*\n\) + void AddText(Position length, const char *text); + void AddStyledText(Position length, const char *c); + void InsertText(Position pos, const char *text); + void ChangeInsertion(Position length, const char *text); + void ClearAll(); + void DeleteRange(Position start, Position lengthDelete); + void ClearDocumentStyle(); + Position Length(); + int CharAt(Position pos); + Position CurrentPos(); + Position Anchor(); + int StyleAt(Position pos); + void Redo(); + void SetUndoCollection(bool collectUndo); + void SelectAll(); + void SetSavePoint(); + Position GetStyledText(void *tr); + bool CanRedo(); + Line MarkerLineFromHandle(int markerHandle); + void MarkerDeleteHandle(int markerHandle); + int MarkerHandleFromLine(Line line, int which); + int MarkerNumberFromLine(Line line, int which); + bool UndoCollection(); + Scintilla::WhiteSpace ViewWS(); + void SetViewWS(Scintilla::WhiteSpace viewWS); + Scintilla::TabDrawMode TabDrawMode(); + void SetTabDrawMode(Scintilla::TabDrawMode tabDrawMode); + Position PositionFromPoint(int x, int y); + Position PositionFromPointClose(int x, int y); + void GotoLine(Line line); + void GotoPos(Position caret); + void SetAnchor(Position anchor); + Position GetCurLine(Position length, char *text); + std::string GetCurLine(Position length); + Position EndStyled(); + void ConvertEOLs(Scintilla::EndOfLine eolMode); + Scintilla::EndOfLine EOLMode(); + void SetEOLMode(Scintilla::EndOfLine eolMode); + void StartStyling(Position start, int unused); + void SetStyling(Position length, int style); + bool BufferedDraw(); + void SetBufferedDraw(bool buffered); + void SetTabWidth(int tabWidth); + int TabWidth(); + void SetTabMinimumWidth(int pixels); + int TabMinimumWidth(); + void ClearTabStops(Line line); + void AddTabStop(Line line, int x); + int GetNextTabStop(Line line, int x); + void SetCodePage(int codePage); + void SetFontLocale(const char *localeName); + int FontLocale(char *localeName); + std::string FontLocale(); + Scintilla::IMEInteraction IMEInteraction(); + void SetIMEInteraction(Scintilla::IMEInteraction imeInteraction); + void MarkerDefine(int markerNumber, Scintilla::MarkerSymbol markerSymbol); + void MarkerSetFore(int markerNumber, Colour fore); + void MarkerSetBack(int markerNumber, Colour back); + void MarkerSetBackSelected(int markerNumber, Colour back); + void MarkerSetForeTranslucent(int markerNumber, ColourAlpha fore); + void MarkerSetBackTranslucent(int markerNumber, ColourAlpha back); + void MarkerSetBackSelectedTranslucent(int markerNumber, ColourAlpha back); + void MarkerSetStrokeWidth(int markerNumber, int hundredths); + void MarkerEnableHighlight(bool enabled); + int MarkerAdd(Line line, int markerNumber); + void MarkerDelete(Line line, int markerNumber); + void MarkerDeleteAll(int markerNumber); + int MarkerGet(Line line); + Line MarkerNext(Line lineStart, int markerMask); + Line MarkerPrevious(Line lineStart, int markerMask); + void MarkerDefinePixmap(int markerNumber, const char *pixmap); + void MarkerAddSet(Line line, int markerSet); + void MarkerSetAlpha(int markerNumber, Scintilla::Alpha alpha); + Scintilla::Layer MarkerGetLayer(int markerNumber); + void MarkerSetLayer(int markerNumber, Scintilla::Layer layer); + void SetMarginTypeN(int margin, Scintilla::MarginType marginType); + Scintilla::MarginType MarginTypeN(int margin); + void SetMarginWidthN(int margin, int pixelWidth); + int MarginWidthN(int margin); + void SetMarginMaskN(int margin, int mask); + int MarginMaskN(int margin); + void SetMarginSensitiveN(int margin, bool sensitive); + bool MarginSensitiveN(int margin); + void SetMarginCursorN(int margin, Scintilla::CursorShape cursor); + Scintilla::CursorShape MarginCursorN(int margin); + void SetMarginBackN(int margin, Colour back); + Colour MarginBackN(int margin); + void SetMargins(int margins); + int Margins(); + void StyleClearAll(); + void StyleSetFore(int style, Colour fore); + void StyleSetBack(int style, Colour back); + void StyleSetBold(int style, bool bold); + void StyleSetItalic(int style, bool italic); + void StyleSetSize(int style, int sizePoints); + void StyleSetFont(int style, const char *fontName); + void StyleSetEOLFilled(int style, bool eolFilled); + void StyleResetDefault(); + void StyleSetUnderline(int style, bool underline); + Colour StyleGetFore(int style); + Colour StyleGetBack(int style); + bool StyleGetBold(int style); + bool StyleGetItalic(int style); + int StyleGetSize(int style); + int StyleGetFont(int style, char *fontName); + std::string StyleGetFont(int style); + bool StyleGetEOLFilled(int style); + bool StyleGetUnderline(int style); + Scintilla::CaseVisible StyleGetCase(int style); + Scintilla::CharacterSet StyleGetCharacterSet(int style); + bool StyleGetVisible(int style); + bool StyleGetChangeable(int style); + bool StyleGetHotSpot(int style); + void StyleSetCase(int style, Scintilla::CaseVisible caseVisible); + void StyleSetSizeFractional(int style, int sizeHundredthPoints); + int StyleGetSizeFractional(int style); + void StyleSetWeight(int style, Scintilla::FontWeight weight); + Scintilla::FontWeight StyleGetWeight(int style); + void StyleSetCharacterSet(int style, Scintilla::CharacterSet characterSet); + void StyleSetHotSpot(int style, bool hotspot); + void SetElementColour(Scintilla::Element element, ColourAlpha colourElement); + ColourAlpha ElementColour(Scintilla::Element element); + void ResetElementColour(Scintilla::Element element); + bool ElementIsSet(Scintilla::Element element); + bool ElementAllowsTranslucent(Scintilla::Element element); + ColourAlpha ElementBaseColour(Scintilla::Element element); + void SetSelFore(bool useSetting, Colour fore); + void SetSelBack(bool useSetting, Colour back); + Scintilla::Alpha SelAlpha(); + void SetSelAlpha(Scintilla::Alpha alpha); + bool SelEOLFilled(); + void SetSelEOLFilled(bool filled); + Scintilla::Layer SelectionLayer(); + void SetSelectionLayer(Scintilla::Layer layer); + Scintilla::Layer CaretLineLayer(); + void SetCaretLineLayer(Scintilla::Layer layer); + void SetCaretFore(Colour fore); + void AssignCmdKey(int keyDefinition, int sciCommand); + void ClearCmdKey(int keyDefinition); + void ClearAllCmdKeys(); + void SetStylingEx(Position length, const char *styles); + void StyleSetVisible(int style, bool visible); + int CaretPeriod(); + void SetCaretPeriod(int periodMilliseconds); + void SetWordChars(const char *characters); + int WordChars(char *characters); + std::string WordChars(); + void SetCharacterCategoryOptimization(int countCharacters); + int CharacterCategoryOptimization(); + void BeginUndoAction(); + void EndUndoAction(); + void IndicSetStyle(int indicator, Scintilla::IndicatorStyle indicatorStyle); + Scintilla::IndicatorStyle IndicGetStyle(int indicator); + void IndicSetFore(int indicator, Colour fore); + Colour IndicGetFore(int indicator); + void IndicSetUnder(int indicator, bool under); + bool IndicGetUnder(int indicator); + void IndicSetHoverStyle(int indicator, Scintilla::IndicatorStyle indicatorStyle); + Scintilla::IndicatorStyle IndicGetHoverStyle(int indicator); + void IndicSetHoverFore(int indicator, Colour fore); + Colour IndicGetHoverFore(int indicator); + void IndicSetFlags(int indicator, Scintilla::IndicFlag flags); + Scintilla::IndicFlag IndicGetFlags(int indicator); + void IndicSetStrokeWidth(int indicator, int hundredths); + int IndicGetStrokeWidth(int indicator); + void SetWhitespaceFore(bool useSetting, Colour fore); + void SetWhitespaceBack(bool useSetting, Colour back); + void SetWhitespaceSize(int size); + int WhitespaceSize(); + void SetLineState(Line line, int state); + int LineState(Line line); + int MaxLineState(); + bool CaretLineVisible(); + void SetCaretLineVisible(bool show); + Colour CaretLineBack(); + void SetCaretLineBack(Colour back); + int CaretLineFrame(); + void SetCaretLineFrame(int width); + void StyleSetChangeable(int style, bool changeable); + void AutoCShow(Position lengthEntered, const char *itemList); + void AutoCCancel(); + bool AutoCActive(); + Position AutoCPosStart(); + void AutoCComplete(); + void AutoCStops(const char *characterSet); + void AutoCSetSeparator(int separatorCharacter); + int AutoCGetSeparator(); + void AutoCSelect(const char *select); + void AutoCSetCancelAtStart(bool cancel); + bool AutoCGetCancelAtStart(); + void AutoCSetFillUps(const char *characterSet); + void AutoCSetChooseSingle(bool chooseSingle); + bool AutoCGetChooseSingle(); + void AutoCSetIgnoreCase(bool ignoreCase); + bool AutoCGetIgnoreCase(); + void UserListShow(int listType, const char *itemList); + void AutoCSetAutoHide(bool autoHide); + bool AutoCGetAutoHide(); + void AutoCSetOptions(Scintilla::AutoCompleteOption options); + Scintilla::AutoCompleteOption AutoCGetOptions(); + void AutoCSetDropRestOfWord(bool dropRestOfWord); + bool AutoCGetDropRestOfWord(); + void RegisterImage(int type, const char *xpmData); + void ClearRegisteredImages(); + int AutoCGetTypeSeparator(); + void AutoCSetTypeSeparator(int separatorCharacter); + void AutoCSetMaxWidth(int characterCount); + int AutoCGetMaxWidth(); + void AutoCSetMaxHeight(int rowCount); + int AutoCGetMaxHeight(); + void SetIndent(int indentSize); + int Indent(); + void SetUseTabs(bool useTabs); + bool UseTabs(); + void SetLineIndentation(Line line, int indentation); + int LineIndentation(Line line); + Position LineIndentPosition(Line line); + Position Column(Position pos); + Position CountCharacters(Position start, Position end); + Position CountCodeUnits(Position start, Position end); + void SetHScrollBar(bool visible); + bool HScrollBar(); + void SetIndentationGuides(Scintilla::IndentView indentView); + Scintilla::IndentView IndentationGuides(); + void SetHighlightGuide(Position column); + Position HighlightGuide(); + Position LineEndPosition(Line line); + int CodePage(); + Colour CaretFore(); + bool ReadOnly(); + void SetCurrentPos(Position caret); + void SetSelectionStart(Position anchor); + Position SelectionStart(); + void SetSelectionEnd(Position caret); + Position SelectionEnd(); + void SetEmptySelection(Position caret); + void SetPrintMagnification(int magnification); + int PrintMagnification(); + void SetPrintColourMode(Scintilla::PrintOption mode); + Scintilla::PrintOption PrintColourMode(); + Position FindText(Scintilla::FindOption searchFlags, void *ft); + Position FormatRange(bool draw, void *fr); + Line FirstVisibleLine(); + Position GetLine(Line line, char *text); + std::string GetLine(Line line); + Line LineCount(); + void AllocateLines(Line lines); + void SetMarginLeft(int pixelWidth); + int MarginLeft(); + void SetMarginRight(int pixelWidth); + int MarginRight(); + bool Modify(); + void SetSel(Position anchor, Position caret); + Position GetSelText(char *text); + std::string GetSelText(); + Position GetTextRange(void *tr); + void HideSelection(bool hide); + int PointXFromPosition(Position pos); + int PointYFromPosition(Position pos); + Line LineFromPosition(Position pos); + Position PositionFromLine(Line line); + void LineScroll(Position columns, Line lines); + void ScrollCaret(); + void ScrollRange(Position secondary, Position primary); + void ReplaceSel(const char *text); + void SetReadOnly(bool readOnly); + void Null(); + bool CanPaste(); + bool CanUndo(); + void EmptyUndoBuffer(); + void Undo(); + void Cut(); + void Copy(); + void Paste(); + void Clear(); + void SetText(const char *text); + Position GetText(Position length, char *text); + std::string GetText(Position length); + Position TextLength(); + void *DirectFunction(); + void *DirectStatusFunction(); + void *DirectPointer(); + void SetOvertype(bool overType); + bool Overtype(); + void SetCaretWidth(int pixelWidth); + int CaretWidth(); + void SetTargetStart(Position start); + Position TargetStart(); + void SetTargetStartVirtualSpace(Position space); + Position TargetStartVirtualSpace(); + void SetTargetEnd(Position end); + Position TargetEnd(); + void SetTargetEndVirtualSpace(Position space); + Position TargetEndVirtualSpace(); + void SetTargetRange(Position start, Position end); + Position TargetText(char *text); + std::string TargetText(); + void TargetFromSelection(); + void TargetWholeDocument(); + Position ReplaceTarget(Position length, const char *text); + Position ReplaceTargetRE(Position length, const char *text); + Position SearchInTarget(Position length, const char *text); + void SetSearchFlags(Scintilla::FindOption searchFlags); + Scintilla::FindOption SearchFlags(); + void CallTipShow(Position pos, const char *definition); + void CallTipCancel(); + bool CallTipActive(); + Position CallTipPosStart(); + void CallTipSetPosStart(Position posStart); + void CallTipSetHlt(Position highlightStart, Position highlightEnd); + void CallTipSetBack(Colour back); + void CallTipSetFore(Colour fore); + void CallTipSetForeHlt(Colour fore); + void CallTipUseStyle(int tabSize); + void CallTipSetPosition(bool above); + Line VisibleFromDocLine(Line docLine); + Line DocLineFromVisible(Line displayLine); + Line WrapCount(Line docLine); + void SetFoldLevel(Line line, Scintilla::FoldLevel level); + Scintilla::FoldLevel FoldLevel(Line line); + Line LastChild(Line line, Scintilla::FoldLevel level); + Line FoldParent(Line line); + void ShowLines(Line lineStart, Line lineEnd); + void HideLines(Line lineStart, Line lineEnd); + bool LineVisible(Line line); + bool AllLinesVisible(); + void SetFoldExpanded(Line line, bool expanded); + bool FoldExpanded(Line line); + void ToggleFold(Line line); + void ToggleFoldShowText(Line line, const char *text); + void FoldDisplayTextSetStyle(Scintilla::FoldDisplayTextStyle style); + Scintilla::FoldDisplayTextStyle FoldDisplayTextGetStyle(); + void SetDefaultFoldDisplayText(const char *text); + int GetDefaultFoldDisplayText(char *text); + std::string GetDefaultFoldDisplayText(); + void FoldLine(Line line, Scintilla::FoldAction action); + void FoldChildren(Line line, Scintilla::FoldAction action); + void ExpandChildren(Line line, Scintilla::FoldLevel level); + void FoldAll(Scintilla::FoldAction action); + void EnsureVisible(Line line); + void SetAutomaticFold(Scintilla::AutomaticFold automaticFold); + Scintilla::AutomaticFold AutomaticFold(); + void SetFoldFlags(Scintilla::FoldFlag flags); + void EnsureVisibleEnforcePolicy(Line line); + void SetTabIndents(bool tabIndents); + bool TabIndents(); + void SetBackSpaceUnIndents(bool bsUnIndents); + bool BackSpaceUnIndents(); + void SetMouseDwellTime(int periodMilliseconds); + int MouseDwellTime(); + Position WordStartPosition(Position pos, bool onlyWordCharacters); + Position WordEndPosition(Position pos, bool onlyWordCharacters); + bool IsRangeWord(Position start, Position end); + void SetIdleStyling(Scintilla::IdleStyling idleStyling); + Scintilla::IdleStyling IdleStyling(); + void SetWrapMode(Scintilla::Wrap wrapMode); + Scintilla::Wrap WrapMode(); + void SetWrapVisualFlags(Scintilla::WrapVisualFlag wrapVisualFlags); + Scintilla::WrapVisualFlag WrapVisualFlags(); + void SetWrapVisualFlagsLocation(Scintilla::WrapVisualLocation wrapVisualFlagsLocation); + Scintilla::WrapVisualLocation WrapVisualFlagsLocation(); + void SetWrapStartIndent(int indent); + int WrapStartIndent(); + void SetWrapIndentMode(Scintilla::WrapIndentMode wrapIndentMode); + Scintilla::WrapIndentMode WrapIndentMode(); + void SetLayoutCache(Scintilla::LineCache cacheMode); + Scintilla::LineCache LayoutCache(); + void SetScrollWidth(int pixelWidth); + int ScrollWidth(); + void SetScrollWidthTracking(bool tracking); + bool ScrollWidthTracking(); + int TextWidth(int style, const char *text); + void SetEndAtLastLine(bool endAtLastLine); + bool EndAtLastLine(); + int TextHeight(Line line); + void SetVScrollBar(bool visible); + bool VScrollBar(); + void AppendText(Position length, const char *text); + Scintilla::PhasesDraw PhasesDraw(); + void SetPhasesDraw(Scintilla::PhasesDraw phases); + void SetFontQuality(Scintilla::FontQuality fontQuality); + Scintilla::FontQuality FontQuality(); + void SetFirstVisibleLine(Line displayLine); + void SetMultiPaste(Scintilla::MultiPaste multiPaste); + Scintilla::MultiPaste MultiPaste(); + int Tag(int tagNumber, char *tagValue); + std::string Tag(int tagNumber); + void LinesJoin(); + void LinesSplit(int pixelWidth); + void SetFoldMarginColour(bool useSetting, Colour back); + void SetFoldMarginHiColour(bool useSetting, Colour fore); + void SetAccessibility(Scintilla::Accessibility accessibility); + Scintilla::Accessibility Accessibility(); + void LineDown(); + void LineDownExtend(); + void LineUp(); + void LineUpExtend(); + void CharLeft(); + void CharLeftExtend(); + void CharRight(); + void CharRightExtend(); + void WordLeft(); + void WordLeftExtend(); + void WordRight(); + void WordRightExtend(); + void Home(); + void HomeExtend(); + void LineEnd(); + void LineEndExtend(); + void DocumentStart(); + void DocumentStartExtend(); + void DocumentEnd(); + void DocumentEndExtend(); + void PageUp(); + void PageUpExtend(); + void PageDown(); + void PageDownExtend(); + void EditToggleOvertype(); + void Cancel(); + void DeleteBack(); + void Tab(); + void BackTab(); + void NewLine(); + void FormFeed(); + void VCHome(); + void VCHomeExtend(); + void ZoomIn(); + void ZoomOut(); + void DelWordLeft(); + void DelWordRight(); + void DelWordRightEnd(); + void LineCut(); + void LineDelete(); + void LineTranspose(); + void LineReverse(); + void LineDuplicate(); + void LowerCase(); + void UpperCase(); + void LineScrollDown(); + void LineScrollUp(); + void DeleteBackNotLine(); + void HomeDisplay(); + void HomeDisplayExtend(); + void LineEndDisplay(); + void LineEndDisplayExtend(); + void HomeWrap(); + void HomeWrapExtend(); + void LineEndWrap(); + void LineEndWrapExtend(); + void VCHomeWrap(); + void VCHomeWrapExtend(); + void LineCopy(); + void MoveCaretInsideView(); + Position LineLength(Line line); + void BraceHighlight(Position posA, Position posB); + void BraceHighlightIndicator(bool useSetting, int indicator); + void BraceBadLight(Position pos); + void BraceBadLightIndicator(bool useSetting, int indicator); + Position BraceMatch(Position pos, int maxReStyle); + Position BraceMatchNext(Position pos, Position startPos); + bool ViewEOL(); + void SetViewEOL(bool visible); + void *DocPointer(); + void SetDocPointer(void *doc); + void SetModEventMask(Scintilla::ModificationFlags eventMask); + Position EdgeColumn(); + void SetEdgeColumn(Position column); + Scintilla::EdgeVisualStyle EdgeMode(); + void SetEdgeMode(Scintilla::EdgeVisualStyle edgeMode); + Colour EdgeColour(); + void SetEdgeColour(Colour edgeColour); + void MultiEdgeAddLine(Position column, Colour edgeColour); + void MultiEdgeClearAll(); + Position MultiEdgeColumn(int which); + void SearchAnchor(); + Position SearchNext(Scintilla::FindOption searchFlags, const char *text); + Position SearchPrev(Scintilla::FindOption searchFlags, const char *text); + Line LinesOnScreen(); + void UsePopUp(Scintilla::PopUp popUpMode); + bool SelectionIsRectangle(); + void SetZoom(int zoomInPoints); + int Zoom(); + void *CreateDocument(Position bytes, Scintilla::DocumentOption documentOptions); + void AddRefDocument(void *doc); + void ReleaseDocument(void *doc); + Scintilla::DocumentOption DocumentOptions(); + Scintilla::ModificationFlags ModEventMask(); + void SetCommandEvents(bool commandEvents); + bool CommandEvents(); + void SetFocus(bool focus); + bool Focus(); + void SetStatus(Scintilla::Status status); + Scintilla::Status Status(); + void SetMouseDownCaptures(bool captures); + bool MouseDownCaptures(); + void SetMouseWheelCaptures(bool captures); + bool MouseWheelCaptures(); + void SetCursor(Scintilla::CursorShape cursorType); + Scintilla::CursorShape Cursor(); + void SetControlCharSymbol(int symbol); + int ControlCharSymbol(); + void WordPartLeft(); + void WordPartLeftExtend(); + void WordPartRight(); + void WordPartRightExtend(); + void SetVisiblePolicy(Scintilla::VisiblePolicy visiblePolicy, int visibleSlop); + void DelLineLeft(); + void DelLineRight(); + void SetXOffset(int xOffset); + int XOffset(); + void ChooseCaretX(); + void GrabFocus(); + void SetXCaretPolicy(Scintilla::CaretPolicy caretPolicy, int caretSlop); + void SetYCaretPolicy(Scintilla::CaretPolicy caretPolicy, int caretSlop); + void SetPrintWrapMode(Scintilla::Wrap wrapMode); + Scintilla::Wrap PrintWrapMode(); + void SetHotspotActiveFore(bool useSetting, Colour fore); + Colour HotspotActiveFore(); + void SetHotspotActiveBack(bool useSetting, Colour back); + Colour HotspotActiveBack(); + void SetHotspotActiveUnderline(bool underline); + bool HotspotActiveUnderline(); + void SetHotspotSingleLine(bool singleLine); + bool HotspotSingleLine(); + void ParaDown(); + void ParaDownExtend(); + void ParaUp(); + void ParaUpExtend(); + Position PositionBefore(Position pos); + Position PositionAfter(Position pos); + Position PositionRelative(Position pos, Position relative); + Position PositionRelativeCodeUnits(Position pos, Position relative); + void CopyRange(Position start, Position end); + void CopyText(Position length, const char *text); + void SetSelectionMode(Scintilla::SelectionMode selectionMode); + Scintilla::SelectionMode SelectionMode(); + bool MoveExtendsSelection(); + Position GetLineSelStartPosition(Line line); + Position GetLineSelEndPosition(Line line); + void LineDownRectExtend(); + void LineUpRectExtend(); + void CharLeftRectExtend(); + void CharRightRectExtend(); + void HomeRectExtend(); + void VCHomeRectExtend(); + void LineEndRectExtend(); + void PageUpRectExtend(); + void PageDownRectExtend(); + void StutteredPageUp(); + void StutteredPageUpExtend(); + void StutteredPageDown(); + void StutteredPageDownExtend(); + void WordLeftEnd(); + void WordLeftEndExtend(); + void WordRightEnd(); + void WordRightEndExtend(); + void SetWhitespaceChars(const char *characters); + int WhitespaceChars(char *characters); + std::string WhitespaceChars(); + void SetPunctuationChars(const char *characters); + int PunctuationChars(char *characters); + std::string PunctuationChars(); + void SetCharsDefault(); + int AutoCGetCurrent(); + int AutoCGetCurrentText(char *text); + std::string AutoCGetCurrentText(); + void AutoCSetCaseInsensitiveBehaviour(Scintilla::CaseInsensitiveBehaviour behaviour); + Scintilla::CaseInsensitiveBehaviour AutoCGetCaseInsensitiveBehaviour(); + void AutoCSetMulti(Scintilla::MultiAutoComplete multi); + Scintilla::MultiAutoComplete AutoCGetMulti(); + void AutoCSetOrder(Scintilla::Ordering order); + Scintilla::Ordering AutoCGetOrder(); + void Allocate(Position bytes); + Position TargetAsUTF8(char *s); + std::string TargetAsUTF8(); + void SetLengthForEncode(Position bytes); + Position EncodedFromUTF8(const char *utf8, char *encoded); + std::string EncodedFromUTF8(const char *utf8); + Position FindColumn(Line line, Position column); + Scintilla::CaretSticky CaretSticky(); + void SetCaretSticky(Scintilla::CaretSticky useCaretStickyBehaviour); + void ToggleCaretSticky(); + void SetPasteConvertEndings(bool convert); + bool PasteConvertEndings(); + void ReplaceRectangular(Position length, const char *text); + void SelectionDuplicate(); + void SetCaretLineBackAlpha(Scintilla::Alpha alpha); + Scintilla::Alpha CaretLineBackAlpha(); + void SetCaretStyle(Scintilla::CaretStyle caretStyle); + Scintilla::CaretStyle CaretStyle(); + void SetIndicatorCurrent(int indicator); + int IndicatorCurrent(); + void SetIndicatorValue(int value); + int IndicatorValue(); + void IndicatorFillRange(Position start, Position lengthFill); + void IndicatorClearRange(Position start, Position lengthClear); + int IndicatorAllOnFor(Position pos); + int IndicatorValueAt(int indicator, Position pos); + Position IndicatorStart(int indicator, Position pos); + Position IndicatorEnd(int indicator, Position pos); + void SetPositionCache(int size); + int PositionCache(); + void CopyAllowLine(); + void *CharacterPointer(); + void *RangePointer(Position start, Position lengthRange); + Position GapPosition(); + void IndicSetAlpha(int indicator, Scintilla::Alpha alpha); + Scintilla::Alpha IndicGetAlpha(int indicator); + void IndicSetOutlineAlpha(int indicator, Scintilla::Alpha alpha); + Scintilla::Alpha IndicGetOutlineAlpha(int indicator); + void SetExtraAscent(int extraAscent); + int ExtraAscent(); + void SetExtraDescent(int extraDescent); + int ExtraDescent(); + int MarkerSymbolDefined(int markerNumber); + void MarginSetText(Line line, const char *text); + int MarginGetText(Line line, char *text); + std::string MarginGetText(Line line); + void MarginSetStyle(Line line, int style); + int MarginGetStyle(Line line); + void MarginSetStyles(Line line, const char *styles); + int MarginGetStyles(Line line, char *styles); + std::string MarginGetStyles(Line line); + void MarginTextClearAll(); + void MarginSetStyleOffset(int style); + int MarginGetStyleOffset(); + void SetMarginOptions(Scintilla::MarginOption marginOptions); + Scintilla::MarginOption MarginOptions(); + void AnnotationSetText(Line line, const char *text); + int AnnotationGetText(Line line, char *text); + std::string AnnotationGetText(Line line); + void AnnotationSetStyle(Line line, int style); + int AnnotationGetStyle(Line line); + void AnnotationSetStyles(Line line, const char *styles); + int AnnotationGetStyles(Line line, char *styles); + std::string AnnotationGetStyles(Line line); + int AnnotationGetLines(Line line); + void AnnotationClearAll(); + void AnnotationSetVisible(Scintilla::AnnotationVisible visible); + Scintilla::AnnotationVisible AnnotationGetVisible(); + void AnnotationSetStyleOffset(int style); + int AnnotationGetStyleOffset(); + void ReleaseAllExtendedStyles(); + int AllocateExtendedStyles(int numberStyles); + void AddUndoAction(int token, Scintilla::UndoFlags flags); + Position CharPositionFromPoint(int x, int y); + Position CharPositionFromPointClose(int x, int y); + void SetMouseSelectionRectangularSwitch(bool mouseSelectionRectangularSwitch); + bool MouseSelectionRectangularSwitch(); + void SetMultipleSelection(bool multipleSelection); + bool MultipleSelection(); + void SetAdditionalSelectionTyping(bool additionalSelectionTyping); + bool AdditionalSelectionTyping(); + void SetAdditionalCaretsBlink(bool additionalCaretsBlink); + bool AdditionalCaretsBlink(); + void SetAdditionalCaretsVisible(bool additionalCaretsVisible); + bool AdditionalCaretsVisible(); + int Selections(); + bool SelectionEmpty(); + void ClearSelections(); + void SetSelection(Position caret, Position anchor); + void AddSelection(Position caret, Position anchor); + void DropSelectionN(int selection); + void SetMainSelection(int selection); + int MainSelection(); + void SetSelectionNCaret(int selection, Position caret); + Position SelectionNCaret(int selection); + void SetSelectionNAnchor(int selection, Position anchor); + Position SelectionNAnchor(int selection); + void SetSelectionNCaretVirtualSpace(int selection, Position space); + Position SelectionNCaretVirtualSpace(int selection); + void SetSelectionNAnchorVirtualSpace(int selection, Position space); + Position SelectionNAnchorVirtualSpace(int selection); + void SetSelectionNStart(int selection, Position anchor); + Position SelectionNStart(int selection); + Position SelectionNStartVirtualSpace(int selection); + void SetSelectionNEnd(int selection, Position caret); + Position SelectionNEndVirtualSpace(int selection); + Position SelectionNEnd(int selection); + void SetRectangularSelectionCaret(Position caret); + Position RectangularSelectionCaret(); + void SetRectangularSelectionAnchor(Position anchor); + Position RectangularSelectionAnchor(); + void SetRectangularSelectionCaretVirtualSpace(Position space); + Position RectangularSelectionCaretVirtualSpace(); + void SetRectangularSelectionAnchorVirtualSpace(Position space); + Position RectangularSelectionAnchorVirtualSpace(); + void SetVirtualSpaceOptions(Scintilla::VirtualSpace virtualSpaceOptions); + Scintilla::VirtualSpace VirtualSpaceOptions(); + void SetRectangularSelectionModifier(int modifier); + int RectangularSelectionModifier(); + void SetAdditionalSelFore(Colour fore); + void SetAdditionalSelBack(Colour back); + void SetAdditionalSelAlpha(Scintilla::Alpha alpha); + Scintilla::Alpha AdditionalSelAlpha(); + void SetAdditionalCaretFore(Colour fore); + Colour AdditionalCaretFore(); + void RotateSelection(); + void SwapMainAnchorCaret(); + void MultipleSelectAddNext(); + void MultipleSelectAddEach(); + int ChangeLexerState(Position start, Position end); + Line ContractedFoldNext(Line lineStart); + void VerticalCentreCaret(); + void MoveSelectedLinesUp(); + void MoveSelectedLinesDown(); + void SetIdentifier(int identifier); + int Identifier(); + void RGBAImageSetWidth(int width); + void RGBAImageSetHeight(int height); + void RGBAImageSetScale(int scalePercent); + void MarkerDefineRGBAImage(int markerNumber, const char *pixels); + void RegisterRGBAImage(int type, const char *pixels); + void ScrollToStart(); + void ScrollToEnd(); + void SetTechnology(Scintilla::Technology technology); + Scintilla::Technology Technology(); + void *CreateLoader(Position bytes, Scintilla::DocumentOption documentOptions); + void FindIndicatorShow(Position start, Position end); + void FindIndicatorFlash(Position start, Position end); + void FindIndicatorHide(); + void VCHomeDisplay(); + void VCHomeDisplayExtend(); + bool CaretLineVisibleAlways(); + void SetCaretLineVisibleAlways(bool alwaysVisible); + void SetLineEndTypesAllowed(Scintilla::LineEndType lineEndBitSet); + Scintilla::LineEndType LineEndTypesAllowed(); + Scintilla::LineEndType LineEndTypesActive(); + void SetRepresentation(const char *encodedCharacter, const char *representation); + int Representation(const char *encodedCharacter, char *representation); + std::string Representation(const char *encodedCharacter); + void ClearRepresentation(const char *encodedCharacter); + void ClearAllRepresentations(); + void SetRepresentationAppearance(const char *encodedCharacter, Scintilla::RepresentationAppearance appearance); + Scintilla::RepresentationAppearance RepresentationAppearance(const char *encodedCharacter); + void SetRepresentationColour(const char *encodedCharacter, ColourAlpha colour); + ColourAlpha RepresentationColour(const char *encodedCharacter); + void EOLAnnotationSetText(Line line, const char *text); + int EOLAnnotationGetText(Line line, char *text); + std::string EOLAnnotationGetText(Line line); + void EOLAnnotationSetStyle(Line line, int style); + int EOLAnnotationGetStyle(Line line); + void EOLAnnotationClearAll(); + void EOLAnnotationSetVisible(Scintilla::EOLAnnotationVisible visible); + Scintilla::EOLAnnotationVisible EOLAnnotationGetVisible(); + void EOLAnnotationSetStyleOffset(int style); + int EOLAnnotationGetStyleOffset(); + bool SupportsFeature(Scintilla::Supports feature); + Scintilla::LineCharacterIndexType LineCharacterIndex(); + void AllocateLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); + void ReleaseLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); + Line LineFromIndexPosition(Position pos, Scintilla::LineCharacterIndexType lineCharacterIndex); + Position IndexPositionFromLine(Line line, Scintilla::LineCharacterIndexType lineCharacterIndex); + void StartRecord(); + void StopRecord(); + int Lexer(); + void Colourise(Position start, Position end); + void SetProperty(const char *key, const char *value); + void SetKeyWords(int keyWordSet, const char *keyWords); + int Property(const char *key, char *value); + std::string Property(const char *key); + int PropertyExpanded(const char *key, char *value); + std::string PropertyExpanded(const char *key); + int PropertyInt(const char *key, int defaultValue); + int LexerLanguage(char *language); + std::string LexerLanguage(); + void *PrivateLexerCall(int operation, void *pointer); + int PropertyNames(char *names); + std::string PropertyNames(); + Scintilla::TypeProperty PropertyType(const char *name); + int DescribeProperty(const char *name, char *description); + std::string DescribeProperty(const char *name); + int DescribeKeyWordSets(char *descriptions); + std::string DescribeKeyWordSets(); + int LineEndTypesSupported(); + int AllocateSubStyles(int styleBase, int numberStyles); + int SubStylesStart(int styleBase); + int SubStylesLength(int styleBase); + int StyleFromSubStyle(int subStyle); + int PrimaryStyleFromStyle(int style); + void FreeSubStyles(); + void SetIdentifiers(int style, const char *identifiers); + int DistanceToSecondaryStyles(); + int SubStyleBases(char *styles); + std::string SubStyleBases(); + int NamedStyles(); + int NameOfStyle(int style, char *name); + std::string NameOfStyle(int style); + int TagsOfStyle(int style, char *tags); + std::string TagsOfStyle(int style); + int DescriptionOfStyle(int style, char *description); + std::string DescriptionOfStyle(int style); + void SetILexer(void *ilexer); + Scintilla::Bidirectional Bidirectional(); + void SetBidirectional(Scintilla::Bidirectional bidirectional); + +//--Autogenerated -- end of section automatically generated from Scintilla.iface + +}; + +} + +#endif diff --git a/scintilla/include/ScintillaMessages.h b/scintilla/include/ScintillaMessages.h new file mode 100644 index 0000000000..9293a5a6b8 --- /dev/null +++ b/scintilla/include/ScintillaMessages.h @@ -0,0 +1,788 @@ +// Scintilla source code edit control +/** @file ScintillaMessages.h + ** Enumerate the messages that can be sent to Scintilla. + **/ +// Copyright 1998-2019 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +/* Most of this file is automatically generated from the Scintilla.iface interface definition + * file which contains any comments about the definitions. ScintillaAPIFacer.py does the generation. */ + +#ifndef SCINTILLAMESSAGES_H +#define SCINTILLAMESSAGES_H + +namespace Scintilla { + +// Enumerations +//++Autogenerated -- start of section automatically generated from Scintilla.iface +enum class Message { + AddText = 2001, + AddStyledText = 2002, + InsertText = 2003, + ChangeInsertion = 2672, + ClearAll = 2004, + DeleteRange = 2645, + ClearDocumentStyle = 2005, + GetLength = 2006, + GetCharAt = 2007, + GetCurrentPos = 2008, + GetAnchor = 2009, + GetStyleAt = 2010, + Redo = 2011, + SetUndoCollection = 2012, + SelectAll = 2013, + SetSavePoint = 2014, + GetStyledText = 2015, + CanRedo = 2016, + MarkerLineFromHandle = 2017, + MarkerDeleteHandle = 2018, + MarkerHandleFromLine = 2732, + MarkerNumberFromLine = 2733, + GetUndoCollection = 2019, + GetViewWS = 2020, + SetViewWS = 2021, + GetTabDrawMode = 2698, + SetTabDrawMode = 2699, + PositionFromPoint = 2022, + PositionFromPointClose = 2023, + GotoLine = 2024, + GotoPos = 2025, + SetAnchor = 2026, + GetCurLine = 2027, + GetEndStyled = 2028, + ConvertEOLs = 2029, + GetEOLMode = 2030, + SetEOLMode = 2031, + StartStyling = 2032, + SetStyling = 2033, + GetBufferedDraw = 2034, + SetBufferedDraw = 2035, + SetTabWidth = 2036, + GetTabWidth = 2121, + SetTabMinimumWidth = 2724, + GetTabMinimumWidth = 2725, + ClearTabStops = 2675, + AddTabStop = 2676, + GetNextTabStop = 2677, + SetCodePage = 2037, + SetFontLocale = 2760, + GetFontLocale = 2761, + GetIMEInteraction = 2678, + SetIMEInteraction = 2679, + MarkerDefine = 2040, + MarkerSetFore = 2041, + MarkerSetBack = 2042, + MarkerSetBackSelected = 2292, + MarkerSetForeTranslucent = 2294, + MarkerSetBackTranslucent = 2295, + MarkerSetBackSelectedTranslucent = 2296, + MarkerSetStrokeWidth = 2297, + MarkerEnableHighlight = 2293, + MarkerAdd = 2043, + MarkerDelete = 2044, + MarkerDeleteAll = 2045, + MarkerGet = 2046, + MarkerNext = 2047, + MarkerPrevious = 2048, + MarkerDefinePixmap = 2049, + MarkerAddSet = 2466, + MarkerSetAlpha = 2476, + MarkerGetLayer = 2734, + MarkerSetLayer = 2735, + SetMarginTypeN = 2240, + GetMarginTypeN = 2241, + SetMarginWidthN = 2242, + GetMarginWidthN = 2243, + SetMarginMaskN = 2244, + GetMarginMaskN = 2245, + SetMarginSensitiveN = 2246, + GetMarginSensitiveN = 2247, + SetMarginCursorN = 2248, + GetMarginCursorN = 2249, + SetMarginBackN = 2250, + GetMarginBackN = 2251, + SetMargins = 2252, + GetMargins = 2253, + StyleClearAll = 2050, + StyleSetFore = 2051, + StyleSetBack = 2052, + StyleSetBold = 2053, + StyleSetItalic = 2054, + StyleSetSize = 2055, + StyleSetFont = 2056, + StyleSetEOLFilled = 2057, + StyleResetDefault = 2058, + StyleSetUnderline = 2059, + StyleGetFore = 2481, + StyleGetBack = 2482, + StyleGetBold = 2483, + StyleGetItalic = 2484, + StyleGetSize = 2485, + StyleGetFont = 2486, + StyleGetEOLFilled = 2487, + StyleGetUnderline = 2488, + StyleGetCase = 2489, + StyleGetCharacterSet = 2490, + StyleGetVisible = 2491, + StyleGetChangeable = 2492, + StyleGetHotSpot = 2493, + StyleSetCase = 2060, + StyleSetSizeFractional = 2061, + StyleGetSizeFractional = 2062, + StyleSetWeight = 2063, + StyleGetWeight = 2064, + StyleSetCharacterSet = 2066, + StyleSetHotSpot = 2409, + SetElementColour = 2753, + GetElementColour = 2754, + ResetElementColour = 2755, + GetElementIsSet = 2756, + GetElementAllowsTranslucent = 2757, + GetElementBaseColour = 2758, + SetSelFore = 2067, + SetSelBack = 2068, + GetSelAlpha = 2477, + SetSelAlpha = 2478, + GetSelEOLFilled = 2479, + SetSelEOLFilled = 2480, + GetSelectionLayer = 2762, + SetSelectionLayer = 2763, + GetCaretLineLayer = 2764, + SetCaretLineLayer = 2765, + SetCaretFore = 2069, + AssignCmdKey = 2070, + ClearCmdKey = 2071, + ClearAllCmdKeys = 2072, + SetStylingEx = 2073, + StyleSetVisible = 2074, + GetCaretPeriod = 2075, + SetCaretPeriod = 2076, + SetWordChars = 2077, + GetWordChars = 2646, + SetCharacterCategoryOptimization = 2720, + GetCharacterCategoryOptimization = 2721, + BeginUndoAction = 2078, + EndUndoAction = 2079, + IndicSetStyle = 2080, + IndicGetStyle = 2081, + IndicSetFore = 2082, + IndicGetFore = 2083, + IndicSetUnder = 2510, + IndicGetUnder = 2511, + IndicSetHoverStyle = 2680, + IndicGetHoverStyle = 2681, + IndicSetHoverFore = 2682, + IndicGetHoverFore = 2683, + IndicSetFlags = 2684, + IndicGetFlags = 2685, + IndicSetStrokeWidth = 2751, + IndicGetStrokeWidth = 2752, + SetWhitespaceFore = 2084, + SetWhitespaceBack = 2085, + SetWhitespaceSize = 2086, + GetWhitespaceSize = 2087, + SetLineState = 2092, + GetLineState = 2093, + GetMaxLineState = 2094, + GetCaretLineVisible = 2095, + SetCaretLineVisible = 2096, + GetCaretLineBack = 2097, + SetCaretLineBack = 2098, + GetCaretLineFrame = 2704, + SetCaretLineFrame = 2705, + StyleSetChangeable = 2099, + AutoCShow = 2100, + AutoCCancel = 2101, + AutoCActive = 2102, + AutoCPosStart = 2103, + AutoCComplete = 2104, + AutoCStops = 2105, + AutoCSetSeparator = 2106, + AutoCGetSeparator = 2107, + AutoCSelect = 2108, + AutoCSetCancelAtStart = 2110, + AutoCGetCancelAtStart = 2111, + AutoCSetFillUps = 2112, + AutoCSetChooseSingle = 2113, + AutoCGetChooseSingle = 2114, + AutoCSetIgnoreCase = 2115, + AutoCGetIgnoreCase = 2116, + UserListShow = 2117, + AutoCSetAutoHide = 2118, + AutoCGetAutoHide = 2119, + AutoCSetOptions = 2638, + AutoCGetOptions = 2639, + AutoCSetDropRestOfWord = 2270, + AutoCGetDropRestOfWord = 2271, + RegisterImage = 2405, + ClearRegisteredImages = 2408, + AutoCGetTypeSeparator = 2285, + AutoCSetTypeSeparator = 2286, + AutoCSetMaxWidth = 2208, + AutoCGetMaxWidth = 2209, + AutoCSetMaxHeight = 2210, + AutoCGetMaxHeight = 2211, + SetIndent = 2122, + GetIndent = 2123, + SetUseTabs = 2124, + GetUseTabs = 2125, + SetLineIndentation = 2126, + GetLineIndentation = 2127, + GetLineIndentPosition = 2128, + GetColumn = 2129, + CountCharacters = 2633, + CountCodeUnits = 2715, + SetHScrollBar = 2130, + GetHScrollBar = 2131, + SetIndentationGuides = 2132, + GetIndentationGuides = 2133, + SetHighlightGuide = 2134, + GetHighlightGuide = 2135, + GetLineEndPosition = 2136, + GetCodePage = 2137, + GetCaretFore = 2138, + GetReadOnly = 2140, + SetCurrentPos = 2141, + SetSelectionStart = 2142, + GetSelectionStart = 2143, + SetSelectionEnd = 2144, + GetSelectionEnd = 2145, + SetEmptySelection = 2556, + SetPrintMagnification = 2146, + GetPrintMagnification = 2147, + SetPrintColourMode = 2148, + GetPrintColourMode = 2149, + FindText = 2150, + FormatRange = 2151, + GetFirstVisibleLine = 2152, + GetLine = 2153, + GetLineCount = 2154, + AllocateLines = 2089, + SetMarginLeft = 2155, + GetMarginLeft = 2156, + SetMarginRight = 2157, + GetMarginRight = 2158, + GetModify = 2159, + SetSel = 2160, + GetSelText = 2161, + GetTextRange = 2162, + HideSelection = 2163, + PointXFromPosition = 2164, + PointYFromPosition = 2165, + LineFromPosition = 2166, + PositionFromLine = 2167, + LineScroll = 2168, + ScrollCaret = 2169, + ScrollRange = 2569, + ReplaceSel = 2170, + SetReadOnly = 2171, + Null = 2172, + CanPaste = 2173, + CanUndo = 2174, + EmptyUndoBuffer = 2175, + Undo = 2176, + Cut = 2177, + Copy = 2178, + Paste = 2179, + Clear = 2180, + SetText = 2181, + GetText = 2182, + GetTextLength = 2183, + GetDirectFunction = 2184, + GetDirectStatusFunction = 2772, + GetDirectPointer = 2185, + SetOvertype = 2186, + GetOvertype = 2187, + SetCaretWidth = 2188, + GetCaretWidth = 2189, + SetTargetStart = 2190, + GetTargetStart = 2191, + SetTargetStartVirtualSpace = 2728, + GetTargetStartVirtualSpace = 2729, + SetTargetEnd = 2192, + GetTargetEnd = 2193, + SetTargetEndVirtualSpace = 2730, + GetTargetEndVirtualSpace = 2731, + SetTargetRange = 2686, + GetTargetText = 2687, + TargetFromSelection = 2287, + TargetWholeDocument = 2690, + ReplaceTarget = 2194, + ReplaceTargetRE = 2195, + SearchInTarget = 2197, + SetSearchFlags = 2198, + GetSearchFlags = 2199, + CallTipShow = 2200, + CallTipCancel = 2201, + CallTipActive = 2202, + CallTipPosStart = 2203, + CallTipSetPosStart = 2214, + CallTipSetHlt = 2204, + CallTipSetBack = 2205, + CallTipSetFore = 2206, + CallTipSetForeHlt = 2207, + CallTipUseStyle = 2212, + CallTipSetPosition = 2213, + VisibleFromDocLine = 2220, + DocLineFromVisible = 2221, + WrapCount = 2235, + SetFoldLevel = 2222, + GetFoldLevel = 2223, + GetLastChild = 2224, + GetFoldParent = 2225, + ShowLines = 2226, + HideLines = 2227, + GetLineVisible = 2228, + GetAllLinesVisible = 2236, + SetFoldExpanded = 2229, + GetFoldExpanded = 2230, + ToggleFold = 2231, + ToggleFoldShowText = 2700, + FoldDisplayTextSetStyle = 2701, + FoldDisplayTextGetStyle = 2707, + SetDefaultFoldDisplayText = 2722, + GetDefaultFoldDisplayText = 2723, + FoldLine = 2237, + FoldChildren = 2238, + ExpandChildren = 2239, + FoldAll = 2662, + EnsureVisible = 2232, + SetAutomaticFold = 2663, + GetAutomaticFold = 2664, + SetFoldFlags = 2233, + EnsureVisibleEnforcePolicy = 2234, + SetTabIndents = 2260, + GetTabIndents = 2261, + SetBackSpaceUnIndents = 2262, + GetBackSpaceUnIndents = 2263, + SetMouseDwellTime = 2264, + GetMouseDwellTime = 2265, + WordStartPosition = 2266, + WordEndPosition = 2267, + IsRangeWord = 2691, + SetIdleStyling = 2692, + GetIdleStyling = 2693, + SetWrapMode = 2268, + GetWrapMode = 2269, + SetWrapVisualFlags = 2460, + GetWrapVisualFlags = 2461, + SetWrapVisualFlagsLocation = 2462, + GetWrapVisualFlagsLocation = 2463, + SetWrapStartIndent = 2464, + GetWrapStartIndent = 2465, + SetWrapIndentMode = 2472, + GetWrapIndentMode = 2473, + SetLayoutCache = 2272, + GetLayoutCache = 2273, + SetScrollWidth = 2274, + GetScrollWidth = 2275, + SetScrollWidthTracking = 2516, + GetScrollWidthTracking = 2517, + TextWidth = 2276, + SetEndAtLastLine = 2277, + GetEndAtLastLine = 2278, + TextHeight = 2279, + SetVScrollBar = 2280, + GetVScrollBar = 2281, + AppendText = 2282, + GetPhasesDraw = 2673, + SetPhasesDraw = 2674, + SetFontQuality = 2611, + GetFontQuality = 2612, + SetFirstVisibleLine = 2613, + SetMultiPaste = 2614, + GetMultiPaste = 2615, + GetTag = 2616, + LinesJoin = 2288, + LinesSplit = 2289, + SetFoldMarginColour = 2290, + SetFoldMarginHiColour = 2291, + SetAccessibility = 2702, + GetAccessibility = 2703, + LineDown = 2300, + LineDownExtend = 2301, + LineUp = 2302, + LineUpExtend = 2303, + CharLeft = 2304, + CharLeftExtend = 2305, + CharRight = 2306, + CharRightExtend = 2307, + WordLeft = 2308, + WordLeftExtend = 2309, + WordRight = 2310, + WordRightExtend = 2311, + Home = 2312, + HomeExtend = 2313, + LineEnd = 2314, + LineEndExtend = 2315, + DocumentStart = 2316, + DocumentStartExtend = 2317, + DocumentEnd = 2318, + DocumentEndExtend = 2319, + PageUp = 2320, + PageUpExtend = 2321, + PageDown = 2322, + PageDownExtend = 2323, + EditToggleOvertype = 2324, + Cancel = 2325, + DeleteBack = 2326, + Tab = 2327, + BackTab = 2328, + NewLine = 2329, + FormFeed = 2330, + VCHome = 2331, + VCHomeExtend = 2332, + ZoomIn = 2333, + ZoomOut = 2334, + DelWordLeft = 2335, + DelWordRight = 2336, + DelWordRightEnd = 2518, + LineCut = 2337, + LineDelete = 2338, + LineTranspose = 2339, + LineReverse = 2354, + LineDuplicate = 2404, + LowerCase = 2340, + UpperCase = 2341, + LineScrollDown = 2342, + LineScrollUp = 2343, + DeleteBackNotLine = 2344, + HomeDisplay = 2345, + HomeDisplayExtend = 2346, + LineEndDisplay = 2347, + LineEndDisplayExtend = 2348, + HomeWrap = 2349, + HomeWrapExtend = 2450, + LineEndWrap = 2451, + LineEndWrapExtend = 2452, + VCHomeWrap = 2453, + VCHomeWrapExtend = 2454, + LineCopy = 2455, + MoveCaretInsideView = 2401, + LineLength = 2350, + BraceHighlight = 2351, + BraceHighlightIndicator = 2498, + BraceBadLight = 2352, + BraceBadLightIndicator = 2499, + BraceMatch = 2353, + BraceMatchNext = 2369, + GetViewEOL = 2355, + SetViewEOL = 2356, + GetDocPointer = 2357, + SetDocPointer = 2358, + SetModEventMask = 2359, + GetEdgeColumn = 2360, + SetEdgeColumn = 2361, + GetEdgeMode = 2362, + SetEdgeMode = 2363, + GetEdgeColour = 2364, + SetEdgeColour = 2365, + MultiEdgeAddLine = 2694, + MultiEdgeClearAll = 2695, + GetMultiEdgeColumn = 2749, + SearchAnchor = 2366, + SearchNext = 2367, + SearchPrev = 2368, + LinesOnScreen = 2370, + UsePopUp = 2371, + SelectionIsRectangle = 2372, + SetZoom = 2373, + GetZoom = 2374, + CreateDocument = 2375, + AddRefDocument = 2376, + ReleaseDocument = 2377, + GetDocumentOptions = 2379, + GetModEventMask = 2378, + SetCommandEvents = 2717, + GetCommandEvents = 2718, + SetFocus = 2380, + GetFocus = 2381, + SetStatus = 2382, + GetStatus = 2383, + SetMouseDownCaptures = 2384, + GetMouseDownCaptures = 2385, + SetMouseWheelCaptures = 2696, + GetMouseWheelCaptures = 2697, + SetCursor = 2386, + GetCursor = 2387, + SetControlCharSymbol = 2388, + GetControlCharSymbol = 2389, + WordPartLeft = 2390, + WordPartLeftExtend = 2391, + WordPartRight = 2392, + WordPartRightExtend = 2393, + SetVisiblePolicy = 2394, + DelLineLeft = 2395, + DelLineRight = 2396, + SetXOffset = 2397, + GetXOffset = 2398, + ChooseCaretX = 2399, + GrabFocus = 2400, + SetXCaretPolicy = 2402, + SetYCaretPolicy = 2403, + SetPrintWrapMode = 2406, + GetPrintWrapMode = 2407, + SetHotspotActiveFore = 2410, + GetHotspotActiveFore = 2494, + SetHotspotActiveBack = 2411, + GetHotspotActiveBack = 2495, + SetHotspotActiveUnderline = 2412, + GetHotspotActiveUnderline = 2496, + SetHotspotSingleLine = 2421, + GetHotspotSingleLine = 2497, + ParaDown = 2413, + ParaDownExtend = 2414, + ParaUp = 2415, + ParaUpExtend = 2416, + PositionBefore = 2417, + PositionAfter = 2418, + PositionRelative = 2670, + PositionRelativeCodeUnits = 2716, + CopyRange = 2419, + CopyText = 2420, + SetSelectionMode = 2422, + GetSelectionMode = 2423, + GetMoveExtendsSelection = 2706, + GetLineSelStartPosition = 2424, + GetLineSelEndPosition = 2425, + LineDownRectExtend = 2426, + LineUpRectExtend = 2427, + CharLeftRectExtend = 2428, + CharRightRectExtend = 2429, + HomeRectExtend = 2430, + VCHomeRectExtend = 2431, + LineEndRectExtend = 2432, + PageUpRectExtend = 2433, + PageDownRectExtend = 2434, + StutteredPageUp = 2435, + StutteredPageUpExtend = 2436, + StutteredPageDown = 2437, + StutteredPageDownExtend = 2438, + WordLeftEnd = 2439, + WordLeftEndExtend = 2440, + WordRightEnd = 2441, + WordRightEndExtend = 2442, + SetWhitespaceChars = 2443, + GetWhitespaceChars = 2647, + SetPunctuationChars = 2648, + GetPunctuationChars = 2649, + SetCharsDefault = 2444, + AutoCGetCurrent = 2445, + AutoCGetCurrentText = 2610, + AutoCSetCaseInsensitiveBehaviour = 2634, + AutoCGetCaseInsensitiveBehaviour = 2635, + AutoCSetMulti = 2636, + AutoCGetMulti = 2637, + AutoCSetOrder = 2660, + AutoCGetOrder = 2661, + Allocate = 2446, + TargetAsUTF8 = 2447, + SetLengthForEncode = 2448, + EncodedFromUTF8 = 2449, + FindColumn = 2456, + GetCaretSticky = 2457, + SetCaretSticky = 2458, + ToggleCaretSticky = 2459, + SetPasteConvertEndings = 2467, + GetPasteConvertEndings = 2468, + ReplaceRectangular = 2771, + SelectionDuplicate = 2469, + SetCaretLineBackAlpha = 2470, + GetCaretLineBackAlpha = 2471, + SetCaretStyle = 2512, + GetCaretStyle = 2513, + SetIndicatorCurrent = 2500, + GetIndicatorCurrent = 2501, + SetIndicatorValue = 2502, + GetIndicatorValue = 2503, + IndicatorFillRange = 2504, + IndicatorClearRange = 2505, + IndicatorAllOnFor = 2506, + IndicatorValueAt = 2507, + IndicatorStart = 2508, + IndicatorEnd = 2509, + SetPositionCache = 2514, + GetPositionCache = 2515, + CopyAllowLine = 2519, + GetCharacterPointer = 2520, + GetRangePointer = 2643, + GetGapPosition = 2644, + IndicSetAlpha = 2523, + IndicGetAlpha = 2524, + IndicSetOutlineAlpha = 2558, + IndicGetOutlineAlpha = 2559, + SetExtraAscent = 2525, + GetExtraAscent = 2526, + SetExtraDescent = 2527, + GetExtraDescent = 2528, + MarkerSymbolDefined = 2529, + MarginSetText = 2530, + MarginGetText = 2531, + MarginSetStyle = 2532, + MarginGetStyle = 2533, + MarginSetStyles = 2534, + MarginGetStyles = 2535, + MarginTextClearAll = 2536, + MarginSetStyleOffset = 2537, + MarginGetStyleOffset = 2538, + SetMarginOptions = 2539, + GetMarginOptions = 2557, + AnnotationSetText = 2540, + AnnotationGetText = 2541, + AnnotationSetStyle = 2542, + AnnotationGetStyle = 2543, + AnnotationSetStyles = 2544, + AnnotationGetStyles = 2545, + AnnotationGetLines = 2546, + AnnotationClearAll = 2547, + AnnotationSetVisible = 2548, + AnnotationGetVisible = 2549, + AnnotationSetStyleOffset = 2550, + AnnotationGetStyleOffset = 2551, + ReleaseAllExtendedStyles = 2552, + AllocateExtendedStyles = 2553, + AddUndoAction = 2560, + CharPositionFromPoint = 2561, + CharPositionFromPointClose = 2562, + SetMouseSelectionRectangularSwitch = 2668, + GetMouseSelectionRectangularSwitch = 2669, + SetMultipleSelection = 2563, + GetMultipleSelection = 2564, + SetAdditionalSelectionTyping = 2565, + GetAdditionalSelectionTyping = 2566, + SetAdditionalCaretsBlink = 2567, + GetAdditionalCaretsBlink = 2568, + SetAdditionalCaretsVisible = 2608, + GetAdditionalCaretsVisible = 2609, + GetSelections = 2570, + GetSelectionEmpty = 2650, + ClearSelections = 2571, + SetSelection = 2572, + AddSelection = 2573, + DropSelectionN = 2671, + SetMainSelection = 2574, + GetMainSelection = 2575, + SetSelectionNCaret = 2576, + GetSelectionNCaret = 2577, + SetSelectionNAnchor = 2578, + GetSelectionNAnchor = 2579, + SetSelectionNCaretVirtualSpace = 2580, + GetSelectionNCaretVirtualSpace = 2581, + SetSelectionNAnchorVirtualSpace = 2582, + GetSelectionNAnchorVirtualSpace = 2583, + SetSelectionNStart = 2584, + GetSelectionNStart = 2585, + GetSelectionNStartVirtualSpace = 2726, + SetSelectionNEnd = 2586, + GetSelectionNEndVirtualSpace = 2727, + GetSelectionNEnd = 2587, + SetRectangularSelectionCaret = 2588, + GetRectangularSelectionCaret = 2589, + SetRectangularSelectionAnchor = 2590, + GetRectangularSelectionAnchor = 2591, + SetRectangularSelectionCaretVirtualSpace = 2592, + GetRectangularSelectionCaretVirtualSpace = 2593, + SetRectangularSelectionAnchorVirtualSpace = 2594, + GetRectangularSelectionAnchorVirtualSpace = 2595, + SetVirtualSpaceOptions = 2596, + GetVirtualSpaceOptions = 2597, + SetRectangularSelectionModifier = 2598, + GetRectangularSelectionModifier = 2599, + SetAdditionalSelFore = 2600, + SetAdditionalSelBack = 2601, + SetAdditionalSelAlpha = 2602, + GetAdditionalSelAlpha = 2603, + SetAdditionalCaretFore = 2604, + GetAdditionalCaretFore = 2605, + RotateSelection = 2606, + SwapMainAnchorCaret = 2607, + MultipleSelectAddNext = 2688, + MultipleSelectAddEach = 2689, + ChangeLexerState = 2617, + ContractedFoldNext = 2618, + VerticalCentreCaret = 2619, + MoveSelectedLinesUp = 2620, + MoveSelectedLinesDown = 2621, + SetIdentifier = 2622, + GetIdentifier = 2623, + RGBAImageSetWidth = 2624, + RGBAImageSetHeight = 2625, + RGBAImageSetScale = 2651, + MarkerDefineRGBAImage = 2626, + RegisterRGBAImage = 2627, + ScrollToStart = 2628, + ScrollToEnd = 2629, + SetTechnology = 2630, + GetTechnology = 2631, + CreateLoader = 2632, + FindIndicatorShow = 2640, + FindIndicatorFlash = 2641, + FindIndicatorHide = 2642, + VCHomeDisplay = 2652, + VCHomeDisplayExtend = 2653, + GetCaretLineVisibleAlways = 2654, + SetCaretLineVisibleAlways = 2655, + SetLineEndTypesAllowed = 2656, + GetLineEndTypesAllowed = 2657, + GetLineEndTypesActive = 2658, + SetRepresentation = 2665, + GetRepresentation = 2666, + ClearRepresentation = 2667, + ClearAllRepresentations = 2770, + SetRepresentationAppearance = 2766, + GetRepresentationAppearance = 2767, + SetRepresentationColour = 2768, + GetRepresentationColour = 2769, + EOLAnnotationSetText = 2740, + EOLAnnotationGetText = 2741, + EOLAnnotationSetStyle = 2742, + EOLAnnotationGetStyle = 2743, + EOLAnnotationClearAll = 2744, + EOLAnnotationSetVisible = 2745, + EOLAnnotationGetVisible = 2746, + EOLAnnotationSetStyleOffset = 2747, + EOLAnnotationGetStyleOffset = 2748, + SupportsFeature = 2750, + GetLineCharacterIndex = 2710, + AllocateLineCharacterIndex = 2711, + ReleaseLineCharacterIndex = 2712, + LineFromIndexPosition = 2713, + IndexPositionFromLine = 2714, + StartRecord = 3001, + StopRecord = 3002, + GetLexer = 4002, + Colourise = 4003, + SetProperty = 4004, + SetKeyWords = 4005, + GetProperty = 4008, + GetPropertyExpanded = 4009, + GetPropertyInt = 4010, + GetLexerLanguage = 4012, + PrivateLexerCall = 4013, + PropertyNames = 4014, + PropertyType = 4015, + DescribeProperty = 4016, + DescribeKeyWordSets = 4017, + GetLineEndTypesSupported = 4018, + AllocateSubStyles = 4020, + GetSubStylesStart = 4021, + GetSubStylesLength = 4022, + GetStyleFromSubStyle = 4027, + GetPrimaryStyleFromStyle = 4028, + FreeSubStyles = 4023, + SetIdentifiers = 4024, + DistanceToSecondaryStyles = 4025, + GetSubStyleBases = 4026, + GetNamedStyles = 4029, + NameOfStyle = 4030, + TagsOfStyle = 4031, + DescriptionOfStyle = 4032, + SetILexer = 4033, + GetBidirectional = 2708, + SetBidirectional = 2709, +}; +//--Autogenerated -- end of section automatically generated from Scintilla.iface + +} + +#endif diff --git a/scintilla/include/ScintillaStructures.h b/scintilla/include/ScintillaStructures.h new file mode 100644 index 0000000000..6bd16e8c1b --- /dev/null +++ b/scintilla/include/ScintillaStructures.h @@ -0,0 +1,103 @@ +// Scintilla source code edit control +/** @file ScintillaStructures.h + ** Structures used to communicate with Scintilla. + ** The same structures are defined for C in Scintilla.h. + ** Uses definitions from ScintillaTypes.h. + **/ +// Copyright 2021 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef SCINTILLASTRUCTURES_H +#define SCINTILLASTRUCTURES_H + +namespace Scintilla { + +using PositionCR = long; + +struct CharacterRange { + PositionCR cpMin; + PositionCR cpMax; +}; + +struct TextRange { + CharacterRange chrg; + char *lpstrText; +}; + +struct TextToFind { + CharacterRange chrg; + const char *lpstrText; + CharacterRange chrgText; +}; + +using SurfaceID = void *; + +struct Rectangle { + int left; + int top; + int right; + int bottom; +}; + +/* This structure is used in printing. Not needed by most client code. */ + +struct RangeToFormat { + SurfaceID hdc; + SurfaceID hdcTarget; + Rectangle rc; + Rectangle rcPage; + CharacterRange chrg; +}; + +struct NotifyHeader { + /* Compatible with Windows NMHDR. + * hwndFrom is really an environment specific window handle or pointer + * but most clients of Scintilla.h do not have this type visible. */ + void *hwndFrom; + uptr_t idFrom; + Notification code; +}; + +struct NotificationData { + NotifyHeader nmhdr; + Position position; + /* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */ + /* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */ + /* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */ + /* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ + /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */ + + int ch; + /* SCN_CHARADDED, SCN_KEY, SCN_AUTOCCOMPLETED, SCN_AUTOCSELECTION, */ + /* SCN_USERLISTSELECTION */ + KeyMod modifiers; + /* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */ + /* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ + + ModificationFlags modificationType; /* SCN_MODIFIED */ + const char *text; + /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */ + + Position length; /* SCN_MODIFIED */ + Position linesAdded; /* SCN_MODIFIED */ + Message message; /* SCN_MACRORECORD */ + uptr_t wParam; /* SCN_MACRORECORD */ + sptr_t lParam; /* SCN_MACRORECORD */ + Position line; /* SCN_MODIFIED */ + FoldLevel foldLevelNow; /* SCN_MODIFIED */ + FoldLevel foldLevelPrev; /* SCN_MODIFIED */ + int margin; /* SCN_MARGINCLICK */ + int listType; /* SCN_USERLISTSELECTION */ + int x; /* SCN_DWELLSTART, SCN_DWELLEND */ + int y; /* SCN_DWELLSTART, SCN_DWELLEND */ + int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */ + Position annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */ + Update updated; /* SCN_UPDATEUI */ + CompletionMethods listCompletionMethod; + /* SCN_AUTOCSELECTION, SCN_AUTOCCOMPLETED, SCN_USERLISTSELECTION, */ + CharacterSource characterSource; /* SCN_CHARADDED */ +}; + +} + +#endif diff --git a/scintilla/include/ScintillaTypes.h b/scintilla/include/ScintillaTypes.h new file mode 100644 index 0000000000..830ccadba5 --- /dev/null +++ b/scintilla/include/ScintillaTypes.h @@ -0,0 +1,803 @@ +// Scintilla source code edit control +/** @file ScintillaTypes.h + ** Types used to communicate with Scintilla. + **/ +// Copyright 1998-2019 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +/* Most of this file is automatically generated from the Scintilla.iface interface definition + * file which contains any comments about the definitions. ScintillaAPIFacer.py does the generation. */ + +#ifndef SCINTILLATYPES_H +#define SCINTILLATYPES_H + +namespace Scintilla { + +// Enumerations +//++Autogenerated -- start of section automatically generated from Scintilla.iface + +enum class WhiteSpace { + Invisible = 0, + VisibleAlways = 1, + VisibleAfterIndent = 2, + VisibleOnlyInIndent = 3, +}; + +enum class TabDrawMode { + LongArrow = 0, + StrikeOut = 1, +}; + +enum class EndOfLine { + CrLf = 0, + Cr = 1, + Lf = 2, +}; + +enum class IMEInteraction { + Windowed = 0, + Inline = 1, +}; + +enum class Alpha { + Transparent = 0, + Opaque = 255, + NoAlpha = 256, +}; + +enum class CursorShape { + Normal = -1, + Arrow = 2, + Wait = 4, + ReverseArrow = 7, +}; + +enum class MarkerSymbol { + Circle = 0, + RoundRect = 1, + Arrow = 2, + SmallRect = 3, + ShortArrow = 4, + Empty = 5, + ArrowDown = 6, + Minus = 7, + Plus = 8, + VLine = 9, + LCorner = 10, + TCorner = 11, + BoxPlus = 12, + BoxPlusConnected = 13, + BoxMinus = 14, + BoxMinusConnected = 15, + LCornerCurve = 16, + TCornerCurve = 17, + CirclePlus = 18, + CirclePlusConnected = 19, + CircleMinus = 20, + CircleMinusConnected = 21, + Background = 22, + DotDotDot = 23, + Arrows = 24, + Pixmap = 25, + FullRect = 26, + LeftRect = 27, + Available = 28, + Underline = 29, + RgbaImage = 30, + Bookmark = 31, + VerticalBookmark = 32, + Character = 10000, +}; + +enum class MarkerOutline { + FolderEnd = 25, + FolderOpenMid = 26, + FolderMidTail = 27, + FolderTail = 28, + FolderSub = 29, + Folder = 30, + FolderOpen = 31, +}; + +enum class MarginType { + Symbol = 0, + Number = 1, + Back = 2, + Fore = 3, + Text = 4, + RText = 5, + Colour = 6, +}; + +enum class StylesCommon { + Default = 32, + LineNumber = 33, + BraceLight = 34, + BraceBad = 35, + ControlChar = 36, + IndentGuide = 37, + CallTip = 38, + FoldDisplayText = 39, + LastPredefined = 39, + Max = 255, +}; + +enum class CharacterSet { + Ansi = 0, + Default = 1, + Baltic = 186, + ChineseBig5 = 136, + EastEurope = 238, + GB2312 = 134, + Greek = 161, + Hangul = 129, + Mac = 77, + Oem = 255, + Russian = 204, + Oem866 = 866, + Cyrillic = 1251, + ShiftJis = 128, + Symbol = 2, + Turkish = 162, + Johab = 130, + Hebrew = 177, + Arabic = 178, + Vietnamese = 163, + Thai = 222, + Iso8859_15 = 1000, +}; + +enum class CaseVisible { + Mixed = 0, + Upper = 1, + Lower = 2, + Camel = 3, +}; + +enum class FontWeight { + Normal = 400, + SemiBold = 600, + Bold = 700, +}; + +enum class Element { + List = 0, + ListBack = 1, + ListSelected = 2, + ListSelectedBack = 3, + SelectionText = 10, + SelectionBack = 11, + SelectionAdditionalText = 12, + SelectionAdditionalBack = 13, + SelectionSecondaryText = 14, + SelectionSecondaryBack = 15, + SelectionInactiveText = 16, + SelectionInactiveBack = 17, + Caret = 40, + CaretAdditional = 41, + CaretLineBack = 50, + WhiteSpace = 60, + WhiteSpaceBack = 61, + HotSpotActive = 70, + HotSpotActiveBack = 71, +}; + +enum class Layer { + Base = 0, + UnderText = 1, + OverText = 2, +}; + +enum class IndicatorStyle { + Plain = 0, + Squiggle = 1, + TT = 2, + Diagonal = 3, + Strike = 4, + Hidden = 5, + Box = 6, + RoundBox = 7, + StraightBox = 8, + Dash = 9, + Dots = 10, + SquiggleLow = 11, + DotBox = 12, + SquigglePixmap = 13, + CompositionThick = 14, + CompositionThin = 15, + FullBox = 16, + TextFore = 17, + Point = 18, + PointCharacter = 19, + Gradient = 20, + GradientCentre = 21, +}; + +enum class IndicatorNumbers { + Container = 8, + Ime = 32, + ImeMax = 35, + Max = 35, +}; + +enum class IndicValue { + Bit = 0x1000000, + Mask = 0xFFFFFF, +}; + +enum class IndicFlag { + None = 0, + ValueFore = 1, +}; + +enum class AutoCompleteOption { + Normal = 0, + FixedSize = 1, +}; + +enum class IndentView { + None = 0, + Real = 1, + LookForward = 2, + LookBoth = 3, +}; + +enum class PrintOption { + Normal = 0, + InvertLight = 1, + BlackOnWhite = 2, + ColourOnWhite = 3, + ColourOnWhiteDefaultBG = 4, + ScreenColours = 5, +}; + +enum class FindOption { + None = 0x0, + WholeWord = 0x2, + MatchCase = 0x4, + WordStart = 0x00100000, + RegExp = 0x00200000, + Posix = 0x00400000, + Cxx11RegEx = 0x00800000, +}; + +enum class FoldLevel { + None = 0x0, + Base = 0x400, + WhiteFlag = 0x1000, + HeaderFlag = 0x2000, + NumberMask = 0x0FFF, +}; + +enum class FoldDisplayTextStyle { + Hidden = 0, + Standard = 1, + Boxed = 2, +}; + +enum class FoldAction { + Contract = 0, + Expand = 1, + Toggle = 2, +}; + +enum class AutomaticFold { + None = 0x0000, + Show = 0x0001, + Click = 0x0002, + Change = 0x0004, +}; + +enum class FoldFlag { + None = 0x0000, + LineBeforeExpanded = 0x0002, + LineBeforeContracted = 0x0004, + LineAfterExpanded = 0x0008, + LineAfterContracted = 0x0010, + LevelNumbers = 0x0040, + LineState = 0x0080, +}; + +enum class IdleStyling { + None = 0, + ToVisible = 1, + AfterVisible = 2, + All = 3, +}; + +enum class Wrap { + None = 0, + Word = 1, + Char = 2, + WhiteSpace = 3, +}; + +enum class WrapVisualFlag { + None = 0x0000, + End = 0x0001, + Start = 0x0002, + Margin = 0x0004, +}; + +enum class WrapVisualLocation { + Default = 0x0000, + EndByText = 0x0001, + StartByText = 0x0002, +}; + +enum class WrapIndentMode { + Fixed = 0, + Same = 1, + Indent = 2, + DeepIndent = 3, +}; + +enum class LineCache { + None = 0, + Caret = 1, + Page = 2, + Document = 3, +}; + +enum class PhasesDraw { + One = 0, + Two = 1, + Multiple = 2, +}; + +enum class FontQuality { + QualityMask = 0xF, + QualityDefault = 0, + QualityNonAntialiased = 1, + QualityAntialiased = 2, + QualityLcdOptimized = 3, +}; + +enum class MultiPaste { + Once = 0, + Each = 1, +}; + +enum class Accessibility { + Disabled = 0, + Enabled = 1, +}; + +enum class EdgeVisualStyle { + None = 0, + Line = 1, + Background = 2, + MultiLine = 3, +}; + +enum class PopUp { + Never = 0, + All = 1, + Text = 2, +}; + +enum class DocumentOption { + Default = 0, + StylesNone = 0x1, + TextLarge = 0x100, +}; + +enum class Status { + Ok = 0, + Failure = 1, + BadAlloc = 2, + WarnStart = 1000, + RegEx = 1001, +}; + +enum class VisiblePolicy { + Slop = 0x01, + Strict = 0x04, +}; + +enum class CaretPolicy { + Slop = 0x01, + Strict = 0x04, + Jumps = 0x10, + Even = 0x08, +}; + +enum class SelectionMode { + Stream = 0, + Rectangle = 1, + Lines = 2, + Thin = 3, +}; + +enum class CaseInsensitiveBehaviour { + RespectCase = 0, + IgnoreCase = 1, +}; + +enum class MultiAutoComplete { + Once = 0, + Each = 1, +}; + +enum class Ordering { + PreSorted = 0, + PerformSort = 1, + Custom = 2, +}; + +enum class CaretSticky { + Off = 0, + On = 1, + WhiteSpace = 2, +}; + +enum class CaretStyle { + Invisible = 0, + Line = 1, + Block = 2, + OverstrikeBar = 0, + OverstrikeBlock = 0x10, + InsMask = 0xF, + BlockAfter = 0x100, +}; + +enum class MarginOption { + None = 0, + SubLineSelect = 1, +}; + +enum class AnnotationVisible { + Hidden = 0, + Standard = 1, + Boxed = 2, + Indented = 3, +}; + +enum class UndoFlags { + None = 0, + MayCoalesce = 1, +}; + +enum class VirtualSpace { + None = 0, + RectangularSelection = 1, + UserAccessible = 2, + NoWrapLineStart = 4, +}; + +enum class Technology { + Default = 0, + DirectWrite = 1, + DirectWriteRetain = 2, + DirectWriteDC = 3, +}; + +enum class LineEndType { + Default = 0, + Unicode = 1, +}; + +enum class RepresentationAppearance { + Plain = 0, + Blob = 1, + Colour = 0x10, +}; + +enum class EOLAnnotationVisible { + Hidden = 0x0, + Standard = 0x1, + Boxed = 0x2, + Stadium = 0x100, + FlatCircle = 0x101, + AngleCircle = 0x102, + CircleFlat = 0x110, + Flats = 0x111, + AngleFlat = 0x112, + CircleAngle = 0x120, + FlatAngle = 0x121, + Angles = 0x122, +}; + +enum class Supports { + LineDrawsFinal = 0, + PixelDivisions = 1, + FractionalStrokeWidth = 2, + TranslucentStroke = 3, + PixelModification = 4, +}; + +enum class LineCharacterIndexType { + None = 0, + Utf32 = 1, + Utf16 = 2, +}; + +enum class TypeProperty { + Boolean = 0, + Integer = 1, + String = 2, +}; + +enum class ModificationFlags { + None = 0x0, + InsertText = 0x1, + DeleteText = 0x2, + ChangeStyle = 0x4, + ChangeFold = 0x8, + User = 0x10, + Undo = 0x20, + Redo = 0x40, + MultiStepUndoRedo = 0x80, + LastStepInUndoRedo = 0x100, + ChangeMarker = 0x200, + BeforeInsert = 0x400, + BeforeDelete = 0x800, + MultilineUndoRedo = 0x1000, + StartAction = 0x2000, + ChangeIndicator = 0x4000, + ChangeLineState = 0x8000, + ChangeMargin = 0x10000, + ChangeAnnotation = 0x20000, + Container = 0x40000, + LexerState = 0x80000, + InsertCheck = 0x100000, + ChangeTabStops = 0x200000, + ChangeEOLAnnotation = 0x400000, + EventMaskAll = 0x7FFFFF, +}; + +enum class Update { + None = 0x0, + Content = 0x1, + Selection = 0x2, + VScroll = 0x4, + HScroll = 0x8, +}; + +enum class FocusChange { + Change = 768, + Setfocus = 512, + Killfocus = 256, +}; + +enum class Keys { + Down = 300, + Up = 301, + Left = 302, + Right = 303, + Home = 304, + End = 305, + Prior = 306, + Next = 307, + Delete = 308, + Insert = 309, + Escape = 7, + Back = 8, + Tab = 9, + Return = 13, + Add = 310, + Subtract = 311, + Divide = 312, + Win = 313, + RWin = 314, + Menu = 315, +}; + +enum class KeyMod { + Norm = 0, + Shift = 1, + Ctrl = 2, + Alt = 4, + Super = 8, + Meta = 16, +}; + +enum class CompletionMethods { + FillUp = 1, + DoubleClick = 2, + Tab = 3, + Newline = 4, + Command = 5, +}; + +enum class CharacterSource { + DirectInput = 0, + TentativeInput = 1, + ImeResult = 2, +}; + +enum class Bidirectional { + Disabled = 0, + L2R = 1, + R2L = 2, +}; + +enum class Notification { + StyleNeeded = 2000, + CharAdded = 2001, + SavePointReached = 2002, + SavePointLeft = 2003, + ModifyAttemptRO = 2004, + Key = 2005, + DoubleClick = 2006, + UpdateUI = 2007, + Modified = 2008, + MacroRecord = 2009, + MarginClick = 2010, + NeedShown = 2011, + Painted = 2013, + UserListSelection = 2014, + URIDropped = 2015, + DwellStart = 2016, + DwellEnd = 2017, + Zoom = 2018, + HotSpotClick = 2019, + HotSpotDoubleClick = 2020, + CallTipClick = 2021, + AutoCSelection = 2022, + IndicatorClick = 2023, + IndicatorRelease = 2024, + AutoCCancelled = 2025, + AutoCCharDeleted = 2026, + HotSpotReleaseClick = 2027, + FocusIn = 2028, + FocusOut = 2029, + AutoCCompleted = 2030, + MarginRightClick = 2031, + AutoCSelectionChange = 2032, +}; +//--Autogenerated -- end of section automatically generated from Scintilla.iface + +using Position = intptr_t; +using Line = intptr_t; +using Colour = int; +using ColourAlpha = int; +using uptr_t = uintptr_t; +using sptr_t = intptr_t; + +//++Autogenerated -- start of section automatically generated from Scintilla.iface +//**1 \(\*\n\) +constexpr Position InvalidPosition = -1; +constexpr int CpUtf8 = 65001; +constexpr int MarkerMax = 31; +constexpr int MaskFolders = 0xFE000000; +constexpr int MaxMargin = 4; +constexpr int FontSizeMultiplier = 100; +constexpr int TimeForever = 10000000; +constexpr int KeywordsetMax = 8; + +//--Autogenerated -- end of section automatically generated from Scintilla.iface + +constexpr int IndicatorMax = static_cast(IndicatorNumbers::Max); + +// Functions to manipulate fields from a MarkerOutline + +inline int operator<<(int i, MarkerOutline marker) noexcept { + return i << static_cast(marker); +} + +// Functions to manipulate fields from a FindOption + +constexpr FindOption operator|(FindOption a, FindOption b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +inline FindOption &operator|=(FindOption &self, FindOption a) noexcept { + self = self | a; + return self; +} + +// Functions to retrieve and manipulate fields from a FoldLevel + +constexpr FoldLevel operator&(FoldLevel lhs, FoldLevel rhs) noexcept { + return static_cast(static_cast(lhs) & static_cast(rhs)); +} + +constexpr FoldLevel LevelNumberPart(FoldLevel level) noexcept { + return level & FoldLevel::NumberMask; +} + +constexpr int LevelNumber(FoldLevel level) noexcept { + return static_cast(LevelNumberPart(level)); +} + +constexpr bool LevelIsHeader(FoldLevel level) noexcept { + return (level & FoldLevel::HeaderFlag) == FoldLevel::HeaderFlag; +} + +constexpr bool LevelIsWhitespace(FoldLevel level) noexcept { + return (level & FoldLevel::WhiteFlag) == FoldLevel::WhiteFlag; +} + +// Functions to manipulate fields from a FoldFlag + +constexpr FoldFlag operator|(FoldFlag a, FoldFlag b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +// Functions to manipulate fields from a FontQuality + +constexpr FontQuality operator&(FontQuality a, FontQuality b) noexcept { + return static_cast(static_cast(a) & static_cast(b)); +} + +// Functions to manipulate fields from a DocumentOption + +constexpr DocumentOption operator|(DocumentOption a, DocumentOption b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +// Functions to manipulate fields from a CaretPolicy + +constexpr CaretPolicy operator|(CaretPolicy a, CaretPolicy b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +// Functions to manipulate fields from a CaretStyle + +constexpr CaretStyle operator|(CaretStyle a, CaretStyle b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +constexpr CaretStyle operator&(CaretStyle a, CaretStyle b) noexcept { + return static_cast(static_cast(a) & static_cast(b)); +} + +// Functions to manipulate fields from a LineEndType + +constexpr LineEndType operator&(LineEndType a, LineEndType b) noexcept { + return static_cast(static_cast(a) & static_cast(b)); +} + +// Functions to manipulate fields from a RepresentationAppearance + +constexpr RepresentationAppearance operator|(RepresentationAppearance a, RepresentationAppearance b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +// Functions to manipulate fields from a LineCharacterIndexType + +constexpr LineCharacterIndexType operator|(LineCharacterIndexType a, LineCharacterIndexType b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +// Functions to manipulate fields from a ModificationFlags + +constexpr ModificationFlags operator|(ModificationFlags a, ModificationFlags b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +constexpr ModificationFlags operator&(ModificationFlags a, ModificationFlags b) noexcept { + return static_cast(static_cast(a) & static_cast(b)); +} + +inline ModificationFlags &operator|=(ModificationFlags &self, ModificationFlags a) noexcept { + self = self | a; + return self; +} + +// Functions to manipulate fields from a Update + +constexpr Update operator|(Update a, Update b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +// Functions to manipulate fields from a KeyMod + +constexpr KeyMod operator|(KeyMod a, KeyMod b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + +constexpr KeyMod operator&(KeyMod a, KeyMod b) noexcept { + return static_cast(static_cast(a) & static_cast(b)); +} + +// Test if an enum class value has some bit flag(s) of test set. +template +constexpr bool FlagSet(T value, T test) { + return (static_cast(value) & static_cast(test)) != 0; +} + +} + +#endif diff --git a/scintilla/julia_lexilla_v5.patch b/scintilla/julia_lexilla_v5.patch deleted file mode 100644 index 0b96180e0f..0000000000 --- a/scintilla/julia_lexilla_v5.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git a/lexilla/lexers/LexJulia.cxx b/geany/scintilla/lexers/LexJulia.cxx -index 6730074..ccf947d 100644 ---- a/lexilla/lexers/LexJulia.cxx -+++ b/geany/scintilla/lexers/LexJulia.cxx -@@ -39,7 +39,8 @@ - #include "DefaultLexer.h" - - using namespace Scintilla; --using namespace Lexilla; -+// Geany still uses Scintilla v3.5 -+//using namespace Lexilla; - - static const int MAX_JULIA_IDENT_CHARS = 1023; - -@@ -138,7 +139,9 @@ public: - delete this; - } - int SCI_METHOD Version() const override { -- return lvRelease5; -+ // Geany still uses Scintilla v3.5 -+ //return lvRelease5; -+ return lvIdentity; - } - const char * SCI_METHOD PropertyNames() override { - return osJulia.PropertyNames(); -@@ -163,7 +166,9 @@ public: - return 0; - } - -- static ILexer5 *LexerFactoryJulia() { -+ // Geany still uses Scintilla v3.5 -+ //static ILexer5 *LexerFactoryJulia() { -+ static ILexer *LexerFactoryJulia() { - return new LexerJulia(); - } - }; diff --git a/scintilla/lexilla/License.txt b/scintilla/lexilla/License.txt new file mode 100644 index 0000000000..e93ac62f2d --- /dev/null +++ b/scintilla/lexilla/License.txt @@ -0,0 +1,20 @@ +License for Lexilla, Scintilla, and SciTE + +Copyright 1998-2021 by Neil Hodgson + +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. + +NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/scintilla/lexilla/include/LexicalStyles.iface b/scintilla/lexilla/include/LexicalStyles.iface new file mode 100644 index 0000000000..6bd95368de --- /dev/null +++ b/scintilla/lexilla/include/LexicalStyles.iface @@ -0,0 +1,2252 @@ +## This file defines the interface to Lexilla + +## Copyright 2000-2020 by Neil Hodgson +## The License.txt file describes the conditions under which this software may be distributed. + +## Similar file structure as Scintilla.iface but only contains constants. + +cat Default + +################################################ +# For SciLexer.h +enu Lexer=SCLEX_ +val SCLEX_CONTAINER=0 +val SCLEX_NULL=1 +val SCLEX_PYTHON=2 +val SCLEX_CPP=3 +val SCLEX_HTML=4 +val SCLEX_XML=5 +val SCLEX_PERL=6 +val SCLEX_SQL=7 +val SCLEX_VB=8 +val SCLEX_PROPERTIES=9 +val SCLEX_ERRORLIST=10 +val SCLEX_MAKEFILE=11 +val SCLEX_BATCH=12 +val SCLEX_XCODE=13 +val SCLEX_LATEX=14 +val SCLEX_LUA=15 +val SCLEX_DIFF=16 +val SCLEX_CONF=17 +val SCLEX_PASCAL=18 +val SCLEX_AVE=19 +val SCLEX_ADA=20 +val SCLEX_LISP=21 +val SCLEX_RUBY=22 +val SCLEX_EIFFEL=23 +val SCLEX_EIFFELKW=24 +val SCLEX_TCL=25 +val SCLEX_NNCRONTAB=26 +val SCLEX_BULLANT=27 +val SCLEX_VBSCRIPT=28 +val SCLEX_BAAN=31 +val SCLEX_MATLAB=32 +val SCLEX_SCRIPTOL=33 +val SCLEX_ASM=34 +val SCLEX_CPPNOCASE=35 +val SCLEX_FORTRAN=36 +val SCLEX_F77=37 +val SCLEX_CSS=38 +val SCLEX_POV=39 +val SCLEX_LOUT=40 +val SCLEX_ESCRIPT=41 +val SCLEX_PS=42 +val SCLEX_NSIS=43 +val SCLEX_MMIXAL=44 +val SCLEX_CLW=45 +val SCLEX_CLWNOCASE=46 +val SCLEX_LOT=47 +val SCLEX_YAML=48 +val SCLEX_TEX=49 +val SCLEX_METAPOST=50 +val SCLEX_POWERBASIC=51 +val SCLEX_FORTH=52 +val SCLEX_ERLANG=53 +val SCLEX_OCTAVE=54 +val SCLEX_MSSQL=55 +val SCLEX_VERILOG=56 +val SCLEX_KIX=57 +val SCLEX_GUI4CLI=58 +val SCLEX_SPECMAN=59 +val SCLEX_AU3=60 +val SCLEX_APDL=61 +val SCLEX_BASH=62 +val SCLEX_ASN1=63 +val SCLEX_VHDL=64 +val SCLEX_CAML=65 +val SCLEX_BLITZBASIC=66 +val SCLEX_PUREBASIC=67 +val SCLEX_HASKELL=68 +val SCLEX_PHPSCRIPT=69 +val SCLEX_TADS3=70 +val SCLEX_REBOL=71 +val SCLEX_SMALLTALK=72 +val SCLEX_FLAGSHIP=73 +val SCLEX_CSOUND=74 +val SCLEX_FREEBASIC=75 +val SCLEX_INNOSETUP=76 +val SCLEX_OPAL=77 +val SCLEX_SPICE=78 +val SCLEX_D=79 +val SCLEX_CMAKE=80 +val SCLEX_GAP=81 +val SCLEX_PLM=82 +val SCLEX_PROGRESS=83 +val SCLEX_ABAQUS=84 +val SCLEX_ASYMPTOTE=85 +val SCLEX_R=86 +val SCLEX_MAGIK=87 +val SCLEX_POWERSHELL=88 +val SCLEX_MYSQL=89 +val SCLEX_PO=90 +val SCLEX_TAL=91 +val SCLEX_COBOL=92 +val SCLEX_TACL=93 +val SCLEX_SORCUS=94 +val SCLEX_POWERPRO=95 +val SCLEX_NIMROD=96 +val SCLEX_SML=97 +val SCLEX_MARKDOWN=98 +val SCLEX_TXT2TAGS=99 +val SCLEX_A68K=100 +val SCLEX_MODULA=101 +val SCLEX_COFFEESCRIPT=102 +val SCLEX_TCMD=103 +val SCLEX_AVS=104 +val SCLEX_ECL=105 +val SCLEX_OSCRIPT=106 +val SCLEX_VISUALPROLOG=107 +val SCLEX_LITERATEHASKELL=108 +val SCLEX_STTXT=109 +val SCLEX_KVIRC=110 +val SCLEX_RUST=111 +val SCLEX_DMAP=112 +val SCLEX_AS=113 +val SCLEX_DMIS=114 +val SCLEX_REGISTRY=115 +val SCLEX_BIBTEX=116 +val SCLEX_SREC=117 +val SCLEX_IHEX=118 +val SCLEX_TEHEX=119 +val SCLEX_JSON=120 +val SCLEX_EDIFACT=121 +val SCLEX_INDENT=122 +val SCLEX_MAXIMA=123 +val SCLEX_STATA=124 +val SCLEX_SAS=125 +val SCLEX_NIM=126 +val SCLEX_CIL=127 +val SCLEX_X12=128 +val SCLEX_DATAFLEX=129 +val SCLEX_HOLLYWOOD=130 +val SCLEX_RAKU=131 +val SCLEX_FSHARP=132 +val SCLEX_JULIA=133 + +# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a +# value assigned in sequence from SCLEX_AUTOMATIC+1. +val SCLEX_AUTOMATIC=1000 +# Lexical states for SCLEX_PYTHON +lex Python=SCLEX_PYTHON SCE_P_ +lex Nimrod=SCLEX_NIMROD SCE_P_ +val SCE_P_DEFAULT=0 +val SCE_P_COMMENTLINE=1 +val SCE_P_NUMBER=2 +val SCE_P_STRING=3 +val SCE_P_CHARACTER=4 +val SCE_P_WORD=5 +val SCE_P_TRIPLE=6 +val SCE_P_TRIPLEDOUBLE=7 +val SCE_P_CLASSNAME=8 +val SCE_P_DEFNAME=9 +val SCE_P_OPERATOR=10 +val SCE_P_IDENTIFIER=11 +val SCE_P_COMMENTBLOCK=12 +val SCE_P_STRINGEOL=13 +val SCE_P_WORD2=14 +val SCE_P_DECORATOR=15 +val SCE_P_FSTRING=16 +val SCE_P_FCHARACTER=17 +val SCE_P_FTRIPLE=18 +val SCE_P_FTRIPLEDOUBLE=19 +# Lexical states for SCLEX_CPP +# Lexical states for SCLEX_BULLANT +# Lexical states for SCLEX_COBOL +# Lexical states for SCLEX_TACL +# Lexical states for SCLEX_TAL +lex Cpp=SCLEX_CPP SCE_C_ +lex BullAnt=SCLEX_BULLANT SCE_C_ +lex COBOL=SCLEX_COBOL SCE_C_ +lex TACL=SCLEX_TACL SCE_C_ +lex TAL=SCLEX_TAL SCE_C_ +val SCE_C_DEFAULT=0 +val SCE_C_COMMENT=1 +val SCE_C_COMMENTLINE=2 +val SCE_C_COMMENTDOC=3 +val SCE_C_NUMBER=4 +val SCE_C_WORD=5 +val SCE_C_STRING=6 +val SCE_C_CHARACTER=7 +val SCE_C_UUID=8 +val SCE_C_PREPROCESSOR=9 +val SCE_C_OPERATOR=10 +val SCE_C_IDENTIFIER=11 +val SCE_C_STRINGEOL=12 +val SCE_C_VERBATIM=13 +val SCE_C_REGEX=14 +val SCE_C_COMMENTLINEDOC=15 +val SCE_C_WORD2=16 +val SCE_C_COMMENTDOCKEYWORD=17 +val SCE_C_COMMENTDOCKEYWORDERROR=18 +val SCE_C_GLOBALCLASS=19 +val SCE_C_STRINGRAW=20 +val SCE_C_TRIPLEVERBATIM=21 +val SCE_C_HASHQUOTEDSTRING=22 +val SCE_C_PREPROCESSORCOMMENT=23 +val SCE_C_PREPROCESSORCOMMENTDOC=24 +val SCE_C_USERLITERAL=25 +val SCE_C_TASKMARKER=26 +val SCE_C_ESCAPESEQUENCE=27 +# Lexical states for SCLEX_D +lex D=SCLEX_D SCE_D_ +val SCE_D_DEFAULT=0 +val SCE_D_COMMENT=1 +val SCE_D_COMMENTLINE=2 +val SCE_D_COMMENTDOC=3 +val SCE_D_COMMENTNESTED=4 +val SCE_D_NUMBER=5 +val SCE_D_WORD=6 +val SCE_D_WORD2=7 +val SCE_D_WORD3=8 +val SCE_D_TYPEDEF=9 +val SCE_D_STRING=10 +val SCE_D_STRINGEOL=11 +val SCE_D_CHARACTER=12 +val SCE_D_OPERATOR=13 +val SCE_D_IDENTIFIER=14 +val SCE_D_COMMENTLINEDOC=15 +val SCE_D_COMMENTDOCKEYWORD=16 +val SCE_D_COMMENTDOCKEYWORDERROR=17 +val SCE_D_STRINGB=18 +val SCE_D_STRINGR=19 +val SCE_D_WORD5=20 +val SCE_D_WORD6=21 +val SCE_D_WORD7=22 +# Lexical states for SCLEX_TCL +lex TCL=SCLEX_TCL SCE_TCL_ +val SCE_TCL_DEFAULT=0 +val SCE_TCL_COMMENT=1 +val SCE_TCL_COMMENTLINE=2 +val SCE_TCL_NUMBER=3 +val SCE_TCL_WORD_IN_QUOTE=4 +val SCE_TCL_IN_QUOTE=5 +val SCE_TCL_OPERATOR=6 +val SCE_TCL_IDENTIFIER=7 +val SCE_TCL_SUBSTITUTION=8 +val SCE_TCL_SUB_BRACE=9 +val SCE_TCL_MODIFIER=10 +val SCE_TCL_EXPAND=11 +val SCE_TCL_WORD=12 +val SCE_TCL_WORD2=13 +val SCE_TCL_WORD3=14 +val SCE_TCL_WORD4=15 +val SCE_TCL_WORD5=16 +val SCE_TCL_WORD6=17 +val SCE_TCL_WORD7=18 +val SCE_TCL_WORD8=19 +val SCE_TCL_COMMENT_BOX=20 +val SCE_TCL_BLOCK_COMMENT=21 +# Lexical states for SCLEX_HTML, SCLEX_XML +lex HTML=SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ +lex XML=SCLEX_XML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ +val SCE_H_DEFAULT=0 +val SCE_H_TAG=1 +val SCE_H_TAGUNKNOWN=2 +val SCE_H_ATTRIBUTE=3 +val SCE_H_ATTRIBUTEUNKNOWN=4 +val SCE_H_NUMBER=5 +val SCE_H_DOUBLESTRING=6 +val SCE_H_SINGLESTRING=7 +val SCE_H_OTHER=8 +val SCE_H_COMMENT=9 +val SCE_H_ENTITY=10 +# XML and ASP +val SCE_H_TAGEND=11 +val SCE_H_XMLSTART=12 +val SCE_H_XMLEND=13 +val SCE_H_SCRIPT=14 +val SCE_H_ASP=15 +val SCE_H_ASPAT=16 +val SCE_H_CDATA=17 +val SCE_H_QUESTION=18 +# More HTML +val SCE_H_VALUE=19 +# X-Code +val SCE_H_XCCOMMENT=20 +# SGML +val SCE_H_SGML_DEFAULT=21 +val SCE_H_SGML_COMMAND=22 +val SCE_H_SGML_1ST_PARAM=23 +val SCE_H_SGML_DOUBLESTRING=24 +val SCE_H_SGML_SIMPLESTRING=25 +val SCE_H_SGML_ERROR=26 +val SCE_H_SGML_SPECIAL=27 +val SCE_H_SGML_ENTITY=28 +val SCE_H_SGML_COMMENT=29 +val SCE_H_SGML_1ST_PARAM_COMMENT=30 +val SCE_H_SGML_BLOCK_DEFAULT=31 +# Embedded Javascript +val SCE_HJ_START=40 +val SCE_HJ_DEFAULT=41 +val SCE_HJ_COMMENT=42 +val SCE_HJ_COMMENTLINE=43 +val SCE_HJ_COMMENTDOC=44 +val SCE_HJ_NUMBER=45 +val SCE_HJ_WORD=46 +val SCE_HJ_KEYWORD=47 +val SCE_HJ_DOUBLESTRING=48 +val SCE_HJ_SINGLESTRING=49 +val SCE_HJ_SYMBOLS=50 +val SCE_HJ_STRINGEOL=51 +val SCE_HJ_REGEX=52 +# ASP Javascript +val SCE_HJA_START=55 +val SCE_HJA_DEFAULT=56 +val SCE_HJA_COMMENT=57 +val SCE_HJA_COMMENTLINE=58 +val SCE_HJA_COMMENTDOC=59 +val SCE_HJA_NUMBER=60 +val SCE_HJA_WORD=61 +val SCE_HJA_KEYWORD=62 +val SCE_HJA_DOUBLESTRING=63 +val SCE_HJA_SINGLESTRING=64 +val SCE_HJA_SYMBOLS=65 +val SCE_HJA_STRINGEOL=66 +val SCE_HJA_REGEX=67 +# Embedded VBScript +val SCE_HB_START=70 +val SCE_HB_DEFAULT=71 +val SCE_HB_COMMENTLINE=72 +val SCE_HB_NUMBER=73 +val SCE_HB_WORD=74 +val SCE_HB_STRING=75 +val SCE_HB_IDENTIFIER=76 +val SCE_HB_STRINGEOL=77 +# ASP VBScript +val SCE_HBA_START=80 +val SCE_HBA_DEFAULT=81 +val SCE_HBA_COMMENTLINE=82 +val SCE_HBA_NUMBER=83 +val SCE_HBA_WORD=84 +val SCE_HBA_STRING=85 +val SCE_HBA_IDENTIFIER=86 +val SCE_HBA_STRINGEOL=87 +# Embedded Python +val SCE_HP_START=90 +val SCE_HP_DEFAULT=91 +val SCE_HP_COMMENTLINE=92 +val SCE_HP_NUMBER=93 +val SCE_HP_STRING=94 +val SCE_HP_CHARACTER=95 +val SCE_HP_WORD=96 +val SCE_HP_TRIPLE=97 +val SCE_HP_TRIPLEDOUBLE=98 +val SCE_HP_CLASSNAME=99 +val SCE_HP_DEFNAME=100 +val SCE_HP_OPERATOR=101 +val SCE_HP_IDENTIFIER=102 +# PHP +val SCE_HPHP_COMPLEX_VARIABLE=104 +# ASP Python +val SCE_HPA_START=105 +val SCE_HPA_DEFAULT=106 +val SCE_HPA_COMMENTLINE=107 +val SCE_HPA_NUMBER=108 +val SCE_HPA_STRING=109 +val SCE_HPA_CHARACTER=110 +val SCE_HPA_WORD=111 +val SCE_HPA_TRIPLE=112 +val SCE_HPA_TRIPLEDOUBLE=113 +val SCE_HPA_CLASSNAME=114 +val SCE_HPA_DEFNAME=115 +val SCE_HPA_OPERATOR=116 +val SCE_HPA_IDENTIFIER=117 +# PHP +val SCE_HPHP_DEFAULT=118 +val SCE_HPHP_HSTRING=119 +val SCE_HPHP_SIMPLESTRING=120 +val SCE_HPHP_WORD=121 +val SCE_HPHP_NUMBER=122 +val SCE_HPHP_VARIABLE=123 +val SCE_HPHP_COMMENT=124 +val SCE_HPHP_COMMENTLINE=125 +val SCE_HPHP_HSTRING_VARIABLE=126 +val SCE_HPHP_OPERATOR=127 +# Lexical states for SCLEX_PERL +lex Perl=SCLEX_PERL SCE_PL_ +val SCE_PL_DEFAULT=0 +val SCE_PL_ERROR=1 +val SCE_PL_COMMENTLINE=2 +val SCE_PL_POD=3 +val SCE_PL_NUMBER=4 +val SCE_PL_WORD=5 +val SCE_PL_STRING=6 +val SCE_PL_CHARACTER=7 +val SCE_PL_PUNCTUATION=8 +val SCE_PL_PREPROCESSOR=9 +val SCE_PL_OPERATOR=10 +val SCE_PL_IDENTIFIER=11 +val SCE_PL_SCALAR=12 +val SCE_PL_ARRAY=13 +val SCE_PL_HASH=14 +val SCE_PL_SYMBOLTABLE=15 +val SCE_PL_VARIABLE_INDEXER=16 +val SCE_PL_REGEX=17 +val SCE_PL_REGSUBST=18 +val SCE_PL_LONGQUOTE=19 +val SCE_PL_BACKTICKS=20 +val SCE_PL_DATASECTION=21 +val SCE_PL_HERE_DELIM=22 +val SCE_PL_HERE_Q=23 +val SCE_PL_HERE_QQ=24 +val SCE_PL_HERE_QX=25 +val SCE_PL_STRING_Q=26 +val SCE_PL_STRING_QQ=27 +val SCE_PL_STRING_QX=28 +val SCE_PL_STRING_QR=29 +val SCE_PL_STRING_QW=30 +val SCE_PL_POD_VERB=31 +val SCE_PL_SUB_PROTOTYPE=40 +val SCE_PL_FORMAT_IDENT=41 +val SCE_PL_FORMAT=42 +val SCE_PL_STRING_VAR=43 +val SCE_PL_XLAT=44 +val SCE_PL_REGEX_VAR=54 +val SCE_PL_REGSUBST_VAR=55 +val SCE_PL_BACKTICKS_VAR=57 +val SCE_PL_HERE_QQ_VAR=61 +val SCE_PL_HERE_QX_VAR=62 +val SCE_PL_STRING_QQ_VAR=64 +val SCE_PL_STRING_QX_VAR=65 +val SCE_PL_STRING_QR_VAR=66 +# Lexical states for SCLEX_RUBY +lex Ruby=SCLEX_RUBY SCE_RB_ +val SCE_RB_DEFAULT=0 +val SCE_RB_ERROR=1 +val SCE_RB_COMMENTLINE=2 +val SCE_RB_POD=3 +val SCE_RB_NUMBER=4 +val SCE_RB_WORD=5 +val SCE_RB_STRING=6 +val SCE_RB_CHARACTER=7 +val SCE_RB_CLASSNAME=8 +val SCE_RB_DEFNAME=9 +val SCE_RB_OPERATOR=10 +val SCE_RB_IDENTIFIER=11 +val SCE_RB_REGEX=12 +val SCE_RB_GLOBAL=13 +val SCE_RB_SYMBOL=14 +val SCE_RB_MODULE_NAME=15 +val SCE_RB_INSTANCE_VAR=16 +val SCE_RB_CLASS_VAR=17 +val SCE_RB_BACKTICKS=18 +val SCE_RB_DATASECTION=19 +val SCE_RB_HERE_DELIM=20 +val SCE_RB_HERE_Q=21 +val SCE_RB_HERE_QQ=22 +val SCE_RB_HERE_QX=23 +val SCE_RB_STRING_Q=24 +val SCE_RB_STRING_QQ=25 +val SCE_RB_STRING_QX=26 +val SCE_RB_STRING_QR=27 +val SCE_RB_STRING_QW=28 +val SCE_RB_WORD_DEMOTED=29 +val SCE_RB_STDIN=30 +val SCE_RB_STDOUT=31 +val SCE_RB_STDERR=40 +val SCE_RB_UPPER_BOUND=41 +# Lexical states for SCLEX_VB, SCLEX_VBSCRIPT, SCLEX_POWERBASIC, SCLEX_BLITZBASIC, SCLEX_PUREBASIC, SCLEX_FREEBASIC +lex VB=SCLEX_VB SCE_B_ +lex VBScript=SCLEX_VBSCRIPT SCE_B_ +lex PowerBasic=SCLEX_POWERBASIC SCE_B_ +lex BlitzBasic=SCLEX_BLITZBASIC SCE_B_ +lex PureBasic=SCLEX_PUREBASIC SCE_B_ +lex FreeBasic=SCLEX_FREEBASIC SCE_B_ +val SCE_B_DEFAULT=0 +val SCE_B_COMMENT=1 +val SCE_B_NUMBER=2 +val SCE_B_KEYWORD=3 +val SCE_B_STRING=4 +val SCE_B_PREPROCESSOR=5 +val SCE_B_OPERATOR=6 +val SCE_B_IDENTIFIER=7 +val SCE_B_DATE=8 +val SCE_B_STRINGEOL=9 +val SCE_B_KEYWORD2=10 +val SCE_B_KEYWORD3=11 +val SCE_B_KEYWORD4=12 +val SCE_B_CONSTANT=13 +val SCE_B_ASM=14 +val SCE_B_LABEL=15 +val SCE_B_ERROR=16 +val SCE_B_HEXNUMBER=17 +val SCE_B_BINNUMBER=18 +val SCE_B_COMMENTBLOCK=19 +val SCE_B_DOCLINE=20 +val SCE_B_DOCBLOCK=21 +val SCE_B_DOCKEYWORD=22 +# Lexical states for SCLEX_PROPERTIES +lex Properties=SCLEX_PROPERTIES SCE_PROPS_ +val SCE_PROPS_DEFAULT=0 +val SCE_PROPS_COMMENT=1 +val SCE_PROPS_SECTION=2 +val SCE_PROPS_ASSIGNMENT=3 +val SCE_PROPS_DEFVAL=4 +val SCE_PROPS_KEY=5 +# Lexical states for SCLEX_LATEX +lex LaTeX=SCLEX_LATEX SCE_L_ +val SCE_L_DEFAULT=0 +val SCE_L_COMMAND=1 +val SCE_L_TAG=2 +val SCE_L_MATH=3 +val SCE_L_COMMENT=4 +val SCE_L_TAG2=5 +val SCE_L_MATH2=6 +val SCE_L_COMMENT2=7 +val SCE_L_VERBATIM=8 +val SCE_L_SHORTCMD=9 +val SCE_L_SPECIAL=10 +val SCE_L_CMDOPT=11 +val SCE_L_ERROR=12 +# Lexical states for SCLEX_LUA +lex Lua=SCLEX_LUA SCE_LUA_ +val SCE_LUA_DEFAULT=0 +val SCE_LUA_COMMENT=1 +val SCE_LUA_COMMENTLINE=2 +val SCE_LUA_COMMENTDOC=3 +val SCE_LUA_NUMBER=4 +val SCE_LUA_WORD=5 +val SCE_LUA_STRING=6 +val SCE_LUA_CHARACTER=7 +val SCE_LUA_LITERALSTRING=8 +val SCE_LUA_PREPROCESSOR=9 +val SCE_LUA_OPERATOR=10 +val SCE_LUA_IDENTIFIER=11 +val SCE_LUA_STRINGEOL=12 +val SCE_LUA_WORD2=13 +val SCE_LUA_WORD3=14 +val SCE_LUA_WORD4=15 +val SCE_LUA_WORD5=16 +val SCE_LUA_WORD6=17 +val SCE_LUA_WORD7=18 +val SCE_LUA_WORD8=19 +val SCE_LUA_LABEL=20 +# Lexical states for SCLEX_ERRORLIST +lex ErrorList=SCLEX_ERRORLIST SCE_ERR_ +val SCE_ERR_DEFAULT=0 +val SCE_ERR_PYTHON=1 +val SCE_ERR_GCC=2 +val SCE_ERR_MS=3 +val SCE_ERR_CMD=4 +val SCE_ERR_BORLAND=5 +val SCE_ERR_PERL=6 +val SCE_ERR_NET=7 +val SCE_ERR_LUA=8 +val SCE_ERR_CTAG=9 +val SCE_ERR_DIFF_CHANGED=10 +val SCE_ERR_DIFF_ADDITION=11 +val SCE_ERR_DIFF_DELETION=12 +val SCE_ERR_DIFF_MESSAGE=13 +val SCE_ERR_PHP=14 +val SCE_ERR_ELF=15 +val SCE_ERR_IFC=16 +val SCE_ERR_IFORT=17 +val SCE_ERR_ABSF=18 +val SCE_ERR_TIDY=19 +val SCE_ERR_JAVA_STACK=20 +val SCE_ERR_VALUE=21 +val SCE_ERR_GCC_INCLUDED_FROM=22 +val SCE_ERR_ESCSEQ=23 +val SCE_ERR_ESCSEQ_UNKNOWN=24 +val SCE_ERR_GCC_EXCERPT=25 +val SCE_ERR_ES_BLACK=40 +val SCE_ERR_ES_RED=41 +val SCE_ERR_ES_GREEN=42 +val SCE_ERR_ES_BROWN=43 +val SCE_ERR_ES_BLUE=44 +val SCE_ERR_ES_MAGENTA=45 +val SCE_ERR_ES_CYAN=46 +val SCE_ERR_ES_GRAY=47 +val SCE_ERR_ES_DARK_GRAY=48 +val SCE_ERR_ES_BRIGHT_RED=49 +val SCE_ERR_ES_BRIGHT_GREEN=50 +val SCE_ERR_ES_YELLOW=51 +val SCE_ERR_ES_BRIGHT_BLUE=52 +val SCE_ERR_ES_BRIGHT_MAGENTA=53 +val SCE_ERR_ES_BRIGHT_CYAN=54 +val SCE_ERR_ES_WHITE=55 +# Lexical states for SCLEX_BATCH +lex Batch=SCLEX_BATCH SCE_BAT_ +val SCE_BAT_DEFAULT=0 +val SCE_BAT_COMMENT=1 +val SCE_BAT_WORD=2 +val SCE_BAT_LABEL=3 +val SCE_BAT_HIDE=4 +val SCE_BAT_COMMAND=5 +val SCE_BAT_IDENTIFIER=6 +val SCE_BAT_OPERATOR=7 +# Lexical states for SCLEX_TCMD +lex TCMD=SCLEX_TCMD SCE_TCMD_ +val SCE_TCMD_DEFAULT=0 +val SCE_TCMD_COMMENT=1 +val SCE_TCMD_WORD=2 +val SCE_TCMD_LABEL=3 +val SCE_TCMD_HIDE=4 +val SCE_TCMD_COMMAND=5 +val SCE_TCMD_IDENTIFIER=6 +val SCE_TCMD_OPERATOR=7 +val SCE_TCMD_ENVIRONMENT=8 +val SCE_TCMD_EXPANSION=9 +val SCE_TCMD_CLABEL=10 +# Lexical states for SCLEX_MAKEFILE +lex MakeFile=SCLEX_MAKEFILE SCE_MAKE_ +val SCE_MAKE_DEFAULT=0 +val SCE_MAKE_COMMENT=1 +val SCE_MAKE_PREPROCESSOR=2 +val SCE_MAKE_IDENTIFIER=3 +val SCE_MAKE_OPERATOR=4 +val SCE_MAKE_TARGET=5 +val SCE_MAKE_IDEOL=9 +# Lexical states for SCLEX_DIFF +lex Diff=SCLEX_DIFF SCE_DIFF_ +val SCE_DIFF_DEFAULT=0 +val SCE_DIFF_COMMENT=1 +val SCE_DIFF_COMMAND=2 +val SCE_DIFF_HEADER=3 +val SCE_DIFF_POSITION=4 +val SCE_DIFF_DELETED=5 +val SCE_DIFF_ADDED=6 +val SCE_DIFF_CHANGED=7 +val SCE_DIFF_PATCH_ADD=8 +val SCE_DIFF_PATCH_DELETE=9 +val SCE_DIFF_REMOVED_PATCH_ADD=10 +val SCE_DIFF_REMOVED_PATCH_DELETE=11 +# Lexical states for SCLEX_CONF (Apache Configuration Files Lexer) +lex Conf=SCLEX_CONF SCE_CONF_ +val SCE_CONF_DEFAULT=0 +val SCE_CONF_COMMENT=1 +val SCE_CONF_NUMBER=2 +val SCE_CONF_IDENTIFIER=3 +val SCE_CONF_EXTENSION=4 +val SCE_CONF_PARAMETER=5 +val SCE_CONF_STRING=6 +val SCE_CONF_OPERATOR=7 +val SCE_CONF_IP=8 +val SCE_CONF_DIRECTIVE=9 +# Lexical states for SCLEX_AVE, Avenue +lex Avenue=SCLEX_AVE SCE_AVE_ +val SCE_AVE_DEFAULT=0 +val SCE_AVE_COMMENT=1 +val SCE_AVE_NUMBER=2 +val SCE_AVE_WORD=3 +val SCE_AVE_STRING=6 +val SCE_AVE_ENUM=7 +val SCE_AVE_STRINGEOL=8 +val SCE_AVE_IDENTIFIER=9 +val SCE_AVE_OPERATOR=10 +val SCE_AVE_WORD1=11 +val SCE_AVE_WORD2=12 +val SCE_AVE_WORD3=13 +val SCE_AVE_WORD4=14 +val SCE_AVE_WORD5=15 +val SCE_AVE_WORD6=16 +# Lexical states for SCLEX_ADA +lex Ada=SCLEX_ADA SCE_ADA_ +val SCE_ADA_DEFAULT=0 +val SCE_ADA_WORD=1 +val SCE_ADA_IDENTIFIER=2 +val SCE_ADA_NUMBER=3 +val SCE_ADA_DELIMITER=4 +val SCE_ADA_CHARACTER=5 +val SCE_ADA_CHARACTEREOL=6 +val SCE_ADA_STRING=7 +val SCE_ADA_STRINGEOL=8 +val SCE_ADA_LABEL=9 +val SCE_ADA_COMMENTLINE=10 +val SCE_ADA_ILLEGAL=11 +# Lexical states for SCLEX_BAAN +lex Baan=SCLEX_BAAN SCE_BAAN_ +val SCE_BAAN_DEFAULT=0 +val SCE_BAAN_COMMENT=1 +val SCE_BAAN_COMMENTDOC=2 +val SCE_BAAN_NUMBER=3 +val SCE_BAAN_WORD=4 +val SCE_BAAN_STRING=5 +val SCE_BAAN_PREPROCESSOR=6 +val SCE_BAAN_OPERATOR=7 +val SCE_BAAN_IDENTIFIER=8 +val SCE_BAAN_STRINGEOL=9 +val SCE_BAAN_WORD2=10 +val SCE_BAAN_WORD3=11 +val SCE_BAAN_WORD4=12 +val SCE_BAAN_WORD5=13 +val SCE_BAAN_WORD6=14 +val SCE_BAAN_WORD7=15 +val SCE_BAAN_WORD8=16 +val SCE_BAAN_WORD9=17 +val SCE_BAAN_TABLEDEF=18 +val SCE_BAAN_TABLESQL=19 +val SCE_BAAN_FUNCTION=20 +val SCE_BAAN_DOMDEF=21 +val SCE_BAAN_FUNCDEF=22 +val SCE_BAAN_OBJECTDEF=23 +val SCE_BAAN_DEFINEDEF=24 +# Lexical states for SCLEX_LISP +lex Lisp=SCLEX_LISP SCE_LISP_ +val SCE_LISP_DEFAULT=0 +val SCE_LISP_COMMENT=1 +val SCE_LISP_NUMBER=2 +val SCE_LISP_KEYWORD=3 +val SCE_LISP_KEYWORD_KW=4 +val SCE_LISP_SYMBOL=5 +val SCE_LISP_STRING=6 +val SCE_LISP_STRINGEOL=8 +val SCE_LISP_IDENTIFIER=9 +val SCE_LISP_OPERATOR=10 +val SCE_LISP_SPECIAL=11 +val SCE_LISP_MULTI_COMMENT=12 +# Lexical states for SCLEX_EIFFEL and SCLEX_EIFFELKW +lex Eiffel=SCLEX_EIFFEL SCE_EIFFEL_ +lex EiffelKW=SCLEX_EIFFELKW SCE_EIFFEL_ +val SCE_EIFFEL_DEFAULT=0 +val SCE_EIFFEL_COMMENTLINE=1 +val SCE_EIFFEL_NUMBER=2 +val SCE_EIFFEL_WORD=3 +val SCE_EIFFEL_STRING=4 +val SCE_EIFFEL_CHARACTER=5 +val SCE_EIFFEL_OPERATOR=6 +val SCE_EIFFEL_IDENTIFIER=7 +val SCE_EIFFEL_STRINGEOL=8 +# Lexical states for SCLEX_NNCRONTAB (nnCron crontab Lexer) +lex NNCronTab=SCLEX_NNCRONTAB SCE_NNCRONTAB_ +val SCE_NNCRONTAB_DEFAULT=0 +val SCE_NNCRONTAB_COMMENT=1 +val SCE_NNCRONTAB_TASK=2 +val SCE_NNCRONTAB_SECTION=3 +val SCE_NNCRONTAB_KEYWORD=4 +val SCE_NNCRONTAB_MODIFIER=5 +val SCE_NNCRONTAB_ASTERISK=6 +val SCE_NNCRONTAB_NUMBER=7 +val SCE_NNCRONTAB_STRING=8 +val SCE_NNCRONTAB_ENVIRONMENT=9 +val SCE_NNCRONTAB_IDENTIFIER=10 +# Lexical states for SCLEX_FORTH (Forth Lexer) +lex Forth=SCLEX_FORTH SCE_FORTH_ +val SCE_FORTH_DEFAULT=0 +val SCE_FORTH_COMMENT=1 +val SCE_FORTH_COMMENT_ML=2 +val SCE_FORTH_IDENTIFIER=3 +val SCE_FORTH_CONTROL=4 +val SCE_FORTH_KEYWORD=5 +val SCE_FORTH_DEFWORD=6 +val SCE_FORTH_PREWORD1=7 +val SCE_FORTH_PREWORD2=8 +val SCE_FORTH_NUMBER=9 +val SCE_FORTH_STRING=10 +val SCE_FORTH_LOCALE=11 +# Lexical states for SCLEX_MATLAB +lex MatLab=SCLEX_MATLAB SCE_MATLAB_ +val SCE_MATLAB_DEFAULT=0 +val SCE_MATLAB_COMMENT=1 +val SCE_MATLAB_COMMAND=2 +val SCE_MATLAB_NUMBER=3 +val SCE_MATLAB_KEYWORD=4 +# single quoted string +val SCE_MATLAB_STRING=5 +val SCE_MATLAB_OPERATOR=6 +val SCE_MATLAB_IDENTIFIER=7 +val SCE_MATLAB_DOUBLEQUOTESTRING=8 +# Lexical states for SCLEX_MAXIMA +lex Maxima=SCLEX_MAXIMA SCE_MAXIMA_ +val SCE_MAXIMA_OPERATOR=0 +val SCE_MAXIMA_COMMANDENDING=1 +val SCE_MAXIMA_COMMENT=2 +val SCE_MAXIMA_NUMBER=3 +val SCE_MAXIMA_STRING=4 +val SCE_MAXIMA_COMMAND=5 +val SCE_MAXIMA_VARIABLE=6 +val SCE_MAXIMA_UNKNOWN=7 +# Lexical states for SCLEX_SCRIPTOL +lex Sol=SCLEX_SCRIPTOL SCE_SCRIPTOL_ +val SCE_SCRIPTOL_DEFAULT=0 +val SCE_SCRIPTOL_WHITE=1 +val SCE_SCRIPTOL_COMMENTLINE=2 +val SCE_SCRIPTOL_PERSISTENT=3 +val SCE_SCRIPTOL_CSTYLE=4 +val SCE_SCRIPTOL_COMMENTBLOCK=5 +val SCE_SCRIPTOL_NUMBER=6 +val SCE_SCRIPTOL_STRING=7 +val SCE_SCRIPTOL_CHARACTER=8 +val SCE_SCRIPTOL_STRINGEOL=9 +val SCE_SCRIPTOL_KEYWORD=10 +val SCE_SCRIPTOL_OPERATOR=11 +val SCE_SCRIPTOL_IDENTIFIER=12 +val SCE_SCRIPTOL_TRIPLE=13 +val SCE_SCRIPTOL_CLASSNAME=14 +val SCE_SCRIPTOL_PREPROCESSOR=15 +# Lexical states for SCLEX_ASM, SCLEX_AS +lex Asm=SCLEX_ASM SCE_ASM_ +lex As=SCLEX_AS SCE_ASM_ +val SCE_ASM_DEFAULT=0 +val SCE_ASM_COMMENT=1 +val SCE_ASM_NUMBER=2 +val SCE_ASM_STRING=3 +val SCE_ASM_OPERATOR=4 +val SCE_ASM_IDENTIFIER=5 +val SCE_ASM_CPUINSTRUCTION=6 +val SCE_ASM_MATHINSTRUCTION=7 +val SCE_ASM_REGISTER=8 +val SCE_ASM_DIRECTIVE=9 +val SCE_ASM_DIRECTIVEOPERAND=10 +val SCE_ASM_COMMENTBLOCK=11 +val SCE_ASM_CHARACTER=12 +val SCE_ASM_STRINGEOL=13 +val SCE_ASM_EXTINSTRUCTION=14 +val SCE_ASM_COMMENTDIRECTIVE=15 +# Lexical states for SCLEX_FORTRAN +lex Fortran=SCLEX_FORTRAN SCE_F_ +lex F77=SCLEX_F77 SCE_F_ +val SCE_F_DEFAULT=0 +val SCE_F_COMMENT=1 +val SCE_F_NUMBER=2 +val SCE_F_STRING1=3 +val SCE_F_STRING2=4 +val SCE_F_STRINGEOL=5 +val SCE_F_OPERATOR=6 +val SCE_F_IDENTIFIER=7 +val SCE_F_WORD=8 +val SCE_F_WORD2=9 +val SCE_F_WORD3=10 +val SCE_F_PREPROCESSOR=11 +val SCE_F_OPERATOR2=12 +val SCE_F_LABEL=13 +val SCE_F_CONTINUATION=14 +# Lexical states for SCLEX_CSS +lex CSS=SCLEX_CSS SCE_CSS_ +val SCE_CSS_DEFAULT=0 +val SCE_CSS_TAG=1 +val SCE_CSS_CLASS=2 +val SCE_CSS_PSEUDOCLASS=3 +val SCE_CSS_UNKNOWN_PSEUDOCLASS=4 +val SCE_CSS_OPERATOR=5 +val SCE_CSS_IDENTIFIER=6 +val SCE_CSS_UNKNOWN_IDENTIFIER=7 +val SCE_CSS_VALUE=8 +val SCE_CSS_COMMENT=9 +val SCE_CSS_ID=10 +val SCE_CSS_IMPORTANT=11 +val SCE_CSS_DIRECTIVE=12 +val SCE_CSS_DOUBLESTRING=13 +val SCE_CSS_SINGLESTRING=14 +val SCE_CSS_IDENTIFIER2=15 +val SCE_CSS_ATTRIBUTE=16 +val SCE_CSS_IDENTIFIER3=17 +val SCE_CSS_PSEUDOELEMENT=18 +val SCE_CSS_EXTENDED_IDENTIFIER=19 +val SCE_CSS_EXTENDED_PSEUDOCLASS=20 +val SCE_CSS_EXTENDED_PSEUDOELEMENT=21 +val SCE_CSS_MEDIA=22 +val SCE_CSS_VARIABLE=23 +# Lexical states for SCLEX_POV +lex POV=SCLEX_POV SCE_POV_ +val SCE_POV_DEFAULT=0 +val SCE_POV_COMMENT=1 +val SCE_POV_COMMENTLINE=2 +val SCE_POV_NUMBER=3 +val SCE_POV_OPERATOR=4 +val SCE_POV_IDENTIFIER=5 +val SCE_POV_STRING=6 +val SCE_POV_STRINGEOL=7 +val SCE_POV_DIRECTIVE=8 +val SCE_POV_BADDIRECTIVE=9 +val SCE_POV_WORD2=10 +val SCE_POV_WORD3=11 +val SCE_POV_WORD4=12 +val SCE_POV_WORD5=13 +val SCE_POV_WORD6=14 +val SCE_POV_WORD7=15 +val SCE_POV_WORD8=16 +# Lexical states for SCLEX_LOUT +lex LOUT=SCLEX_LOUT SCE_LOUT_ +val SCE_LOUT_DEFAULT=0 +val SCE_LOUT_COMMENT=1 +val SCE_LOUT_NUMBER=2 +val SCE_LOUT_WORD=3 +val SCE_LOUT_WORD2=4 +val SCE_LOUT_WORD3=5 +val SCE_LOUT_WORD4=6 +val SCE_LOUT_STRING=7 +val SCE_LOUT_OPERATOR=8 +val SCE_LOUT_IDENTIFIER=9 +val SCE_LOUT_STRINGEOL=10 +# Lexical states for SCLEX_ESCRIPT +lex ESCRIPT=SCLEX_ESCRIPT SCE_ESCRIPT_ +val SCE_ESCRIPT_DEFAULT=0 +val SCE_ESCRIPT_COMMENT=1 +val SCE_ESCRIPT_COMMENTLINE=2 +val SCE_ESCRIPT_COMMENTDOC=3 +val SCE_ESCRIPT_NUMBER=4 +val SCE_ESCRIPT_WORD=5 +val SCE_ESCRIPT_STRING=6 +val SCE_ESCRIPT_OPERATOR=7 +val SCE_ESCRIPT_IDENTIFIER=8 +val SCE_ESCRIPT_BRACE=9 +val SCE_ESCRIPT_WORD2=10 +val SCE_ESCRIPT_WORD3=11 +# Lexical states for SCLEX_PS +lex PS=SCLEX_PS SCE_PS_ +val SCE_PS_DEFAULT=0 +val SCE_PS_COMMENT=1 +val SCE_PS_DSC_COMMENT=2 +val SCE_PS_DSC_VALUE=3 +val SCE_PS_NUMBER=4 +val SCE_PS_NAME=5 +val SCE_PS_KEYWORD=6 +val SCE_PS_LITERAL=7 +val SCE_PS_IMMEVAL=8 +val SCE_PS_PAREN_ARRAY=9 +val SCE_PS_PAREN_DICT=10 +val SCE_PS_PAREN_PROC=11 +val SCE_PS_TEXT=12 +val SCE_PS_HEXSTRING=13 +val SCE_PS_BASE85STRING=14 +val SCE_PS_BADSTRINGCHAR=15 +# Lexical states for SCLEX_NSIS +lex NSIS=SCLEX_NSIS SCE_NSIS_ +val SCE_NSIS_DEFAULT=0 +val SCE_NSIS_COMMENT=1 +val SCE_NSIS_STRINGDQ=2 +val SCE_NSIS_STRINGLQ=3 +val SCE_NSIS_STRINGRQ=4 +val SCE_NSIS_FUNCTION=5 +val SCE_NSIS_VARIABLE=6 +val SCE_NSIS_LABEL=7 +val SCE_NSIS_USERDEFINED=8 +val SCE_NSIS_SECTIONDEF=9 +val SCE_NSIS_SUBSECTIONDEF=10 +val SCE_NSIS_IFDEFINEDEF=11 +val SCE_NSIS_MACRODEF=12 +val SCE_NSIS_STRINGVAR=13 +val SCE_NSIS_NUMBER=14 +val SCE_NSIS_SECTIONGROUP=15 +val SCE_NSIS_PAGEEX=16 +val SCE_NSIS_FUNCTIONDEF=17 +val SCE_NSIS_COMMENTBOX=18 +# Lexical states for SCLEX_MMIXAL +lex MMIXAL=SCLEX_MMIXAL SCE_MMIXAL_ +val SCE_MMIXAL_LEADWS=0 +val SCE_MMIXAL_COMMENT=1 +val SCE_MMIXAL_LABEL=2 +val SCE_MMIXAL_OPCODE=3 +val SCE_MMIXAL_OPCODE_PRE=4 +val SCE_MMIXAL_OPCODE_VALID=5 +val SCE_MMIXAL_OPCODE_UNKNOWN=6 +val SCE_MMIXAL_OPCODE_POST=7 +val SCE_MMIXAL_OPERANDS=8 +val SCE_MMIXAL_NUMBER=9 +val SCE_MMIXAL_REF=10 +val SCE_MMIXAL_CHAR=11 +val SCE_MMIXAL_STRING=12 +val SCE_MMIXAL_REGISTER=13 +val SCE_MMIXAL_HEX=14 +val SCE_MMIXAL_OPERATOR=15 +val SCE_MMIXAL_SYMBOL=16 +val SCE_MMIXAL_INCLUDE=17 +# Lexical states for SCLEX_CLW +lex Clarion=SCLEX_CLW SCE_CLW_ +val SCE_CLW_DEFAULT=0 +val SCE_CLW_LABEL=1 +val SCE_CLW_COMMENT=2 +val SCE_CLW_STRING=3 +val SCE_CLW_USER_IDENTIFIER=4 +val SCE_CLW_INTEGER_CONSTANT=5 +val SCE_CLW_REAL_CONSTANT=6 +val SCE_CLW_PICTURE_STRING=7 +val SCE_CLW_KEYWORD=8 +val SCE_CLW_COMPILER_DIRECTIVE=9 +val SCE_CLW_RUNTIME_EXPRESSIONS=10 +val SCE_CLW_BUILTIN_PROCEDURES_FUNCTION=11 +val SCE_CLW_STRUCTURE_DATA_TYPE=12 +val SCE_CLW_ATTRIBUTE=13 +val SCE_CLW_STANDARD_EQUATE=14 +val SCE_CLW_ERROR=15 +val SCE_CLW_DEPRECATED=16 +# Lexical states for SCLEX_LOT +lex LOT=SCLEX_LOT SCE_LOT_ +val SCE_LOT_DEFAULT=0 +val SCE_LOT_HEADER=1 +val SCE_LOT_BREAK=2 +val SCE_LOT_SET=3 +val SCE_LOT_PASS=4 +val SCE_LOT_FAIL=5 +val SCE_LOT_ABORT=6 +# Lexical states for SCLEX_YAML +lex YAML=SCLEX_YAML SCE_YAML_ +val SCE_YAML_DEFAULT=0 +val SCE_YAML_COMMENT=1 +val SCE_YAML_IDENTIFIER=2 +val SCE_YAML_KEYWORD=3 +val SCE_YAML_NUMBER=4 +val SCE_YAML_REFERENCE=5 +val SCE_YAML_DOCUMENT=6 +val SCE_YAML_TEXT=7 +val SCE_YAML_ERROR=8 +val SCE_YAML_OPERATOR=9 +# Lexical states for SCLEX_TEX +lex TeX=SCLEX_TEX SCE_TEX_ +val SCE_TEX_DEFAULT=0 +val SCE_TEX_SPECIAL=1 +val SCE_TEX_GROUP=2 +val SCE_TEX_SYMBOL=3 +val SCE_TEX_COMMAND=4 +val SCE_TEX_TEXT=5 +lex Metapost=SCLEX_METAPOST SCE_METAPOST_ +val SCE_METAPOST_DEFAULT=0 +val SCE_METAPOST_SPECIAL=1 +val SCE_METAPOST_GROUP=2 +val SCE_METAPOST_SYMBOL=3 +val SCE_METAPOST_COMMAND=4 +val SCE_METAPOST_TEXT=5 +val SCE_METAPOST_EXTRA=6 +# Lexical states for SCLEX_ERLANG +lex Erlang=SCLEX_ERLANG SCE_ERLANG_ +val SCE_ERLANG_DEFAULT=0 +val SCE_ERLANG_COMMENT=1 +val SCE_ERLANG_VARIABLE=2 +val SCE_ERLANG_NUMBER=3 +val SCE_ERLANG_KEYWORD=4 +val SCE_ERLANG_STRING=5 +val SCE_ERLANG_OPERATOR=6 +val SCE_ERLANG_ATOM=7 +val SCE_ERLANG_FUNCTION_NAME=8 +val SCE_ERLANG_CHARACTER=9 +val SCE_ERLANG_MACRO=10 +val SCE_ERLANG_RECORD=11 +val SCE_ERLANG_PREPROC=12 +val SCE_ERLANG_NODE_NAME=13 +val SCE_ERLANG_COMMENT_FUNCTION=14 +val SCE_ERLANG_COMMENT_MODULE=15 +val SCE_ERLANG_COMMENT_DOC=16 +val SCE_ERLANG_COMMENT_DOC_MACRO=17 +val SCE_ERLANG_ATOM_QUOTED=18 +val SCE_ERLANG_MACRO_QUOTED=19 +val SCE_ERLANG_RECORD_QUOTED=20 +val SCE_ERLANG_NODE_NAME_QUOTED=21 +val SCE_ERLANG_BIFS=22 +val SCE_ERLANG_MODULES=23 +val SCE_ERLANG_MODULES_ATT=24 +val SCE_ERLANG_UNKNOWN=31 +# Lexical states for SCLEX_OCTAVE are identical to MatLab +lex Octave=SCLEX_OCTAVE SCE_MATLAB_ +# Lexical states for SCLEX_JULIA +lex Julia=SCLEX_JULIA SCE_JULIA_ +val SCE_JULIA_DEFAULT=0 +val SCE_JULIA_COMMENT=1 +val SCE_JULIA_NUMBER=2 +val SCE_JULIA_KEYWORD1=3 +val SCE_JULIA_KEYWORD2=4 +val SCE_JULIA_KEYWORD3=5 +val SCE_JULIA_CHAR=6 +val SCE_JULIA_OPERATOR=7 +val SCE_JULIA_BRACKET=8 +val SCE_JULIA_IDENTIFIER=9 +val SCE_JULIA_STRING=10 +val SCE_JULIA_SYMBOL=11 +val SCE_JULIA_MACRO=12 +val SCE_JULIA_STRINGINTERP=13 +val SCE_JULIA_DOCSTRING=14 +val SCE_JULIA_STRINGLITERAL=15 +val SCE_JULIA_COMMAND=16 +val SCE_JULIA_COMMANDLITERAL=17 +val SCE_JULIA_TYPEANNOT=18 +val SCE_JULIA_LEXERROR=19 +val SCE_JULIA_KEYWORD4=20 +val SCE_JULIA_TYPEOPERATOR=21 +# Lexical states for SCLEX_MSSQL +lex MSSQL=SCLEX_MSSQL SCE_MSSQL_ +val SCE_MSSQL_DEFAULT=0 +val SCE_MSSQL_COMMENT=1 +val SCE_MSSQL_LINE_COMMENT=2 +val SCE_MSSQL_NUMBER=3 +val SCE_MSSQL_STRING=4 +val SCE_MSSQL_OPERATOR=5 +val SCE_MSSQL_IDENTIFIER=6 +val SCE_MSSQL_VARIABLE=7 +val SCE_MSSQL_COLUMN_NAME=8 +val SCE_MSSQL_STATEMENT=9 +val SCE_MSSQL_DATATYPE=10 +val SCE_MSSQL_SYSTABLE=11 +val SCE_MSSQL_GLOBAL_VARIABLE=12 +val SCE_MSSQL_FUNCTION=13 +val SCE_MSSQL_STORED_PROCEDURE=14 +val SCE_MSSQL_DEFAULT_PREF_DATATYPE=15 +val SCE_MSSQL_COLUMN_NAME_2=16 +# Lexical states for SCLEX_VERILOG +lex Verilog=SCLEX_VERILOG SCE_V_ +val SCE_V_DEFAULT=0 +val SCE_V_COMMENT=1 +val SCE_V_COMMENTLINE=2 +val SCE_V_COMMENTLINEBANG=3 +val SCE_V_NUMBER=4 +val SCE_V_WORD=5 +val SCE_V_STRING=6 +val SCE_V_WORD2=7 +val SCE_V_WORD3=8 +val SCE_V_PREPROCESSOR=9 +val SCE_V_OPERATOR=10 +val SCE_V_IDENTIFIER=11 +val SCE_V_STRINGEOL=12 +val SCE_V_USER=19 +val SCE_V_COMMENT_WORD=20 +val SCE_V_INPUT=21 +val SCE_V_OUTPUT=22 +val SCE_V_INOUT=23 +val SCE_V_PORT_CONNECT=24 +# Lexical states for SCLEX_KIX +lex Kix=SCLEX_KIX SCE_KIX_ +val SCE_KIX_DEFAULT=0 +val SCE_KIX_COMMENT=1 +val SCE_KIX_STRING1=2 +val SCE_KIX_STRING2=3 +val SCE_KIX_NUMBER=4 +val SCE_KIX_VAR=5 +val SCE_KIX_MACRO=6 +val SCE_KIX_KEYWORD=7 +val SCE_KIX_FUNCTIONS=8 +val SCE_KIX_OPERATOR=9 +val SCE_KIX_COMMENTSTREAM=10 +val SCE_KIX_IDENTIFIER=31 +# Lexical states for SCLEX_GUI4CLI +lex Gui4Cli=SCLEX_GUI4CLI SCE_GC_ +val SCE_GC_DEFAULT=0 +val SCE_GC_COMMENTLINE=1 +val SCE_GC_COMMENTBLOCK=2 +val SCE_GC_GLOBAL=3 +val SCE_GC_EVENT=4 +val SCE_GC_ATTRIBUTE=5 +val SCE_GC_CONTROL=6 +val SCE_GC_COMMAND=7 +val SCE_GC_STRING=8 +val SCE_GC_OPERATOR=9 +# Lexical states for SCLEX_SPECMAN +lex Specman=SCLEX_SPECMAN SCE_SN_ +val SCE_SN_DEFAULT=0 +val SCE_SN_CODE=1 +val SCE_SN_COMMENTLINE=2 +val SCE_SN_COMMENTLINEBANG=3 +val SCE_SN_NUMBER=4 +val SCE_SN_WORD=5 +val SCE_SN_STRING=6 +val SCE_SN_WORD2=7 +val SCE_SN_WORD3=8 +val SCE_SN_PREPROCESSOR=9 +val SCE_SN_OPERATOR=10 +val SCE_SN_IDENTIFIER=11 +val SCE_SN_STRINGEOL=12 +val SCE_SN_REGEXTAG=13 +val SCE_SN_SIGNAL=14 +val SCE_SN_USER=19 +# Lexical states for SCLEX_AU3 +lex Au3=SCLEX_AU3 SCE_AU3_ +val SCE_AU3_DEFAULT=0 +val SCE_AU3_COMMENT=1 +val SCE_AU3_COMMENTBLOCK=2 +val SCE_AU3_NUMBER=3 +val SCE_AU3_FUNCTION=4 +val SCE_AU3_KEYWORD=5 +val SCE_AU3_MACRO=6 +val SCE_AU3_STRING=7 +val SCE_AU3_OPERATOR=8 +val SCE_AU3_VARIABLE=9 +val SCE_AU3_SENT=10 +val SCE_AU3_PREPROCESSOR=11 +val SCE_AU3_SPECIAL=12 +val SCE_AU3_EXPAND=13 +val SCE_AU3_COMOBJ=14 +val SCE_AU3_UDF=15 +# Lexical states for SCLEX_APDL +lex APDL=SCLEX_APDL SCE_APDL_ +val SCE_APDL_DEFAULT=0 +val SCE_APDL_COMMENT=1 +val SCE_APDL_COMMENTBLOCK=2 +val SCE_APDL_NUMBER=3 +val SCE_APDL_STRING=4 +val SCE_APDL_OPERATOR=5 +val SCE_APDL_WORD=6 +val SCE_APDL_PROCESSOR=7 +val SCE_APDL_COMMAND=8 +val SCE_APDL_SLASHCOMMAND=9 +val SCE_APDL_STARCOMMAND=10 +val SCE_APDL_ARGUMENT=11 +val SCE_APDL_FUNCTION=12 +# Lexical states for SCLEX_BASH +lex Bash=SCLEX_BASH SCE_SH_ +val SCE_SH_DEFAULT=0 +val SCE_SH_ERROR=1 +val SCE_SH_COMMENTLINE=2 +val SCE_SH_NUMBER=3 +val SCE_SH_WORD=4 +val SCE_SH_STRING=5 +val SCE_SH_CHARACTER=6 +val SCE_SH_OPERATOR=7 +val SCE_SH_IDENTIFIER=8 +val SCE_SH_SCALAR=9 +val SCE_SH_PARAM=10 +val SCE_SH_BACKTICKS=11 +val SCE_SH_HERE_DELIM=12 +val SCE_SH_HERE_Q=13 +# Lexical states for SCLEX_ASN1 +lex Asn1=SCLEX_ASN1 SCE_ASN1_ +val SCE_ASN1_DEFAULT=0 +val SCE_ASN1_COMMENT=1 +val SCE_ASN1_IDENTIFIER=2 +val SCE_ASN1_STRING=3 +val SCE_ASN1_OID=4 +val SCE_ASN1_SCALAR=5 +val SCE_ASN1_KEYWORD=6 +val SCE_ASN1_ATTRIBUTE=7 +val SCE_ASN1_DESCRIPTOR=8 +val SCE_ASN1_TYPE=9 +val SCE_ASN1_OPERATOR=10 +# Lexical states for SCLEX_VHDL +lex VHDL=SCLEX_VHDL SCE_VHDL_ +val SCE_VHDL_DEFAULT=0 +val SCE_VHDL_COMMENT=1 +val SCE_VHDL_COMMENTLINEBANG=2 +val SCE_VHDL_NUMBER=3 +val SCE_VHDL_STRING=4 +val SCE_VHDL_OPERATOR=5 +val SCE_VHDL_IDENTIFIER=6 +val SCE_VHDL_STRINGEOL=7 +val SCE_VHDL_KEYWORD=8 +val SCE_VHDL_STDOPERATOR=9 +val SCE_VHDL_ATTRIBUTE=10 +val SCE_VHDL_STDFUNCTION=11 +val SCE_VHDL_STDPACKAGE=12 +val SCE_VHDL_STDTYPE=13 +val SCE_VHDL_USERWORD=14 +val SCE_VHDL_BLOCK_COMMENT=15 +# Lexical states for SCLEX_CAML +lex Caml=SCLEX_CAML SCE_CAML_ +val SCE_CAML_DEFAULT=0 +val SCE_CAML_IDENTIFIER=1 +val SCE_CAML_TAGNAME=2 +val SCE_CAML_KEYWORD=3 +val SCE_CAML_KEYWORD2=4 +val SCE_CAML_KEYWORD3=5 +val SCE_CAML_LINENUM=6 +val SCE_CAML_OPERATOR=7 +val SCE_CAML_NUMBER=8 +val SCE_CAML_CHAR=9 +val SCE_CAML_WHITE=10 +val SCE_CAML_STRING=11 +val SCE_CAML_COMMENT=12 +val SCE_CAML_COMMENT1=13 +val SCE_CAML_COMMENT2=14 +val SCE_CAML_COMMENT3=15 +# Lexical states for SCLEX_HASKELL +lex Haskell=SCLEX_HASKELL SCE_HA_ +val SCE_HA_DEFAULT=0 +val SCE_HA_IDENTIFIER=1 +val SCE_HA_KEYWORD=2 +val SCE_HA_NUMBER=3 +val SCE_HA_STRING=4 +val SCE_HA_CHARACTER=5 +val SCE_HA_CLASS=6 +val SCE_HA_MODULE=7 +val SCE_HA_CAPITAL=8 +val SCE_HA_DATA=9 +val SCE_HA_IMPORT=10 +val SCE_HA_OPERATOR=11 +val SCE_HA_INSTANCE=12 +val SCE_HA_COMMENTLINE=13 +val SCE_HA_COMMENTBLOCK=14 +val SCE_HA_COMMENTBLOCK2=15 +val SCE_HA_COMMENTBLOCK3=16 +val SCE_HA_PRAGMA=17 +val SCE_HA_PREPROCESSOR=18 +val SCE_HA_STRINGEOL=19 +val SCE_HA_RESERVED_OPERATOR=20 +val SCE_HA_LITERATE_COMMENT=21 +val SCE_HA_LITERATE_CODEDELIM=22 +# Lexical states of SCLEX_TADS3 +lex TADS3=SCLEX_TADS3 SCE_T3_ +val SCE_T3_DEFAULT=0 +val SCE_T3_X_DEFAULT=1 +val SCE_T3_PREPROCESSOR=2 +val SCE_T3_BLOCK_COMMENT=3 +val SCE_T3_LINE_COMMENT=4 +val SCE_T3_OPERATOR=5 +val SCE_T3_KEYWORD=6 +val SCE_T3_NUMBER=7 +val SCE_T3_IDENTIFIER=8 +val SCE_T3_S_STRING=9 +val SCE_T3_D_STRING=10 +val SCE_T3_X_STRING=11 +val SCE_T3_LIB_DIRECTIVE=12 +val SCE_T3_MSG_PARAM=13 +val SCE_T3_HTML_TAG=14 +val SCE_T3_HTML_DEFAULT=15 +val SCE_T3_HTML_STRING=16 +val SCE_T3_USER1=17 +val SCE_T3_USER2=18 +val SCE_T3_USER3=19 +val SCE_T3_BRACE=20 +# Lexical states for SCLEX_REBOL +lex Rebol=SCLEX_REBOL SCE_REBOL_ +val SCE_REBOL_DEFAULT=0 +val SCE_REBOL_COMMENTLINE=1 +val SCE_REBOL_COMMENTBLOCK=2 +val SCE_REBOL_PREFACE=3 +val SCE_REBOL_OPERATOR=4 +val SCE_REBOL_CHARACTER=5 +val SCE_REBOL_QUOTEDSTRING=6 +val SCE_REBOL_BRACEDSTRING=7 +val SCE_REBOL_NUMBER=8 +val SCE_REBOL_PAIR=9 +val SCE_REBOL_TUPLE=10 +val SCE_REBOL_BINARY=11 +val SCE_REBOL_MONEY=12 +val SCE_REBOL_ISSUE=13 +val SCE_REBOL_TAG=14 +val SCE_REBOL_FILE=15 +val SCE_REBOL_EMAIL=16 +val SCE_REBOL_URL=17 +val SCE_REBOL_DATE=18 +val SCE_REBOL_TIME=19 +val SCE_REBOL_IDENTIFIER=20 +val SCE_REBOL_WORD=21 +val SCE_REBOL_WORD2=22 +val SCE_REBOL_WORD3=23 +val SCE_REBOL_WORD4=24 +val SCE_REBOL_WORD5=25 +val SCE_REBOL_WORD6=26 +val SCE_REBOL_WORD7=27 +val SCE_REBOL_WORD8=28 +# Lexical states for SCLEX_SQL +lex SQL=SCLEX_SQL SCE_SQL_ +val SCE_SQL_DEFAULT=0 +val SCE_SQL_COMMENT=1 +val SCE_SQL_COMMENTLINE=2 +val SCE_SQL_COMMENTDOC=3 +val SCE_SQL_NUMBER=4 +val SCE_SQL_WORD=5 +val SCE_SQL_STRING=6 +val SCE_SQL_CHARACTER=7 +val SCE_SQL_SQLPLUS=8 +val SCE_SQL_SQLPLUS_PROMPT=9 +val SCE_SQL_OPERATOR=10 +val SCE_SQL_IDENTIFIER=11 +val SCE_SQL_SQLPLUS_COMMENT=13 +val SCE_SQL_COMMENTLINEDOC=15 +val SCE_SQL_WORD2=16 +val SCE_SQL_COMMENTDOCKEYWORD=17 +val SCE_SQL_COMMENTDOCKEYWORDERROR=18 +val SCE_SQL_USER1=19 +val SCE_SQL_USER2=20 +val SCE_SQL_USER3=21 +val SCE_SQL_USER4=22 +val SCE_SQL_QUOTEDIDENTIFIER=23 +val SCE_SQL_QOPERATOR=24 +# Lexical states for SCLEX_SMALLTALK +lex Smalltalk=SCLEX_SMALLTALK SCE_ST_ +val SCE_ST_DEFAULT=0 +val SCE_ST_STRING=1 +val SCE_ST_NUMBER=2 +val SCE_ST_COMMENT=3 +val SCE_ST_SYMBOL=4 +val SCE_ST_BINARY=5 +val SCE_ST_BOOL=6 +val SCE_ST_SELF=7 +val SCE_ST_SUPER=8 +val SCE_ST_NIL=9 +val SCE_ST_GLOBAL=10 +val SCE_ST_RETURN=11 +val SCE_ST_SPECIAL=12 +val SCE_ST_KWSEND=13 +val SCE_ST_ASSIGN=14 +val SCE_ST_CHARACTER=15 +val SCE_ST_SPEC_SEL=16 +# Lexical states for SCLEX_FLAGSHIP (clipper) +lex FlagShip=SCLEX_FLAGSHIP SCE_FS_ +val SCE_FS_DEFAULT=0 +val SCE_FS_COMMENT=1 +val SCE_FS_COMMENTLINE=2 +val SCE_FS_COMMENTDOC=3 +val SCE_FS_COMMENTLINEDOC=4 +val SCE_FS_COMMENTDOCKEYWORD=5 +val SCE_FS_COMMENTDOCKEYWORDERROR=6 +val SCE_FS_KEYWORD=7 +val SCE_FS_KEYWORD2=8 +val SCE_FS_KEYWORD3=9 +val SCE_FS_KEYWORD4=10 +val SCE_FS_NUMBER=11 +val SCE_FS_STRING=12 +val SCE_FS_PREPROCESSOR=13 +val SCE_FS_OPERATOR=14 +val SCE_FS_IDENTIFIER=15 +val SCE_FS_DATE=16 +val SCE_FS_STRINGEOL=17 +val SCE_FS_CONSTANT=18 +val SCE_FS_WORDOPERATOR=19 +val SCE_FS_DISABLEDCODE=20 +val SCE_FS_DEFAULT_C=21 +val SCE_FS_COMMENTDOC_C=22 +val SCE_FS_COMMENTLINEDOC_C=23 +val SCE_FS_KEYWORD_C=24 +val SCE_FS_KEYWORD2_C=25 +val SCE_FS_NUMBER_C=26 +val SCE_FS_STRING_C=27 +val SCE_FS_PREPROCESSOR_C=28 +val SCE_FS_OPERATOR_C=29 +val SCE_FS_IDENTIFIER_C=30 +val SCE_FS_STRINGEOL_C=31 +# Lexical states for SCLEX_CSOUND +lex Csound=SCLEX_CSOUND SCE_CSOUND_ +val SCE_CSOUND_DEFAULT=0 +val SCE_CSOUND_COMMENT=1 +val SCE_CSOUND_NUMBER=2 +val SCE_CSOUND_OPERATOR=3 +val SCE_CSOUND_INSTR=4 +val SCE_CSOUND_IDENTIFIER=5 +val SCE_CSOUND_OPCODE=6 +val SCE_CSOUND_HEADERSTMT=7 +val SCE_CSOUND_USERKEYWORD=8 +val SCE_CSOUND_COMMENTBLOCK=9 +val SCE_CSOUND_PARAM=10 +val SCE_CSOUND_ARATE_VAR=11 +val SCE_CSOUND_KRATE_VAR=12 +val SCE_CSOUND_IRATE_VAR=13 +val SCE_CSOUND_GLOBAL_VAR=14 +val SCE_CSOUND_STRINGEOL=15 +# Lexical states for SCLEX_INNOSETUP +lex Inno=SCLEX_INNOSETUP SCE_INNO_ +val SCE_INNO_DEFAULT=0 +val SCE_INNO_COMMENT=1 +val SCE_INNO_KEYWORD=2 +val SCE_INNO_PARAMETER=3 +val SCE_INNO_SECTION=4 +val SCE_INNO_PREPROC=5 +val SCE_INNO_INLINE_EXPANSION=6 +val SCE_INNO_COMMENT_PASCAL=7 +val SCE_INNO_KEYWORD_PASCAL=8 +val SCE_INNO_KEYWORD_USER=9 +val SCE_INNO_STRING_DOUBLE=10 +val SCE_INNO_STRING_SINGLE=11 +val SCE_INNO_IDENTIFIER=12 +# Lexical states for SCLEX_OPAL +lex Opal=SCLEX_OPAL SCE_OPAL_ +val SCE_OPAL_SPACE=0 +val SCE_OPAL_COMMENT_BLOCK=1 +val SCE_OPAL_COMMENT_LINE=2 +val SCE_OPAL_INTEGER=3 +val SCE_OPAL_KEYWORD=4 +val SCE_OPAL_SORT=5 +val SCE_OPAL_STRING=6 +val SCE_OPAL_PAR=7 +val SCE_OPAL_BOOL_CONST=8 +val SCE_OPAL_DEFAULT=32 +# Lexical states for SCLEX_SPICE +lex Spice=SCLEX_SPICE SCE_SPICE_ +val SCE_SPICE_DEFAULT=0 +val SCE_SPICE_IDENTIFIER=1 +val SCE_SPICE_KEYWORD=2 +val SCE_SPICE_KEYWORD2=3 +val SCE_SPICE_KEYWORD3=4 +val SCE_SPICE_NUMBER=5 +val SCE_SPICE_DELIMITER=6 +val SCE_SPICE_VALUE=7 +val SCE_SPICE_COMMENTLINE=8 +# Lexical states for SCLEX_CMAKE +lex CMAKE=SCLEX_CMAKE SCE_CMAKE_ +val SCE_CMAKE_DEFAULT=0 +val SCE_CMAKE_COMMENT=1 +val SCE_CMAKE_STRINGDQ=2 +val SCE_CMAKE_STRINGLQ=3 +val SCE_CMAKE_STRINGRQ=4 +val SCE_CMAKE_COMMANDS=5 +val SCE_CMAKE_PARAMETERS=6 +val SCE_CMAKE_VARIABLE=7 +val SCE_CMAKE_USERDEFINED=8 +val SCE_CMAKE_WHILEDEF=9 +val SCE_CMAKE_FOREACHDEF=10 +val SCE_CMAKE_IFDEFINEDEF=11 +val SCE_CMAKE_MACRODEF=12 +val SCE_CMAKE_STRINGVAR=13 +val SCE_CMAKE_NUMBER=14 +# Lexical states for SCLEX_GAP +lex Gap=SCLEX_GAP SCE_GAP_ +val SCE_GAP_DEFAULT=0 +val SCE_GAP_IDENTIFIER=1 +val SCE_GAP_KEYWORD=2 +val SCE_GAP_KEYWORD2=3 +val SCE_GAP_KEYWORD3=4 +val SCE_GAP_KEYWORD4=5 +val SCE_GAP_STRING=6 +val SCE_GAP_CHAR=7 +val SCE_GAP_OPERATOR=8 +val SCE_GAP_COMMENT=9 +val SCE_GAP_NUMBER=10 +val SCE_GAP_STRINGEOL=11 +# Lexical state for SCLEX_PLM +lex PLM=SCLEX_PLM SCE_PLM_ +val SCE_PLM_DEFAULT=0 +val SCE_PLM_COMMENT=1 +val SCE_PLM_STRING=2 +val SCE_PLM_NUMBER=3 +val SCE_PLM_IDENTIFIER=4 +val SCE_PLM_OPERATOR=5 +val SCE_PLM_CONTROL=6 +val SCE_PLM_KEYWORD=7 +# Lexical state for SCLEX_PROGRESS +lex Progress=SCLEX_PROGRESS SCE_ABL_ +val SCE_ABL_DEFAULT=0 +val SCE_ABL_NUMBER=1 +val SCE_ABL_WORD=2 +val SCE_ABL_STRING=3 +val SCE_ABL_CHARACTER=4 +val SCE_ABL_PREPROCESSOR=5 +val SCE_ABL_OPERATOR=6 +val SCE_ABL_IDENTIFIER=7 +val SCE_ABL_BLOCK=8 +val SCE_ABL_END=9 +val SCE_ABL_COMMENT=10 +val SCE_ABL_TASKMARKER=11 +val SCE_ABL_LINECOMMENT=12 +# Lexical states for SCLEX_ABAQUS +lex ABAQUS=SCLEX_ABAQUS SCE_ABAQUS_ +val SCE_ABAQUS_DEFAULT=0 +val SCE_ABAQUS_COMMENT=1 +val SCE_ABAQUS_COMMENTBLOCK=2 +val SCE_ABAQUS_NUMBER=3 +val SCE_ABAQUS_STRING=4 +val SCE_ABAQUS_OPERATOR=5 +val SCE_ABAQUS_WORD=6 +val SCE_ABAQUS_PROCESSOR=7 +val SCE_ABAQUS_COMMAND=8 +val SCE_ABAQUS_SLASHCOMMAND=9 +val SCE_ABAQUS_STARCOMMAND=10 +val SCE_ABAQUS_ARGUMENT=11 +val SCE_ABAQUS_FUNCTION=12 +# Lexical states for SCLEX_ASYMPTOTE +lex Asymptote=SCLEX_ASYMPTOTE SCE_ASY_ +val SCE_ASY_DEFAULT=0 +val SCE_ASY_COMMENT=1 +val SCE_ASY_COMMENTLINE=2 +val SCE_ASY_NUMBER=3 +val SCE_ASY_WORD=4 +val SCE_ASY_STRING=5 +val SCE_ASY_CHARACTER=6 +val SCE_ASY_OPERATOR=7 +val SCE_ASY_IDENTIFIER=8 +val SCE_ASY_STRINGEOL=9 +val SCE_ASY_COMMENTLINEDOC=10 +val SCE_ASY_WORD2=11 +# Lexical states for SCLEX_R +lex R=SCLEX_R SCE_R_ +val SCE_R_DEFAULT=0 +val SCE_R_COMMENT=1 +val SCE_R_KWORD=2 +val SCE_R_BASEKWORD=3 +val SCE_R_OTHERKWORD=4 +val SCE_R_NUMBER=5 +val SCE_R_STRING=6 +val SCE_R_STRING2=7 +val SCE_R_OPERATOR=8 +val SCE_R_IDENTIFIER=9 +val SCE_R_INFIX=10 +val SCE_R_INFIXEOL=11 +# Lexical state for SCLEX_MAGIK +lex MagikSF=SCLEX_MAGIK SCE_MAGIK_ +val SCE_MAGIK_DEFAULT=0 +val SCE_MAGIK_COMMENT=1 +val SCE_MAGIK_HYPER_COMMENT=16 +val SCE_MAGIK_STRING=2 +val SCE_MAGIK_CHARACTER=3 +val SCE_MAGIK_NUMBER=4 +val SCE_MAGIK_IDENTIFIER=5 +val SCE_MAGIK_OPERATOR=6 +val SCE_MAGIK_FLOW=7 +val SCE_MAGIK_CONTAINER=8 +val SCE_MAGIK_BRACKET_BLOCK=9 +val SCE_MAGIK_BRACE_BLOCK=10 +val SCE_MAGIK_SQBRACKET_BLOCK=11 +val SCE_MAGIK_UNKNOWN_KEYWORD=12 +val SCE_MAGIK_KEYWORD=13 +val SCE_MAGIK_PRAGMA=14 +val SCE_MAGIK_SYMBOL=15 +# Lexical state for SCLEX_POWERSHELL +lex PowerShell=SCLEX_POWERSHELL SCE_POWERSHELL_ +val SCE_POWERSHELL_DEFAULT=0 +val SCE_POWERSHELL_COMMENT=1 +val SCE_POWERSHELL_STRING=2 +val SCE_POWERSHELL_CHARACTER=3 +val SCE_POWERSHELL_NUMBER=4 +val SCE_POWERSHELL_VARIABLE=5 +val SCE_POWERSHELL_OPERATOR=6 +val SCE_POWERSHELL_IDENTIFIER=7 +val SCE_POWERSHELL_KEYWORD=8 +val SCE_POWERSHELL_CMDLET=9 +val SCE_POWERSHELL_ALIAS=10 +val SCE_POWERSHELL_FUNCTION=11 +val SCE_POWERSHELL_USER1=12 +val SCE_POWERSHELL_COMMENTSTREAM=13 +val SCE_POWERSHELL_HERE_STRING=14 +val SCE_POWERSHELL_HERE_CHARACTER=15 +val SCE_POWERSHELL_COMMENTDOCKEYWORD=16 +# Lexical state for SCLEX_MYSQL +lex MySQL=SCLEX_MYSQL SCE_MYSQL_ +val SCE_MYSQL_DEFAULT=0 +val SCE_MYSQL_COMMENT=1 +val SCE_MYSQL_COMMENTLINE=2 +val SCE_MYSQL_VARIABLE=3 +val SCE_MYSQL_SYSTEMVARIABLE=4 +val SCE_MYSQL_KNOWNSYSTEMVARIABLE=5 +val SCE_MYSQL_NUMBER=6 +val SCE_MYSQL_MAJORKEYWORD=7 +val SCE_MYSQL_KEYWORD=8 +val SCE_MYSQL_DATABASEOBJECT=9 +val SCE_MYSQL_PROCEDUREKEYWORD=10 +val SCE_MYSQL_STRING=11 +val SCE_MYSQL_SQSTRING=12 +val SCE_MYSQL_DQSTRING=13 +val SCE_MYSQL_OPERATOR=14 +val SCE_MYSQL_FUNCTION=15 +val SCE_MYSQL_IDENTIFIER=16 +val SCE_MYSQL_QUOTEDIDENTIFIER=17 +val SCE_MYSQL_USER1=18 +val SCE_MYSQL_USER2=19 +val SCE_MYSQL_USER3=20 +val SCE_MYSQL_HIDDENCOMMAND=21 +val SCE_MYSQL_PLACEHOLDER=22 +# Lexical state for SCLEX_PO +lex Po=SCLEX_PO SCE_PO_ +val SCE_PO_DEFAULT=0 +val SCE_PO_COMMENT=1 +val SCE_PO_MSGID=2 +val SCE_PO_MSGID_TEXT=3 +val SCE_PO_MSGSTR=4 +val SCE_PO_MSGSTR_TEXT=5 +val SCE_PO_MSGCTXT=6 +val SCE_PO_MSGCTXT_TEXT=7 +val SCE_PO_FUZZY=8 +val SCE_PO_PROGRAMMER_COMMENT=9 +val SCE_PO_REFERENCE=10 +val SCE_PO_FLAGS=11 +val SCE_PO_MSGID_TEXT_EOL=12 +val SCE_PO_MSGSTR_TEXT_EOL=13 +val SCE_PO_MSGCTXT_TEXT_EOL=14 +val SCE_PO_ERROR=15 +# Lexical states for SCLEX_PASCAL +lex Pascal=SCLEX_PASCAL SCE_PAS_ +val SCE_PAS_DEFAULT=0 +val SCE_PAS_IDENTIFIER=1 +val SCE_PAS_COMMENT=2 +val SCE_PAS_COMMENT2=3 +val SCE_PAS_COMMENTLINE=4 +val SCE_PAS_PREPROCESSOR=5 +val SCE_PAS_PREPROCESSOR2=6 +val SCE_PAS_NUMBER=7 +val SCE_PAS_HEXNUMBER=8 +val SCE_PAS_WORD=9 +val SCE_PAS_STRING=10 +val SCE_PAS_STRINGEOL=11 +val SCE_PAS_CHARACTER=12 +val SCE_PAS_OPERATOR=13 +val SCE_PAS_ASM=14 +# Lexical state for SCLEX_SORCUS +lex SORCUS=SCLEX_SORCUS SCE_SORCUS_ +val SCE_SORCUS_DEFAULT=0 +val SCE_SORCUS_COMMAND=1 +val SCE_SORCUS_PARAMETER=2 +val SCE_SORCUS_COMMENTLINE=3 +val SCE_SORCUS_STRING=4 +val SCE_SORCUS_STRINGEOL=5 +val SCE_SORCUS_IDENTIFIER=6 +val SCE_SORCUS_OPERATOR=7 +val SCE_SORCUS_NUMBER=8 +val SCE_SORCUS_CONSTANT=9 +# Lexical state for SCLEX_POWERPRO +lex PowerPro=SCLEX_POWERPRO SCE_POWERPRO_ +val SCE_POWERPRO_DEFAULT=0 +val SCE_POWERPRO_COMMENTBLOCK=1 +val SCE_POWERPRO_COMMENTLINE=2 +val SCE_POWERPRO_NUMBER=3 +val SCE_POWERPRO_WORD=4 +val SCE_POWERPRO_WORD2=5 +val SCE_POWERPRO_WORD3=6 +val SCE_POWERPRO_WORD4=7 +val SCE_POWERPRO_DOUBLEQUOTEDSTRING=8 +val SCE_POWERPRO_SINGLEQUOTEDSTRING=9 +val SCE_POWERPRO_LINECONTINUE=10 +val SCE_POWERPRO_OPERATOR=11 +val SCE_POWERPRO_IDENTIFIER=12 +val SCE_POWERPRO_STRINGEOL=13 +val SCE_POWERPRO_VERBATIM=14 +val SCE_POWERPRO_ALTQUOTE=15 +val SCE_POWERPRO_FUNCTION=16 +# Lexical states for SCLEX_SML +lex SML=SCLEX_SML SCE_SML_ +val SCE_SML_DEFAULT=0 +val SCE_SML_IDENTIFIER=1 +val SCE_SML_TAGNAME=2 +val SCE_SML_KEYWORD=3 +val SCE_SML_KEYWORD2=4 +val SCE_SML_KEYWORD3=5 +val SCE_SML_LINENUM=6 +val SCE_SML_OPERATOR=7 +val SCE_SML_NUMBER=8 +val SCE_SML_CHAR=9 +val SCE_SML_STRING=11 +val SCE_SML_COMMENT=12 +val SCE_SML_COMMENT1=13 +val SCE_SML_COMMENT2=14 +val SCE_SML_COMMENT3=15 +# Lexical state for SCLEX_MARKDOWN +lex Markdown=SCLEX_MARKDOWN SCE_MARKDOWN_ +val SCE_MARKDOWN_DEFAULT=0 +val SCE_MARKDOWN_LINE_BEGIN=1 +val SCE_MARKDOWN_STRONG1=2 +val SCE_MARKDOWN_STRONG2=3 +val SCE_MARKDOWN_EM1=4 +val SCE_MARKDOWN_EM2=5 +val SCE_MARKDOWN_HEADER1=6 +val SCE_MARKDOWN_HEADER2=7 +val SCE_MARKDOWN_HEADER3=8 +val SCE_MARKDOWN_HEADER4=9 +val SCE_MARKDOWN_HEADER5=10 +val SCE_MARKDOWN_HEADER6=11 +val SCE_MARKDOWN_PRECHAR=12 +val SCE_MARKDOWN_ULIST_ITEM=13 +val SCE_MARKDOWN_OLIST_ITEM=14 +val SCE_MARKDOWN_BLOCKQUOTE=15 +val SCE_MARKDOWN_STRIKEOUT=16 +val SCE_MARKDOWN_HRULE=17 +val SCE_MARKDOWN_LINK=18 +val SCE_MARKDOWN_CODE=19 +val SCE_MARKDOWN_CODE2=20 +val SCE_MARKDOWN_CODEBK=21 +# Lexical state for SCLEX_TXT2TAGS +lex Txt2tags=SCLEX_TXT2TAGS SCE_TXT2TAGS_ +val SCE_TXT2TAGS_DEFAULT=0 +val SCE_TXT2TAGS_LINE_BEGIN=1 +val SCE_TXT2TAGS_STRONG1=2 +val SCE_TXT2TAGS_STRONG2=3 +val SCE_TXT2TAGS_EM1=4 +val SCE_TXT2TAGS_EM2=5 +val SCE_TXT2TAGS_HEADER1=6 +val SCE_TXT2TAGS_HEADER2=7 +val SCE_TXT2TAGS_HEADER3=8 +val SCE_TXT2TAGS_HEADER4=9 +val SCE_TXT2TAGS_HEADER5=10 +val SCE_TXT2TAGS_HEADER6=11 +val SCE_TXT2TAGS_PRECHAR=12 +val SCE_TXT2TAGS_ULIST_ITEM=13 +val SCE_TXT2TAGS_OLIST_ITEM=14 +val SCE_TXT2TAGS_BLOCKQUOTE=15 +val SCE_TXT2TAGS_STRIKEOUT=16 +val SCE_TXT2TAGS_HRULE=17 +val SCE_TXT2TAGS_LINK=18 +val SCE_TXT2TAGS_CODE=19 +val SCE_TXT2TAGS_CODE2=20 +val SCE_TXT2TAGS_CODEBK=21 +val SCE_TXT2TAGS_COMMENT=22 +val SCE_TXT2TAGS_OPTION=23 +val SCE_TXT2TAGS_PREPROC=24 +val SCE_TXT2TAGS_POSTPROC=25 +# Lexical states for SCLEX_A68K +lex A68k=SCLEX_A68K SCE_A68K_ +val SCE_A68K_DEFAULT=0 +val SCE_A68K_COMMENT=1 +val SCE_A68K_NUMBER_DEC=2 +val SCE_A68K_NUMBER_BIN=3 +val SCE_A68K_NUMBER_HEX=4 +val SCE_A68K_STRING1=5 +val SCE_A68K_OPERATOR=6 +val SCE_A68K_CPUINSTRUCTION=7 +val SCE_A68K_EXTINSTRUCTION=8 +val SCE_A68K_REGISTER=9 +val SCE_A68K_DIRECTIVE=10 +val SCE_A68K_MACRO_ARG=11 +val SCE_A68K_LABEL=12 +val SCE_A68K_STRING2=13 +val SCE_A68K_IDENTIFIER=14 +val SCE_A68K_MACRO_DECLARATION=15 +val SCE_A68K_COMMENT_WORD=16 +val SCE_A68K_COMMENT_SPECIAL=17 +val SCE_A68K_COMMENT_DOXYGEN=18 +# Lexical states for SCLEX_MODULA +lex Modula=SCLEX_MODULA SCE_MODULA_ +val SCE_MODULA_DEFAULT=0 +val SCE_MODULA_COMMENT=1 +val SCE_MODULA_DOXYCOMM=2 +val SCE_MODULA_DOXYKEY=3 +val SCE_MODULA_KEYWORD=4 +val SCE_MODULA_RESERVED=5 +val SCE_MODULA_NUMBER=6 +val SCE_MODULA_BASENUM=7 +val SCE_MODULA_FLOAT=8 +val SCE_MODULA_STRING=9 +val SCE_MODULA_STRSPEC=10 +val SCE_MODULA_CHAR=11 +val SCE_MODULA_CHARSPEC=12 +val SCE_MODULA_PROC=13 +val SCE_MODULA_PRAGMA=14 +val SCE_MODULA_PRGKEY=15 +val SCE_MODULA_OPERATOR=16 +val SCE_MODULA_BADSTR=17 +# Lexical states for SCLEX_COFFEESCRIPT +lex CoffeeScript=SCLEX_COFFEESCRIPT SCE_COFFEESCRIPT_ +val SCE_COFFEESCRIPT_DEFAULT=0 +val SCE_COFFEESCRIPT_COMMENT=1 +val SCE_COFFEESCRIPT_COMMENTLINE=2 +val SCE_COFFEESCRIPT_COMMENTDOC=3 +val SCE_COFFEESCRIPT_NUMBER=4 +val SCE_COFFEESCRIPT_WORD=5 +val SCE_COFFEESCRIPT_STRING=6 +val SCE_COFFEESCRIPT_CHARACTER=7 +val SCE_COFFEESCRIPT_UUID=8 +val SCE_COFFEESCRIPT_PREPROCESSOR=9 +val SCE_COFFEESCRIPT_OPERATOR=10 +val SCE_COFFEESCRIPT_IDENTIFIER=11 +val SCE_COFFEESCRIPT_STRINGEOL=12 +val SCE_COFFEESCRIPT_VERBATIM=13 +val SCE_COFFEESCRIPT_REGEX=14 +val SCE_COFFEESCRIPT_COMMENTLINEDOC=15 +val SCE_COFFEESCRIPT_WORD2=16 +val SCE_COFFEESCRIPT_COMMENTDOCKEYWORD=17 +val SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR=18 +val SCE_COFFEESCRIPT_GLOBALCLASS=19 +val SCE_COFFEESCRIPT_STRINGRAW=20 +val SCE_COFFEESCRIPT_TRIPLEVERBATIM=21 +val SCE_COFFEESCRIPT_COMMENTBLOCK=22 +val SCE_COFFEESCRIPT_VERBOSE_REGEX=23 +val SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT=24 +val SCE_COFFEESCRIPT_INSTANCEPROPERTY=25 +# Lexical states for SCLEX_AVS +lex AVS=SCLEX_AVS SCE_AVS_ +val SCE_AVS_DEFAULT=0 +val SCE_AVS_COMMENTBLOCK=1 +val SCE_AVS_COMMENTBLOCKN=2 +val SCE_AVS_COMMENTLINE=3 +val SCE_AVS_NUMBER=4 +val SCE_AVS_OPERATOR=5 +val SCE_AVS_IDENTIFIER=6 +val SCE_AVS_STRING=7 +val SCE_AVS_TRIPLESTRING=8 +val SCE_AVS_KEYWORD=9 +val SCE_AVS_FILTER=10 +val SCE_AVS_PLUGIN=11 +val SCE_AVS_FUNCTION=12 +val SCE_AVS_CLIPPROP=13 +val SCE_AVS_USERDFN=14 +# Lexical states for SCLEX_ECL +lex ECL=SCLEX_ECL SCE_ECL_ +val SCE_ECL_DEFAULT=0 +val SCE_ECL_COMMENT=1 +val SCE_ECL_COMMENTLINE=2 +val SCE_ECL_NUMBER=3 +val SCE_ECL_STRING=4 +val SCE_ECL_WORD0=5 +val SCE_ECL_OPERATOR=6 +val SCE_ECL_CHARACTER=7 +val SCE_ECL_UUID=8 +val SCE_ECL_PREPROCESSOR=9 +val SCE_ECL_UNKNOWN=10 +val SCE_ECL_IDENTIFIER=11 +val SCE_ECL_STRINGEOL=12 +val SCE_ECL_VERBATIM=13 +val SCE_ECL_REGEX=14 +val SCE_ECL_COMMENTLINEDOC=15 +val SCE_ECL_WORD1=16 +val SCE_ECL_COMMENTDOCKEYWORD=17 +val SCE_ECL_COMMENTDOCKEYWORDERROR=18 +val SCE_ECL_WORD2=19 +val SCE_ECL_WORD3=20 +val SCE_ECL_WORD4=21 +val SCE_ECL_WORD5=22 +val SCE_ECL_COMMENTDOC=23 +val SCE_ECL_ADDED=24 +val SCE_ECL_DELETED=25 +val SCE_ECL_CHANGED=26 +val SCE_ECL_MOVED=27 +# Lexical states for SCLEX_OSCRIPT +lex OScript=SCLEX_OSCRIPT SCE_OSCRIPT_ +val SCE_OSCRIPT_DEFAULT=0 +val SCE_OSCRIPT_LINE_COMMENT=1 +val SCE_OSCRIPT_BLOCK_COMMENT=2 +val SCE_OSCRIPT_DOC_COMMENT=3 +val SCE_OSCRIPT_PREPROCESSOR=4 +val SCE_OSCRIPT_NUMBER=5 +val SCE_OSCRIPT_SINGLEQUOTE_STRING=6 +val SCE_OSCRIPT_DOUBLEQUOTE_STRING=7 +val SCE_OSCRIPT_CONSTANT=8 +val SCE_OSCRIPT_IDENTIFIER=9 +val SCE_OSCRIPT_GLOBAL=10 +val SCE_OSCRIPT_KEYWORD=11 +val SCE_OSCRIPT_OPERATOR=12 +val SCE_OSCRIPT_LABEL=13 +val SCE_OSCRIPT_TYPE=14 +val SCE_OSCRIPT_FUNCTION=15 +val SCE_OSCRIPT_OBJECT=16 +val SCE_OSCRIPT_PROPERTY=17 +val SCE_OSCRIPT_METHOD=18 +# Lexical states for SCLEX_VISUALPROLOG +lex VisualProlog=SCLEX_VISUALPROLOG SCE_VISUALPROLOG_ +val SCE_VISUALPROLOG_DEFAULT=0 +val SCE_VISUALPROLOG_KEY_MAJOR=1 +val SCE_VISUALPROLOG_KEY_MINOR=2 +val SCE_VISUALPROLOG_KEY_DIRECTIVE=3 +val SCE_VISUALPROLOG_COMMENT_BLOCK=4 +val SCE_VISUALPROLOG_COMMENT_LINE=5 +val SCE_VISUALPROLOG_COMMENT_KEY=6 +val SCE_VISUALPROLOG_COMMENT_KEY_ERROR=7 +val SCE_VISUALPROLOG_IDENTIFIER=8 +val SCE_VISUALPROLOG_VARIABLE=9 +val SCE_VISUALPROLOG_ANONYMOUS=10 +val SCE_VISUALPROLOG_NUMBER=11 +val SCE_VISUALPROLOG_OPERATOR=12 +val SCE_VISUALPROLOG_CHARACTER=13 +val SCE_VISUALPROLOG_CHARACTER_TOO_MANY=14 +val SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR=15 +val SCE_VISUALPROLOG_STRING=16 +val SCE_VISUALPROLOG_STRING_ESCAPE=17 +val SCE_VISUALPROLOG_STRING_ESCAPE_ERROR=18 +val SCE_VISUALPROLOG_STRING_EOL_OPEN=19 +val SCE_VISUALPROLOG_STRING_VERBATIM=20 +val SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL=21 +val SCE_VISUALPROLOG_STRING_VERBATIM_EOL=22 +# Lexical states for SCLEX_STTXT +lex StructuredText=SCLEX_STTXT SCE_STTXT_ +val SCE_STTXT_DEFAULT=0 +val SCE_STTXT_COMMENT=1 +val SCE_STTXT_COMMENTLINE=2 +val SCE_STTXT_KEYWORD=3 +val SCE_STTXT_TYPE=4 +val SCE_STTXT_FUNCTION=5 +val SCE_STTXT_FB=6 +val SCE_STTXT_NUMBER=7 +val SCE_STTXT_HEXNUMBER=8 +val SCE_STTXT_PRAGMA=9 +val SCE_STTXT_OPERATOR=10 +val SCE_STTXT_CHARACTER=11 +val SCE_STTXT_STRING1=12 +val SCE_STTXT_STRING2=13 +val SCE_STTXT_STRINGEOL=14 +val SCE_STTXT_IDENTIFIER=15 +val SCE_STTXT_DATETIME=16 +val SCE_STTXT_VARS=17 +val SCE_STTXT_PRAGMAS=18 +# Lexical states for SCLEX_KVIRC +lex KVIrc=SCLEX_KVIRC SCE_KVIRC_ +val SCE_KVIRC_DEFAULT=0 +val SCE_KVIRC_COMMENT=1 +val SCE_KVIRC_COMMENTBLOCK=2 +val SCE_KVIRC_STRING=3 +val SCE_KVIRC_WORD=4 +val SCE_KVIRC_KEYWORD=5 +val SCE_KVIRC_FUNCTION_KEYWORD=6 +val SCE_KVIRC_FUNCTION=7 +val SCE_KVIRC_VARIABLE=8 +val SCE_KVIRC_NUMBER=9 +val SCE_KVIRC_OPERATOR=10 +val SCE_KVIRC_STRING_FUNCTION=11 +val SCE_KVIRC_STRING_VARIABLE=12 +# Lexical states for SCLEX_RUST +lex Rust=SCLEX_RUST SCE_RUST_ +val SCE_RUST_DEFAULT=0 +val SCE_RUST_COMMENTBLOCK=1 +val SCE_RUST_COMMENTLINE=2 +val SCE_RUST_COMMENTBLOCKDOC=3 +val SCE_RUST_COMMENTLINEDOC=4 +val SCE_RUST_NUMBER=5 +val SCE_RUST_WORD=6 +val SCE_RUST_WORD2=7 +val SCE_RUST_WORD3=8 +val SCE_RUST_WORD4=9 +val SCE_RUST_WORD5=10 +val SCE_RUST_WORD6=11 +val SCE_RUST_WORD7=12 +val SCE_RUST_STRING=13 +val SCE_RUST_STRINGR=14 +val SCE_RUST_CHARACTER=15 +val SCE_RUST_OPERATOR=16 +val SCE_RUST_IDENTIFIER=17 +val SCE_RUST_LIFETIME=18 +val SCE_RUST_MACRO=19 +val SCE_RUST_LEXERROR=20 +val SCE_RUST_BYTESTRING=21 +val SCE_RUST_BYTESTRINGR=22 +val SCE_RUST_BYTECHARACTER=23 +# Lexical states for SCLEX_DMAP +lex DMAP=SCLEX_DMAP SCE_DMAP_ +val SCE_DMAP_DEFAULT=0 +val SCE_DMAP_COMMENT=1 +val SCE_DMAP_NUMBER=2 +val SCE_DMAP_STRING1=3 +val SCE_DMAP_STRING2=4 +val SCE_DMAP_STRINGEOL=5 +val SCE_DMAP_OPERATOR=6 +val SCE_DMAP_IDENTIFIER=7 +val SCE_DMAP_WORD=8 +val SCE_DMAP_WORD2=9 +val SCE_DMAP_WORD3=10 +# Lexical states for SCLEX_DMIS +lex DMIS=SCLEX_DMIS SCE_DMIS_ +val SCE_DMIS_DEFAULT=0 +val SCE_DMIS_COMMENT=1 +val SCE_DMIS_STRING=2 +val SCE_DMIS_NUMBER=3 +val SCE_DMIS_KEYWORD=4 +val SCE_DMIS_MAJORWORD=5 +val SCE_DMIS_MINORWORD=6 +val SCE_DMIS_UNSUPPORTED_MAJOR=7 +val SCE_DMIS_UNSUPPORTED_MINOR=8 +val SCE_DMIS_LABEL=9 +# Lexical states for SCLEX_REGISTRY +lex REG=SCLEX_REGISTRY SCE_REG_ +val SCE_REG_DEFAULT=0 +val SCE_REG_COMMENT=1 +val SCE_REG_VALUENAME=2 +val SCE_REG_STRING=3 +val SCE_REG_HEXDIGIT=4 +val SCE_REG_VALUETYPE=5 +val SCE_REG_ADDEDKEY=6 +val SCE_REG_DELETEDKEY=7 +val SCE_REG_ESCAPED=8 +val SCE_REG_KEYPATH_GUID=9 +val SCE_REG_STRING_GUID=10 +val SCE_REG_PARAMETER=11 +val SCE_REG_OPERATOR=12 +# Lexical state for SCLEX_BIBTEX +lex BibTeX=SCLEX_BIBTEX SCE_BIBTEX_ +val SCE_BIBTEX_DEFAULT=0 +val SCE_BIBTEX_ENTRY=1 +val SCE_BIBTEX_UNKNOWN_ENTRY=2 +val SCE_BIBTEX_KEY=3 +val SCE_BIBTEX_PARAMETER=4 +val SCE_BIBTEX_VALUE=5 +val SCE_BIBTEX_COMMENT=6 +# Lexical state for SCLEX_SREC +lex Srec=SCLEX_SREC SCE_HEX_ +val SCE_HEX_DEFAULT=0 +val SCE_HEX_RECSTART=1 +val SCE_HEX_RECTYPE=2 +val SCE_HEX_RECTYPE_UNKNOWN=3 +val SCE_HEX_BYTECOUNT=4 +val SCE_HEX_BYTECOUNT_WRONG=5 +val SCE_HEX_NOADDRESS=6 +val SCE_HEX_DATAADDRESS=7 +val SCE_HEX_RECCOUNT=8 +val SCE_HEX_STARTADDRESS=9 +val SCE_HEX_ADDRESSFIELD_UNKNOWN=10 +val SCE_HEX_EXTENDEDADDRESS=11 +val SCE_HEX_DATA_ODD=12 +val SCE_HEX_DATA_EVEN=13 +val SCE_HEX_DATA_UNKNOWN=14 +val SCE_HEX_DATA_EMPTY=15 +val SCE_HEX_CHECKSUM=16 +val SCE_HEX_CHECKSUM_WRONG=17 +val SCE_HEX_GARBAGE=18 +# Lexical state for SCLEX_IHEX (shared with Srec) +lex IHex=SCLEX_IHEX SCE_HEX_ +# Lexical state for SCLEX_TEHEX (shared with Srec) +lex TEHex=SCLEX_TEHEX SCE_HEX_ +# Lexical states for SCLEX_JSON +lex JSON=SCLEX_JSON SCE_JSON_ +val SCE_JSON_DEFAULT=0 +val SCE_JSON_NUMBER=1 +val SCE_JSON_STRING=2 +val SCE_JSON_STRINGEOL=3 +val SCE_JSON_PROPERTYNAME=4 +val SCE_JSON_ESCAPESEQUENCE=5 +val SCE_JSON_LINECOMMENT=6 +val SCE_JSON_BLOCKCOMMENT=7 +val SCE_JSON_OPERATOR=8 +val SCE_JSON_URI=9 +val SCE_JSON_COMPACTIRI=10 +val SCE_JSON_KEYWORD=11 +val SCE_JSON_LDKEYWORD=12 +val SCE_JSON_ERROR=13 +lex EDIFACT=SCLEX_EDIFACT SCE_EDI_ +val SCE_EDI_DEFAULT=0 +val SCE_EDI_SEGMENTSTART=1 +val SCE_EDI_SEGMENTEND=2 +val SCE_EDI_SEP_ELEMENT=3 +val SCE_EDI_SEP_COMPOSITE=4 +val SCE_EDI_SEP_RELEASE=5 +val SCE_EDI_UNA=6 +val SCE_EDI_UNH=7 +val SCE_EDI_BADSEGMENT=8 +# Lexical states for SCLEX_STATA +lex STATA=SCLEX_STATA SCE_STATA_ +val SCE_STATA_DEFAULT=0 +val SCE_STATA_COMMENT=1 +val SCE_STATA_COMMENTLINE=2 +val SCE_STATA_COMMENTBLOCK=3 +val SCE_STATA_NUMBER=4 +val SCE_STATA_OPERATOR=5 +val SCE_STATA_IDENTIFIER=6 +val SCE_STATA_STRING=7 +val SCE_STATA_TYPE=8 +val SCE_STATA_WORD=9 +val SCE_STATA_GLOBAL_MACRO=10 +val SCE_STATA_MACRO=11 +# Lexical states for SCLEX_SAS +lex SAS=SCLEX_SAS SCE_SAS_ +val SCE_SAS_DEFAULT=0 +val SCE_SAS_COMMENT=1 +val SCE_SAS_COMMENTLINE=2 +val SCE_SAS_COMMENTBLOCK=3 +val SCE_SAS_NUMBER=4 +val SCE_SAS_OPERATOR=5 +val SCE_SAS_IDENTIFIER=6 +val SCE_SAS_STRING=7 +val SCE_SAS_TYPE=8 +val SCE_SAS_WORD=9 +val SCE_SAS_GLOBAL_MACRO=10 +val SCE_SAS_MACRO=11 +val SCE_SAS_MACRO_KEYWORD=12 +val SCE_SAS_BLOCK_KEYWORD=13 +val SCE_SAS_MACRO_FUNCTION=14 +val SCE_SAS_STATEMENT=15 +# Lexical states for SCLEX_NIM +lex Nim=SCLEX_NIM SCE_NIM_ +val SCE_NIM_DEFAULT=0 +val SCE_NIM_COMMENT=1 +val SCE_NIM_COMMENTDOC=2 +val SCE_NIM_COMMENTLINE=3 +val SCE_NIM_COMMENTLINEDOC=4 +val SCE_NIM_NUMBER=5 +val SCE_NIM_STRING=6 +val SCE_NIM_CHARACTER=7 +val SCE_NIM_WORD=8 +val SCE_NIM_TRIPLE=9 +val SCE_NIM_TRIPLEDOUBLE=10 +val SCE_NIM_BACKTICKS=11 +val SCE_NIM_FUNCNAME=12 +val SCE_NIM_STRINGEOL=13 +val SCE_NIM_NUMERROR=14 +val SCE_NIM_OPERATOR=15 +val SCE_NIM_IDENTIFIER=16 +# Lexical states for SCLEX_CIL +lex CIL=SCLEX_CIL SCE_CIL_ +val SCE_CIL_DEFAULT=0 +val SCE_CIL_COMMENT=1 +val SCE_CIL_COMMENTLINE=2 +val SCE_CIL_WORD=3 +val SCE_CIL_WORD2=4 +val SCE_CIL_WORD3=5 +val SCE_CIL_STRING=6 +val SCE_CIL_LABEL=7 +val SCE_CIL_OPERATOR=8 +val SCE_CIL_IDENTIFIER=9 +val SCE_CIL_STRINGEOL=10 +# Lexical states for SCLEX_X12 +lex X12=SCLEX_X12 SCE_X12_ +val SCE_X12_DEFAULT=0 +val SCE_X12_BAD=1 +val SCE_X12_ENVELOPE=2 +val SCE_X12_FUNCTIONGROUP=3 +val SCE_X12_TRANSACTIONSET=4 +val SCE_X12_SEGMENTHEADER=5 +val SCE_X12_SEGMENTEND=6 +val SCE_X12_SEP_ELEMENT=7 +val SCE_X12_SEP_SUBELEMENT=8 +# Lexical states for SCLEX_DATAFLEX +lex Dataflex=SCLEX_DATAFLEX SCE_DF_ +val SCE_DF_DEFAULT=0 +val SCE_DF_IDENTIFIER=1 +val SCE_DF_METATAG=2 +val SCE_DF_IMAGE=3 +val SCE_DF_COMMENTLINE=4 +val SCE_DF_PREPROCESSOR=5 +val SCE_DF_PREPROCESSOR2=6 +val SCE_DF_NUMBER=7 +val SCE_DF_HEXNUMBER=8 +val SCE_DF_WORD=9 +val SCE_DF_STRING=10 +val SCE_DF_STRINGEOL=11 +val SCE_DF_SCOPEWORD=12 +val SCE_DF_OPERATOR=13 +val SCE_DF_ICODE=14 +# Lexical states for SCLEX_HOLLYWOOD +lex Hollywood=SCLEX_HOLLYWOOD SCE_HOLLYWOOD_ +val SCE_HOLLYWOOD_DEFAULT=0 +val SCE_HOLLYWOOD_COMMENT=1 +val SCE_HOLLYWOOD_COMMENTBLOCK=2 +val SCE_HOLLYWOOD_NUMBER=3 +val SCE_HOLLYWOOD_KEYWORD=4 +val SCE_HOLLYWOOD_STDAPI=5 +val SCE_HOLLYWOOD_PLUGINAPI=6 +val SCE_HOLLYWOOD_PLUGINMETHOD=7 +val SCE_HOLLYWOOD_STRING=8 +val SCE_HOLLYWOOD_STRINGBLOCK=9 +val SCE_HOLLYWOOD_PREPROCESSOR=10 +val SCE_HOLLYWOOD_OPERATOR=11 +val SCE_HOLLYWOOD_IDENTIFIER=12 +val SCE_HOLLYWOOD_CONSTANT=13 +val SCE_HOLLYWOOD_HEXNUMBER=14 +# Lexical states for SCLEX_RAKU +lex Raku=SCLEX_RAKU SCE_RAKU_ +val SCE_RAKU_DEFAULT=0 +val SCE_RAKU_ERROR=1 +val SCE_RAKU_COMMENTLINE=2 +val SCE_RAKU_COMMENTEMBED=3 +val SCE_RAKU_POD=4 +val SCE_RAKU_CHARACTER=5 +val SCE_RAKU_HEREDOC_Q=6 +val SCE_RAKU_HEREDOC_QQ=7 +val SCE_RAKU_STRING=8 +val SCE_RAKU_STRING_Q=9 +val SCE_RAKU_STRING_QQ=10 +val SCE_RAKU_STRING_Q_LANG=11 +val SCE_RAKU_STRING_VAR=12 +val SCE_RAKU_REGEX=13 +val SCE_RAKU_REGEX_VAR=14 +val SCE_RAKU_ADVERB=15 +val SCE_RAKU_NUMBER=16 +val SCE_RAKU_PREPROCESSOR=17 +val SCE_RAKU_OPERATOR=18 +val SCE_RAKU_WORD=19 +val SCE_RAKU_FUNCTION=20 +val SCE_RAKU_IDENTIFIER=21 +val SCE_RAKU_TYPEDEF=22 +val SCE_RAKU_MU=23 +val SCE_RAKU_POSITIONAL=24 +val SCE_RAKU_ASSOCIATIVE=25 +val SCE_RAKU_CALLABLE=26 +val SCE_RAKU_GRAMMAR=27 +val SCE_RAKU_CLASS=28 +# Lexical states for SCLEX_FSHARP +lex FSharp=SCLEX_FSHARP SCE_FSHARP_ +val SCE_FSHARP_DEFAULT=0 +val SCE_FSHARP_KEYWORD=1 +val SCE_FSHARP_KEYWORD2=2 +val SCE_FSHARP_KEYWORD3=3 +val SCE_FSHARP_KEYWORD4=4 +val SCE_FSHARP_KEYWORD5=5 +val SCE_FSHARP_IDENTIFIER=6 +val SCE_FSHARP_QUOT_IDENTIFIER=7 +val SCE_FSHARP_COMMENT=8 +val SCE_FSHARP_COMMENTLINE=9 +val SCE_FSHARP_PREPROCESSOR=10 +val SCE_FSHARP_LINENUM=11 +val SCE_FSHARP_OPERATOR=12 +val SCE_FSHARP_NUMBER=13 +val SCE_FSHARP_CHARACTER=14 +val SCE_FSHARP_STRING=15 +val SCE_FSHARP_VERBATIM=16 +val SCE_FSHARP_QUOTATION=17 +val SCE_FSHARP_ATTRIBUTE=18 +val SCE_FSHARP_FORMAT_SPEC=19 diff --git a/scintilla/lexilla/include/Lexilla.h b/scintilla/lexilla/include/Lexilla.h new file mode 100644 index 0000000000..4a1a3be200 --- /dev/null +++ b/scintilla/lexilla/include/Lexilla.h @@ -0,0 +1,108 @@ +// Lexilla lexer library +/** @file Lexilla.h + ** Lexilla definitions for dynamic and static linking. + ** For C++, more features and type safety are available with the LexillaAccess module. + **/ +// Copyright 2020 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef LEXILLA_H +#define LEXILLA_H + +// Define the default Lexilla shared library name for each platform +#if _WIN32 +#define LEXILLA_LIB "lexilla" +#define LEXILLA_EXTENSION ".dll" +#else +#define LEXILLA_LIB "liblexilla" +#if defined(__APPLE__) +#define LEXILLA_EXTENSION ".dylib" +#else +#define LEXILLA_EXTENSION ".so" +#endif +#endif + +// On Win32 use the stdcall calling convention otherwise use the standard calling convention +#if _WIN32 +#define LEXILLA_CALL __stdcall +#else +#define LEXILLA_CALL +#endif + +#if defined(__OBJC2__) +// Objective C(++) treats '[' as a message expression. +#define DEPRECATE_DEFINITION +#elif defined(__cplusplus) +#define DEPRECATE_DEFINITION [[deprecated]] +#elif defined(__GNUC__) || defined(__clang__) +#define DEPRECATE_DEFINITION __attribute__((deprecated)) +#else +// MSVC __declspec(deprecated) has different positioning rules to GCC so define to nothing +#define DEPRECATE_DEFINITION +#endif + +#ifdef __cplusplus +// Must have already included ILexer.h to have Scintilla::ILexer5 defined. +using Scintilla::ILexer5; +#else +typedef void ILexer5; +#endif + +typedef ILexer5 *(*LexerFactoryFunction)(); + +#ifdef __cplusplus +namespace Lexilla { +#endif + +typedef int (LEXILLA_CALL *GetLexerCountFn)(); +typedef void (LEXILLA_CALL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); +typedef LexerFactoryFunction(LEXILLA_CALL *GetLexerFactoryFn)(unsigned int Index); +typedef ILexer5*(LEXILLA_CALL *CreateLexerFn)(const char *name); +DEPRECATE_DEFINITION typedef const char *(LEXILLA_CALL *LexerNameFromIDFn)(int identifier); +typedef const char *(LEXILLA_CALL *GetLibraryPropertyNamesFn)(); +typedef void(LEXILLA_CALL *SetLibraryPropertyFn)(const char *key, const char *value); +typedef const char *(LEXILLA_CALL *GetNameSpaceFn)(); + +#ifdef __cplusplus +} +#endif + +#define LEXILLA_NAMESPACE_SEPARATOR '.' + +#define LEXILLA_GETLEXERCOUNT "GetLexerCount" +#define LEXILLA_GETLEXERNAME "GetLexerName" +#define LEXILLA_GETLEXERFACTORY "GetLexerFactory" +#define LEXILLA_CREATELEXER "CreateLexer" +#define LEXILLA_LEXERNAMEFROMID "LexerNameFromID" +#define LEXILLA_GETLIBRARYPROPERTYNAMES "GetLibraryPropertyNames" +#define LEXILLA_SETLIBRARYPROPERTY "SetLibraryProperty" +#define LEXILLA_GETNAMESPACE "GetNameSpace" + +// Static linking prototypes + +#ifdef __cplusplus +extern "C" { +#endif + +ILexer5 * LEXILLA_CALL CreateLexer(const char *name); +int LEXILLA_CALL GetLexerCount(); +void LEXILLA_CALL GetLexerName(unsigned int index, char *name, int buflength); +LexerFactoryFunction LEXILLA_CALL GetLexerFactory(unsigned int index); +DEPRECATE_DEFINITION const char *LEXILLA_CALL LexerNameFromID(int identifier); +const char * LEXILLA_CALL GetLibraryPropertyNames(); +void LEXILLA_CALL SetLibraryProperty(const char *key, const char *value); +const char *LEXILLA_CALL GetNameSpace(); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +namespace Lexilla { + class LexerModule; +} +// Add a static lexer (in the same binary) to Lexilla's list +void AddStaticLexerModule(Lexilla::LexerModule *plm); +#endif + +#endif diff --git a/scintilla/include/SciLexer.h b/scintilla/lexilla/include/SciLexer.h similarity index 98% rename from scintilla/include/SciLexer.h rename to scintilla/lexilla/include/SciLexer.h index 3086688319..762a466638 100644 --- a/scintilla/include/SciLexer.h +++ b/scintilla/lexilla/include/SciLexer.h @@ -144,8 +144,8 @@ #define SCLEX_DATAFLEX 129 #define SCLEX_HOLLYWOOD 130 #define SCLEX_RAKU 131 +#define SCLEX_FSHARP 132 #define SCLEX_JULIA 133 -#define SCLEX_LPEG 999 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 @@ -1982,6 +1982,26 @@ #define SCE_RAKU_CALLABLE 26 #define SCE_RAKU_GRAMMAR 27 #define SCE_RAKU_CLASS 28 +#define SCE_FSHARP_DEFAULT 0 +#define SCE_FSHARP_KEYWORD 1 +#define SCE_FSHARP_KEYWORD2 2 +#define SCE_FSHARP_KEYWORD3 3 +#define SCE_FSHARP_KEYWORD4 4 +#define SCE_FSHARP_KEYWORD5 5 +#define SCE_FSHARP_IDENTIFIER 6 +#define SCE_FSHARP_QUOT_IDENTIFIER 7 +#define SCE_FSHARP_COMMENT 8 +#define SCE_FSHARP_COMMENTLINE 9 +#define SCE_FSHARP_PREPROCESSOR 10 +#define SCE_FSHARP_LINENUM 11 +#define SCE_FSHARP_OPERATOR 12 +#define SCE_FSHARP_NUMBER 13 +#define SCE_FSHARP_CHARACTER 14 +#define SCE_FSHARP_STRING 15 +#define SCE_FSHARP_VERBATIM 16 +#define SCE_FSHARP_QUOTATION 17 +#define SCE_FSHARP_ATTRIBUTE 18 +#define SCE_FSHARP_FORMAT_SPEC 19 /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ #endif diff --git a/scintilla/lexers/LexAbaqus.cxx b/scintilla/lexilla/lexers/LexAbaqus.cxx similarity index 99% rename from scintilla/lexers/LexAbaqus.cxx rename to scintilla/lexilla/lexers/LexAbaqus.cxx index 0b9bfb62a7..e9aba9c9e2 100644 --- a/scintilla/lexers/LexAbaqus.cxx +++ b/scintilla/lexilla/lexers/LexAbaqus.cxx @@ -15,6 +15,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -26,7 +29,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static inline bool IsAKeywordChar(const int ch) { return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' '))); diff --git a/scintilla/lexers/LexAda.cxx b/scintilla/lexilla/lexers/LexAda.cxx similarity index 99% rename from scintilla/lexers/LexAda.cxx rename to scintilla/lexilla/lexers/LexAda.cxx index 9d7f5d0f72..4c2b5d15c6 100644 --- a/scintilla/lexers/LexAda.cxx +++ b/scintilla/lexilla/lexers/LexAda.cxx @@ -13,6 +13,7 @@ #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -25,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; /* * Interface diff --git a/scintilla/lexers/LexAsm.cxx b/scintilla/lexilla/lexers/LexAsm.cxx similarity index 98% rename from scintilla/lexers/LexAsm.cxx rename to scintilla/lexilla/lexers/LexAsm.cxx index 7f9c7d50b4..44f399a26e 100644 --- a/scintilla/lexers/LexAsm.cxx +++ b/scintilla/lexilla/lexers/LexAsm.cxx @@ -17,8 +17,10 @@ #include #include +#include #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -33,6 +35,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || @@ -165,7 +168,7 @@ class LexerAsm : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvIdentity; + return lvRelease5; } const char * SCI_METHOD PropertyNames() override { return osAsm.PropertyNames(); @@ -191,11 +194,11 @@ class LexerAsm : public DefaultLexer { return 0; } - static ILexer *LexerFactoryAsm() { + static ILexer5 *LexerFactoryAsm() { return new LexerAsm("asm", SCLEX_ASM, ';'); } - static ILexer *LexerFactoryAs() { + static ILexer5 *LexerFactoryAs() { return new LexerAsm("as", SCLEX_AS, '#'); } }; diff --git a/scintilla/lexers/LexBash.cxx b/scintilla/lexilla/lexers/LexBash.cxx similarity index 99% rename from scintilla/lexers/LexBash.cxx rename to scintilla/lexilla/lexers/LexBash.cxx index 66bec38469..be66ad9f43 100644 --- a/scintilla/lexers/LexBash.cxx +++ b/scintilla/lexilla/lexers/LexBash.cxx @@ -13,8 +13,10 @@ #include #include +#include #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -31,6 +33,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; #define HERE_DELIM_MAX 256 @@ -210,7 +213,7 @@ class LexerBash : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvIdentity; + return lvRelease5; } const char * SCI_METHOD PropertyNames() override { return osBash.PropertyNames(); @@ -265,7 +268,7 @@ class LexerBash : public DefaultLexer { return styleSubable; } - static ILexer *LexerFactoryBash() { + static ILexer5 *LexerFactoryBash() { return new LexerBash(); } }; diff --git a/scintilla/lexers/LexBasic.cxx b/scintilla/lexilla/lexers/LexBasic.cxx similarity index 98% rename from scintilla/lexers/LexBasic.cxx rename to scintilla/lexilla/lexers/LexBasic.cxx index a288f9daa7..5057fa7d9f 100644 --- a/scintilla/lexers/LexBasic.cxx +++ b/scintilla/lexilla/lexers/LexBasic.cxx @@ -25,7 +25,9 @@ #include #include +#include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -40,6 +42,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; /* Bits: * 1 - whitespace @@ -245,7 +248,7 @@ class LexerBasic : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvIdentity; + return lvRelease5; } const char * SCI_METHOD PropertyNames() override { return osBasic.PropertyNames(); @@ -270,13 +273,13 @@ class LexerBasic : public DefaultLexer { void * SCI_METHOD PrivateCall(int, void *) override { return 0; } - static ILexer *LexerFactoryBlitzBasic() { + static ILexer5 *LexerFactoryBlitzBasic() { return new LexerBasic("blitzbasic", SCLEX_BLITZBASIC, ';', CheckBlitzFoldPoint, blitzbasicWordListDesc); } - static ILexer *LexerFactoryPureBasic() { + static ILexer5 *LexerFactoryPureBasic() { return new LexerBasic("purebasic", SCLEX_PUREBASIC, ';', CheckPureFoldPoint, purebasicWordListDesc); } - static ILexer *LexerFactoryFreeBasic() { + static ILexer5 *LexerFactoryFreeBasic() { return new LexerBasic("freebasic", SCLEX_FREEBASIC, '\'', CheckFreeFoldPoint, freebasicWordListDesc ); } }; diff --git a/scintilla/lexers/LexBatch.cxx b/scintilla/lexilla/lexers/LexBatch.cxx similarity index 91% rename from scintilla/lexers/LexBatch.cxx rename to scintilla/lexilla/lexers/LexBatch.cxx index 857b60ce69..0973d053b8 100644 --- a/scintilla/lexers/LexBatch.cxx +++ b/scintilla/lexilla/lexers/LexBatch.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -23,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static bool Is0To9(char ch) { return (ch >= '0') && (ch <= '9'); @@ -398,14 +401,54 @@ static void ColouriseBatchDoc( // Reset Offset to re-process remainder of word offset -= (wbl - 2); // Check for Expanded Argument (%~...) / Variable (%%~...) + // Expanded Argument: %~[] + // Expanded Variable: %%~[] + // Path operators are exclusively alphabetic. + // Expanded arguments have a single digit at the end. + // Expanded variables have a single identifier character as variable name. } else if (((wbl > 1) && (wordBuffer[1] == '~')) || ((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) { // Check for External Command / Program if (cmdLoc == offset - wbl) { cmdLoc = offset - (wbl - wbo); } - // Colorize Expanded Argument / Variable - styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); + bool isArgument = (wordBuffer[1] == '~'); + if (isArgument) { + Sci_PositionU expansionStopOffset = 2; + bool isValid = false; + for (; expansionStopOffset < wbl; expansionStopOffset++) { + if (isArgument && Is0To9(wordBuffer[expansionStopOffset])) { + expansionStopOffset++; + isValid = true; + wbo = expansionStopOffset; + // Colorize Expanded Argument + styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); + break; + } + } + if (!isValid) { + // not a valid expanded argument or variable + styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); + } + // Expanded Variable + } else { + // start after ~ + wbo = 3; + // Search to end of word for another % (can be a long path) + while ((wbo < wbl) && + (wordBuffer[wbo] != '%') && + (!IsBOperator(wordBuffer[wbo])) && + (!IsBSeparator(wordBuffer[wbo]))) { + wbo++; + } + if (wbo > 3) { + // Colorize Expanded Variable + styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); + } else { + // not a valid expanded argument or variable + styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); + } + } // Reset Offset to re-process remainder of word offset -= (wbl - wbo); // Check for Environment Variable (%x...%) @@ -435,6 +478,14 @@ static void ColouriseBatchDoc( styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER); // Reset Offset to re-process remainder of word offset -= (wbl - 3); + // escaped % + } else if ( + (wbl > 1) && + (wordBuffer[1] == '%')) { + + // Reset Offset to re-process remainder of word + styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_DEFAULT); + offset -= (wbl - 2); } // Check for Environment Variable (!x...!) } else if (wordBuffer[0] == '!') { diff --git a/scintilla/lexers/LexCOBOL.cxx b/scintilla/lexilla/lexers/LexCOBOL.cxx similarity index 99% rename from scintilla/lexers/LexCOBOL.cxx rename to scintilla/lexilla/lexers/LexCOBOL.cxx index f0374824fc..39682f55d2 100644 --- a/scintilla/lexers/LexCOBOL.cxx +++ b/scintilla/lexilla/lexers/LexCOBOL.cxx @@ -15,6 +15,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -26,7 +29,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; #define IN_DIVISION 0x01 #define IN_DECLARATIVES 0x02 diff --git a/scintilla/lexers/LexCPP.cxx b/scintilla/lexilla/lexers/LexCPP.cxx similarity index 94% rename from scintilla/lexers/LexCPP.cxx rename to scintilla/lexilla/lexers/LexCPP.cxx index c7d09a7a3b..050a4b9268 100644 --- a/scintilla/lexers/LexCPP.cxx +++ b/scintilla/lexilla/lexers/LexCPP.cxx @@ -12,10 +12,12 @@ #include #include +#include #include #include #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -33,6 +35,7 @@ #include "SubStyles.h" using namespace Scintilla; +using namespace Lexilla; namespace { // Use an unnamed namespace to protect the functions and classes from name conflicts @@ -257,9 +260,6 @@ class LinePPState { // level is the nesting level of #if constructs int level = -1; static const int maximumNestingLevel = 31; - bool ValidLevel() const noexcept { - return level >= 0 && level < maximumNestingLevel; - } int maskLevel() const noexcept { if (level >= 0) { return 1 << level; @@ -270,6 +270,9 @@ class LinePPState { public: LinePPState() noexcept { } + bool ValidLevel() const noexcept { + return level >= 0 && level < maximumNestingLevel; + } bool IsActive() const noexcept { return state == 0; } @@ -493,11 +496,11 @@ LexicalClass lexicalClasses[] = { 27, "SCE_C_ESCAPESEQUENCE", "literal string escapesequence", "Escape sequence", }; -const int sizeLexicalClasses = static_cast(Sci::size(lexicalClasses)); +const int sizeLexicalClasses = static_cast(std::size(lexicalClasses)); } -class LexerCPP : public ILexerWithIdentity { +class LexerCPP : public ILexer5 { bool caseSensitive; CharacterSet setWord; CharacterSet setNegationOp; @@ -517,7 +520,7 @@ class LexerCPP : public ILexerWithIdentity { struct SymbolValue { std::string value; std::string arguments; - SymbolValue() = default; + SymbolValue() noexcept = default; SymbolValue(const std::string &value_, const std::string &arguments_) : value(value_), arguments(arguments_) { } SymbolValue &operator = (const std::string &value_) { @@ -541,7 +544,7 @@ class LexerCPP : public ILexerWithIdentity { public: explicit LexerCPP(bool caseSensitive_) : caseSensitive(caseSensitive_), - setWord(CharacterSet::setAlphaNum, "._", 0x80, true), + setWord(CharacterSet::setAlphaNum, "._", true), setNegationOp(CharacterSet::setNone, "!"), setAddOp(CharacterSet::setNone, "+-"), setMultOp(CharacterSet::setNone, "*/%"), @@ -560,7 +563,7 @@ class LexerCPP : public ILexerWithIdentity { delete this; } int SCI_METHOD Version() const noexcept override { - return lvIdentity; + return lvRelease5; } const char * SCI_METHOD PropertyNames() override { return osCPP.PropertyNames(); @@ -670,7 +673,7 @@ class LexerCPP : public ILexerWithIdentity { return ""; } - // ILexerWithIdentity methods + // ILexer5 methods const char * SCI_METHOD GetName() override { return caseSensitive ? "cpp" : "cppnocase"; } @@ -679,10 +682,10 @@ class LexerCPP : public ILexerWithIdentity { } const char * SCI_METHOD PropertyGet(const char *key) override; - static ILexer *LexerFactoryCPP() { + static ILexer5 *LexerFactoryCPP() { return new LexerCPP(true); } - static ILexer *LexerFactoryCPPInsensitive() { + static ILexer5 *LexerFactoryCPPInsensitive() { return new LexerCPP(false); } constexpr static int MaskActive(int style) noexcept { @@ -696,7 +699,7 @@ class LexerCPP : public ILexerWithIdentity { Sci_Position SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) { if (osCPP.PropertySet(&options, key, val)) { if (strcmp(key, "lexer.cpp.allow.dollars") == 0) { - setWord = CharacterSet(CharacterSet::setAlphaNum, "._", 0x80, true); + setWord = CharacterSet(CharacterSet::setAlphaNum, "._", true); if (options.identifiersAllowDollars) { setWord.Add('$'); } @@ -778,7 +781,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]"); - setWordStart = CharacterSet(CharacterSet::setAlpha, "_", 0x80, true); + setWordStart = CharacterSet(CharacterSet::setAlpha, "_", true); CharacterSet setInvalidRawFirst(CharacterSet::setNone, " )\\\t\v\f\n"); @@ -1032,6 +1035,10 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i styleBeforeDCKeyword = SCE_C_COMMENTDOC; sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet); } + } else if ((sc.ch == '<' && sc.chNext != '/') + || (sc.ch == '/' && sc.chPrev == '<')) { // XML comment style + styleBeforeDCKeyword = SCE_C_COMMENTDOC; + sc.ForwardSetState(SCE_C_COMMENTDOCKEYWORD | activitySet); } break; case SCE_C_COMMENTLINE: @@ -1051,6 +1058,10 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC; sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet); } + } else if ((sc.ch == '<' && sc.chNext != '/') + || (sc.ch == '/' && sc.chPrev == '<')) { // XML comment style + styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC; + sc.ForwardSetState(SCE_C_COMMENTDOCKEYWORD | activitySet); } break; case SCE_C_COMMENTDOCKEYWORD: @@ -1071,7 +1082,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } if (!(IsASpace(sc.ch) || (sc.ch == 0))) { sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet); - } else if (!keywords3.InList(s + 1)) { + } else if (!keywords3.InList(s + 1) && !keywords3.InList(s)) { int subStyleCDKW = classifierDocKeyWords.ValueFor(s+1); if (subStyleCDKW >= 0) { sc.ChangeState(subStyleCDKW|activitySet); @@ -1081,6 +1092,23 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } sc.SetState(styleBeforeDCKeyword|activitySet); seenDocKeyBrace = false; + } else if (sc.ch == '>') { + char s[100]; + if (caseSensitive) { + sc.GetCurrent(s, sizeof(s)); + } else { + sc.GetCurrentLowered(s, sizeof(s)); + } + if (!keywords3.InList(s)) { + int subStyleCDKW = classifierDocKeyWords.ValueFor(s + 1); + if (subStyleCDKW >= 0) { + sc.ChangeState(subStyleCDKW | activitySet); + } else { + sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR | activitySet); + } + } + sc.SetState(styleBeforeDCKeyword | activitySet); + seenDocKeyBrace = false; } break; case SCE_C_STRING: @@ -1215,6 +1243,8 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i vlls.Add(lineCurrent, preproc); } + const bool atLineEndBeforeStateEntry = sc.atLineEnd; + // Determine if a new state should be entered. if (MaskActive(sc.state) == SCE_C_DEFAULT) { if (sc.Match('@', '\"')) { @@ -1294,12 +1324,10 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i do { sc.Forward(); } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); - if (sc.atLineEnd) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } else if (sc.Match("include")) { + if (sc.Match("include")) { isIncludePreprocessor = true; } else { - if (options.trackPreprocessor) { + if (options.trackPreprocessor && IsAlphaNumeric(sc.ch)) { // If #if is nested too deeply (>31 levels) the active/inactive appearance // will stop reflecting the code. if (sc.Match("ifdef") || sc.Match("ifndef")) { @@ -1315,43 +1343,48 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } else if (sc.Match("else")) { // #else is shown as active if either preceding or following section is active // as that means that it contributed to the result. - if (!preproc.CurrentIfTaken()) { - // Inactive, may become active if parent scope active - assert(sc.state == (SCE_C_PREPROCESSOR|inactiveFlag)); - preproc.InvertCurrentLevel(); - activitySet = preproc.ActiveState(); - // If following is active then show "else" as active - if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR); - } else if (preproc.IsActive()) { - // Active -> inactive - assert(sc.state == SCE_C_PREPROCESSOR); - preproc.InvertCurrentLevel(); - activitySet = preproc.ActiveState(); - // Continue to show "else" as active as it ends active section. + if (preproc.ValidLevel()) { + // If #else has no corresponding #if then take no action as invalid + if (!preproc.CurrentIfTaken()) { + // Inactive, may become active if parent scope active + assert(sc.state == (SCE_C_PREPROCESSOR | inactiveFlag)); + preproc.InvertCurrentLevel(); + activitySet = preproc.ActiveState(); + // If following is active then show "else" as active + if (!activitySet) + sc.ChangeState(SCE_C_PREPROCESSOR); + } else if (preproc.IsActive()) { + // Active -> inactive + assert(sc.state == SCE_C_PREPROCESSOR); + preproc.InvertCurrentLevel(); + activitySet = preproc.ActiveState(); + // Continue to show "else" as active as it ends active section. + } } } else if (sc.Match("elif")) { // Ensure only one chosen out of #if .. #elif .. #elif .. #else .. #endif // #elif is shown as active if either preceding or following section is active // as that means that it contributed to the result. - if (!preproc.CurrentIfTaken()) { - // Inactive, if expression true then may become active if parent scope active - assert(sc.state == (SCE_C_PREPROCESSOR|inactiveFlag)); - // Similar to #if - std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 4, true); - const bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions); - if (ifGood) { + if (preproc.ValidLevel()) { + if (!preproc.CurrentIfTaken()) { + // Inactive, if expression true then may become active if parent scope active + assert(sc.state == (SCE_C_PREPROCESSOR | inactiveFlag)); + // Similar to #if + std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 4, true); + const bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions); + if (ifGood) { + preproc.InvertCurrentLevel(); + activitySet = preproc.ActiveState(); + if (!activitySet) + sc.ChangeState(SCE_C_PREPROCESSOR); + } + } else if (preproc.IsActive()) { + // Active -> inactive + assert(sc.state == SCE_C_PREPROCESSOR); preproc.InvertCurrentLevel(); activitySet = preproc.ActiveState(); - if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR); + // Continue to show "elif" as active as it ends active section. } - } else if (preproc.IsActive()) { - // Active -> inactive - assert(sc.state == SCE_C_PREPROCESSOR); - preproc.InvertCurrentLevel(); - activitySet = preproc.ActiveState(); - // Continue to show "elif" as active as it ends active section. } } else if (sc.Match("endif")) { preproc.EndSection(); @@ -1414,6 +1447,13 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } } + if (sc.atLineEnd && !atLineEndBeforeStateEntry) { + // State entry processing consumed characters up to end of line. + lineCurrent++; + lineEndNext = styler.LineEnd(lineCurrent); + vlls.Add(lineCurrent, preproc); + } + if (!IsASpace(sc.ch) && !IsSpaceEquiv(MaskActive(sc.state))) { chPrevNonWhite = sc.ch; visibleChars++; diff --git a/scintilla/lexers/LexCSS.cxx b/scintilla/lexilla/lexers/LexCSS.cxx similarity index 99% rename from scintilla/lexers/LexCSS.cxx rename to scintilla/lexilla/lexers/LexCSS.cxx index c1a86f5371..2cfcd125a9 100644 --- a/scintilla/lexers/LexCSS.cxx +++ b/scintilla/lexilla/lexers/LexCSS.cxx @@ -21,6 +21,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -32,7 +35,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static inline bool IsAWordChar(const unsigned int ch) { diff --git a/scintilla/lexers/LexCaml.cxx b/scintilla/lexilla/lexers/LexCaml.cxx similarity index 73% rename from scintilla/lexers/LexCaml.cxx rename to scintilla/lexilla/lexers/LexCaml.cxx index 1339b5dcc7..72bb3f39aa 100644 --- a/scintilla/lexers/LexCaml.cxx +++ b/scintilla/lexilla/lexers/LexCaml.cxx @@ -25,11 +25,13 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" -#include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" @@ -50,138 +52,9 @@ static const int baseT[24] = { 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */ }; -using namespace Scintilla; - -#ifdef BUILD_AS_EXTERNAL_LEXER -/* - (actually seems to work!) -*/ -#include -#include "WindowAccessor.h" -#include "ExternalLexer.h" - -#undef EXT_LEXER_DECL -#define EXT_LEXER_DECL __declspec( dllexport ) __stdcall - -#if PLAT_WIN -#include -#endif +using namespace Lexilla; static void ColouriseCamlDoc( - Sci_PositionU startPos, Sci_Position length, - int initStyle, - WordList *keywordlists[], - Accessor &styler); - -static void FoldCamlDoc( - Sci_PositionU startPos, Sci_Position length, - int initStyle, - WordList *keywordlists[], - Accessor &styler); - -static void InternalLexOrFold(int lexOrFold, Sci_PositionU startPos, Sci_Position length, - int initStyle, char *words[], WindowID window, char *props); - -static const char* LexerName = "caml"; - -#ifdef TRACE -void Platform::DebugPrintf(const char *format, ...) { - char buffer[2000]; - va_list pArguments; - va_start(pArguments, format); - vsprintf(buffer,format,pArguments); - va_end(pArguments); - Platform::DebugDisplay(buffer); -} -#else -void Platform::DebugPrintf(const char *, ...) { -} -#endif - -bool Platform::IsDBCSLeadByte(int codePage, char ch) { - return ::IsDBCSLeadByteEx(codePage, ch) != 0; -} - -long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) { - return ::SendMessage(reinterpret_cast(w), msg, wParam, lParam); -} - -long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) { - return ::SendMessage(reinterpret_cast(w), msg, wParam, - reinterpret_cast(lParam)); -} - -void EXT_LEXER_DECL Fold(unsigned int lexer, Sci_PositionU startPos, Sci_Position length, - int initStyle, char *words[], WindowID window, char *props) -{ - // below useless evaluation(s) to supress "not used" warnings - lexer; - // build expected data structures and do the Fold - InternalLexOrFold(1, startPos, length, initStyle, words, window, props); - -} - -int EXT_LEXER_DECL GetLexerCount() -{ - return 1; // just us [Objective] Caml lexers here! -} - -void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength) -{ - // below useless evaluation(s) to supress "not used" warnings - Index; - // return as much of our lexer name as will fit (what's up with Index?) - if (buflength > 0) { - buflength--; - int n = strlen(LexerName); - if (n > buflength) - n = buflength; - memcpy(name, LexerName, n), name[n] = '\0'; - } -} - -void EXT_LEXER_DECL Lex(unsigned int lexer, Sci_PositionU startPos, Sci_Position length, - int initStyle, char *words[], WindowID window, char *props) -{ - // below useless evaluation(s) to supress "not used" warnings - lexer; - // build expected data structures and do the Lex - InternalLexOrFold(0, startPos, length, initStyle, words, window, props); -} - -static void InternalLexOrFold(int foldOrLex, Sci_PositionU startPos, Sci_Position length, - int initStyle, char *words[], WindowID window, char *props) -{ - // create and initialize a WindowAccessor (including contained PropSet) - PropSetSimple ps; - ps.SetMultiple(props); - WindowAccessor wa(window, ps); - // create and initialize WordList(s) - int nWL = 0; - for (; words[nWL]; nWL++) ; // count # of WordList PTRs needed - WordList** wl = new WordList* [nWL + 1];// alloc WordList PTRs - int i = 0; - for (; i < nWL; i++) { - wl[i] = new WordList(); // (works or THROWS bad_alloc EXCEPTION) - wl[i]->Set(words[i]); - } - wl[i] = 0; - // call our "internal" folder/lexer (... then do Flush!) - if (foldOrLex) - FoldCamlDoc(startPos, length, initStyle, wl, wa); - else - ColouriseCamlDoc(startPos, length, initStyle, wl, wa); - wa.Flush(); - // clean up before leaving - for (i = nWL - 1; i >= 0; i--) - delete wl[i]; - delete [] wl; -} - -static -#endif /* BUILD_AS_EXTERNAL_LEXER */ - -void ColouriseCamlDoc( Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], @@ -437,9 +310,7 @@ void ColouriseCamlDoc( sc.Complete(); } -#ifdef BUILD_AS_EXTERNAL_LEXER static -#endif /* BUILD_AS_EXTERNAL_LEXER */ void FoldCamlDoc( Sci_PositionU, Sci_Position, int, @@ -455,6 +326,4 @@ static const char * const camlWordListDesc[] = { 0 }; -#ifndef BUILD_AS_EXTERNAL_LEXER LexerModule lmCaml(SCLEX_CAML, ColouriseCamlDoc, "caml", FoldCamlDoc, camlWordListDesc); -#endif /* BUILD_AS_EXTERNAL_LEXER */ diff --git a/scintilla/lexers/LexCmake.cxx b/scintilla/lexilla/lexers/LexCmake.cxx similarity index 99% rename from scintilla/lexers/LexCmake.cxx rename to scintilla/lexilla/lexers/LexCmake.cxx index e3835c5c35..5302c20969 100644 --- a/scintilla/lexers/LexCmake.cxx +++ b/scintilla/lexilla/lexers/LexCmake.cxx @@ -13,6 +13,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -24,7 +27,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static bool isCmakeNumber(char ch) { diff --git a/scintilla/lexers/LexCoffeeScript.cxx b/scintilla/lexilla/lexers/LexCoffeeScript.cxx similarity index 99% rename from scintilla/lexers/LexCoffeeScript.cxx rename to scintilla/lexilla/lexers/LexCoffeeScript.cxx index a001623354..317497a20a 100644 --- a/scintilla/lexers/LexCoffeeScript.cxx +++ b/scintilla/lexilla/lexers/LexCoffeeScript.cxx @@ -14,6 +14,9 @@ #include #include +#include +#include + #include #include "ILexer.h" @@ -27,7 +30,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static bool IsSpaceEquiv(int state) { return (state == SCE_COFFEESCRIPT_DEFAULT diff --git a/scintilla/lexers/LexD.cxx b/scintilla/lexilla/lexers/LexD.cxx similarity index 98% rename from scintilla/lexers/LexD.cxx rename to scintilla/lexilla/lexers/LexD.cxx index a661b4f133..5b8dab9b8f 100644 --- a/scintilla/lexers/LexD.cxx +++ b/scintilla/lexilla/lexers/LexD.cxx @@ -15,7 +15,9 @@ #include #include +#include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -30,6 +32,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; /* Nested comments require keeping the value of the nesting level for every position in the document. But since scintilla always styles line by line, @@ -166,7 +169,7 @@ class LexerD : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvIdentity; + return lvRelease5; } const char * SCI_METHOD PropertyNames() override { return osD.PropertyNames(); @@ -192,10 +195,10 @@ class LexerD : public DefaultLexer { return 0; } - static ILexer *LexerFactoryD() { + static ILexer5 *LexerFactoryD() { return new LexerD(true); } - static ILexer *LexerFactoryDInsensitive() { + static ILexer5 *LexerFactoryDInsensitive() { return new LexerD(false); } }; diff --git a/scintilla/lexers/LexDiff.cxx b/scintilla/lexilla/lexers/LexDiff.cxx similarity index 98% rename from scintilla/lexers/LexDiff.cxx rename to scintilla/lexilla/lexers/LexDiff.cxx index dd008c5cb4..9fdd7e4f49 100644 --- a/scintilla/lexers/LexDiff.cxx +++ b/scintilla/lexilla/lexers/LexDiff.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -23,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static inline bool AtEOL(Accessor &styler, Sci_PositionU i) { return (styler[i] == '\n') || diff --git a/scintilla/lexers/LexErlang.cxx b/scintilla/lexilla/lexers/LexErlang.cxx similarity index 98% rename from scintilla/lexers/LexErlang.cxx rename to scintilla/lexilla/lexers/LexErlang.cxx index 4ca5962c30..b08f99b2a1 100644 --- a/scintilla/lexers/LexErlang.cxx +++ b/scintilla/lexilla/lexers/LexErlang.cxx @@ -16,6 +16,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -27,7 +30,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static int is_radix(int radix, int ch) { int digit; @@ -142,7 +145,7 @@ static void ColouriseErlangDoc(Sci_PositionU startPos, Sci_Position length, int } // All comments types fall here. - if (sc.atLineEnd) { + if (sc.MatchLineEnd()) { to_late_to_comment = false; sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; @@ -173,7 +176,7 @@ static void ColouriseErlangDoc(Sci_PositionU startPos, Sci_Position length, int parse_state = old_parse_state; } - if (sc.atLineEnd) { + if (sc.MatchLineEnd()) { to_late_to_comment = false; sc.ChangeState(old_style); sc.SetState(SCE_ERLANG_DEFAULT); @@ -194,11 +197,15 @@ static void ColouriseErlangDoc(Sci_PositionU startPos, Sci_Position length, int parse_state = STATE_NULL; } else { sc.Forward(); - if (isalnum(sc.ch)) { + if (isalnum(sc.ch) || (sc.ch == '\'')) { sc.GetCurrent(cur, sizeof(cur)); sc.ChangeState(SCE_ERLANG_MODULES); sc.SetState(SCE_ERLANG_MODULES); } + if (sc.ch == '\'') { + parse_state = ATOM_QUOTED; + } + } } else if (!IsAWordChar(sc.ch)) { @@ -225,7 +232,7 @@ static void ColouriseErlangDoc(Sci_PositionU startPos, Sci_Position length, int if ( '@' == sc.ch ){ parse_state = NODE_NAME_QUOTED; } else if ('\'' == sc.ch && '\\' != sc.chPrev) { - sc.ChangeState(SCE_ERLANG_ATOM); + sc.ChangeState(SCE_ERLANG_ATOM_QUOTED); sc.ForwardSetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } diff --git a/scintilla/lexers/LexForth.cxx b/scintilla/lexilla/lexers/LexForth.cxx similarity index 98% rename from scintilla/lexers/LexForth.cxx rename to scintilla/lexilla/lexers/LexForth.cxx index 80842097d1..bea5256810 100644 --- a/scintilla/lexers/LexForth.cxx +++ b/scintilla/lexilla/lexers/LexForth.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -23,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static inline bool IsAWordStart(int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.'); diff --git a/scintilla/lexers/LexFortran.cxx b/scintilla/lexilla/lexers/LexFortran.cxx similarity index 99% rename from scintilla/lexers/LexFortran.cxx rename to scintilla/lexilla/lexers/LexFortran.cxx index 28298b3ed6..a7d79cb802 100644 --- a/scintilla/lexers/LexFortran.cxx +++ b/scintilla/lexilla/lexers/LexFortran.cxx @@ -12,6 +12,9 @@ #include #include #include + +#include +#include /***************************************/ #include "ILexer.h" #include "Scintilla.h" @@ -25,7 +28,7 @@ #include "LexerModule.h" /***************************************/ -using namespace Scintilla; +using namespace Lexilla; /***********************************************/ static inline bool IsAWordChar(const int ch) { diff --git a/scintilla/lexers/LexHTML.cxx b/scintilla/lexilla/lexers/LexHTML.cxx similarity index 97% rename from scintilla/lexers/LexHTML.cxx rename to scintilla/lexilla/lexers/LexHTML.cxx index 9d474fb0eb..ea6696519b 100644 --- a/scintilla/lexers/LexHTML.cxx +++ b/scintilla/lexilla/lexers/LexHTML.cxx @@ -11,14 +11,16 @@ #include #include #include + #include +#include #include #include +#include #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" -#include "StringCopy.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" @@ -29,6 +31,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; namespace { @@ -532,7 +535,7 @@ bool isPHPStringState(int state) { Sci_Position FindPhpStringDelimiter(std::string &phpStringDelimiter, Sci_Position i, const Sci_Position lengthDoc, Accessor &styler, bool &isSimpleString) { Sci_Position j; const Sci_Position beginning = i - 1; - bool isValidSimpleString = false; + bool isQuoted = false; while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t')) i++; @@ -540,10 +543,11 @@ Sci_Position FindPhpStringDelimiter(std::string &phpStringDelimiter, Sci_Positio const char chNext = styler.SafeGetCharAt(i + 1); phpStringDelimiter.clear(); if (!IsPhpWordStart(ch)) { - if (ch == '\'' && IsPhpWordStart(chNext)) { + if ((ch == '\'' || ch == '\"') && IsPhpWordStart(chNext)) { + isSimpleString = ch == '\''; + isQuoted = true; i++; ch = chNext; - isSimpleString = true; } else { return beginning; } @@ -551,9 +555,9 @@ Sci_Position FindPhpStringDelimiter(std::string &phpStringDelimiter, Sci_Positio phpStringDelimiter.push_back(ch); i++; for (j = i; j < lengthDoc && !isLineEnd(styler[j]); j++) { - if (!IsPhpWordChar(styler[j])) { - if (isSimpleString && (styler[j] == '\'') && isLineEnd(styler.SafeGetCharAt(j + 1))) { - isValidSimpleString = true; + if (!IsPhpWordChar(styler[j]) && isQuoted) { + if (((isSimpleString && styler[j] == '\'') || (!isSimpleString && styler[j] == '\"')) && isLineEnd(styler.SafeGetCharAt(j + 1))) { + isQuoted = false; j++; break; } else { @@ -563,7 +567,7 @@ Sci_Position FindPhpStringDelimiter(std::string &phpStringDelimiter, Sci_Positio } phpStringDelimiter.push_back(styler[j]); } - if (isSimpleString && !isValidSimpleString) { + if (isQuoted) { phpStringDelimiter.clear(); return beginning; } @@ -865,8 +869,8 @@ class LexerHTML : public DefaultLexer { DefaultLexer( isXml_ ? "xml" : (isPHPScript_ ? "phpscript" : "hypertext"), isXml_ ? SCLEX_XML : (isPHPScript_ ? SCLEX_PHPSCRIPT : SCLEX_HTML), - isXml_ ? lexicalClassesHTML : lexicalClassesXML, - isXml_ ? Sci::size(lexicalClassesHTML) : Sci::size(lexicalClassesXML)), + isXml_ ? lexicalClassesXML : lexicalClassesHTML, + isXml_ ? std::size(lexicalClassesXML) : std::size(lexicalClassesHTML)), isXml(isXml_), isPHPScript(isPHPScript_), osHTML(isPHPScript_), @@ -897,13 +901,13 @@ class LexerHTML : public DefaultLexer { void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; // No Fold as all folding performs in Lex. - static ILexer *LexerFactoryHTML() { + static ILexer5 *LexerFactoryHTML() { return new LexerHTML(false, false); } - static ILexer *LexerFactoryXML() { + static ILexer5 *LexerFactoryXML() { return new LexerHTML(true, false); } - static ILexer *LexerFactoryPHPScript() { + static ILexer5 *LexerFactoryPHPScript() { return new LexerHTML(false, true); } }; @@ -1029,9 +1033,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int const bool allowScripts = options.allowScripts; const bool isMako = options.isMako; const bool isDjango = options.isDjango; - const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true); - const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true); - const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true); + const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", true); + const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", true); + const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", true); // TODO: also handle + and - (except if they're part of ++ or --) and return keywords const CharacterSet setOKBeforeJSRE(CharacterSet::setNone, "([{=,:;!%^&*|?~"); @@ -1393,6 +1397,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int i += 2; // place as if it was the second next char treated visibleChars += 2; state = SCE_H_ASPAT; + scriptLanguage = eScriptVBS; } else if ((chNext2 == '-') && (styler.SafeGetCharAt(i + 3) == '-')) { styler.ColourTo(i + 3, SCE_H_ASP); state = SCE_H_XCCOMMENT; @@ -1408,8 +1413,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int } state = StateForScript(aspScript); + scriptLanguage = aspScript; } - scriptLanguage = eScriptVBS; styler.ColourTo(i, SCE_H_ASP); // fold whole script if (foldHTMLPreprocessor) @@ -2034,10 +2039,6 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int } else if (ch == '\"') { styler.ColourTo(i, statePrintForState(SCE_HJ_DOUBLESTRING, inScriptType)); state = SCE_HJ_DEFAULT; - } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_COMMENTLINE; - i += 2; } else if (isLineEnd(ch)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_STRINGEOL; @@ -2051,10 +2052,6 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int } else if (ch == '\'') { styler.ColourTo(i, statePrintForState(SCE_HJ_SINGLESTRING, inScriptType)); state = SCE_HJ_DEFAULT; - } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_COMMENTLINE; - i += 2; } else if (isLineEnd(ch)) { styler.ColourTo(i - 1, StateToPrint); if (chPrev != '\\' && (chPrev2 != '\\' || chPrev != '\r' || ch != '\n')) { @@ -2284,7 +2281,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int } else if (ch == '/' && chNext == '/') { i++; state = SCE_HPHP_COMMENTLINE; - } else if (ch == '#') { + } else if (ch == '#' && chNext != '[') { state = SCE_HPHP_COMMENTLINE; } else if (ch == '\"') { state = SCE_HPHP_HSTRING; @@ -2311,7 +2308,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int case SCE_HPHP_NUMBER: // recognize bases 8,10 or 16 integers OR floating-point numbers if (!IsADigit(ch) - && strchr(".xXabcdefABCDEF", ch) == NULL + && strchr(".xXabcdefABCDEF_", ch) == NULL && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) { styler.ColourTo(i - 1, SCE_HPHP_NUMBER); if (IsOperator(ch)) @@ -2353,13 +2350,10 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int if (phpStringDelimiter == "\"") { styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; - } else if (isLineEnd(chPrev)) { + } else if (lineStartVisibleChars == 1) { const int psdLength = static_cast(phpStringDelimiter.length()); - const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); - const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); - if (isLineEnd(chAfterPsd) || - (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) { - i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1; + if (!IsPhpWordChar(styler.SafeGetCharAt(i + psdLength))) { + i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1; styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; if (foldHeredoc) levelCurrent--; @@ -2376,12 +2370,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; } - } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter.c_str())) { + } else if (lineStartVisibleChars == 1 && styler.Match(i, phpStringDelimiter.c_str())) { const int psdLength = static_cast(phpStringDelimiter.length()); - const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); - const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); - if (isLineEnd(chAfterPsd) || - (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) { + if (!IsPhpWordChar(styler.SafeGetCharAt(i + psdLength))) { i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1; styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; @@ -2414,7 +2405,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int } else if (ch == '/' && chNext == '/') { i++; state = SCE_HPHP_COMMENTLINE; - } else if (ch == '#') { + } else if (ch == '#' && chNext != '[') { state = SCE_HPHP_COMMENTLINE; } else if (ch == '\"') { state = SCE_HPHP_HSTRING; diff --git a/scintilla/lexers/LexHaskell.cxx b/scintilla/lexilla/lexers/LexHaskell.cxx similarity index 99% rename from scintilla/lexers/LexHaskell.cxx rename to scintilla/lexilla/lexers/LexHaskell.cxx index 93c670a0cd..8f8ce75251 100644 --- a/scintilla/lexers/LexHaskell.cxx +++ b/scintilla/lexilla/lexers/LexHaskell.cxx @@ -26,8 +26,10 @@ #include #include +#include #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -45,6 +47,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; // See https://github.com/ghc/ghc/blob/master/compiler/parser/Lexer.x#L1682 // Note, letter modifiers are prohibited. @@ -402,7 +405,7 @@ class LexerHaskell : public DefaultLexer { } int SCI_METHOD Version() const override { - return lvIdentity; + return lvRelease5; } const char * SCI_METHOD PropertyNames() override { @@ -437,11 +440,11 @@ class LexerHaskell : public DefaultLexer { return 0; } - static ILexer *LexerFactoryHaskell() { + static ILexer5 *LexerFactoryHaskell() { return new LexerHaskell(false); } - static ILexer *LexerFactoryLiterateHaskell() { + static ILexer5 *LexerFactoryLiterateHaskell() { return new LexerHaskell(true); } }; diff --git a/scintilla/lexers/LexJulia.cxx b/scintilla/lexilla/lexers/LexJulia.cxx similarity index 99% rename from scintilla/lexers/LexJulia.cxx rename to scintilla/lexilla/lexers/LexJulia.cxx index ccf947dc4f..7bbbe51efa 100644 --- a/scintilla/lexers/LexJulia.cxx +++ b/scintilla/lexilla/lexers/LexJulia.cxx @@ -27,7 +27,6 @@ #include "StringCopy.h" #include "PropSetSimple.h" -#include "StringCopy.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" @@ -39,8 +38,7 @@ #include "DefaultLexer.h" using namespace Scintilla; -// Geany still uses Scintilla v3.5 -//using namespace Lexilla; +using namespace Lexilla; static const int MAX_JULIA_IDENT_CHARS = 1023; @@ -139,9 +137,7 @@ class LexerJulia : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - // Geany still uses Scintilla v3.5 - //return lvRelease5; - return lvIdentity; + return lvRelease5; } const char * SCI_METHOD PropertyNames() override { return osJulia.PropertyNames(); @@ -166,9 +162,7 @@ class LexerJulia : public DefaultLexer { return 0; } - // Geany still uses Scintilla v3.5 - //static ILexer5 *LexerFactoryJulia() { - static ILexer *LexerFactoryJulia() { + static ILexer5 *LexerFactoryJulia() { return new LexerJulia(); } }; diff --git a/scintilla/lexers/LexLaTeX.cxx b/scintilla/lexilla/lexers/LexLaTeX.cxx similarity index 99% rename from scintilla/lexers/LexLaTeX.cxx rename to scintilla/lexilla/lexers/LexLaTeX.cxx index 4b6cbdc6e2..c4e1cf4b96 100644 --- a/scintilla/lexers/LexLaTeX.cxx +++ b/scintilla/lexilla/lexers/LexLaTeX.cxx @@ -13,6 +13,9 @@ #include #include #include + +#include +#include #include #include "ILexer.h" @@ -30,6 +33,7 @@ #include "LexerBase.h" using namespace Scintilla; +using namespace Lexilla; using namespace std; @@ -84,13 +88,13 @@ class LexerLaTeX : public LexerBase { saves.resize(numLines + 128); } public: - static ILexer *LexerFactoryLaTeX() { + static ILexer5 *LexerFactoryLaTeX() { return new LexerLaTeX(); } void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; - // ILexerWithIdentity methods + // ILexer5 methods const char * SCI_METHOD GetName() override { return "latex"; } diff --git a/scintilla/lexers/LexLisp.cxx b/scintilla/lexilla/lexers/LexLisp.cxx similarity index 99% rename from scintilla/lexers/LexLisp.cxx rename to scintilla/lexilla/lexers/LexLisp.cxx index 8e75863558..d482541a68 100644 --- a/scintilla/lexers/LexLisp.cxx +++ b/scintilla/lexilla/lexers/LexLisp.cxx @@ -13,6 +13,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -24,7 +27,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; #define SCE_LISP_CHARACTER 29 #define SCE_LISP_MACRO 30 diff --git a/scintilla/lexers/LexLua.cxx b/scintilla/lexilla/lexers/LexLua.cxx similarity index 93% rename from scintilla/lexers/LexLua.cxx rename to scintilla/lexilla/lexers/LexLua.cxx index 9e6e8a70c6..fc9cef97da 100644 --- a/scintilla/lexers/LexLua.cxx +++ b/scintilla/lexilla/lexers/LexLua.cxx @@ -15,6 +15,7 @@ #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -28,7 +29,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; // Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ], // return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on. @@ -59,8 +60,8 @@ static void ColouriseLuaDoc( const WordList &keywords8 = *keywordlists[7]; // Accepts accented characters - CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); - CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); + CharacterSet setWordStart(CharacterSet::setAlpha, "_", true); + CharacterSet setWord(CharacterSet::setAlphaNum, "_", true); // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. [pP] is for hex floats. CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP"); @@ -69,17 +70,15 @@ static void ColouriseLuaDoc( CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\"); Sci_Position currentLine = styler.GetLine(startPos); - // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level, + // Initialize long string [[ ... ]] or block comment --[[ ... ]], // if we are inside such a string. Block comment was introduced in Lua 5.0, // blocks with separators [=[ ... ]=] in Lua 5.1. // Continuation of a string (\z whitespace escaping) is controlled by stringWs. - int nestLevel = 0; int sepCount = 0; int stringWs = 0; if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT || initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) { const int lineState = styler.GetLineState(currentLine - 1); - nestLevel = lineState >> 9; sepCount = lineState & 0xFF; stringWs = lineState & 0x100; } @@ -110,7 +109,7 @@ static void ColouriseLuaDoc( case SCE_LUA_STRING: case SCE_LUA_CHARACTER: // Inside a literal string, block comment or string, we set the line state - styler.SetLineState(currentLine, (nestLevel << 9) | stringWs | sepCount); + styler.SetLineState(currentLine, stringWs | sepCount); break; default: // Reset the line state @@ -254,25 +253,11 @@ static void ColouriseLuaDoc( sc.ChangeState(SCE_LUA_STRINGEOL); sc.ForwardSetState(SCE_LUA_DEFAULT); } - } else if (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT) { - if (sc.ch == '[') { - const int sep = LongDelimCheck(sc); - if (sep == 1 && sepCount == 1) { // [[-only allowed to nest - nestLevel++; - sc.Forward(); - } - } else if (sc.ch == ']') { - int sep = LongDelimCheck(sc); - if (sep == 1 && sepCount == 1) { // un-nest with ]]-only - nestLevel--; - sc.Forward(); - if (nestLevel == 0) { - sc.ForwardSetState(SCE_LUA_DEFAULT); - } - } else if (sep > 1 && sep == sepCount) { // ]=]-style delim - sc.Forward(sep); - sc.ForwardSetState(SCE_LUA_DEFAULT); - } + } else if (sc.ch == ']' && (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT)) { + const int sep = LongDelimCheck(sc); + if (sep == sepCount) { // ]=]-style delim + sc.Forward(sep); + sc.ForwardSetState(SCE_LUA_DEFAULT); } } @@ -356,7 +341,6 @@ static void ColouriseLuaDoc( if (sepCount == 0) { sc.SetState(SCE_LUA_OPERATOR); } else { - nestLevel = 1; sc.SetState(SCE_LUA_LITERALSTRING); sc.Forward(sepCount); } @@ -366,7 +350,6 @@ static void ColouriseLuaDoc( sc.Forward(2); sepCount = LongDelimCheck(sc); if (sepCount > 0) { - nestLevel = 1; sc.ChangeState(SCE_LUA_COMMENT); sc.Forward(sepCount); } @@ -384,7 +367,7 @@ static void ColouriseLuaDoc( sc.Complete(); } -static void FoldLuaDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[], +static void FoldLuaDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler) { const Sci_PositionU lengthDoc = startPos + length; int visibleChars = 0; @@ -393,12 +376,14 @@ static void FoldLuaDoc(Sci_PositionU startPos, Sci_Position length, int /* initS int levelCurrent = levelPrev; char chNext = styler[startPos]; const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + int style = initStyle; int styleNext = styler.StyleAt(startPos); for (Sci_PositionU i = startPos; i < lengthDoc; i++) { const char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); - const int style = styleNext; + const int stylePrev = style; + style = styleNext; styleNext = styler.StyleAt(i + 1); const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_LUA_WORD) { @@ -426,9 +411,9 @@ static void FoldLuaDoc(Sci_PositionU startPos, Sci_Position length, int /* initS levelCurrent--; } } else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) { - if (ch == '[') { + if (stylePrev != style) { levelCurrent++; - } else if (ch == ']') { + } else if (styleNext != style) { levelCurrent--; } } diff --git a/scintilla/lexers/LexMake.cxx b/scintilla/lexilla/lexers/LexMake.cxx similarity index 98% rename from scintilla/lexers/LexMake.cxx rename to scintilla/lexilla/lexers/LexMake.cxx index b3dc12aa1d..3e8451255c 100644 --- a/scintilla/lexers/LexMake.cxx +++ b/scintilla/lexilla/lexers/LexMake.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -23,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static inline bool AtEOL(Accessor &styler, Sci_PositionU i) { return (styler[i] == '\n') || diff --git a/scintilla/lexers/LexMarkdown.cxx b/scintilla/lexilla/lexers/LexMarkdown.cxx similarity index 87% rename from scintilla/lexers/LexMarkdown.cxx rename to scintilla/lexilla/lexers/LexMarkdown.cxx index e3410f6cad..7e0c567cca 100644 --- a/scintilla/lexers/LexMarkdown.cxx +++ b/scintilla/lexilla/lexers/LexMarkdown.cxx @@ -40,6 +40,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -51,7 +54,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static inline bool IsNewline(const int ch) { return (ch == '\n' || ch == '\r'); @@ -59,7 +62,7 @@ static inline bool IsNewline(const int ch) { // True if can follow ch down to the end with possibly trailing whitespace static bool FollowToLineEnd(const int ch, const int state, const Sci_PositionU endPos, StyleContext &sc) { - Sci_PositionU i = 0; + Sci_Position i = 0; while (sc.GetRelative(++i) == ch) ; // Skip over whitespace @@ -103,9 +106,10 @@ static bool HasPrevLineContent(StyleContext &sc) { while ((--i + (Sci_Position)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i))) ; while ((--i + (Sci_Position)sc.currentPos) >= 0) { - if (IsNewline(sc.GetRelative(i))) + const int ch = sc.GetRelative(i); + if (ch == '\n') break; - if (!IsASpaceOrTab(sc.GetRelative(i))) + if (!((ch == '\r' || IsASpaceOrTab(ch)))) return true; } return false; @@ -115,9 +119,25 @@ static bool AtTermStart(StyleContext &sc) { return sc.currentPos == 0 || sc.chPrev == 0 || isspacechar(sc.chPrev); } +static bool IsCompleteStyleRegion(StyleContext &sc, const char *token) { + bool found = false; + const size_t start = strlen(token); + Sci_Position i = static_cast(start); + while (!IsNewline(sc.GetRelative(i))) { + // make sure an empty pair of single-char tokens doesn't match + // with a longer token: {*}{*} != {**} + if (sc.GetRelative(i) == *token && sc.GetRelative(i - 1) != *token) { + found = start > 1U ? sc.GetRelative(i + 1) == token[1] : true; + break; + } + i++; + } + return AtTermStart(sc) && found; +} + static bool IsValidHrule(const Sci_PositionU endPos, StyleContext &sc) { int count = 1; - Sci_PositionU i = 0; + Sci_Position i = 0; for (;;) { ++i; int c = sc.GetRelative(i); @@ -151,7 +171,7 @@ static void ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int // in the default state. bool freezeCursor = false; - StyleContext sc(startPos, length, initStyle, styler); + StyleContext sc(startPos, static_cast(length), initStyle, styler); while (sc.More()) { // Skip past escaped characters @@ -166,8 +186,9 @@ static void ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int // Conditional state-based actions if (sc.state == SCE_MARKDOWN_CODE2) { - if (sc.Match("``") && sc.GetRelative(-2) != ' ') { - sc.Forward(2); + if (sc.Match("``")) { + const int closingSpan = (sc.GetRelative(2) == '`') ? 3 : 2; + sc.Forward(closingSpan); sc.SetState(SCE_MARKDOWN_DEFAULT); } } @@ -202,24 +223,24 @@ static void ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int */ // Strong else if (sc.state == SCE_MARKDOWN_STRONG1) { - if (sc.Match("**") && sc.chPrev != ' ') { + if ((sc.Match("**") && sc.chPrev != ' ') || IsNewline(sc.GetRelative(2))) { sc.Forward(2); sc.SetState(SCE_MARKDOWN_DEFAULT); } } else if (sc.state == SCE_MARKDOWN_STRONG2) { - if (sc.Match("__") && sc.chPrev != ' ') { + if ((sc.Match("__") && sc.chPrev != ' ') || IsNewline(sc.GetRelative(2))) { sc.Forward(2); sc.SetState(SCE_MARKDOWN_DEFAULT); } } // Emphasis else if (sc.state == SCE_MARKDOWN_EM1) { - if (sc.ch == '*' && sc.chPrev != ' ') + if ((sc.ch == '*' && sc.chPrev != ' ') || IsNewline(sc.chNext)) sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); } else if (sc.state == SCE_MARKDOWN_EM2) { - if (sc.ch == '_' && sc.chPrev != ' ') + if ((sc.ch == '_' && sc.chPrev != ' ') || IsNewline(sc.chNext)) sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); } else if (sc.state == SCE_MARKDOWN_CODEBK) { @@ -232,7 +253,7 @@ static void ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int } } else if (sc.state == SCE_MARKDOWN_STRIKEOUT) { - if (sc.Match("~~") && sc.chPrev != ' ') { + if ((sc.Match("~~") && sc.chPrev != ' ') || IsNewline(sc.GetRelative(2))) { sc.Forward(2); sc.SetState(SCE_MARKDOWN_DEFAULT); } @@ -368,38 +389,38 @@ static void ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int // Links and Images if (sc.Match("![")) { sc.SetState(SCE_MARKDOWN_LINK); - sc.Forward(2); + sc.Forward(1); } else if (sc.ch == '[' && sc.GetRelative(-1) != '\\') { sc.SetState(SCE_MARKDOWN_LINK); - sc.Forward(); } // Code - also a special case for alternate inside spacing else if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) { + const int openingSpan = (sc.GetRelative(2) == '`') ? 2 : 1; sc.SetState(SCE_MARKDOWN_CODE2); - sc.Forward(); + sc.Forward(openingSpan); } - else if (sc.ch == '`' && sc.chNext != ' ' && AtTermStart(sc)) { + else if (sc.ch == '`' && sc.chNext != ' ' && IsCompleteStyleRegion(sc, "`")) { sc.SetState(SCE_MARKDOWN_CODE); } // Strong - else if (sc.Match("**") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) { + else if (sc.Match("**") && sc.GetRelative(2) != ' ' && IsCompleteStyleRegion(sc, "**")) { sc.SetState(SCE_MARKDOWN_STRONG1); sc.Forward(); } - else if (sc.Match("__") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) { + else if (sc.Match("__") && sc.GetRelative(2) != ' ' && IsCompleteStyleRegion(sc, "__")) { sc.SetState(SCE_MARKDOWN_STRONG2); sc.Forward(); } // Emphasis - else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) { + else if (sc.ch == '*' && sc.chNext != ' ' && IsCompleteStyleRegion(sc, "*")) { sc.SetState(SCE_MARKDOWN_EM1); - } - else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) { + } else if (sc.ch == '_' && sc.chNext != ' ' && IsCompleteStyleRegion(sc, "_")) { sc.SetState(SCE_MARKDOWN_EM2); } // Strikeout - else if (sc.Match("~~") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) { + else if (sc.Match("~~") && !(sc.GetRelative(2) == '~' || sc.GetRelative(2) == ' ') && + IsCompleteStyleRegion(sc, "~~")) { sc.SetState(SCE_MARKDOWN_STRIKEOUT); sc.Forward(); } diff --git a/scintilla/lexers/LexMatlab.cxx b/scintilla/lexilla/lexers/LexMatlab.cxx similarity index 99% rename from scintilla/lexers/LexMatlab.cxx rename to scintilla/lexilla/lexers/LexMatlab.cxx index 3d08c9a33e..e9b2409fd9 100644 --- a/scintilla/lexers/LexMatlab.cxx +++ b/scintilla/lexilla/lexers/LexMatlab.cxx @@ -33,6 +33,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -44,7 +47,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static bool IsMatlabCommentChar(int c) { return (c == '%') ; @@ -185,7 +188,7 @@ static void ColouriseMatlabOctaveDoc( } } } else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) { - if (sc.ch == '\\') { + if (sc.ch == '\\' && !ismatlab) { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } diff --git a/scintilla/lexers/LexNsis.cxx b/scintilla/lexilla/lexers/LexNsis.cxx similarity index 99% rename from scintilla/lexers/LexNsis.cxx rename to scintilla/lexilla/lexers/LexNsis.cxx index 3b2b8a3ad9..e9fa5fdb66 100644 --- a/scintilla/lexers/LexNsis.cxx +++ b/scintilla/lexilla/lexers/LexNsis.cxx @@ -13,6 +13,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -24,7 +27,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; /* // located in SciLexer.h diff --git a/scintilla/lexers/LexNull.cxx b/scintilla/lexilla/lexers/LexNull.cxx similarity index 94% rename from scintilla/lexers/LexNull.cxx rename to scintilla/lexilla/lexers/LexNull.cxx index 15a3a50aae..92f12c19ff 100644 --- a/scintilla/lexers/LexNull.cxx +++ b/scintilla/lexilla/lexers/LexNull.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -23,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static void ColouriseNullDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) { diff --git a/scintilla/lexers/LexPO.cxx b/scintilla/lexilla/lexers/LexPO.cxx similarity index 98% rename from scintilla/lexers/LexPO.cxx rename to scintilla/lexilla/lexers/LexPO.cxx index 875c334f8d..d5dbeb6398 100644 --- a/scintilla/lexers/LexPO.cxx +++ b/scintilla/lexilla/lexers/LexPO.cxx @@ -20,6 +20,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -31,7 +34,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static void ColourisePODoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler) { StyleContext sc(startPos, length, initStyle, styler); diff --git a/scintilla/lexers/LexPascal.cxx b/scintilla/lexilla/lexers/LexPascal.cxx similarity index 99% rename from scintilla/lexers/LexPascal.cxx rename to scintilla/lexilla/lexers/LexPascal.cxx index 426b3c3f3c..4aa88a96cf 100644 --- a/scintilla/lexers/LexPascal.cxx +++ b/scintilla/lexilla/lexers/LexPascal.cxx @@ -117,6 +117,9 @@ contains requires #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -128,7 +131,7 @@ contains requires #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static void GetRangeLowered(Sci_PositionU start, Sci_PositionU end, diff --git a/scintilla/lexers/LexPerl.cxx b/scintilla/lexilla/lexers/LexPerl.cxx similarity index 99% rename from scintilla/lexers/LexPerl.cxx rename to scintilla/lexilla/lexers/LexPerl.cxx index dab7eb6f37..1ba426e177 100644 --- a/scintilla/lexers/LexPerl.cxx +++ b/scintilla/lexilla/lexers/LexPerl.cxx @@ -15,7 +15,9 @@ #include #include +#include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -30,6 +32,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; // Info for HERE document handling from perldata.pod (reformatted): // ---------------------------------------------------------------- @@ -435,7 +438,7 @@ class LexerPerl : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvIdentity; + return lvRelease5; } const char *SCI_METHOD PropertyNames() override { return osPerl.PropertyNames(); @@ -461,7 +464,7 @@ class LexerPerl : public DefaultLexer { return 0; } - static ILexer *LexerFactoryPerl() { + static ILexer5 *LexerFactoryPerl() { return new LexerPerl(); } int InputSymbolScan(StyleContext &sc); diff --git a/scintilla/lexers/LexPowerShell.cxx b/scintilla/lexilla/lexers/LexPowerShell.cxx similarity index 99% rename from scintilla/lexers/LexPowerShell.cxx rename to scintilla/lexilla/lexers/LexPowerShell.cxx index 9969df35da..4e652787df 100644 --- a/scintilla/lexers/LexPowerShell.cxx +++ b/scintilla/lexilla/lexers/LexPowerShell.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -23,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; // Extended to accept accented characters static inline bool IsAWordChar(int ch) { diff --git a/scintilla/lexers/LexProps.cxx b/scintilla/lexilla/lexers/LexProps.cxx similarity index 99% rename from scintilla/lexers/LexProps.cxx rename to scintilla/lexilla/lexers/LexProps.cxx index 328033dd51..7dadb2c6e1 100644 --- a/scintilla/lexers/LexProps.cxx +++ b/scintilla/lexilla/lexers/LexProps.cxx @@ -13,6 +13,7 @@ #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -25,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static inline bool AtEOL(Accessor &styler, Sci_PositionU i) { return (styler[i] == '\n') || diff --git a/scintilla/lexers/LexPython.cxx b/scintilla/lexilla/lexers/LexPython.cxx similarity index 99% rename from scintilla/lexers/LexPython.cxx rename to scintilla/lexilla/lexers/LexPython.cxx index ec19149f8f..b87192a76b 100644 --- a/scintilla/lexers/LexPython.cxx +++ b/scintilla/lexilla/lexers/LexPython.cxx @@ -10,9 +10,11 @@ #include #include +#include #include #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -31,6 +33,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; namespace { // Use an unnamed namespace to protect the functions and classes from name conflicts @@ -350,7 +353,7 @@ class LexerPython : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvIdentity; + return lvRelease5; } const char *SCI_METHOD PropertyNames() override { return osPython.PropertyNames(); @@ -409,7 +412,7 @@ class LexerPython : public DefaultLexer { return styleSubable; } - static ILexer *LexerFactoryPython() { + static ILexer5 *LexerFactoryPython() { return new LexerPython(); } diff --git a/scintilla/lexers/LexR.cxx b/scintilla/lexilla/lexers/LexR.cxx similarity index 98% rename from scintilla/lexers/LexR.cxx rename to scintilla/lexilla/lexers/LexR.cxx index a3821fa3c7..2a1da0cb62 100644 --- a/scintilla/lexers/LexR.cxx +++ b/scintilla/lexilla/lexers/LexR.cxx @@ -13,6 +13,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -24,7 +27,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); diff --git a/scintilla/lexers/LexRuby.cxx b/scintilla/lexilla/lexers/LexRuby.cxx similarity index 98% rename from scintilla/lexers/LexRuby.cxx rename to scintilla/lexilla/lexers/LexRuby.cxx index 6f7c344048..566d0cc7f8 100644 --- a/scintilla/lexers/LexRuby.cxx +++ b/scintilla/lexilla/lexers/LexRuby.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -23,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; //XXX Identical to Perl, put in common area static inline bool isEOLChar(char ch) { @@ -251,10 +254,10 @@ class QuoteCls { int Count; char Up; char Down; - QuoteCls() { + QuoteCls() noexcept { New(); } - void New() { + void New() noexcept { Count = 0; Up = '\0'; Down = '\0'; @@ -264,21 +267,6 @@ class QuoteCls { Up = u; Down = opposite(Up); } - QuoteCls(const QuoteCls &q) { - // copy constructor -- use this for copying in - Count = q.Count; - Up = q.Up; - Down = q.Down; - } - QuoteCls &operator=(const QuoteCls &q) { // assignment constructor - if (this != &q) { - Count = q.Count; - Up = q.Up; - Down = q.Down; - } - return *this; - } - }; @@ -703,23 +691,17 @@ static void ColouriseRbDoc(Sci_PositionU startPos, Sci_Position length, int init class HereDocCls { public: - int State; + int State = 0; // States // 0: '<<' encountered // 1: collect the delimiter // 1b: text between the end of the delimiter and the EOL // 2: here doc text (lines after the delimiter) - char Quote; // the char after '<<' - bool Quoted; // true if Quote in ('\'','"','`') - int DelimiterLength; // strlen(Delimiter) - char Delimiter[256]; // the Delimiter, limit of 256: from Perl - bool CanBeIndented; - HereDocCls() { - State = 0; - DelimiterLength = 0; - Delimiter[0] = '\0'; - CanBeIndented = false; - } + char Quote = 0; // the char after '<<' + bool Quoted = false; // true if Quote in ('\'','"','`') + int DelimiterLength = 0; // strlen(Delimiter) + char Delimiter[256] {}; // the Delimiter, limit of 256: from Perl + bool CanBeIndented = false; }; HereDocCls HereDoc; @@ -735,8 +717,7 @@ static void ColouriseRbDoc(Sci_PositionU startPos, Sci_Position length, int init int state = initStyle; Sci_Position lengthDoc = startPos + length; - char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero - prevWord[0] = '\0'; + char prevWord[MAX_KEYWORD_LENGTH + 1] = ""; // 1 byte for zero if (length == 0) return; @@ -774,9 +755,9 @@ static void ColouriseRbDoc(Sci_PositionU startPos, Sci_Position length, int init #define INNER_STRINGS_MAX_COUNT 5 // These vars track our instances of "...#{,,,%Q<..#{,,,}...>,,,}..." - int inner_string_types[INNER_STRINGS_MAX_COUNT]; + int inner_string_types[INNER_STRINGS_MAX_COUNT] {}; // Track # braces when we push a new #{ thing - int inner_expn_brace_counts[INNER_STRINGS_MAX_COUNT]; + int inner_expn_brace_counts[INNER_STRINGS_MAX_COUNT] {}; QuoteCls inner_quotes[INNER_STRINGS_MAX_COUNT]; int inner_string_count = 0; int brace_counts = 0; // Number of #{ ... } things within an expression @@ -1304,7 +1285,7 @@ static void ColouriseRbDoc(Sci_PositionU startPos, Sci_Position length, int init if (isEOLChar(chPrev) && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) { styler.ColourTo(i - 1, state); - i += HereDoc.DelimiterLength - 1; + i += static_cast(HereDoc.DelimiterLength) - 1; chNext = styler.SafeGetCharAt(i + 1); if (isEOLChar(chNext)) { styler.ColourTo(i, SCE_RB_HERE_DELIM); @@ -1645,12 +1626,11 @@ static bool keywordDoStartsLoop(Sci_Position pos, Accessor &styler) { char ch; - int style; Sci_Position lineStart = styler.GetLine(pos); Sci_Position lineStartPosn = styler.LineStart(lineStart); styler.Flush(); while (--pos >= lineStartPosn) { - style = actual_style(styler.StyleAt(pos)); + const int style = actual_style(styler.StyleAt(pos)); if (style == SCE_RB_DEFAULT) { if ((ch = styler[pos]) == '\r' || ch == '\n') { // Scintilla's LineStart() and GetLine() routines aren't @@ -1860,7 +1840,6 @@ static void FoldRbDoc(Sci_PositionU startPos, Sci_Position length, int initStyle } // Fill in the real level of the next line, keeping the current flags as they will be filled in later if (!buffer_ends_with_eol) { - lineCurrent++; int new_lev = levelCurrent; if (visibleChars == 0 && foldCompact) new_lev |= SC_FOLDLEVELWHITEFLAG; diff --git a/scintilla/lexers/LexRust.cxx b/scintilla/lexilla/lexers/LexRust.cxx similarity index 99% rename from scintilla/lexers/LexRust.cxx rename to scintilla/lexilla/lexers/LexRust.cxx index f0360b605b..12a6d03ac5 100644 --- a/scintilla/lexers/LexRust.cxx +++ b/scintilla/lexilla/lexers/LexRust.cxx @@ -15,7 +15,9 @@ #include #include +#include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -32,6 +34,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; static const int NUM_RUST_KEYWORD_LISTS = 7; static const int MAX_RUST_IDENT_CHARS = 1023; @@ -128,7 +131,7 @@ class LexerRust : public DefaultLexer { delete this; } int SCI_METHOD Version() const override { - return lvIdentity; + return lvRelease5; } const char * SCI_METHOD PropertyNames() override { return osRust.PropertyNames(); @@ -152,7 +155,7 @@ class LexerRust : public DefaultLexer { void * SCI_METHOD PrivateCall(int, void *) override { return 0; } - static ILexer *LexerFactoryRust() { + static ILexer5 *LexerFactoryRust() { return new LexerRust(); } }; diff --git a/scintilla/lexers/LexSQL.cxx b/scintilla/lexilla/lexers/LexSQL.cxx similarity index 99% rename from scintilla/lexers/LexSQL.cxx rename to scintilla/lexilla/lexers/LexSQL.cxx index 87b852bfde..027d2f2565 100644 --- a/scintilla/lexers/LexSQL.cxx +++ b/scintilla/lexilla/lexers/LexSQL.cxx @@ -15,9 +15,11 @@ #include #include +#include #include #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -34,6 +36,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; static inline bool IsAWordChar(int ch, bool sqlAllowDottedWord) { if (!sqlAllowDottedWord) @@ -308,7 +311,7 @@ public : virtual ~LexerSQL() {} int SCI_METHOD Version () const override { - return lvIdentity; + return lvRelease5; } void SCI_METHOD Release() override { @@ -350,7 +353,7 @@ public : return 0; } - static ILexer *LexerFactorySQL() { + static ILexer5 *LexerFactorySQL() { return new LexerSQL(); } private: diff --git a/scintilla/lexers/LexSmalltalk.cxx b/scintilla/lexilla/lexers/LexSmalltalk.cxx similarity index 99% rename from scintilla/lexers/LexSmalltalk.cxx rename to scintilla/lexilla/lexers/LexSmalltalk.cxx index bd146d59c2..85d1c02c0e 100644 --- a/scintilla/lexers/LexSmalltalk.cxx +++ b/scintilla/lexilla/lexers/LexSmalltalk.cxx @@ -13,6 +13,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -24,7 +27,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; /* | lexTable classificationBlock charClasses | diff --git a/scintilla/lexers/LexTCL.cxx b/scintilla/lexilla/lexers/LexTCL.cxx similarity index 98% rename from scintilla/lexers/LexTCL.cxx rename to scintilla/lexilla/lexers/LexTCL.cxx index 5c73fb52ef..5e34aea34b 100644 --- a/scintilla/lexers/LexTCL.cxx +++ b/scintilla/lexilla/lexers/LexTCL.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -23,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; // Extended to accept accented characters static inline bool IsAWordChar(int ch) { @@ -146,8 +149,8 @@ static void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int , W } else if (!IsAWordChar(sc.ch)) { if ((sc.state == SCE_TCL_IDENTIFIER && expected) || sc.state == SCE_TCL_MODIFIER) { char w[100]; - char *s=w; sc.GetCurrent(w, sizeof(w)); + char *s=w; if (w[strlen(w)-1]=='\r') w[strlen(w)-1]=0; while (*s == ':') // ignore leading : like in ::set a 10 @@ -162,7 +165,7 @@ static void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int , W sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD4); - } else if (sc.GetRelative(-static_cast(strlen(s))-1) == '{' && + } else if (sc.GetRelative(-static_cast(strlen(s))-1) == '{' && keywords5.InList(s) && sc.ch == '}') { // {keyword} exactly no spaces sc.ChangeState(SCE_TCL_EXPAND); } @@ -227,6 +230,7 @@ static void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int , W sc.ForwardSetState(SCE_TCL_DEFAULT); prevSlash = false; previousLevel = currentLevel; + visibleChars = false; goto next; } @@ -315,7 +319,7 @@ static void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int , W break; case '[': expected = true; - // Falls through. + [[fallthrough]]; case ']': case '(': case ')': diff --git a/scintilla/lexers/LexTxt2tags.cxx b/scintilla/lexilla/lexers/LexTxt2tags.cxx similarity index 99% rename from scintilla/lexers/LexTxt2tags.cxx rename to scintilla/lexilla/lexers/LexTxt2tags.cxx index 6d1a954e01..beea5c55b8 100644 --- a/scintilla/lexers/LexTxt2tags.cxx +++ b/scintilla/lexilla/lexers/LexTxt2tags.cxx @@ -23,6 +23,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -34,7 +37,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; diff --git a/scintilla/lexers/LexVHDL.cxx b/scintilla/lexilla/lexers/LexVHDL.cxx similarity index 99% rename from scintilla/lexers/LexVHDL.cxx rename to scintilla/lexilla/lexers/LexVHDL.cxx index a1426c815a..b64eb9ebd0 100644 --- a/scintilla/lexers/LexVHDL.cxx +++ b/scintilla/lexilla/lexers/LexVHDL.cxx @@ -17,6 +17,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -28,7 +31,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static void ColouriseVHDLDoc( Sci_PositionU startPos, diff --git a/scintilla/lexers/LexVerilog.cxx b/scintilla/lexilla/lexers/LexVerilog.cxx similarity index 99% rename from scintilla/lexers/LexVerilog.cxx rename to scintilla/lexilla/lexers/LexVerilog.cxx index d31425e3f7..b2120d475b 100644 --- a/scintilla/lexers/LexVerilog.cxx +++ b/scintilla/lexilla/lexers/LexVerilog.cxx @@ -14,9 +14,11 @@ #include #include +#include #include #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -34,6 +36,7 @@ #include "DefaultLexer.h" using namespace Scintilla; +using namespace Lexilla; namespace { // Use an unnamed namespace to protect the functions and classes from name conflicts @@ -222,7 +225,7 @@ class LexerVerilog : public DefaultLexer { } virtual ~LexerVerilog() {} int SCI_METHOD Version() const override { - return lvIdentity; + return lvRelease5; } void SCI_METHOD Release() override { delete this; @@ -283,7 +286,7 @@ class LexerVerilog : public DefaultLexer { const char * SCI_METHOD GetSubStyleBases() override { return styleSubable; } - static ILexer* LexerFactoryVerilog() { + static ILexer5* LexerFactoryVerilog() { return new LexerVerilog(); } static int MaskActive(int style) { diff --git a/scintilla/lexers/LexYAML.cxx b/scintilla/lexilla/lexers/LexYAML.cxx similarity index 96% rename from scintilla/lexers/LexYAML.cxx rename to scintilla/lexilla/lexers/LexYAML.cxx index 75515603e8..e26ebf8827 100644 --- a/scintilla/lexers/LexYAML.cxx +++ b/scintilla/lexilla/lexers/LexYAML.cxx @@ -12,6 +12,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -23,7 +26,7 @@ #include "CharacterSet.h" #include "LexerModule.h" -using namespace Scintilla; +using namespace Lexilla; static const char * const yamlWordListDesc[] = { "Keywords", @@ -35,6 +38,14 @@ static inline bool AtEOL(Accessor &styler, Sci_PositionU i) { ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); } +/** + * Check for space, tab, line feed, or carriage return. + * See YAML 1.2 spec sections 5.4. Line Break Characters and 5.5. White Space Characters. + */ +static constexpr bool IsWhiteSpaceOrEOL(char ch) noexcept { + return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; +} + static unsigned int SpaceCount(char* lineBuffer) { if (lineBuffer == NULL) return 0; @@ -121,7 +132,7 @@ static void ColouriseYAMLLine( styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; - } else if (lineBuffer[i] == ':' && !bInQuotes) { + } else if (lineBuffer[i] == ':' && !bInQuotes && (IsWhiteSpaceOrEOL(lineBuffer[i + 1]) || i == lengthLine - 1)) { styler.ColourTo(startLine + i - 1, SCE_YAML_IDENTIFIER); styler.ColourTo(startLine + i, SCE_YAML_OPERATOR); // Non-folding scalar diff --git a/scintilla/lexlib/Accessor.cxx b/scintilla/lexilla/lexlib/Accessor.cxx similarity index 88% rename from scintilla/lexlib/Accessor.cxx rename to scintilla/lexilla/lexlib/Accessor.cxx index 7cce9a5544..65e07374dc 100644 --- a/scintilla/lexlib/Accessor.cxx +++ b/scintilla/lexilla/lexlib/Accessor.cxx @@ -8,6 +8,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -17,12 +20,12 @@ #include "LexAccessor.h" #include "Accessor.h" -using namespace Scintilla; +using namespace Lexilla; -Accessor::Accessor(IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) { +Accessor::Accessor(Scintilla::IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) { } -int Accessor::GetPropertyInt(const char *key, int defaultValue) const { +int Accessor::GetPropertyInt(std::string_view key, int defaultValue) const { return pprops->GetInt(key, defaultValue); } diff --git a/scintilla/lexlib/Accessor.h b/scintilla/lexilla/lexlib/Accessor.h similarity index 81% rename from scintilla/lexlib/Accessor.h rename to scintilla/lexilla/lexlib/Accessor.h index 8fc3f641a8..fa58fa004b 100644 --- a/scintilla/lexlib/Accessor.h +++ b/scintilla/lexilla/lexlib/Accessor.h @@ -8,7 +8,7 @@ #ifndef ACCESSOR_H #define ACCESSOR_H -namespace Scintilla { +namespace Lexilla { enum { wsSpace=1, wsTab=2, wsSpaceTab=4, wsInconsistent=8 }; @@ -21,8 +21,8 @@ typedef bool (*PFNIsCommentLeader)(Accessor &styler, Sci_Position pos, Sci_Posit class Accessor : public LexAccessor { public: PropSetSimple *pprops; - Accessor(IDocument *pAccess_, PropSetSimple *pprops_); - int GetPropertyInt(const char *, int defaultValue=0) const; + 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); }; diff --git a/scintilla/lexlib/CatalogueModules.h b/scintilla/lexilla/lexlib/CatalogueModules.h similarity index 88% rename from scintilla/lexlib/CatalogueModules.h rename to scintilla/lexilla/lexlib/CatalogueModules.h index b290a74ea2..f66ef8920d 100644 --- a/scintilla/lexlib/CatalogueModules.h +++ b/scintilla/lexilla/lexlib/CatalogueModules.h @@ -10,7 +10,7 @@ #ifndef CATALOGUEMODULES_H #define CATALOGUEMODULES_H -namespace Scintilla { +namespace Lexilla { class CatalogueModules { std::vector lexerCatalogue; @@ -39,6 +39,10 @@ class CatalogueModules { lexerCatalogue.push_back(plm); } + void AddLexerModules(std::initializer_list modules) { + lexerCatalogue.insert(lexerCatalogue.end(), modules); + } + unsigned int Count() const noexcept { return static_cast(lexerCatalogue.size()); } @@ -56,7 +60,7 @@ class CatalogueModules { return lexerCatalogue[index]->fnFactory; } - ILexer *Create(unsigned int index) const { + Scintilla::ILexer5 *Create(unsigned int index) const { const LexerModule *plm = lexerCatalogue[index]; if (!plm) { return nullptr; diff --git a/scintilla/lexlib/CharacterCategory.cxx b/scintilla/lexilla/lexlib/CharacterCategory.cxx similarity index 97% rename from scintilla/lexlib/CharacterCategory.cxx rename to scintilla/lexilla/lexlib/CharacterCategory.cxx index 6dc22e21fa..bdbbb039a2 100644 --- a/scintilla/lexlib/CharacterCategory.cxx +++ b/scintilla/lexilla/lexlib/CharacterCategory.cxx @@ -13,16 +13,14 @@ #include "CharacterCategory.h" -#include "Compat.h" - -namespace Scintilla { +namespace Lexilla { namespace { // Use an unnamed namespace to protect the declarations from name conflicts const int catRanges[] = { //++Autogenerated -- start of section automatically generated -// Created with Python 3.8.0, Unicode 12.1.0 +// Created with Python 3.9.4, Unicode 13.0.0 25, 1046, 1073, @@ -754,7 +752,7 @@ const int catRanges[] = { 70660, 71357, 71364, -71645, +71965, 72293, 72794, 72805, @@ -924,7 +922,7 @@ const int catRanges[] = { 92518, 92581, 92637, -92869, +92837, 92902, 92957, 93060, @@ -1047,8 +1045,7 @@ const int catRanges[] = { 106109, 106501, 106566, -106653, -106660, +106628, 106941, 106948, 107069, @@ -1076,6 +1073,7 @@ const int catRanges[] = { 110389, 110404, 110621, +110629, 110662, 110749, 110756, @@ -1404,7 +1402,8 @@ const int catRanges[] = { 218589, 218629, 219079, -219133, +219109, +219197, 221189, 221318, 221348, @@ -2029,7 +2028,7 @@ const int catRanges[] = { 355997, 356053, 357085, -357141, +357109, 360448, 361981, 361985, @@ -2232,7 +2231,9 @@ const int catRanges[] = { 378929, 378957, 378993, -379421, +379413, +379473, +379517, 380949, 381789, 381813, @@ -2302,7 +2303,6 @@ const int catRanges[] = { 406090, 406229, 406532, -407421, 407573, 408733, 409092, @@ -2319,10 +2319,9 @@ const int catRanges[] = { 415274, 415765, 425988, -636637, 636949, 638980, -1310237, +1310653, 1310724, 1311395, 1311428, @@ -2571,7 +2570,12 @@ const int catRanges[] = { 1374272, 1374305, 1374336, -1374461, +1374465, +1374496, +1374529, +1374589, +1375904, +1375937, 1375972, 1376003, 1376065, @@ -2586,7 +2590,8 @@ const int catRanges[] = { 1377445, 1377510, 1377557, -1377693, +1377669, +1377725, 1377802, 1378005, 1378067, @@ -2706,7 +2711,9 @@ const int catRanges[] = { 1403764, 1403779, 1403905, -1404189, +1404195, +1404244, +1404317, 1404417, 1406980, 1408102, @@ -2906,7 +2913,7 @@ const int catRanges[] = { 2109845, 2109949, 2109973, -2110365, +2110397, 2110485, 2110525, 2112021, @@ -3064,6 +3071,13 @@ const int catRanges[] = { 2205533, 2214922, 2215933, +2215940, +2217309, +2217317, +2217388, +2217437, +2217476, +2217565, 2220036, 2220970, 2221284, @@ -3073,6 +3087,9 @@ const int catRanges[] = { 2222634, 2222769, 2222941, +2225668, +2226346, +2226589, 2227204, 2227965, 2228230, @@ -3112,7 +3129,8 @@ const int catRanges[] = { 2238481, 2238596, 2238630, -2238717, +2238692, +2238749, 2238980, 2240101, 2240145, @@ -3128,7 +3146,8 @@ const int catRanges[] = { 2242737, 2242853, 2242993, -2243037, +2243014, +2243045, 2243080, 2243396, 2243441, @@ -3213,13 +3232,12 @@ const int catRanges[] = { 2263268, 2263409, 2263560, -2263901, -2263921, +2263889, 2263965, 2263985, 2264005, 2264036, -2264093, +2264157, 2265092, 2266630, 2266725, @@ -3299,7 +3317,30 @@ const int catRanges[] = { 2301258, 2301565, 2301924, -2301981, +2302205, +2302244, +2302301, +2302340, +2302621, +2302628, +2302717, +2302724, +2303494, +2303709, +2303718, +2303805, +2303845, +2303910, +2303941, +2303972, +2304006, +2304036, +2304070, +2304101, +2304145, +2304253, +2304520, +2304861, 2307076, 2307357, 2307396, @@ -3404,6 +3445,8 @@ const int catRanges[] = { 2350758, 2350833, 2350909, +2356740, +2356797, 2357258, 2357941, 2358195, @@ -3470,11 +3513,16 @@ const int catRanges[] = { 3013635, 3013713, 3013731, -3013789, +3013765, +3013821, +3014150, +3014237, 3014660, 3211037, 3211268, -3235453, +3250909, +3252228, +3252541, 3538948, 3548157, 3549700, @@ -3759,11 +3807,8 @@ const int catRanges[] = { 4069941, 4071133, 4071434, -4071869, -4071957, -4074941, -4075029, -4076989, +4071861, +4077021, 4078805, 4079741, 4080149, @@ -3777,11 +3822,11 @@ const int catRanges[] = { 4087829, 4095860, 4096021, -4119261, +4119325, 4119573, 4119997, 4120085, -4120445, +4120509, 4120597, 4124317, 4124693, @@ -3798,32 +3843,38 @@ const int catRanges[] = { 4133149, 4133397, 4134365, +4134421, +4134493, 4136981, -4137373, -4137397, -4140637, -4140661, -4140797, +4140861, 4140885, -4142205, -4142261, -4142461, -4142549, -4143485, +4143517, 4143541, 4147869, 4148245, 4148701, 4148757, -4148893, +4148925, 4149013, 4149117, 4149269, -4149373, +4149501, 4149781, -4149981, +4150589, +4150805, +4151037, +4151317, +4151421, +4151829, +4152061, +4153365, +4158077, +4158101, +4159869, +4161032, +4161373, 4194308, -5561085, +5561309, 5562372, 5695165, 5695492, @@ -3834,6 +3885,8 @@ const int catRanges[] = { 6126653, 6225924, 6243293, +6291460, +6449533, 29360186, 29360221, 29361178, @@ -4027,7 +4080,7 @@ int CharacterCategoryMap::Size() const noexcept { } void CharacterCategoryMap::Optimize(int countCharacters) { - const int characters = Sci::clamp(countCharacters, 256, maxUnicode + 1); + const int characters = std::clamp(countCharacters, 256, maxUnicode + 1); dense.resize(characters); int end = 0; diff --git a/scintilla/lexlib/CharacterCategory.h b/scintilla/lexilla/lexlib/CharacterCategory.h similarity index 98% rename from scintilla/lexlib/CharacterCategory.h rename to scintilla/lexilla/lexlib/CharacterCategory.h index cd3320dd9f..f8e5c7b0d8 100644 --- a/scintilla/lexlib/CharacterCategory.h +++ b/scintilla/lexilla/lexlib/CharacterCategory.h @@ -8,7 +8,7 @@ #ifndef CHARACTERCATEGORY_H #define CHARACTERCATEGORY_H -namespace Scintilla { +namespace Lexilla { enum CharacterCategory { ccLu, ccLl, ccLt, ccLm, ccLo, diff --git a/scintilla/lexlib/CharacterSet.cxx b/scintilla/lexilla/lexlib/CharacterSet.cxx similarity index 95% rename from scintilla/lexlib/CharacterSet.cxx rename to scintilla/lexilla/lexlib/CharacterSet.cxx index b934c2dd4f..1b67700527 100644 --- a/scintilla/lexlib/CharacterSet.cxx +++ b/scintilla/lexilla/lexlib/CharacterSet.cxx @@ -11,9 +11,9 @@ #include "CharacterSet.h" -using namespace Scintilla; +using namespace Lexilla; -namespace Scintilla { +namespace Lexilla { int CompareCaseInsensitive(const char *a, const char *b) noexcept { while (*a && *b) { diff --git a/scintilla/lexlib/CharacterSet.h b/scintilla/lexilla/lexlib/CharacterSet.h similarity index 67% rename from scintilla/lexlib/CharacterSet.h rename to scintilla/lexilla/lexlib/CharacterSet.h index 4a30ca0f07..691ca4b39d 100644 --- a/scintilla/lexlib/CharacterSet.h +++ b/scintilla/lexilla/lexlib/CharacterSet.h @@ -8,12 +8,12 @@ #ifndef CHARACTERSET_H #define CHARACTERSET_H -namespace Scintilla { +namespace Lexilla { -class CharacterSet { - int size; - bool valueAfter; - bool *bset; +template +class CharacterSetArray { + unsigned char bset[(N-1)/8 + 1] = {}; + bool valueAfter = false; public: enum setBase { setNone=0, @@ -23,13 +23,8 @@ class CharacterSet { setAlpha=setLower|setUpper, setAlphaNum=setAlpha|setDigits }; - CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) { - size = size_; + CharacterSetArray(setBase base=setNone, const char *initialSet="", bool valueAfter_=false) noexcept { valueAfter = valueAfter_; - bset = new bool[size]; - for (int i=0; i < size; i++) { - bset[i] = false; - } AddString(initialSet); if (base & setLower) AddString("abcdefghijklmnopqrstuvwxyz"); @@ -38,66 +33,28 @@ class CharacterSet { if (base & setDigits) AddString("0123456789"); } - CharacterSet(const CharacterSet &other) { - size = other.size; - valueAfter = other.valueAfter; - bset = new bool[size]; - for (int i=0; i < size; i++) { - bset[i] = other.bset[i]; - } - } - CharacterSet(CharacterSet &&other) noexcept { - size = other.size; - valueAfter = other.valueAfter; - bset = other.bset; - other.size = 0; - other.bset = nullptr; - } - CharacterSet &operator=(const CharacterSet &other) { - if (this != &other) { - bool *bsetNew = new bool[other.size]; - for (int i = 0; i < other.size; i++) { - bsetNew[i] = other.bset[i]; - } - delete[]bset; - size = other.size; - valueAfter = other.valueAfter; - bset = bsetNew; - } - return *this; - } - CharacterSet &operator=(CharacterSet &&other) noexcept { - if (this != &other) { - delete []bset; - size = other.size; - valueAfter = other.valueAfter; - bset = other.bset; - other.size = 0; - other.bset = nullptr; - } - return *this; + // For compatibility with previous version but should not be used in new code. + CharacterSetArray(setBase base, const char *initialSet, [[maybe_unused]]int size_, bool valueAfter_=false) noexcept : + CharacterSetArray(base, initialSet, valueAfter_) { + assert(size_ == N); } - ~CharacterSet() { - delete []bset; - bset = nullptr; - size = 0; - } - void Add(int val) { + void Add(int val) noexcept { assert(val >= 0); - assert(val < size); - bset[val] = true; + assert(val < N); + bset[val >> 3] |= 1 << (val & 7); } - void AddString(const char *setToAdd) { + void AddString(const char *setToAdd) noexcept { for (const char *cp=setToAdd; *cp; cp++) { const unsigned char uch = *cp; - assert(uch < size); - bset[uch] = true; + assert(uch < N); + Add(uch); } } bool Contains(int val) const noexcept { assert(val >= 0); if (val < 0) return false; - return (val < size) ? bset[val] : valueAfter; + if (val >= N) return valueAfter; + return bset[val >> 3] & (1 << (val & 7)); } bool Contains(char ch) const noexcept { // Overload char as char may be signed @@ -106,8 +63,24 @@ class CharacterSet { } }; +using CharacterSet = CharacterSetArray<0x80>; + // Functions for classifying characters +template +constexpr bool AnyOf(T t, Args... args) noexcept { +#if defined(__clang__) + static_assert(__is_integral(T)); +#endif + return ((t == args) || ...); +} + +// prevent pointer without +template +constexpr void AnyOf([[maybe_unused]] T *t, [[maybe_unused]] Args... args) noexcept {} +template +constexpr void AnyOf([[maybe_unused]] const T *t, [[maybe_unused]] Args... args) noexcept {} + constexpr bool IsASpace(int ch) noexcept { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); } @@ -120,7 +93,7 @@ constexpr bool IsADigit(int ch) noexcept { return (ch >= '0') && (ch <= '9'); } -inline bool IsADigit(int ch, int base) noexcept { +constexpr bool IsADigit(int ch, int base) noexcept { if (base <= 10) { return (ch >= '0') && (ch < '0' + base); } else { @@ -169,7 +142,7 @@ constexpr bool iswordstart(int ch) noexcept { return IsAlphaNumeric(ch) || ch == '_'; } -inline bool isoperator(int ch) noexcept { +constexpr bool isoperator(int ch) noexcept { if (IsAlphaNumeric(ch)) return false; if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || @@ -185,7 +158,7 @@ inline bool isoperator(int ch) noexcept { // Simple case functions for ASCII supersets. template -inline T MakeUpperCase(T ch) noexcept { +constexpr T MakeUpperCase(T ch) noexcept { if (ch < 'a' || ch > 'z') return ch; else @@ -193,7 +166,7 @@ inline T MakeUpperCase(T ch) noexcept { } template -inline T MakeLowerCase(T ch) noexcept { +constexpr T MakeLowerCase(T ch) noexcept { if (ch < 'A' || ch > 'Z') return ch; else diff --git a/scintilla/lexlib/DefaultLexer.cxx b/scintilla/lexilla/lexlib/DefaultLexer.cxx similarity index 95% rename from scintilla/lexlib/DefaultLexer.cxx rename to scintilla/lexilla/lexlib/DefaultLexer.cxx index e0f61084e4..991dc34f7e 100644 --- a/scintilla/lexlib/DefaultLexer.cxx +++ b/scintilla/lexilla/lexlib/DefaultLexer.cxx @@ -9,6 +9,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -20,7 +23,7 @@ #include "LexerModule.h" #include "DefaultLexer.h" -using namespace Scintilla; +using namespace Lexilla; static const char styleSubable[] = { 0 }; @@ -40,7 +43,7 @@ void SCI_METHOD DefaultLexer::Release() { } int SCI_METHOD DefaultLexer::Version() const { - return lvIdentity; + return Scintilla::lvRelease5; } const char * SCI_METHOD DefaultLexer::PropertyNames() { @@ -67,7 +70,7 @@ Sci_Position SCI_METHOD DefaultLexer::WordListSet(int, const char *) { return -1; } -void SCI_METHOD DefaultLexer::Fold(Sci_PositionU, Sci_Position, int, IDocument *) { +void SCI_METHOD DefaultLexer::Fold(Sci_PositionU, Sci_Position, int, Scintilla::IDocument *) { } void * SCI_METHOD DefaultLexer::PrivateCall(int, void *) { @@ -128,7 +131,7 @@ const char * SCI_METHOD DefaultLexer::DescriptionOfStyle(int style) { return (style < NamedStyles()) ? lexClasses[style].description : ""; } -// ILexerWithIdentity methods +// ILexer5 methods const char * SCI_METHOD DefaultLexer::GetName() { return languageName; } diff --git a/scintilla/lexlib/DefaultLexer.h b/scintilla/lexilla/lexlib/DefaultLexer.h similarity index 91% rename from scintilla/lexlib/DefaultLexer.h rename to scintilla/lexilla/lexlib/DefaultLexer.h index 7856a1dd19..9db3f4d88e 100644 --- a/scintilla/lexlib/DefaultLexer.h +++ b/scintilla/lexilla/lexlib/DefaultLexer.h @@ -10,10 +10,10 @@ #ifndef DEFAULTLEXER_H #define DEFAULTLEXER_H -namespace Scintilla { +namespace Lexilla { // A simple lexer with no state -class DefaultLexer : public ILexerWithIdentity { +class DefaultLexer : public Scintilla::ILexer5 { const char *languageName; int language; const LexicalClass *lexClasses; @@ -30,8 +30,8 @@ class DefaultLexer : public ILexerWithIdentity { Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; const char * SCI_METHOD DescribeWordListSets() override; Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override; - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override = 0; - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; + void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override = 0; + void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override; void * SCI_METHOD PrivateCall(int operation, void *pointer) override; int SCI_METHOD LineEndTypesSupported() override; int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override; @@ -47,7 +47,7 @@ class DefaultLexer : public ILexerWithIdentity { const char * SCI_METHOD NameOfStyle(int style) override; const char * SCI_METHOD TagsOfStyle(int style) override; const char * SCI_METHOD DescriptionOfStyle(int style) override; - // ILexerWithIdentity methods + // ILexer5 methods const char * SCI_METHOD GetName() override; int SCI_METHOD GetIdentifier() override; }; diff --git a/scintilla/lexilla/lexlib/LexAccessor.cxx b/scintilla/lexilla/lexlib/LexAccessor.cxx new file mode 100644 index 0000000000..7a15fb6145 --- /dev/null +++ b/scintilla/lexilla/lexlib/LexAccessor.cxx @@ -0,0 +1,70 @@ +// Scintilla source code edit control +/** @file LexAccessor.cxx + ** Interfaces between Scintilla and lexers. + **/ +// Copyright 1998-2010 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. +#include +#include + +#include +#include + +#include "ILexer.h" + +#include "LexAccessor.h" +#include "CharacterSet.h" + +using namespace Lexilla; + +namespace Lexilla { + +bool LexAccessor::MatchIgnoreCase(Sci_Position pos, const char *s) { + for (; *s; s++, pos++) { + if (*s != MakeLowerCase(SafeGetCharAt(pos))) { + return false; + } + } + return true; +} + +void LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) { + assert(startPos_ <= endPos_ && len != 0 && s != nullptr); + endPos_ = std::min(endPos_, startPos_ + len - 1); + len = endPos_ - startPos_; + if (startPos_ >= static_cast(startPos) && endPos_ <= static_cast(endPos)) { + const char * const p = buf + (startPos_ - startPos); + memcpy(s, p, len); + } else { + pAccess->GetCharRange(s, startPos_, len); + } + s[len] = '\0'; +} + +void LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) { + GetRange(startPos_, endPos_, s, len); + while (*s) { + if (*s >= 'A' && *s <= 'Z') { + *s += 'a' - 'A'; + } + ++s; + } +} + +std::string LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_) { + assert(startPos_ < endPos_); + const Sci_PositionU len = endPos_ - startPos_; + std::string s(len, '\0'); + GetRange(startPos_, endPos_, s.data(), len); + return s; +} + +std::string LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_) { + assert(startPos_ < endPos_); + const Sci_PositionU len = endPos_ - startPos_; + std::string s(len, '\0'); + GetRangeLowered(startPos_, endPos_, s.data(), len); + return s; +} + +} diff --git a/scintilla/lexlib/LexAccessor.h b/scintilla/lexilla/lexlib/LexAccessor.h similarity index 82% rename from scintilla/lexlib/LexAccessor.h rename to scintilla/lexilla/lexlib/LexAccessor.h index 81f5a16aea..8f76ed2a4c 100644 --- a/scintilla/lexlib/LexAccessor.h +++ b/scintilla/lexilla/lexlib/LexAccessor.h @@ -8,13 +8,13 @@ #ifndef LEXACCESSOR_H #define LEXACCESSOR_H -namespace Scintilla { +namespace Lexilla { enum class EncodingType { eightBit, unicode, dbcs }; class LexAccessor { private: - IDocument *pAccess; + Scintilla::IDocument *pAccess; enum {extremePosition=0x7FFFFFFF}; /** @a bufferSize is a trade off between time taken to copy the characters * and retrieval overhead. @@ -48,7 +48,7 @@ class LexAccessor { } public: - explicit LexAccessor(IDocument *pAccess_) : + explicit LexAccessor(Scintilla::IDocument *pAccess_) : pAccess(pAccess_), startPos(extremePosition), endPos(0), codePage(pAccess->CodePage()), encodingType(EncodingType::eightBit), @@ -77,11 +77,8 @@ class LexAccessor { } return buf[position - startPos]; } - IDocumentWithLineEnd *MultiByteAccess() const noexcept { - if (documentVersion >= dvLineEnd) { - return static_cast(pAccess); - } - return 0; + Scintilla::IDocument *MultiByteAccess() const noexcept { + return pAccess; } /** Safe version of operator[], returning a defined value for invalid position. */ char SafeGetCharAt(Sci_Position position, char chDefault=' ') { @@ -95,7 +92,10 @@ class LexAccessor { return buf[position - startPos]; } bool IsLeadByte(char ch) const { - return pAccess->IsDBCSLeadByte(ch); + return + (static_cast(ch) >= 0x80) && // non-ASCII + (encodingType == EncodingType::dbcs) && // IsDBCSLeadByte only for DBCS + pAccess->IsDBCSLeadByte(ch); } EncodingType Encoding() const noexcept { return encodingType; @@ -108,6 +108,15 @@ class LexAccessor { } return true; } + bool MatchIgnoreCase(Sci_Position pos, const char *s); + + // Get first len - 1 characters in range [startPos_, endPos_). + void GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len); + void GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len); + // Get all characters in range [startPos_, endPos_). + std::string GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_); + std::string GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_); + char StyleAt(Sci_Position position) const { return pAccess->StyleAt(position); } @@ -117,18 +126,8 @@ class LexAccessor { Sci_Position LineStart(Sci_Position line) const { return pAccess->LineStart(line); } - Sci_Position LineEnd(Sci_Position line) { - if (documentVersion >= dvLineEnd) { - return (static_cast(pAccess))->LineEnd(line); - } else { - // Old interface means only '\r', '\n' and '\r\n' line ends. - Sci_Position startNext = pAccess->LineStart(line+1); - const char chLineEnd = SafeGetCharAt(startNext-1); - if (chLineEnd == '\n' && (SafeGetCharAt(startNext-2) == '\r')) - return startNext - 2; - else - return startNext - 1; - } + Sci_Position LineEnd(Sci_Position line) const { + return pAccess->LineEnd(line); } int LevelAt(Sci_Position line) const { return pAccess->GetLevel(line); @@ -151,7 +150,7 @@ class LexAccessor { } // Style setting void StartAt(Sci_PositionU start) { - pAccess->StartStyling(start, '\377'); + pAccess->StartStyling(start); startPosStyling = start; } Sci_PositionU GetStartSegment() const { diff --git a/scintilla/lexlib/LexerBase.cxx b/scintilla/lexilla/lexlib/LexerBase.cxx similarity index 94% rename from scintilla/lexlib/LexerBase.cxx rename to scintilla/lexilla/lexlib/LexerBase.cxx index 97edc621c4..a45a334b82 100644 --- a/scintilla/lexlib/LexerBase.cxx +++ b/scintilla/lexilla/lexlib/LexerBase.cxx @@ -9,6 +9,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -20,7 +23,7 @@ #include "LexerModule.h" #include "LexerBase.h" -using namespace Scintilla; +using namespace Lexilla; static const char styleSubable[] = { 0 }; @@ -44,7 +47,7 @@ void SCI_METHOD LexerBase::Release() { } int SCI_METHOD LexerBase::Version() const { - return lvIdentity; + return Scintilla::lvRelease5; } const char * SCI_METHOD LexerBase::PropertyNames() { @@ -60,9 +63,7 @@ const char * SCI_METHOD LexerBase::DescribeProperty(const char *) { } Sci_Position SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) { - const char *valOld = props.Get(key); - if (strcmp(val, valOld) != 0) { - props.Set(key, val, strlen(key), strlen(val)); + if (props.Set(key, val)) { return 0; } else { return -1; @@ -144,7 +145,7 @@ const char * SCI_METHOD LexerBase::DescriptionOfStyle(int style) { return (style < NamedStyles()) ? lexClasses[style].description : ""; } -// ILexerWithIdentity methods +// ILexer5 methods const char *SCI_METHOD LexerBase::GetName() { return ""; diff --git a/scintilla/lexlib/LexerBase.h b/scintilla/lexilla/lexlib/LexerBase.h similarity index 91% rename from scintilla/lexlib/LexerBase.h rename to scintilla/lexilla/lexlib/LexerBase.h index a023d0fe17..32a55760f3 100644 --- a/scintilla/lexlib/LexerBase.h +++ b/scintilla/lexilla/lexlib/LexerBase.h @@ -8,10 +8,10 @@ #ifndef LEXERBASE_H #define LEXERBASE_H -namespace Scintilla { +namespace Lexilla { // A simple lexer with no state -class LexerBase : public ILexerWithIdentity { +class LexerBase : public Scintilla::ILexer5 { protected: const LexicalClass *lexClasses; size_t nClasses; @@ -29,8 +29,8 @@ class LexerBase : public ILexerWithIdentity { Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; const char * SCI_METHOD DescribeWordListSets() override; Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override; - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override = 0; - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override = 0; + void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override = 0; + void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override = 0; void * SCI_METHOD PrivateCall(int operation, void *pointer) override; int SCI_METHOD LineEndTypesSupported() override; int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override; @@ -46,7 +46,7 @@ class LexerBase : public ILexerWithIdentity { const char * SCI_METHOD NameOfStyle(int style) override; const char * SCI_METHOD TagsOfStyle(int style) override; const char * SCI_METHOD DescriptionOfStyle(int style) override; - // ILexerWithIdentity methods + // ILexer5 methods const char * SCI_METHOD GetName() override; int SCI_METHOD GetIdentifier() override; const char *SCI_METHOD PropertyGet(const char *key) override; diff --git a/scintilla/lexlib/LexerModule.cxx b/scintilla/lexilla/lexlib/LexerModule.cxx similarity index 96% rename from scintilla/lexlib/LexerModule.cxx rename to scintilla/lexilla/lexlib/LexerModule.cxx index 3ffc781e75..4b550f6bb9 100644 --- a/scintilla/lexlib/LexerModule.cxx +++ b/scintilla/lexilla/lexlib/LexerModule.cxx @@ -9,6 +9,7 @@ #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -22,7 +23,7 @@ #include "LexerBase.h" #include "LexerSimple.h" -using namespace Scintilla; +using namespace Lexilla; LexerModule::LexerModule(int language_, LexerFunction fnLexer_, @@ -90,7 +91,7 @@ size_t LexerModule::NamedStyles() const noexcept { return nClasses; } -ILexer *LexerModule::Create() const { +Scintilla::ILexer5 *LexerModule::Create() const { if (fnFactory) return fnFactory(); else diff --git a/scintilla/lexlib/LexerModule.h b/scintilla/lexilla/lexlib/LexerModule.h similarity index 94% rename from scintilla/lexlib/LexerModule.h rename to scintilla/lexilla/lexlib/LexerModule.h index 771101a91c..d6ab78fcbb 100644 --- a/scintilla/lexlib/LexerModule.h +++ b/scintilla/lexilla/lexlib/LexerModule.h @@ -8,7 +8,7 @@ #ifndef LEXERMODULE_H #define LEXERMODULE_H -namespace Scintilla { +namespace Lexilla { class Accessor; class WordList; @@ -16,7 +16,7 @@ struct LexicalClass; typedef void (*LexerFunction)(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler); -typedef ILexer *(*LexerFactoryFunction)(); +typedef Scintilla::ILexer5 *(*LexerFactoryFunction)(); /** * A LexerModule is responsible for lexing and folding a particular language. @@ -57,7 +57,7 @@ class LexerModule { const LexicalClass *LexClasses() const noexcept; size_t NamedStyles() const noexcept; - ILexer *Create() const; + Scintilla::ILexer5 *Create() const; void Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler) const; @@ -67,7 +67,7 @@ class LexerModule { friend class CatalogueModules; }; -inline int Maximum(int a, int b) noexcept { +constexpr int Maximum(int a, int b) noexcept { return (a > b) ? a : b; } diff --git a/scintilla/lexlib/LexerNoExceptions.cxx b/scintilla/lexilla/lexlib/LexerNoExceptions.cxx similarity index 89% rename from scintilla/lexlib/LexerNoExceptions.cxx rename to scintilla/lexilla/lexlib/LexerNoExceptions.cxx index 3627e188a6..d4c2857515 100644 --- a/scintilla/lexlib/LexerNoExceptions.cxx +++ b/scintilla/lexilla/lexlib/LexerNoExceptions.cxx @@ -8,6 +8,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" @@ -20,7 +23,7 @@ #include "LexerBase.h" #include "LexerNoExceptions.h" -using namespace Scintilla; +using namespace Lexilla; Sci_Position SCI_METHOD LexerNoExceptions::PropertySet(const char *key, const char *val) { try { @@ -40,7 +43,7 @@ Sci_Position SCI_METHOD LexerNoExceptions::WordListSet(int n, const char *wl) { return -1; } -void SCI_METHOD LexerNoExceptions::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) { +void SCI_METHOD LexerNoExceptions::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) { try { Accessor astyler(pAccess, &props); Lexer(startPos, lengthDoc, initStyle, pAccess, astyler); @@ -50,7 +53,7 @@ void SCI_METHOD LexerNoExceptions::Lex(Sci_PositionU startPos, Sci_Position leng pAccess->SetErrorStatus(SC_STATUS_FAILURE); } } -void SCI_METHOD LexerNoExceptions::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) { +void SCI_METHOD LexerNoExceptions::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) { try { Accessor astyler(pAccess, &props); Folder(startPos, lengthDoc, initStyle, pAccess, astyler); diff --git a/scintilla/lexlib/LexerNoExceptions.h b/scintilla/lexilla/lexlib/LexerNoExceptions.h similarity index 76% rename from scintilla/lexlib/LexerNoExceptions.h rename to scintilla/lexilla/lexlib/LexerNoExceptions.h index 5bcb090f0c..6b3a85a6b5 100644 --- a/scintilla/lexlib/LexerNoExceptions.h +++ b/scintilla/lexilla/lexlib/LexerNoExceptions.h @@ -8,7 +8,7 @@ #ifndef LEXERNOEXCEPTIONS_H #define LEXERNOEXCEPTIONS_H -namespace Scintilla { +namespace Lexilla { // A simple lexer with no state class LexerNoExceptions : public LexerBase { @@ -16,11 +16,11 @@ class LexerNoExceptions : public LexerBase { // TODO Also need to prevent exceptions in constructor and destructor Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override; - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *) override; + void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override; + void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *) override; - virtual void Lexer(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess, Accessor &styler) = 0; - virtual void Folder(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess, Accessor &styler) = 0; + virtual void Lexer(Sci_PositionU startPos, Sci_Position length, int initStyle, Scintilla::IDocument *pAccess, Accessor &styler) = 0; + virtual void Folder(Sci_PositionU startPos, Sci_Position length, int initStyle, Scintilla::IDocument *pAccess, Accessor &styler) = 0; }; } diff --git a/scintilla/lexlib/LexerSimple.cxx b/scintilla/lexilla/lexlib/LexerSimple.cxx similarity index 89% rename from scintilla/lexlib/LexerSimple.cxx rename to scintilla/lexilla/lexlib/LexerSimple.cxx index e69c44ad63..2cbb1330ab 100644 --- a/scintilla/lexlib/LexerSimple.cxx +++ b/scintilla/lexilla/lexlib/LexerSimple.cxx @@ -9,6 +9,7 @@ #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -22,7 +23,7 @@ #include "LexerBase.h" #include "LexerSimple.h" -using namespace Scintilla; +using namespace Lexilla; LexerSimple::LexerSimple(const LexerModule *module_) : LexerBase(module_->LexClasses(), module_->NamedStyles()), @@ -38,13 +39,13 @@ const char * SCI_METHOD LexerSimple::DescribeWordListSets() { return wordLists.c_str(); } -void SCI_METHOD LexerSimple::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) { +void SCI_METHOD LexerSimple::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) { Accessor astyler(pAccess, &props); module->Lex(startPos, lengthDoc, initStyle, keyWordLists, astyler); astyler.Flush(); } -void SCI_METHOD LexerSimple::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) { +void SCI_METHOD LexerSimple::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) { if (props.GetInt("fold")) { Accessor astyler(pAccess, &props); module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler); diff --git a/scintilla/lexlib/LexerSimple.h b/scintilla/lexilla/lexlib/LexerSimple.h similarity index 82% rename from scintilla/lexlib/LexerSimple.h rename to scintilla/lexilla/lexlib/LexerSimple.h index a2589cf443..a1d1b290be 100644 --- a/scintilla/lexlib/LexerSimple.h +++ b/scintilla/lexilla/lexlib/LexerSimple.h @@ -8,7 +8,7 @@ #ifndef LEXERSIMPLE_H #define LEXERSIMPLE_H -namespace Scintilla { +namespace Lexilla { // A simple lexer with no state class LexerSimple : public LexerBase { @@ -17,9 +17,9 @@ class LexerSimple : public LexerBase { public: explicit LexerSimple(const LexerModule *module_); const char * SCI_METHOD DescribeWordListSets() override; - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; - // ILexerWithIdentity methods + void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override; + void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override; + // ILexer5 methods const char * SCI_METHOD GetName() override; int SCI_METHOD GetIdentifier() override; }; diff --git a/scintilla/lexlib/OptionSet.h b/scintilla/lexilla/lexlib/OptionSet.h similarity index 97% rename from scintilla/lexlib/OptionSet.h rename to scintilla/lexilla/lexlib/OptionSet.h index 3c282e49b5..1c5c2ec00c 100644 --- a/scintilla/lexlib/OptionSet.h +++ b/scintilla/lexilla/lexlib/OptionSet.h @@ -10,7 +10,7 @@ #ifndef OPTIONSET_H #define OPTIONSET_H -namespace Scintilla { +namespace Lexilla { template class OptionSet { @@ -72,7 +72,7 @@ class OptionSet { return value.c_str(); } }; - typedef std::map OptionMap; + typedef std::map> OptionMap; OptionMap nameToDef; std::string names; std::string wordLists; diff --git a/scintilla/lexilla/lexlib/PropSetSimple.cxx b/scintilla/lexilla/lexlib/PropSetSimple.cxx new file mode 100644 index 0000000000..903d9790b6 --- /dev/null +++ b/scintilla/lexilla/lexlib/PropSetSimple.cxx @@ -0,0 +1,75 @@ +// Scintilla source code edit control +/** @file PropSetSimple.cxx + ** A basic string to string map. + **/ +// Copyright 1998-2010 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +// Maintain a dictionary of properties + +#include +#include + +#include +#include +#include +#include + +#include "PropSetSimple.h" + +using namespace Lexilla; + +namespace { + +typedef std::map> mapss; + +mapss *PropsFromPointer(void *impl) noexcept { + return static_cast(impl); +} + +} + +PropSetSimple::PropSetSimple() { + mapss *props = new mapss; + impl = static_cast(props); +} + +PropSetSimple::~PropSetSimple() { + mapss *props = PropsFromPointer(impl); + delete props; + impl = nullptr; +} + +bool PropSetSimple::Set(std::string_view key, std::string_view val) { + mapss *props = PropsFromPointer(impl); + if (!props) + return false; + mapss::iterator it = props->find(key); + if (it != props->end()) { + if (val == it->second) + return false; + it->second = val; + } else { + props->emplace(key, val); + } + return true; +} + +const char *PropSetSimple::Get(std::string_view key) const { + mapss *props = PropsFromPointer(impl); + if (props) { + mapss::const_iterator keyPos = props->find(key); + if (keyPos != props->end()) { + return keyPos->second.c_str(); + } + } + return ""; +} + +int PropSetSimple::GetInt(std::string_view key, int defaultValue) const { + const char *val = Get(key); + if (*val) { + return atoi(val); + } + return defaultValue; +} diff --git a/scintilla/lexilla/lexlib/PropSetSimple.h b/scintilla/lexilla/lexlib/PropSetSimple.h new file mode 100644 index 0000000000..c5d85f6a90 --- /dev/null +++ b/scintilla/lexilla/lexlib/PropSetSimple.h @@ -0,0 +1,31 @@ +// Scintilla source code edit control +/** @file PropSetSimple.h + ** A basic string to string map. + **/ +// Copyright 1998-2009 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef PROPSETSIMPLE_H +#define PROPSETSIMPLE_H + +namespace Lexilla { + +class PropSetSimple { + void *impl; +public: + PropSetSimple(); + // Deleted so PropSetSimple objects can not be copied. + PropSetSimple(const PropSetSimple&) = delete; + PropSetSimple(PropSetSimple&&) = delete; + PropSetSimple &operator=(const PropSetSimple&) = delete; + PropSetSimple &operator=(PropSetSimple&&) = delete; + virtual ~PropSetSimple(); + + bool Set(std::string_view key, std::string_view val); + const char *Get(std::string_view key) const; + int GetInt(std::string_view key, int defaultValue=0) const; +}; + +} + +#endif diff --git a/scintilla/lexlib/SparseState.h b/scintilla/lexilla/lexlib/SparseState.h similarity index 99% rename from scintilla/lexlib/SparseState.h rename to scintilla/lexilla/lexlib/SparseState.h index 6286c76afb..592b333b79 100644 --- a/scintilla/lexlib/SparseState.h +++ b/scintilla/lexilla/lexlib/SparseState.h @@ -10,7 +10,7 @@ #ifndef SPARSESTATE_H #define SPARSESTATE_H -namespace Scintilla { +namespace Lexilla { template class SparseState { diff --git a/scintilla/lexlib/StringCopy.h b/scintilla/lexilla/lexlib/StringCopy.h similarity index 97% rename from scintilla/lexlib/StringCopy.h rename to scintilla/lexilla/lexlib/StringCopy.h index 1c5442e651..01f30ba9d5 100644 --- a/scintilla/lexlib/StringCopy.h +++ b/scintilla/lexilla/lexlib/StringCopy.h @@ -9,7 +9,7 @@ #ifndef STRINGCOPY_H #define STRINGCOPY_H -namespace Scintilla { +namespace Lexilla { // Safer version of string copy functions like strcpy, wcsncpy, etc. // Instantiate over fixed length strings of both char and wchar_t. diff --git a/scintilla/lexlib/StyleContext.cxx b/scintilla/lexilla/lexlib/StyleContext.cxx similarity index 55% rename from scintilla/lexlib/StyleContext.cxx rename to scintilla/lexilla/lexlib/StyleContext.cxx index fe56e53d7b..e7b5719312 100644 --- a/scintilla/lexlib/StyleContext.cxx +++ b/scintilla/lexilla/lexlib/StyleContext.cxx @@ -8,6 +8,9 @@ #include #include +#include +#include + #include "ILexer.h" #include "LexAccessor.h" @@ -15,7 +18,7 @@ #include "StyleContext.h" #include "CharacterSet.h" -using namespace Scintilla; +using namespace Lexilla; bool StyleContext::MatchIgnoreCase(const char *s) { if (MakeLowerCase(ch) != static_cast(*s)) @@ -33,36 +36,10 @@ bool StyleContext::MatchIgnoreCase(const char *s) { return true; } -static void getRange(Sci_PositionU start, - Sci_PositionU end, - LexAccessor &styler, - char *s, - Sci_PositionU len) { - Sci_PositionU i = 0; - while ((i < end - start + 1) && (i < len-1)) { - s[i] = styler[start + i]; - i++; - } - s[i] = '\0'; -} - void StyleContext::GetCurrent(char *s, Sci_PositionU len) { - getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len); -} - -static void getRangeLowered(Sci_PositionU start, - Sci_PositionU end, - LexAccessor &styler, - char *s, - Sci_PositionU len) { - Sci_PositionU i = 0; - while ((i < end - start + 1) && (i < len-1)) { - s[i] = MakeLowerCase(styler[start + i]); - i++; - } - s[i] = '\0'; + styler.GetRange(styler.GetStartSegment(), currentPos, s, len); } void StyleContext::GetCurrentLowered(char *s, Sci_PositionU len) { - getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len); + styler.GetRangeLowered(styler.GetStartSegment(), currentPos, s, len); } diff --git a/scintilla/lexlib/StyleContext.h b/scintilla/lexilla/lexlib/StyleContext.h similarity index 95% rename from scintilla/lexlib/StyleContext.h rename to scintilla/lexilla/lexlib/StyleContext.h index d8c17d794f..a6c6f9f4d7 100644 --- a/scintilla/lexlib/StyleContext.h +++ b/scintilla/lexilla/lexlib/StyleContext.h @@ -8,7 +8,7 @@ #ifndef STYLECONTEXT_H #define STYLECONTEXT_H -namespace Scintilla { +namespace Lexilla { // All languages handled so far can treat all characters >= 0x80 as one class // which just continues the current token or starts an identifier if in default. @@ -16,7 +16,7 @@ namespace Scintilla { // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80 class StyleContext { LexAccessor &styler; - IDocumentWithLineEnd *multiByteAccess; + Scintilla::IDocument *multiByteAccess; Sci_PositionU endPos; Sci_PositionU lengthDocument; @@ -44,6 +44,7 @@ class StyleContext { Sci_PositionU currentPos; Sci_Position currentLine; Sci_Position lineDocEnd; + Sci_Position lineEnd; Sci_Position lineStartNext; bool atLineStart; bool atLineEnd; @@ -64,6 +65,7 @@ class StyleContext { offsetRelative(0), currentPos(startPos), currentLine(-1), + lineEnd(-1), lineStartNext(-1), atLineEnd(false), state(initStyle & chMask), // Mask off all bits which aren't in the chMask. @@ -78,6 +80,7 @@ class StyleContext { styler.StartAt(startPos /*, chMask*/); styler.StartSegment(startPos); currentLine = styler.GetLine(startPos); + lineEnd = styler.LineEnd(currentLine); lineStartNext = styler.LineStart(currentLine+1); lengthDocument = static_cast(styler.Length()); if (endPos == lengthDocument) @@ -108,6 +111,7 @@ class StyleContext { atLineStart = atLineEnd; if (atLineStart) { currentLine++; + lineEnd = styler.LineEnd(currentLine); lineStartNext = styler.LineStart(currentLine+1); } chPrev = ch; @@ -179,6 +183,9 @@ class StyleContext { return static_cast(styler.SafeGetCharAt(currentPos + n, 0)); } } + bool MatchLineEnd() const noexcept { + return static_cast(currentPos) == lineEnd; + } bool Match(char ch0) const { return ch == static_cast(ch0); } diff --git a/scintilla/lexlib/SubStyles.h b/scintilla/lexilla/lexlib/SubStyles.h similarity index 79% rename from scintilla/lexlib/SubStyles.h rename to scintilla/lexilla/lexlib/SubStyles.h index 4bfe7ebfc9..049039e856 100644 --- a/scintilla/lexlib/SubStyles.h +++ b/scintilla/lexilla/lexlib/SubStyles.h @@ -8,13 +8,14 @@ #ifndef SUBSTYLES_H #define SUBSTYLES_H -namespace Scintilla { +namespace Lexilla { class WordClassifier { int baseStyle; int firstStyle; int lenStyles; - std::map wordToStyle; + using WordStyleMap = std::map>; + WordStyleMap wordToStyle; public: @@ -49,8 +50,8 @@ class WordClassifier { wordToStyle.clear(); } - int ValueFor(const std::string &s) const { - std::map::const_iterator it = wordToStyle.find(s); + int ValueFor(std::string_view s) const { + WordStyleMap::const_iterator it = wordToStyle.find(s); if (it != wordToStyle.end()) return it->second; else @@ -61,8 +62,8 @@ class WordClassifier { return (style >= firstStyle) && (style < (firstStyle + lenStyles)); } - void RemoveStyle(int style) { - std::map::iterator it = wordToStyle.begin(); + void RemoveStyle(int style) noexcept { + WordStyleMap::iterator it = wordToStyle.begin(); while (it != wordToStyle.end()) { if (it->second == style) { it = wordToStyle.erase(it); @@ -74,6 +75,8 @@ class WordClassifier { void SetIdentifiers(int style, const char *identifiers) { RemoveStyle(style); + if (!identifiers) + return; while (*identifiers) { const char *cpSpace = identifiers; while (*cpSpace && !(*cpSpace == ' ' || *cpSpace == '\t' || *cpSpace == '\r' || *cpSpace == '\n')) @@ -106,10 +109,10 @@ class SubStyles { return -1; } - int BlockFromStyle(int style) const { + int BlockFromStyle(int style) const noexcept { int b = 0; - for (std::vector::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) { - if (it->IncludesStyle(style)) + for (const WordClassifier &wc : classifiers) { + if (wc.IncludesStyle(style)) return b; b++; } @@ -155,7 +158,7 @@ class SubStyles { return (block >= 0) ? classifiers[block].Length() : 0; } - int BaseStyle(int subStyle) const { + int BaseStyle(int subStyle) const noexcept { const int block = BlockFromStyle(subStyle); if (block >= 0) return classifiers[block].Base(); @@ -167,20 +170,20 @@ class SubStyles { return secondaryDistance; } - int FirstAllocated() const { + int FirstAllocated() const noexcept { int start = 257; - for (std::vector::const_iterator it = classifiers.begin(); it != classifiers.end(); ++it) { - if (start > it->Start()) - start = it->Start(); + for (const WordClassifier &wc : classifiers) { + if ((wc.Length() > 0) && (start > wc.Start())) + start = wc.Start(); } return (start < 256) ? start : -1; } - int LastAllocated() const { + int LastAllocated() const noexcept { int last = -1; - for (std::vector::const_iterator it = classifiers.begin(); it != classifiers.end(); ++it) { - if (last < it->Last()) - last = it->Last(); + for (const WordClassifier &wc : classifiers) { + if ((wc.Length() > 0) && (last < wc.Last())) + last = wc.Last(); } return last; } @@ -191,10 +194,11 @@ class SubStyles { classifiers[block].SetIdentifiers(style, identifiers); } - void Free() { + void Free() noexcept { allocated = 0; - for (std::vector::iterator it=classifiers.begin(); it != classifiers.end(); ++it) - it->Clear(); + for (WordClassifier &wc : classifiers) { + wc.Clear(); + } } const WordClassifier &Classifier(int baseStyle) const noexcept { diff --git a/scintilla/lexlib/WordList.cxx b/scintilla/lexilla/lexlib/WordList.cxx similarity index 99% rename from scintilla/lexlib/WordList.cxx rename to scintilla/lexilla/lexlib/WordList.cxx index 460995daae..4676717a17 100644 --- a/scintilla/lexlib/WordList.cxx +++ b/scintilla/lexilla/lexlib/WordList.cxx @@ -14,7 +14,7 @@ #include "WordList.h" -using namespace Scintilla; +using namespace Lexilla; /** * Creates an array that points into each word in the string and puts \0 terminators diff --git a/scintilla/lexlib/WordList.h b/scintilla/lexilla/lexlib/WordList.h similarity index 97% rename from scintilla/lexlib/WordList.h rename to scintilla/lexilla/lexlib/WordList.h index 127f00e68c..07ae573bce 100644 --- a/scintilla/lexlib/WordList.h +++ b/scintilla/lexilla/lexlib/WordList.h @@ -8,7 +8,7 @@ #ifndef WORDLIST_H #define WORDLIST_H -namespace Scintilla { +namespace Lexilla { /** */ diff --git a/scintilla/lexilla/src/Lexilla.cxx b/scintilla/lexilla/src/Lexilla.cxx new file mode 100644 index 0000000000..af4a73db4d --- /dev/null +++ b/scintilla/lexilla/src/Lexilla.cxx @@ -0,0 +1,432 @@ +// Lexilla lexer library +/** @file Lexilla.cxx + ** Lexer infrastructure. + ** Provides entry points to shared library. + **/ +// Copyright 2019 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include + +#include +#include + +#if _WIN32 +#define EXPORT_FUNCTION __declspec(dllexport) +#define CALLING_CONVENTION __stdcall +#else +#define EXPORT_FUNCTION __attribute__((visibility("default"))) +#define CALLING_CONVENTION +#endif + +#include "ILexer.h" + +#include "LexerModule.h" +#include "CatalogueModules.h" + +using namespace Lexilla; + +//++Autogenerated -- run lexilla/scripts/LexillaGen.py to regenerate +//**\(extern LexerModule \*;\n\) +extern LexerModule lmA68k; +extern LexerModule lmAbaqus; +extern LexerModule lmAda; +extern LexerModule lmAPDL; +extern LexerModule lmAs; +extern LexerModule lmAsm; +extern LexerModule lmAsn1; +extern LexerModule lmASY; +extern LexerModule lmAU3; +extern LexerModule lmAVE; +extern LexerModule lmAVS; +extern LexerModule lmBaan; +extern LexerModule lmBash; +extern LexerModule lmBatch; +extern LexerModule lmBibTeX; +extern LexerModule lmBlitzBasic; +extern LexerModule lmBullant; +extern LexerModule lmCaml; +extern LexerModule lmCIL; +extern LexerModule lmClw; +extern LexerModule lmClwNoCase; +extern LexerModule lmCmake; +extern LexerModule lmCOBOL; +extern LexerModule lmCoffeeScript; +extern LexerModule lmConf; +extern LexerModule lmCPP; +extern LexerModule lmCPPNoCase; +extern LexerModule lmCsound; +extern LexerModule lmCss; +extern LexerModule lmD; +extern LexerModule lmDataflex; +extern LexerModule lmDiff; +extern LexerModule lmDMAP; +extern LexerModule lmDMIS; +extern LexerModule lmECL; +extern LexerModule lmEDIFACT; +extern LexerModule lmEiffel; +extern LexerModule lmEiffelkw; +extern LexerModule lmErlang; +extern LexerModule lmErrorList; +extern LexerModule lmESCRIPT; +extern LexerModule lmF77; +extern LexerModule lmFlagShip; +extern LexerModule lmForth; +extern LexerModule lmFortran; +extern LexerModule lmFreeBasic; +extern LexerModule lmFSharp; +extern LexerModule lmGAP; +extern LexerModule lmGui4Cli; +extern LexerModule lmHaskell; +extern LexerModule lmHollywood; +extern LexerModule lmHTML; +extern LexerModule lmIHex; +extern LexerModule lmIndent; +extern LexerModule lmInno; +extern LexerModule lmJSON; +extern LexerModule lmJulia; +extern LexerModule lmKix; +extern LexerModule lmKVIrc; +extern LexerModule lmLatex; +extern LexerModule lmLISP; +extern LexerModule lmLiterateHaskell; +extern LexerModule lmLot; +extern LexerModule lmLout; +extern LexerModule lmLua; +extern LexerModule lmMagikSF; +extern LexerModule lmMake; +extern LexerModule lmMarkdown; +extern LexerModule lmMatlab; +extern LexerModule lmMaxima; +extern LexerModule lmMETAPOST; +extern LexerModule lmMMIXAL; +extern LexerModule lmModula; +extern LexerModule lmMSSQL; +extern LexerModule lmMySQL; +extern LexerModule lmNim; +extern LexerModule lmNimrod; +extern LexerModule lmNncrontab; +extern LexerModule lmNsis; +extern LexerModule lmNull; +extern LexerModule lmOctave; +extern LexerModule lmOpal; +extern LexerModule lmOScript; +extern LexerModule lmPascal; +extern LexerModule lmPB; +extern LexerModule lmPerl; +extern LexerModule lmPHPSCRIPT; +extern LexerModule lmPLM; +extern LexerModule lmPO; +extern LexerModule lmPOV; +extern LexerModule lmPowerPro; +extern LexerModule lmPowerShell; +extern LexerModule lmProgress; +extern LexerModule lmProps; +extern LexerModule lmPS; +extern LexerModule lmPureBasic; +extern LexerModule lmPython; +extern LexerModule lmR; +extern LexerModule lmRaku; +extern LexerModule lmREBOL; +extern LexerModule lmRegistry; +extern LexerModule lmRuby; +extern LexerModule lmRust; +extern LexerModule lmSAS; +extern LexerModule lmScriptol; +extern LexerModule lmSmalltalk; +extern LexerModule lmSML; +extern LexerModule lmSorc; +extern LexerModule lmSpecman; +extern LexerModule lmSpice; +extern LexerModule lmSQL; +extern LexerModule lmSrec; +extern LexerModule lmStata; +extern LexerModule lmSTTXT; +extern LexerModule lmTACL; +extern LexerModule lmTADS3; +extern LexerModule lmTAL; +extern LexerModule lmTCL; +extern LexerModule lmTCMD; +extern LexerModule lmTEHex; +extern LexerModule lmTeX; +extern LexerModule lmTxt2tags; +extern LexerModule lmVB; +extern LexerModule lmVBScript; +extern LexerModule lmVerilog; +extern LexerModule lmVHDL; +extern LexerModule lmVisualProlog; +extern LexerModule lmX12; +extern LexerModule lmXML; +extern LexerModule lmYAML; + +//--Autogenerated -- end of automatically generated section + +namespace { + +CatalogueModules catalogueLexilla; + +static void AddGeanyLexers() +{ + catalogueLexilla.AddLexerModules({ + &lmAbaqus, + &lmAda, + &lmAsm, + &lmBash, + &lmBatch, + &lmCaml, + &lmCmake, + &lmCOBOL, + &lmCoffeeScript, + &lmCPP, + &lmCss, + &lmD, + &lmDiff, + &lmErlang, + &lmF77, + &lmForth, + &lmFortran, + &lmFreeBasic, + &lmHaskell, + &lmHTML, + &lmJulia, + &lmLatex, + &lmLISP, + &lmLua, + &lmMake, + &lmMarkdown, + &lmNsis, + &lmNull, + &lmOctave, + &lmPascal, + &lmPerl, + &lmPHPSCRIPT, + &lmPO, + &lmPowerShell, + &lmProps, + &lmPython, + &lmR, + &lmRuby, + &lmRust, + &lmSmalltalk, + &lmSQL, + &lmTCL, + &lmTxt2tags, + &lmVerilog, + &lmVHDL, + &lmXML, + &lmYAML, + }); +} + +void AddEachLexer() { + + if (catalogueLexilla.Count() > 0) { + return; + } + + AddGeanyLexers(); + return; + + catalogueLexilla.AddLexerModules({ +//++Autogenerated -- run scripts/LexillaGen.py to regenerate +//**\(\t\t&\*,\n\) + &lmA68k, + &lmAbaqus, + &lmAda, + &lmAPDL, + &lmAs, + &lmAsm, + &lmAsn1, + &lmASY, + &lmAU3, + &lmAVE, + &lmAVS, + &lmBaan, + &lmBash, + &lmBatch, + &lmBibTeX, + &lmBlitzBasic, + &lmBullant, + &lmCaml, + &lmCIL, + &lmClw, + &lmClwNoCase, + &lmCmake, + &lmCOBOL, + &lmCoffeeScript, + &lmConf, + &lmCPP, + &lmCPPNoCase, + &lmCsound, + &lmCss, + &lmD, + &lmDataflex, + &lmDiff, + &lmDMAP, + &lmDMIS, + &lmECL, + &lmEDIFACT, + &lmEiffel, + &lmEiffelkw, + &lmErlang, + &lmErrorList, + &lmESCRIPT, + &lmF77, + &lmFlagShip, + &lmForth, + &lmFortran, + &lmFreeBasic, + &lmFSharp, + &lmGAP, + &lmGui4Cli, + &lmHaskell, + &lmHollywood, + &lmHTML, + &lmIHex, + &lmIndent, + &lmInno, + &lmJSON, + &lmJulia, + &lmKix, + &lmKVIrc, + &lmLatex, + &lmLISP, + &lmLiterateHaskell, + &lmLot, + &lmLout, + &lmLua, + &lmMagikSF, + &lmMake, + &lmMarkdown, + &lmMatlab, + &lmMaxima, + &lmMETAPOST, + &lmMMIXAL, + &lmModula, + &lmMSSQL, + &lmMySQL, + &lmNim, + &lmNimrod, + &lmNncrontab, + &lmNsis, + &lmNull, + &lmOctave, + &lmOpal, + &lmOScript, + &lmPascal, + &lmPB, + &lmPerl, + &lmPHPSCRIPT, + &lmPLM, + &lmPO, + &lmPOV, + &lmPowerPro, + &lmPowerShell, + &lmProgress, + &lmProps, + &lmPS, + &lmPureBasic, + &lmPython, + &lmR, + &lmRaku, + &lmREBOL, + &lmRegistry, + &lmRuby, + &lmRust, + &lmSAS, + &lmScriptol, + &lmSmalltalk, + &lmSML, + &lmSorc, + &lmSpecman, + &lmSpice, + &lmSQL, + &lmSrec, + &lmStata, + &lmSTTXT, + &lmTACL, + &lmTADS3, + &lmTAL, + &lmTCL, + &lmTCMD, + &lmTEHex, + &lmTeX, + &lmTxt2tags, + &lmVB, + &lmVBScript, + &lmVerilog, + &lmVHDL, + &lmVisualProlog, + &lmX12, + &lmXML, + &lmYAML, + +//--Autogenerated -- end of automatically generated section + }); + +} + +} + +extern "C" { + +EXPORT_FUNCTION int CALLING_CONVENTION GetLexerCount() { + AddEachLexer(); + return catalogueLexilla.Count(); +} + +EXPORT_FUNCTION void CALLING_CONVENTION GetLexerName(unsigned int index, char *name, int buflength) { + AddEachLexer(); + *name = 0; + const char *lexerName = catalogueLexilla.Name(index); + if (static_cast(buflength) > strlen(lexerName)) { + strcpy(name, lexerName); + } +} + +EXPORT_FUNCTION LexerFactoryFunction CALLING_CONVENTION GetLexerFactory(unsigned int index) { + AddEachLexer(); + return catalogueLexilla.Factory(index); +} + +EXPORT_FUNCTION Scintilla::ILexer5 * CALLING_CONVENTION CreateLexer(const char *name) { + AddEachLexer(); + for (unsigned int i = 0; i < catalogueLexilla.Count(); i++) { + const char *lexerName = catalogueLexilla.Name(i); + if (0 == strcmp(lexerName, name)) { + return catalogueLexilla.Create(i); + } + } + return nullptr; +} + +EXPORT_FUNCTION const char * CALLING_CONVENTION LexerNameFromID(int identifier) { + AddEachLexer(); + const LexerModule *pModule = catalogueLexilla.Find(identifier); + if (pModule) { + return pModule->languageName; + } else { + return nullptr; + } +} + +EXPORT_FUNCTION const char * CALLING_CONVENTION GetLibraryPropertyNames() { + return ""; +} + +EXPORT_FUNCTION void CALLING_CONVENTION SetLibraryProperty(const char *, const char *) { + // Null implementation +} + +EXPORT_FUNCTION const char * CALLING_CONVENTION GetNameSpace() { + return "lexilla"; +} + +// Not exported from binary as LexerModule must be built exactly the same as +// modules listed above +void AddStaticLexerModule(LexerModule *plm) { + AddEachLexer(); + catalogueLexilla.AddLexerModule(plm); +} + +} diff --git a/scintilla/lexilla/version.txt b/scintilla/lexilla/version.txt new file mode 100644 index 0000000000..c0556fb20f --- /dev/null +++ b/scintilla/lexilla/version.txt @@ -0,0 +1 @@ +511 diff --git a/scintilla/lexlib/PropSetSimple.cxx b/scintilla/lexlib/PropSetSimple.cxx deleted file mode 100644 index 6ee57d667f..0000000000 --- a/scintilla/lexlib/PropSetSimple.cxx +++ /dev/null @@ -1,157 +0,0 @@ -// Scintilla source code edit control -/** @file PropSetSimple.cxx - ** A basic string to string map. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -// Maintain a dictionary of properties - -#include -#include - -#include -#include - -#include "PropSetSimple.h" - -using namespace Scintilla; - -namespace { - -typedef std::map mapss; - -mapss *PropsFromPointer(void *impl) noexcept { - return static_cast(impl); -} - -constexpr bool IsASpaceCharacter(int ch) noexcept { - return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); -} - -} - -PropSetSimple::PropSetSimple() { - mapss *props = new mapss; - impl = static_cast(props); -} - -PropSetSimple::~PropSetSimple() { - mapss *props = PropsFromPointer(impl); - delete props; - impl = nullptr; -} - -void PropSetSimple::Set(const char *key, const char *val, size_t lenKey, size_t lenVal) { - mapss *props = PropsFromPointer(impl); - if (!*key) // Empty keys are not supported - return; - (*props)[std::string(key, lenKey)] = std::string(val, lenVal); -} - -void PropSetSimple::Set(const char *keyVal) { - while (IsASpaceCharacter(*keyVal)) - keyVal++; - const char *endVal = keyVal; - while (*endVal && (*endVal != '\n')) - endVal++; - const char *eqAt = strchr(keyVal, '='); - if (eqAt) { - Set(keyVal, eqAt + 1, eqAt-keyVal, - endVal - eqAt - 1); - } else if (*keyVal) { // No '=' so assume '=1' - Set(keyVal, "1", endVal-keyVal, 1); - } -} - -void PropSetSimple::SetMultiple(const char *s) { - const char *eol = strchr(s, '\n'); - while (eol) { - Set(s); - s = eol + 1; - eol = strchr(s, '\n'); - } - Set(s); -} - -const char *PropSetSimple::Get(const char *key) const { - mapss *props = PropsFromPointer(impl); - mapss::const_iterator keyPos = props->find(std::string(key)); - if (keyPos != props->end()) { - return keyPos->second.c_str(); - } else { - return ""; - } -} - -// There is some inconsistency between GetExpanded("foo") and Expand("$(foo)"). -// A solution is to keep a stack of variables that have been expanded, so that -// recursive expansions can be skipped. For now I'll just use the C++ stack -// for that, through a recursive function and a simple chain of pointers. - -struct VarChain { - VarChain(const char *var_=nullptr, const VarChain *link_= nullptr) noexcept : var(var_), link(link_) {} - - bool contains(const char *testVar) const { - return (var && (0 == strcmp(var, testVar))) - || (link && link->contains(testVar)); - } - - const char *var; - const VarChain *link; -}; - -static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) { - size_t varStart = withVars.find("$("); - while ((varStart != std::string::npos) && (maxExpands > 0)) { - const size_t varEnd = withVars.find(')', varStart+2); - if (varEnd == std::string::npos) { - break; - } - - // For consistency, when we see '$(ab$(cde))', expand the inner variable first, - // regardless whether there is actually a degenerate variable named 'ab$(cde'. - size_t innerVarStart = withVars.find("$(", varStart+2); - while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) { - varStart = innerVarStart; - innerVarStart = withVars.find("$(", varStart+2); - } - - std::string var(withVars, varStart + 2, varEnd - varStart - 2); - std::string val = props.Get(var.c_str()); - - if (blankVars.contains(var.c_str())) { - val = ""; // treat blankVar as an empty string (e.g. to block self-reference) - } - - if (--maxExpands >= 0) { - maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars)); - } - - withVars.erase(varStart, varEnd-varStart+1); - withVars.insert(varStart, val.c_str(), val.length()); - - varStart = withVars.find("$("); - } - - return maxExpands; -} - -size_t PropSetSimple::GetExpanded(const char *key, char *result) const { - std::string val = Get(key); - ExpandAllInPlace(*this, val, 100, VarChain(key)); - const size_t n = val.size(); - if (result) { - memcpy(result, val.c_str(), n+1); - } - return n; // Not including NUL -} - -int PropSetSimple::GetInt(const char *key, int defaultValue) const { - std::string val = Get(key); - ExpandAllInPlace(*this, val, 100, VarChain(key)); - if (!val.empty()) { - return atoi(val.c_str()); - } - return defaultValue; -} diff --git a/scintilla/lexlib/PropSetSimple.h b/scintilla/lexlib/PropSetSimple.h deleted file mode 100644 index d4a5b2243d..0000000000 --- a/scintilla/lexlib/PropSetSimple.h +++ /dev/null @@ -1,28 +0,0 @@ -// Scintilla source code edit control -/** @file PropSetSimple.h - ** A basic string to string map. - **/ -// Copyright 1998-2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef PROPSETSIMPLE_H -#define PROPSETSIMPLE_H - -namespace Scintilla { - -class PropSetSimple { - void *impl; - void Set(const char *keyVal); -public: - PropSetSimple(); - virtual ~PropSetSimple(); - void Set(const char *key, const char *val, size_t lenKey, size_t lenVal); - void SetMultiple(const char *); - const char *Get(const char *key) const; - size_t GetExpanded(const char *key, char *result) const; - int GetInt(const char *key, int defaultValue=0) const; -}; - -} - -#endif diff --git a/scintilla/scintilla_changes.patch b/scintilla/scintilla_changes.patch index c0b53aea2d..08f74780f5 100644 --- a/scintilla/scintilla_changes.patch +++ b/scintilla/scintilla_changes.patch @@ -1,5 +1,5 @@ A patch to Scintilla 3.54 containing our changes to Scintilla -(removing unused lexers, exporting symbols, and an updated marshallers file). +(removing unused lexers, exporting symbols). diff --git scintilla/gtk/ScintillaGTK.cxx scintilla/gtk/ScintillaGTK.cxx index 0871ca2..49dc278 100644 --- scintilla/gtk/ScintillaGTK.cxx @@ -11,7 +11,7 @@ index 0871ca2..49dc278 100644 +GEANY_API_SYMBOL sptr_t scintilla_send_message(ScintillaObject *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { ScintillaGTK *psci = static_cast(sci->pscin); - return psci->WndProc(iMessage, wParam, lParam); + return psci->WndProc(static_cast(iMessage), wParam, lParam); } +GEANY_API_SYMBOL @@ -19,7 +19,7 @@ index 0871ca2..49dc278 100644 return scintilla_send_message(sci, iMessage, wParam, lParam); } @@ -3062,6 +3064,7 @@ extern void Platform_Initialise(); - extern void Platform_Finalise(); + static void scintilla_init(ScintillaObject *sci); /* legacy name for scintilla_object_get_type */ +GEANY_API_SYMBOL @@ -58,142 +58,76 @@ index 0871ca2..49dc278 100644 GType scnotification_get_type(void) { static gsize type_id = 0; if (g_once_init_enter(&type_id)) { -diff --git scintilla/src/Catalogue.cxx scintilla/src/Catalogue.cxx -index ed47aa8..e58f1ab 100644 ---- scintilla/src/Catalogue.cxx -+++ scintilla/src/Catalogue.cxx -@@ -60,133 +60,50 @@ +diff --git scintilla/lexilla/src/Lexilla.cxx scintilla/lexilla/src/Lexilla.cxx +index cd4b23617..af4a73db4 100644 +--- scintilla/lexilla/src/Lexilla.cxx ++++ scintilla/lexilla/src/Lexilla.cxx +@@ -165,12 +165,68 @@ namespace { - //++Autogenerated -- run scripts/LexGen.py to regenerate - //**\(\tLINK_LEXER(\*);\n\) -- LINK_LEXER(lmA68k); - LINK_LEXER(lmAbaqus); - LINK_LEXER(lmAda); -- LINK_LEXER(lmAPDL); -- LINK_LEXER(lmAs); - LINK_LEXER(lmAsm); -- LINK_LEXER(lmAsn1); -- LINK_LEXER(lmASY); -- LINK_LEXER(lmAU3); -- LINK_LEXER(lmAVE); -- LINK_LEXER(lmAVS); -- LINK_LEXER(lmBaan); - LINK_LEXER(lmBash); - LINK_LEXER(lmBatch); -- LINK_LEXER(lmBibTeX); -- LINK_LEXER(lmBlitzBasic); -- LINK_LEXER(lmBullant); - LINK_LEXER(lmCaml); -- LINK_LEXER(lmCIL); -- LINK_LEXER(lmClw); -- LINK_LEXER(lmClwNoCase); - LINK_LEXER(lmCmake); - LINK_LEXER(lmCOBOL); - LINK_LEXER(lmCoffeeScript); -- LINK_LEXER(lmConf); - LINK_LEXER(lmCPP); -- LINK_LEXER(lmCPPNoCase); -- LINK_LEXER(lmCsound); - LINK_LEXER(lmCss); - LINK_LEXER(lmD); -- LINK_LEXER(lmDataflex); - LINK_LEXER(lmDiff); -- LINK_LEXER(lmDMAP); -- LINK_LEXER(lmDMIS); -- LINK_LEXER(lmECL); -- LINK_LEXER(lmEDIFACT); -- LINK_LEXER(lmEiffel); -- LINK_LEXER(lmEiffelkw); - LINK_LEXER(lmErlang); -- LINK_LEXER(lmErrorList); -- LINK_LEXER(lmESCRIPT); - LINK_LEXER(lmF77); -- LINK_LEXER(lmFlagShip); - LINK_LEXER(lmForth); - LINK_LEXER(lmFortran); - LINK_LEXER(lmFreeBasic); -- LINK_LEXER(lmGAP); -- LINK_LEXER(lmGui4Cli); - LINK_LEXER(lmHaskell); -- LINK_LEXER(lmHollywood); - LINK_LEXER(lmHTML); -- LINK_LEXER(lmIHex); -- LINK_LEXER(lmIndent); -- LINK_LEXER(lmInno); -- LINK_LEXER(lmJSON); -- LINK_LEXER(lmKix); -- LINK_LEXER(lmKVIrc); - LINK_LEXER(lmLatex); - LINK_LEXER(lmLISP); -- LINK_LEXER(lmLiterateHaskell); -- LINK_LEXER(lmLot); -- LINK_LEXER(lmLout); -- LINK_LEXER(lmLPeg); - LINK_LEXER(lmLua); -- LINK_LEXER(lmMagikSF); - LINK_LEXER(lmMake); - LINK_LEXER(lmMarkdown); -- LINK_LEXER(lmMatlab); -- LINK_LEXER(lmMaxima); -- LINK_LEXER(lmMETAPOST); -- LINK_LEXER(lmMMIXAL); -- LINK_LEXER(lmModula); -- LINK_LEXER(lmMSSQL); -- LINK_LEXER(lmMySQL); -- LINK_LEXER(lmNim); -- LINK_LEXER(lmNimrod); -- LINK_LEXER(lmNncrontab); -+ // We use Octave instead of Matlab - LINK_LEXER(lmNsis); - LINK_LEXER(lmNull); - LINK_LEXER(lmOctave); -- LINK_LEXER(lmOpal); -- LINK_LEXER(lmOScript); - LINK_LEXER(lmPascal); -- LINK_LEXER(lmPB); - LINK_LEXER(lmPerl); - LINK_LEXER(lmPHPSCRIPT); -- LINK_LEXER(lmPLM); - LINK_LEXER(lmPO); -- LINK_LEXER(lmPOV); -- LINK_LEXER(lmPowerPro); - LINK_LEXER(lmPowerShell); -- LINK_LEXER(lmProgress); - LINK_LEXER(lmProps); -- LINK_LEXER(lmPS); -- LINK_LEXER(lmPureBasic); - LINK_LEXER(lmPython); - LINK_LEXER(lmR); -- LINK_LEXER(lmRaku); -- LINK_LEXER(lmREBOL); -- LINK_LEXER(lmRegistry); - LINK_LEXER(lmRuby); - LINK_LEXER(lmRust); -- LINK_LEXER(lmSAS); -- LINK_LEXER(lmScriptol); - LINK_LEXER(lmSmalltalk); -- LINK_LEXER(lmSML); -- LINK_LEXER(lmSorc); -- LINK_LEXER(lmSpecman); -- LINK_LEXER(lmSpice); - LINK_LEXER(lmSQL); -- LINK_LEXER(lmSrec); -- LINK_LEXER(lmStata); -- LINK_LEXER(lmSTTXT); -- LINK_LEXER(lmTACL); -- LINK_LEXER(lmTADS3); -- LINK_LEXER(lmTAL); - LINK_LEXER(lmTCL); -- LINK_LEXER(lmTCMD); -- LINK_LEXER(lmTEHex); -- LINK_LEXER(lmTeX); - LINK_LEXER(lmTxt2tags); -- LINK_LEXER(lmVB); -- LINK_LEXER(lmVBScript); - LINK_LEXER(lmVerilog); - LINK_LEXER(lmVHDL); -- LINK_LEXER(lmVisualProlog); -- LINK_LEXER(lmX12); - LINK_LEXER(lmXML); - LINK_LEXER(lmYAML); + CatalogueModules catalogueLexilla; ++static void AddGeanyLexers() ++{ ++ catalogueLexilla.AddLexerModules({ ++ &lmAbaqus, ++ &lmAda, ++ &lmAsm, ++ &lmBash, ++ &lmBatch, ++ &lmCaml, ++ &lmCmake, ++ &lmCOBOL, ++ &lmCoffeeScript, ++ &lmCPP, ++ &lmCss, ++ &lmD, ++ &lmDiff, ++ &lmErlang, ++ &lmF77, ++ &lmForth, ++ &lmFortran, ++ &lmFreeBasic, ++ &lmHaskell, ++ &lmHTML, ++ &lmJulia, ++ &lmLatex, ++ &lmLISP, ++ &lmLua, ++ &lmMake, ++ &lmMarkdown, ++ &lmNsis, ++ &lmNull, ++ &lmOctave, ++ &lmPascal, ++ &lmPerl, ++ &lmPHPSCRIPT, ++ &lmPO, ++ &lmPowerShell, ++ &lmProps, ++ &lmPython, ++ &lmR, ++ &lmRuby, ++ &lmRust, ++ &lmSmalltalk, ++ &lmSQL, ++ &lmTCL, ++ &lmTxt2tags, ++ &lmVerilog, ++ &lmVHDL, ++ &lmXML, ++ &lmYAML, ++ }); ++} ++ + void AddEachLexer() { + + if (catalogueLexilla.Count() > 0) { + return; + } + ++ AddGeanyLexers(); ++ return; ++ + catalogueLexilla.AddLexerModules({ + //++Autogenerated -- run scripts/LexillaGen.py to regenerate + //**\(\t\t&\*,\n\) diff --git a/scintilla/src/AutoComplete.cxx b/scintilla/src/AutoComplete.cxx index 886ace4af0..87077e92ad 100644 --- a/scintilla/src/AutoComplete.cxx +++ b/scintilla/src/AutoComplete.cxx @@ -13,18 +13,25 @@ #include #include +#include #include +#include #include #include +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" + +#include "Debugging.h" +#include "Geometry.h" #include "Platform.h" -#include "Scintilla.h" -#include "CharacterSet.h" +#include "CharacterType.h" #include "Position.h" #include "AutoComplete.h" using namespace Scintilla; +using namespace Scintilla::Internal; AutoComplete::AutoComplete() : active(false), @@ -32,16 +39,17 @@ AutoComplete::AutoComplete() : typesep('?'), ignoreCase(false), chooseSingle(false), + options(AutoCompleteOption::Normal), posStart(0), startLen(0), cancelAtStartPos(true), autoHide(true), dropRestOfWord(false), - ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE), + ignoreCaseBehaviour(CaseInsensitiveBehaviour::RespectCase), widthLBDefault(100), heightLBDefault(100), - autoSort(SC_ORDER_PRESORTED) { - lb.reset(ListBox::Allocate()); + autoSort(Ordering::PreSorted) { + lb = ListBox::Allocate(); } AutoComplete::~AutoComplete() { @@ -56,10 +64,11 @@ bool AutoComplete::Active() const noexcept { void AutoComplete::Start(Window &parent, int ctrlID, Sci::Position position, Point location, Sci::Position startLen_, - int lineHeight, bool unicodeMode, int technology) { + int lineHeight, bool unicodeMode, Technology technology, ListOptions listOptions) { if (active) { Cancel(); } + lb->SetOptions(listOptions); lb->Create(parent, ctrlID, location, lineHeight, unicodeMode, technology); lb->Clear(); active = true; @@ -127,7 +136,7 @@ struct Sorter { indices.push_back(i); // index of last position } - bool operator()(int a, int b) { + bool operator()(int a, int b) noexcept { const int lenA = indices[a * 2 + 1] - indices[a * 2]; const int lenB = indices[b * 2 + 1] - indices[b * 2]; const int len = std::min(lenA, lenB); @@ -143,7 +152,7 @@ struct Sorter { }; void AutoComplete::SetList(const char *list) { - if (autoSort == SC_ORDER_PRESORTED) { + if (autoSort == Ordering::PreSorted) { lb->SetList(list, separator, typesep); sortMatrix.clear(); for (int i = 0; i < lb->Length(); ++i) @@ -156,7 +165,7 @@ void AutoComplete::SetList(const char *list) { for (int i = 0; i < static_cast(IndexSort.indices.size()) / 2; ++i) sortMatrix.push_back(i); std::sort(sortMatrix.begin(), sortMatrix.end(), IndexSort); - if (autoSort == SC_ORDER_CUSTOM || sortMatrix.size() < 2) { + if (autoSort == Ordering::Custom || sortMatrix.size() < 2) { lb->SetList(list, separator, typesep); PLATFORM_ASSERT(lb->Length() == static_cast(sortMatrix.size())); return; @@ -193,9 +202,7 @@ int AutoComplete::GetSelection() const { } std::string AutoComplete::GetValue(int item) const { - char value[maxItemLen]; - lb->GetValue(item, value, sizeof(value)); - return std::string(value); + return lb->GetValue(item); } void AutoComplete::Show(bool show) { @@ -231,36 +238,35 @@ void AutoComplete::Select(const char *word) { int end = lb->Length() - 1; // upper bound of the api array block to search while ((start <= end) && (location == -1)) { // Binary searching loop int pivot = (start + end) / 2; - char item[maxItemLen]; - lb->GetValue(sortMatrix[pivot], item, maxItemLen); + std::string item = GetValue(sortMatrix[pivot]); int cond; if (ignoreCase) - cond = CompareNCaseInsensitive(word, item, lenWord); + cond = CompareNCaseInsensitive(word, item.c_str(), lenWord); else - cond = strncmp(word, item, lenWord); + cond = strncmp(word, item.c_str(), lenWord); if (!cond) { // Find first match while (pivot > start) { - lb->GetValue(sortMatrix[pivot-1], item, maxItemLen); + item = lb->GetValue(sortMatrix[pivot-1]); if (ignoreCase) - cond = CompareNCaseInsensitive(word, item, lenWord); + cond = CompareNCaseInsensitive(word, item.c_str(), lenWord); else - cond = strncmp(word, item, lenWord); + cond = strncmp(word, item.c_str(), lenWord); if (0 != cond) break; --pivot; } location = pivot; if (ignoreCase - && ignoreCaseBehaviour == SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) { + && ignoreCaseBehaviour == CaseInsensitiveBehaviour::RespectCase) { // Check for exact-case match for (; pivot <= end; pivot++) { - lb->GetValue(sortMatrix[pivot], item, maxItemLen); - if (!strncmp(word, item, lenWord)) { + item = lb->GetValue(sortMatrix[pivot]); + if (!strncmp(word, item.c_str(), lenWord)) { location = pivot; break; } - if (CompareNCaseInsensitive(word, item, lenWord)) + if (CompareNCaseInsensitive(word, item.c_str(), lenWord)) break; } } @@ -276,14 +282,13 @@ void AutoComplete::Select(const char *word) { else lb->Select(-1); } else { - if (autoSort == SC_ORDER_CUSTOM) { + if (autoSort == Ordering::Custom) { // Check for a logically earlier match - char item[maxItemLen]; for (int i = location + 1; i <= end; ++i) { - lb->GetValue(sortMatrix[i], item, maxItemLen); - if (CompareNCaseInsensitive(word, item, lenWord)) + std::string item = lb->GetValue(sortMatrix[i]); + if (CompareNCaseInsensitive(word, item.c_str(), lenWord)) break; - if (sortMatrix[i] < sortMatrix[location] && !strncmp(word, item, lenWord)) + if (sortMatrix[i] < sortMatrix[location] && !strncmp(word, item.c_str(), lenWord)) location = i; } } diff --git a/scintilla/src/AutoComplete.h b/scintilla/src/AutoComplete.h index c5b40ad146..fa8f57287e 100644 --- a/scintilla/src/AutoComplete.h +++ b/scintilla/src/AutoComplete.h @@ -8,7 +8,7 @@ #ifndef AUTOCOMPLETE_H #define AUTOCOMPLETE_H -namespace Scintilla { +namespace Scintilla::Internal { /** */ @@ -25,6 +25,7 @@ class AutoComplete { bool ignoreCase; bool chooseSingle; + AutoCompleteOption options; std::unique_ptr lb; Sci::Position posStart; Sci::Position startLen; @@ -32,14 +33,14 @@ class AutoComplete { bool cancelAtStartPos; bool autoHide; bool dropRestOfWord; - unsigned int ignoreCaseBehaviour; + Scintilla::CaseInsensitiveBehaviour ignoreCaseBehaviour; int widthLBDefault; int heightLBDefault; - /** SC_ORDER_PRESORTED: Assume the list is presorted; selection will fail if it is not alphabetical
- * SC_ORDER_PERFORMSORT: Sort the list alphabetically; start up performance cost for sorting
- * SC_ORDER_CUSTOM: Handle non-alphabetical entries; start up performance cost for generating a sorted lookup table + /** Ordering::PreSorted: Assume the list is presorted; selection will fail if it is not alphabetical
+ * Ordering::PerformSort: Sort the list alphabetically; start up performance cost for sorting
+ * Ordering::Custom: Handle non-alphabetical entries; start up performance cost for generating a sorted lookup table */ - int autoSort; + Scintilla::Ordering autoSort; AutoComplete(); ~AutoComplete(); @@ -49,7 +50,8 @@ class AutoComplete { /// Display the auto completion list positioned to be near a character position void Start(Window &parent, int ctrlID, Sci::Position position, Point location, - Sci::Position startLen_, int lineHeight, bool unicodeMode, int technology); + Sci::Position startLen_, int lineHeight, bool unicodeMode, Scintilla::Technology technology, + ListOptions listOptions); /// The stop chars are characters which, when typed, cause the auto completion list to disappear void SetStopChars(const char *stopChars_); diff --git a/scintilla/src/CallTip.cxx b/scintilla/src/CallTip.cxx index 96b54224c9..18caddea1c 100644 --- a/scintilla/src/CallTip.cxx +++ b/scintilla/src/CallTip.cxx @@ -14,19 +14,24 @@ #include #include +#include #include +#include #include #include -#include "Platform.h" +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" -#include "Scintilla.h" +#include "Debugging.h" +#include "Geometry.h" +#include "Platform.h" #include "Position.h" -#include "IntegerRectangle.h" #include "CallTip.h" using namespace Scintilla; +using namespace Scintilla::Internal; size_t Chunk::Length() const noexcept { return end - start; @@ -51,21 +56,20 @@ CallTip::CallTip() noexcept { #ifdef __APPLE__ // proper apple colours for the default - colourBG = ColourDesired(0xff, 0xff, 0xc6); - colourUnSel = ColourDesired(0, 0, 0); + colourBG = ColourRGBA(0xff, 0xff, 0xc6); + colourUnSel = ColourRGBA(0, 0, 0); #else - colourBG = ColourDesired(0xff, 0xff, 0xff); - colourUnSel = ColourDesired(0x80, 0x80, 0x80); + colourBG = ColourRGBA(0xff, 0xff, 0xff); + colourUnSel = ColourRGBA(0x80, 0x80, 0x80); #endif - colourSel = ColourDesired(0, 0, 0x80); - colourShade = ColourDesired(0, 0, 0); - colourLight = ColourDesired(0xc0, 0xc0, 0xc0); + colourSel = ColourRGBA(0, 0, 0x80); + colourShade = ColourRGBA(0, 0, 0); + colourLight = ColourRGBA(0xc0, 0xc0, 0xc0); codePage = 0; clickPlace = 0; } CallTip::~CallTip() { - font.Release(); wCallTip.Destroy(); } @@ -91,30 +95,32 @@ constexpr bool IsArrowCharacter(char ch) noexcept { return (ch == 0) || (ch == '\001') || (ch == '\002'); } -void DrawArrow(Scintilla::Surface *surface, const PRectangle &rc, bool upArrow, ColourDesired colourBG, ColourDesired colourUnSel) { +void DrawArrow(Surface *surface, const PRectangle &rc, bool upArrow, ColourRGBA colourBG, ColourRGBA colourUnSel) { surface->FillRectangle(rc, colourBG); - const int width = static_cast(rc.Width()); - const int halfWidth = width / 2 - 3; - const int quarterWidth = halfWidth / 2; - const int centreX = static_cast(rc.left) + width / 2 - 1; - const int centreY = static_cast(rc.top + rc.bottom) / 2; - const PRectangle rcClientInner(rc.left + 1, rc.top + 1, rc.right - 2, rc.bottom - 1); + const PRectangle rcClientInner = Clamp(rc.Inset(1), Edge::right, rc.right - 2); surface->FillRectangle(rcClientInner, colourUnSel); + const XYPOSITION width = std::floor(rcClientInner.Width()); + const XYPOSITION halfWidth = std::floor(width / 2) - 1; + const XYPOSITION quarterWidth = std::floor(halfWidth / 2); + const XYPOSITION centreX = rcClientInner.left + width / 2; + const XYPOSITION centreY = std::floor((rcClientInner.top + rcClientInner.bottom) / 2); + + constexpr XYPOSITION pixelMove = 0.0f; if (upArrow) { // Up arrow Point pts[] = { - Point::FromInts(centreX - halfWidth, centreY + quarterWidth), - Point::FromInts(centreX + halfWidth, centreY + quarterWidth), - Point::FromInts(centreX, centreY - halfWidth + quarterWidth), + Point(centreX - halfWidth + pixelMove, centreY + quarterWidth + 0.5f), + Point(centreX + halfWidth + pixelMove, centreY + quarterWidth + 0.5f), + Point(centreX + pixelMove, centreY - halfWidth + quarterWidth + 0.5f), }; - surface->Polygon(pts, Sci::size(pts), colourBG, colourBG); + surface->Polygon(pts, std::size(pts), FillStroke(colourBG)); } else { // Down arrow Point pts[] = { - Point::FromInts(centreX - halfWidth, centreY - quarterWidth), - Point::FromInts(centreX + halfWidth, centreY - quarterWidth), - Point::FromInts(centreX, centreY + halfWidth - quarterWidth), + Point(centreX - halfWidth + pixelMove, centreY - quarterWidth + 0.5f), + Point(centreX + halfWidth + pixelMove, centreY - quarterWidth + 0.5f), + Point(centreX + pixelMove, centreY + halfWidth - quarterWidth + 0.5f), }; - surface->Polygon(pts, Sci::size(pts), colourBG, colourBG); + surface->Polygon(pts, std::size(pts), FillStroke(colourBG)); } } @@ -122,9 +128,10 @@ void DrawArrow(Scintilla::Surface *surface, const PRectangle &rc, bool upArrow, // Draw a section of the call tip that does not include \n in one colour. // The text may include tabs or arrow characters. -int CallTip::DrawChunk(Surface *surface, int x, const char *s, size_t len, +int CallTip::DrawChunk(Surface *surface, int x, std::string_view sv, int ytext, PRectangle rcClient, bool asHighlight, bool draw) { - if (len == 0) { + + if (sv.empty()) { return x; } @@ -132,24 +139,24 @@ int CallTip::DrawChunk(Surface *surface, int x, const char *s, size_t len, // single arrows or single tab characters (if tabSize > 0). // Start with single element 0 to simplify append checks. std::vector ends(1); - for (size_t i=0; i 0); int xEnd; - if (IsArrowCharacter(s[startSeg])) { + if (IsArrowCharacter(sv[startSeg])) { xEnd = x + widthArrow; - const bool upArrow = s[startSeg] == '\001'; + const bool upArrow = sv[startSeg] == '\001'; rcClient.left = static_cast(x); rcClient.right = static_cast(xEnd); if (draw) { @@ -161,17 +168,16 @@ int CallTip::DrawChunk(Surface *surface, int x, const char *s, size_t len, } else { rectDown = rcClient; } - } else if (IsTabCharacter(s[startSeg])) { + } else if (IsTabCharacter(sv[startSeg])) { xEnd = NextTabPos(x); } else { - const char *segText = s + startSeg; - xEnd = x + static_cast(Sci::lround(surface->WidthText(font, segText, endSeg - startSeg))); + const std::string_view segText = sv.substr(startSeg, endSeg - startSeg); + xEnd = x + static_cast(std::lround(surface->WidthText(font.get(), segText))); if (draw) { rcClient.left = static_cast(x); rcClient.right = static_cast(xEnd); - surface->DrawTextTransparent(rcClient, font, static_cast(ytext), - segText, endSeg - startSeg, - asHighlight ? colourSel : colourUnSel); + surface->DrawTextTransparent(rcClient, font.get(), static_cast(ytext), + segText, asHighlight ? colourSel : colourUnSel); } } x = xEnd; @@ -187,31 +193,26 @@ int CallTip::PaintContents(Surface *surfaceWindow, bool draw) { PRectangle rcClient(1.0f, 1.0f, rcClientSize.right - 1, rcClientSize.bottom - 1); // To make a nice small call tip window, it is only sized to fit most normal characters without accents - const int ascent = static_cast(Sci::round(surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font))); + const int ascent = static_cast(std::round(surfaceWindow->Ascent(font.get()) - surfaceWindow->InternalLeading(font.get()))); // For each line... // Draw the definition in three parts: before highlight, highlighted, after highlight int ytext = static_cast(rcClient.top) + ascent + 1; - rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1; - const char *remaining = val.c_str(); + rcClient.bottom = ytext + surfaceWindow->Descent(font.get()) + 1; + std::string_view remaining(val); int maxWidth = 0; size_t lineStart = 0; - while (*remaining) { - const char *chunkVal = remaining; - const char *chunkEnd = strchr(remaining, '\n'); - if (!chunkEnd) { - chunkEnd = chunkVal + strlen(chunkVal); - } - const size_t chunkLength = static_cast(chunkEnd - chunkVal); - remaining += chunkLength; - if (*remaining) { - remaining++; // Skip \n + while (!remaining.empty()) { + const std::string_view chunkVal = remaining.substr(0, remaining.find_first_of('\n')); + remaining.remove_prefix(chunkVal.length()); + if (!remaining.empty()) { + remaining.remove_prefix(1); // Skip \n } - const Chunk chunkLine(lineStart, lineStart + chunkLength); + const Chunk chunkLine(lineStart, lineStart + chunkVal.length()); Chunk chunkHighlight( - Sci::clamp(highlight.start, chunkLine.start, chunkLine.end), - Sci::clamp(highlight.end, chunkLine.start, chunkLine.end) + std::clamp(highlight.start, chunkLine.start, chunkLine.end), + std::clamp(highlight.end, chunkLine.start, chunkLine.end) ); chunkHighlight.start -= lineStart; chunkHighlight.end -= lineStart; @@ -220,17 +221,20 @@ int CallTip::PaintContents(Surface *surfaceWindow, bool draw) { int x = insetX; // start each line at this inset - x = DrawChunk(surfaceWindow, x, chunkVal, chunkHighlight.start, + x = DrawChunk(surfaceWindow, x, + chunkVal.substr(0, chunkHighlight.start), ytext, rcClient, false, draw); - x = DrawChunk(surfaceWindow, x, chunkVal + chunkHighlight.start, chunkHighlight.Length(), + x = DrawChunk(surfaceWindow, x, + chunkVal.substr(chunkHighlight.start, chunkHighlight.Length()), ytext, rcClient, true, draw); - x = DrawChunk(surfaceWindow, x, chunkVal + chunkHighlight.end, chunkLength - chunkHighlight.end, + x = DrawChunk(surfaceWindow, x, + chunkVal.substr(chunkHighlight.end), ytext, rcClient, false, draw); ytext += lineHeight; rcClient.bottom += lineHeight; maxWidth = std::max(maxWidth, x); - lineStart += chunkLength + 1; + lineStart += chunkVal.length() + 1; } return maxWidth; } @@ -248,17 +252,14 @@ void CallTip::PaintCT(Surface *surfaceWindow) { offsetMain = insetX; // initial alignment assuming no arrows PaintContents(surfaceWindow, true); -#ifndef __APPLE__ +#if !defined(__APPLE__) && !PLAT_CURSES // OSX doesn't put borders on "help tags" // Draw a raised border around the edges of the window - const IntegerRectangle ircClientSize(rcClientSize); - surfaceWindow->MoveTo(0, ircClientSize.bottom - 1); - surfaceWindow->PenColour(colourShade); - surfaceWindow->LineTo(ircClientSize.right - 1, ircClientSize.bottom - 1); - surfaceWindow->LineTo(ircClientSize.right - 1, 0); - surfaceWindow->PenColour(colourLight); - surfaceWindow->LineTo(0, 0); - surfaceWindow->LineTo(0, ircClientSize.bottom - 1); + constexpr XYPOSITION border = 1.0f; + surfaceWindow->FillRectangle(Side(rcClientSize, Edge::left, border), colourLight); + surfaceWindow->FillRectangle(Side(rcClientSize, Edge::right, border), colourShade); + surfaceWindow->FillRectangle(Side(rcClientSize, Edge::bottom, border), colourShade); + surfaceWindow->FillRectangle(Side(rcClientSize, Edge::top, border), colourLight); #endif } @@ -272,34 +273,39 @@ void CallTip::MouseClick(Point pt) noexcept { PRectangle CallTip::CallTipStart(Sci::Position pos, Point pt, int textHeight, const char *defn, const char *faceName, int size, - int codePage_, int characterSet, - int technology, const Window &wParent) { + int codePage_, CharacterSet characterSet, + Technology technology, + const char *localeName, + const Window &wParent) { clickPlace = 0; val = defn; codePage = codePage_; - std::unique_ptr surfaceMeasure(Surface::Allocate(technology)); + std::unique_ptr surfaceMeasure = Surface::Allocate(technology); surfaceMeasure->Init(wParent.GetID()); - surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage); - surfaceMeasure->SetDBCSMode(codePage); + surfaceMeasure->SetMode(SurfaceMode(codePage, false)); highlight = Chunk(); inCallTipMode = true; posStartCallTip = pos; const XYPOSITION deviceHeight = static_cast(surfaceMeasure->DeviceHeightFont(size)); - const FontParameters fp(faceName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, SC_WEIGHT_NORMAL, false, 0, technology, characterSet); - font.Create(fp); + const FontParameters fp(faceName, deviceHeight / FontSizeMultiplier, FontWeight::Normal, + false, FontQuality::QualityDefault, technology, characterSet, localeName); + font = Font::Allocate(fp); // Look for multiple lines in the text // Only support \n here - simply means container must avoid \r! const int numLines = 1 + static_cast(std::count(val.begin(), val.end(), '\n')); rectUp = PRectangle(0,0,0,0); rectDown = PRectangle(0,0,0,0); offsetMain = insetX; // changed to right edge of any arrows + lineHeight = static_cast(std::lround(surfaceMeasure->Height(font.get()))); +#if !PLAT_CURSES + widthArrow = lineHeight * 9 / 10; +#endif const int width = PaintContents(surfaceMeasure.get(), false) + insetX; - lineHeight = static_cast(Sci::lround(surfaceMeasure->Height(font))); // The returned // rectangle is aligned to the right edge of the last arrow encountered in // the tip text, else to the tip text left edge. - const int height = lineHeight * numLines - static_cast(surfaceMeasure->InternalLeading(font)) + borderHeight * 2; + const int height = lineHeight * numLines - static_cast(surfaceMeasure->InternalLeading(font.get())) + borderHeight * 2; if (above) { return PRectangle(pt.x - offsetMain, pt.y - verticalOffset - height, pt.x + width - offsetMain, pt.y - verticalOffset); } else { @@ -326,7 +332,7 @@ void CallTip::SetHighlight(size_t start, size_t end) { } // Set the tab size (sizes > 0 enable the use of tabs). This also enables the -// use of the STYLE_CALLTIP. +// use of the StyleCallTip. void CallTip::SetTabSize(int tabSz) noexcept { tabSize = tabSz; useStyleCallTip = true; @@ -339,12 +345,12 @@ void CallTip::SetPosition(bool aboveText) noexcept { } bool CallTip::UseStyleCallTip() const noexcept { - return useStyleCallTip; + return useStyleCallTip; } // It might be better to have two access functions for this and to use // them for all settings of colours. -void CallTip::SetForeBack(const ColourDesired &fore, const ColourDesired &back) noexcept { +void CallTip::SetForeBack(const ColourRGBA &fore, const ColourRGBA &back) noexcept { colourBG = back; colourUnSel = fore; } diff --git a/scintilla/src/CallTip.h b/scintilla/src/CallTip.h index 1a0a317cb0..f2889d44a7 100644 --- a/scintilla/src/CallTip.h +++ b/scintilla/src/CallTip.h @@ -8,12 +8,12 @@ #ifndef CALLTIP_H #define CALLTIP_H -namespace Scintilla { +namespace Scintilla::Internal { struct Chunk { size_t start; size_t end; - Chunk(size_t start_=0, size_t end_=0) noexcept : start(start_), end(end_) { + constexpr Chunk(size_t start_=0, size_t end_=0) noexcept : start(start_), end(end_) { assert(start <= end); } size_t Length() const noexcept; @@ -24,16 +24,16 @@ struct Chunk { class CallTip { Chunk highlight; // character offset to start and end of highlighted text std::string val; - Font font; + std::shared_ptr font; PRectangle rectUp; // rectangle of last up angle in the tip PRectangle rectDown; // rectangle of last down arrow in the tip int lineHeight; // vertical line spacing int offsetMain; // The alignment point of the call tip int tabSize; // Tab size in pixels, <=0 no TAB expand - bool useStyleCallTip; // if true, STYLE_CALLTIP should be used + bool useStyleCallTip; // if true, StyleCallTip should be used bool above; // if true, display calltip above text - int DrawChunk(Surface *surface, int x, const char *s, size_t len, + int DrawChunk(Surface *surface, int x, std::string_view sv, int ytext, PRectangle rcClient, bool asHighlight, bool draw); int PaintContents(Surface *surfaceWindow, bool draw); bool IsTabCharacter(char ch) const noexcept; @@ -44,11 +44,11 @@ class CallTip { Window wDraw; bool inCallTipMode; Sci::Position posStartCallTip; - ColourDesired colourBG; - ColourDesired colourUnSel; - ColourDesired colourSel; - ColourDesired colourShade; - ColourDesired colourLight; + ColourRGBA colourBG; + ColourRGBA colourUnSel; + ColourRGBA colourSel; + ColourRGBA colourShade; + ColourRGBA colourLight; int codePage; int clickPlace; @@ -72,7 +72,8 @@ class CallTip { /// Setup the calltip and return a rectangle of the area required. PRectangle CallTipStart(Sci::Position pos, Point pt, int textHeight, const char *defn, const char *faceName, int size, int codePage_, - int characterSet, int technology, const Window &wParent); + Scintilla::CharacterSet characterSet, Scintilla::Technology technology, const char *localeName, + const Window &wParent); void CallTipCancel(); @@ -90,7 +91,7 @@ class CallTip { bool UseStyleCallTip() const noexcept; // Modify foreground and background colours - void SetForeBack(const ColourDesired &fore, const ColourDesired &back) noexcept; + void SetForeBack(const ColourRGBA &fore, const ColourRGBA &back) noexcept; }; } diff --git a/scintilla/src/CaseConvert.cxx b/scintilla/src/CaseConvert.cxx index 26104f33d7..fd1bee2c9b 100644 --- a/scintilla/src/CaseConvert.cxx +++ b/scintilla/src/CaseConvert.cxx @@ -8,20 +8,19 @@ // Copyright 2013 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. +#include #include #include #include +#include #include #include -#include "StringCopy.h" #include "CaseConvert.h" #include "UniConversion.h" -#include "Compat.h" - -using namespace Scintilla; +using namespace Scintilla::Internal; namespace { // Use an unnamed namespace to protect the declarations from name conflicts @@ -243,6 +242,9 @@ int symmetricCaseConversions[] = { 42899,42898, 42900,42948, 42947,42946, +42952,42951, +42954,42953, +42998,42997, 43859,42931, //--Autogenerated -- end of section automatically generated @@ -584,8 +586,15 @@ class CaseConverter : public ICaseConverter { CharacterConversion() noexcept : character(0) { // Empty case: NUL -> "". } - CharacterConversion(int character_=0, const char *conversion_="") noexcept : character(character_) { - StringCopy(conversion.conversion, conversion_); + CharacterConversion(int character_, std::string_view conversion_) noexcept : character(character_) { + assert(conversion_.length() <= maxConversionLength); + try { + // This can never fail as std::string_view::copy should only throw + // std::out_of_range if pos > size() and pos == 0 here + conversion_.copy(conversion.conversion, conversion_.length()); + } catch (...) { + // Ignore any exception + } } bool operator<(const CharacterConversion &other) const noexcept { return character < other.character; @@ -676,28 +685,28 @@ CaseConverter caseConvFold; CaseConverter caseConvUp; CaseConverter caseConvLow; -void AddSymmetric(enum CaseConversion conversion, int lower,int upper) { +void AddSymmetric(CaseConversion conversion, int lower,int upper) { char lowerUTF8[UTF8MaxBytes+1]; UTF8FromUTF32Character(lower, lowerUTF8); char upperUTF8[UTF8MaxBytes+1]; UTF8FromUTF32Character(upper, upperUTF8); switch (conversion) { - case CaseConversionFold: + case CaseConversion::fold: caseConvFold.Add(upper, lowerUTF8); break; - case CaseConversionUpper: + case CaseConversion::upper: caseConvUp.Add(lower, upperUTF8); break; - case CaseConversionLower: + case CaseConversion::lower: caseConvLow.Add(upper, lowerUTF8); break; } } -void SetupConversions(enum CaseConversion conversion) { +void SetupConversions(CaseConversion conversion) { // First initialize for the symmetric ranges - for (size_t i=0; iInitialised()) SetupConversions(conversion); return pCaseConv; } -const char *CaseConvert(int character, enum CaseConversion conversion) { +const char *CaseConvert(int character, CaseConversion conversion) { CaseConverter *pCaseConv = ConverterForConversion(conversion); if (!pCaseConv->Initialised()) SetupConversions(conversion); return pCaseConv->Find(character); } -size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, enum CaseConversion conversion) { +size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, CaseConversion conversion) { CaseConverter *pCaseConv = ConverterForConversion(conversion); if (!pCaseConv->Initialised()) SetupConversions(conversion); return pCaseConv->CaseConvertString(converted, sizeConverted, mixed, lenMixed); } -std::string CaseConvertString(const std::string &s, enum CaseConversion conversion) { +std::string CaseConvertString(const std::string &s, CaseConversion conversion) { std::string retMapped(s.length() * maxExpansionCaseConversion, 0); const size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), conversion); diff --git a/scintilla/src/CaseConvert.h b/scintilla/src/CaseConvert.h index e3057c8410..ca45f175a8 100644 --- a/scintilla/src/CaseConvert.h +++ b/scintilla/src/CaseConvert.h @@ -10,12 +10,12 @@ #ifndef CASECONVERT_H #define CASECONVERT_H -namespace Scintilla { +namespace Scintilla::Internal { -enum CaseConversion { - CaseConversionFold, - CaseConversionUpper, - CaseConversionLower +enum class CaseConversion { + fold, + upper, + lower }; class ICaseConverter { @@ -23,10 +23,10 @@ class ICaseConverter { virtual size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed) = 0; }; -ICaseConverter *ConverterFor(enum CaseConversion conversion); +ICaseConverter *ConverterFor(CaseConversion conversion); // Returns a UTF-8 string. Empty when no conversion -const char *CaseConvert(int character, enum CaseConversion conversion); +const char *CaseConvert(int character, CaseConversion conversion); // When performing CaseConvertString, the converted value may be up to 3 times longer than the input. // Ligatures are often decomposed into multiple characters and long cases include: @@ -36,10 +36,10 @@ constexpr size_t maxExpansionCaseConversion = 3; // Converts a mixed case string using a particular conversion. // Result may be a different length to input and the length is the return value. // If there is not enough space then 0 is returned. -size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, enum CaseConversion conversion); +size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, CaseConversion conversion); // Converts a mixed case string using a particular conversion. -std::string CaseConvertString(const std::string &s, enum CaseConversion conversion); +std::string CaseConvertString(const std::string &s, CaseConversion conversion); } diff --git a/scintilla/src/CaseFolder.cxx b/scintilla/src/CaseFolder.cxx index bce593a982..47f319504d 100644 --- a/scintilla/src/CaseFolder.cxx +++ b/scintilla/src/CaseFolder.cxx @@ -12,7 +12,7 @@ #include "CaseFolder.h" #include "CaseConvert.h" -using namespace Scintilla; +using namespace Scintilla::Internal; CaseFolder::~CaseFolder() { } @@ -53,7 +53,7 @@ void CaseFolderTable::StandardASCII() noexcept { CaseFolderUnicode::CaseFolderUnicode() { StandardASCII(); - converter = ConverterFor(CaseConversionFold); + converter = ConverterFor(CaseConversion::fold); } size_t CaseFolderUnicode::Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { diff --git a/scintilla/src/CaseFolder.h b/scintilla/src/CaseFolder.h index 966069bc4e..1169f9bd76 100644 --- a/scintilla/src/CaseFolder.h +++ b/scintilla/src/CaseFolder.h @@ -8,7 +8,7 @@ #ifndef CASEFOLDER_H #define CASEFOLDER_H -namespace Scintilla { +namespace Scintilla::Internal { class CaseFolder { public: diff --git a/scintilla/src/Catalogue.cxx b/scintilla/src/Catalogue.cxx deleted file mode 100644 index fc9a81aeec..0000000000 --- a/scintilla/src/Catalogue.cxx +++ /dev/null @@ -1,117 +0,0 @@ -// Scintilla source code edit control -/** @file Catalogue.cxx - ** Lexer infrastructure. - ** Contains a list of LexerModules which can be searched to find a module appropriate for a - ** particular language. - **/ -// Copyright 1998-2002 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include - -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "LexerModule.h" -#include "CatalogueModules.h" -#include "Catalogue.h" - -using namespace Scintilla; - -namespace { - -CatalogueModules catalogueDefault; - -} - -const LexerModule *Catalogue::Find(int language) { - return catalogueDefault.Find(language); -} - -const LexerModule *Catalogue::Find(const char *languageName) noexcept { - return catalogueDefault.Find(languageName); -} - -void Catalogue::AddLexerModule(LexerModule *plm) { - catalogueDefault.AddLexerModule(plm); -} - -// To add or remove a lexer, add or remove its file and run LexGen.py. - -// Force a reference to all of the Scintilla lexers so that the linker will -// not remove the code of the lexers. -int Scintilla_LinkLexers() { - - static int initialised = 0; - if (initialised) - return 0; - initialised = 1; - -#if !defined(SCI_EMPTYCATALOGUE) - -// Shorten the code that declares a lexer and ensures it is linked in by calling a method. -#define LINK_LEXER(lexer) extern LexerModule lexer; catalogueDefault.AddLexerModule(&lexer); - -//++Autogenerated -- run scripts/LexGen.py to regenerate -//**\(\tLINK_LEXER(\*);\n\) - LINK_LEXER(lmAbaqus); - LINK_LEXER(lmAda); - LINK_LEXER(lmAsm); - LINK_LEXER(lmBash); - LINK_LEXER(lmBatch); - LINK_LEXER(lmCaml); - LINK_LEXER(lmCmake); - LINK_LEXER(lmCOBOL); - LINK_LEXER(lmCoffeeScript); - LINK_LEXER(lmCPP); - LINK_LEXER(lmCss); - LINK_LEXER(lmD); - LINK_LEXER(lmDiff); - LINK_LEXER(lmErlang); - LINK_LEXER(lmF77); - LINK_LEXER(lmForth); - LINK_LEXER(lmFortran); - LINK_LEXER(lmFreeBasic); - LINK_LEXER(lmHaskell); - LINK_LEXER(lmHTML); - LINK_LEXER(lmJulia); - LINK_LEXER(lmLatex); - LINK_LEXER(lmLISP); - LINK_LEXER(lmLua); - LINK_LEXER(lmMake); - LINK_LEXER(lmMarkdown); - // We use Octave instead of Matlab - LINK_LEXER(lmNsis); - LINK_LEXER(lmNull); - LINK_LEXER(lmOctave); - LINK_LEXER(lmPascal); - LINK_LEXER(lmPerl); - LINK_LEXER(lmPHPSCRIPT); - LINK_LEXER(lmPO); - LINK_LEXER(lmPowerShell); - LINK_LEXER(lmProps); - LINK_LEXER(lmPython); - LINK_LEXER(lmR); - LINK_LEXER(lmRuby); - LINK_LEXER(lmRust); - LINK_LEXER(lmSmalltalk); - LINK_LEXER(lmSQL); - LINK_LEXER(lmTCL); - LINK_LEXER(lmTxt2tags); - LINK_LEXER(lmVerilog); - LINK_LEXER(lmVHDL); - LINK_LEXER(lmXML); - LINK_LEXER(lmYAML); - -//--Autogenerated -- end of automatically generated section - -#endif - - return 1; -} diff --git a/scintilla/src/Catalogue.h b/scintilla/src/Catalogue.h deleted file mode 100644 index 05a1f1d294..0000000000 --- a/scintilla/src/Catalogue.h +++ /dev/null @@ -1,24 +0,0 @@ -// Scintilla source code edit control -/** @file Catalogue.h - ** Lexer infrastructure. - ** Contains a list of LexerModules which can be searched to find a module appropriate for a - ** particular language. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CATALOGUE_H -#define CATALOGUE_H - -namespace Scintilla { - -class Catalogue { -public: - static const LexerModule *Find(int language); - static const LexerModule *Find(const char *languageName) noexcept; - static void AddLexerModule(LexerModule *plm); -}; - -} - -#endif diff --git a/scintilla/src/CellBuffer.cxx b/scintilla/src/CellBuffer.cxx index 661502d336..d94ffaaea0 100644 --- a/scintilla/src/CellBuffer.cxx +++ b/scintilla/src/CellBuffer.cxx @@ -14,20 +14,23 @@ #include #include +#include #include +#include #include #include -#include "Platform.h" +#include "ScintillaTypes.h" + +#include "Debugging.h" -#include "Scintilla.h" #include "Position.h" #include "SplitVector.h" #include "Partitioning.h" #include "CellBuffer.h" #include "UniConversion.h" -namespace Scintilla { +namespace Scintilla::Internal { struct CountWidths { // Measures the number of characters in a string divided into those @@ -68,21 +71,23 @@ class ILineVector { virtual void SetLineStart(Sci::Line line, Sci::Position position) noexcept = 0; virtual void RemoveLine(Sci::Line line) = 0; virtual Sci::Line Lines() const noexcept = 0; + virtual void AllocateLines(Sci::Line lines) = 0; virtual Sci::Line LineFromPosition(Sci::Position pos) const noexcept = 0; virtual Sci::Position LineStart(Sci::Line line) const noexcept = 0; virtual void InsertCharacters(Sci::Line line, CountWidths delta) noexcept = 0; virtual void SetLineCharactersWidth(Sci::Line line, CountWidths width) noexcept = 0; - virtual int LineCharacterIndex() const noexcept = 0; - virtual bool AllocateLineCharacterIndex(int lineCharacterIndex, Sci::Line lines) = 0; - virtual bool ReleaseLineCharacterIndex(int lineCharacterIndex) = 0; - virtual Sci::Position IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept = 0; - virtual Sci::Line LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const noexcept = 0; + virtual Scintilla::LineCharacterIndexType LineCharacterIndex() const noexcept = 0; + virtual bool AllocateLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex, Sci::Line lines) = 0; + virtual bool ReleaseLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex) = 0; + virtual Sci::Position IndexLineStart(Sci::Line line, Scintilla::LineCharacterIndexType lineCharacterIndex) const noexcept = 0; + virtual Sci::Line LineFromPositionIndex(Sci::Position pos, Scintilla::LineCharacterIndexType lineCharacterIndex) const noexcept = 0; virtual ~ILineVector() {} }; } using namespace Scintilla; +using namespace Scintilla::Internal; template class LineStartIndex { @@ -128,6 +133,11 @@ class LineStartIndex { const Sci::Position widthCurrent = LineWidth(line); starts.InsertText(static_cast(line), static_cast(width - widthCurrent)); } + void AllocateLines(Sci::Line lines) { + if (lines > starts.Partitions()) { + starts.ReAllocate(lines); + } + } void InsertLines(Sci::Line line, Sci::Line lines) { // Insert multiple lines with each temporarily 1 character wide. // The line widths will be fixed up by later measuring code. @@ -145,15 +155,16 @@ class LineVector : public ILineVector { PerLine *perLine; LineStartIndex startsUTF16; LineStartIndex startsUTF32; - int activeIndices; + LineCharacterIndexType activeIndices; void SetActiveIndices() noexcept { - activeIndices = (startsUTF32.Active() ? SC_LINECHARACTERINDEX_UTF32 : 0) - | (startsUTF16.Active() ? SC_LINECHARACTERINDEX_UTF16 : 0); + activeIndices = + (startsUTF32.Active() ? LineCharacterIndexType::Utf32 : LineCharacterIndexType::None) + | (startsUTF16.Active() ? LineCharacterIndexType::Utf16 : LineCharacterIndexType::None); } public: - LineVector() : starts(256), perLine(nullptr), activeIndices(0) { + LineVector() : starts(256), perLine(nullptr), activeIndices(LineCharacterIndexType::None) { } // Deleted so LineVector objects can not be copied. LineVector(const LineVector &) = delete; @@ -179,11 +190,11 @@ class LineVector : public ILineVector { void InsertLine(Sci::Line line, Sci::Position position, bool lineStart) override { const POS lineAsPos = static_cast(line); starts.InsertPartition(lineAsPos, static_cast(position)); - if (activeIndices) { - if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { + if (activeIndices != LineCharacterIndexType::None) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf32)) { startsUTF32.InsertLines(line, 1); } - if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf16)) { startsUTF16.InsertLines(line, 1); } } @@ -195,16 +206,16 @@ class LineVector : public ILineVector { } void InsertLines(Sci::Line line, const Sci::Position *positions, size_t lines, bool lineStart) override { const POS lineAsPos = static_cast(line); - if (sizeof(Sci::Position) == sizeof(POS)) { - starts.InsertPartitions(lineAsPos, reinterpret_cast(positions), lines); + if constexpr (sizeof(Sci::Position) == sizeof(POS)) { + starts.InsertPartitions(lineAsPos, positions, lines); } else { starts.InsertPartitionsWithCast(lineAsPos, positions, lines); } - if (activeIndices) { - if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { + if (activeIndices != LineCharacterIndexType::None) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf32)) { startsUTF32.InsertLines(line, lines); } - if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf16)) { startsUTF16.InsertLines(line, lines); } } @@ -219,10 +230,10 @@ class LineVector : public ILineVector { } void RemoveLine(Sci::Line line) override { starts.RemovePartition(static_cast(line)); - if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf32)) { startsUTF32.starts.RemovePartition(static_cast(line)); } - if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf16)) { startsUTF16.starts.RemovePartition(static_cast(line)); } if (perLine) { @@ -232,6 +243,17 @@ class LineVector : public ILineVector { Sci::Line Lines() const noexcept override { return static_cast(starts.Partitions()); } + void AllocateLines(Sci::Line lines) override { + if (lines > Lines()) { + starts.ReAllocate(lines); + if (FlagSet(activeIndices, LineCharacterIndexType::Utf32)) { + startsUTF32.AllocateLines(lines); + } + if (FlagSet(activeIndices, LineCharacterIndexType::Utf16)) { + startsUTF16.AllocateLines(lines); + } + } + } Sci::Line LineFromPosition(Sci::Position pos) const noexcept override { return static_cast(starts.PartitionFromPosition(static_cast(pos))); } @@ -239,60 +261,60 @@ class LineVector : public ILineVector { return starts.PositionFromPartition(static_cast(line)); } void InsertCharacters(Sci::Line line, CountWidths delta) noexcept override { - if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf32)) { startsUTF32.starts.InsertText(static_cast(line), static_cast(delta.WidthUTF32())); } - if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf16)) { startsUTF16.starts.InsertText(static_cast(line), static_cast(delta.WidthUTF16())); } } void SetLineCharactersWidth(Sci::Line line, CountWidths width) noexcept override { - if (activeIndices & SC_LINECHARACTERINDEX_UTF32) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf32)) { assert(startsUTF32.starts.Partitions() == starts.Partitions()); startsUTF32.SetLineWidth(line, width.WidthUTF32()); } - if (activeIndices & SC_LINECHARACTERINDEX_UTF16) { + if (FlagSet(activeIndices, LineCharacterIndexType::Utf16)) { assert(startsUTF16.starts.Partitions() == starts.Partitions()); startsUTF16.SetLineWidth(line, width.WidthUTF16()); } } - int LineCharacterIndex() const noexcept override { + LineCharacterIndexType LineCharacterIndex() const noexcept override { return activeIndices; } - bool AllocateLineCharacterIndex(int lineCharacterIndex, Sci::Line lines) override { - const int activeIndicesStart = activeIndices; - if ((lineCharacterIndex & SC_LINECHARACTERINDEX_UTF32) != 0) { + bool AllocateLineCharacterIndex(LineCharacterIndexType lineCharacterIndex, Sci::Line lines) override { + const LineCharacterIndexType activeIndicesStart = activeIndices; + if (FlagSet(lineCharacterIndex, LineCharacterIndexType::Utf32)) { startsUTF32.Allocate(lines); assert(startsUTF32.starts.Partitions() == starts.Partitions()); } - if ((lineCharacterIndex & SC_LINECHARACTERINDEX_UTF16) != 0) { + if (FlagSet(lineCharacterIndex, LineCharacterIndexType::Utf16)) { startsUTF16.Allocate(lines); assert(startsUTF16.starts.Partitions() == starts.Partitions()); } SetActiveIndices(); return activeIndicesStart != activeIndices; } - bool ReleaseLineCharacterIndex(int lineCharacterIndex) override { - const int activeIndicesStart = activeIndices; - if ((lineCharacterIndex & SC_LINECHARACTERINDEX_UTF32) != 0) { + bool ReleaseLineCharacterIndex(LineCharacterIndexType lineCharacterIndex) override { + const LineCharacterIndexType activeIndicesStart = activeIndices; + if (FlagSet(lineCharacterIndex, LineCharacterIndexType::Utf32)) { startsUTF32.Release(); } - if ((lineCharacterIndex & SC_LINECHARACTERINDEX_UTF16) != 0) { + if (FlagSet(lineCharacterIndex, LineCharacterIndexType::Utf16)) { startsUTF16.Release(); } SetActiveIndices(); return activeIndicesStart != activeIndices; } - Sci::Position IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept override { - if (lineCharacterIndex == SC_LINECHARACTERINDEX_UTF32) { + Sci::Position IndexLineStart(Sci::Line line, LineCharacterIndexType lineCharacterIndex) const noexcept override { + if (lineCharacterIndex == LineCharacterIndexType::Utf32) { return startsUTF32.starts.PositionFromPartition(static_cast(line)); } else { return startsUTF16.starts.PositionFromPartition(static_cast(line)); } } - Sci::Line LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const noexcept override { - if (lineCharacterIndex == SC_LINECHARACTERINDEX_UTF32) { + Sci::Line LineFromPositionIndex(Sci::Position pos, LineCharacterIndexType lineCharacterIndex) const noexcept override { + if (lineCharacterIndex == LineCharacterIndexType::Utf32) { return static_cast(startsUTF32.starts.PartitionFromPosition(static_cast(pos))); } else { return static_cast(startsUTF16.starts.PartitionFromPosition(static_cast(pos))); @@ -301,7 +323,7 @@ class LineVector : public ILineVector { }; Action::Action() noexcept { - at = startAction; + at = ActionType::start; position = 0; lenData = 0; mayCoalesce = false; @@ -310,12 +332,12 @@ Action::Action() noexcept { Action::~Action() { } -void Action::Create(actionType at_, Sci::Position position_, const char *data_, Sci::Position lenData_, bool mayCoalesce_) { +void Action::Create(ActionType at_, Sci::Position position_, const char *data_, Sci::Position lenData_, bool mayCoalesce_) { data = nullptr; position = position_; at = at_; if (lenData_) { - data = Sci::make_unique(lenData_); + data = std::make_unique(lenData_); memcpy(&data[0], data_, lenData_); } lenData = lenData_; @@ -354,7 +376,7 @@ UndoHistory::UndoHistory() { savePoint = 0; tentativePoint = -1; - actions[currentAction].Create(startAction); + actions[currentAction].Create(ActionType::start); } UndoHistory::~UndoHistory() { @@ -369,7 +391,7 @@ void UndoHistory::EnsureUndoRoom() { } } -const char *UndoHistory::AppendAction(actionType at, Sci::Position position, const char *data, Sci::Position lengthData, +const char *UndoHistory::AppendAction(ActionType at, Sci::Position position, const char *data, Sci::Position lengthData, bool &startSequence, bool mayCoalesce) { EnsureUndoRoom(); //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction); @@ -385,7 +407,7 @@ const char *UndoHistory::AppendAction(actionType at, Sci::Position position, con int targetAct = -1; const Action *actPrevious = &(actions[currentAction + targetAct]); // Container actions may forward the coalesce state of Scintilla Actions. - while ((actPrevious->at == containerAction) && actPrevious->mayCoalesce) { + while ((actPrevious->at == ActionType::container) && actPrevious->mayCoalesce) { targetAct--; actPrevious = &(actions[currentAction + targetAct]); } @@ -398,15 +420,15 @@ const char *UndoHistory::AppendAction(actionType at, Sci::Position position, con currentAction++; } else if (!mayCoalesce || !actPrevious->mayCoalesce) { currentAction++; - } else if (at == containerAction || actions[currentAction].at == containerAction) { + } else if (at == ActionType::container || actions[currentAction].at == ActionType::container) { ; // A coalescible containerAction - } else if ((at != actPrevious->at) && (actPrevious->at != startAction)) { + } else if ((at != actPrevious->at) && (actPrevious->at != ActionType::start)) { currentAction++; - } else if ((at == insertAction) && + } else if ((at == ActionType::insert) && (position != (actPrevious->position + actPrevious->lenData))) { // Insertions must be immediately after to coalesce currentAction++; - } else if (at == removeAction) { + } else if (at == ActionType::remove) { if ((lengthData == 1) || (lengthData == 2)) { if ((position + lengthData) == actPrevious->position) { ; // Backspace -> OK @@ -436,7 +458,7 @@ const char *UndoHistory::AppendAction(actionType at, Sci::Position position, con const int actionWithData = currentAction; actions[currentAction].Create(at, position, data, lengthData, mayCoalesce); currentAction++; - actions[currentAction].Create(startAction); + actions[currentAction].Create(ActionType::start); maxAction = currentAction; return actions[actionWithData].data.get(); } @@ -444,9 +466,9 @@ const char *UndoHistory::AppendAction(actionType at, Sci::Position position, con void UndoHistory::BeginUndoAction() { EnsureUndoRoom(); if (undoSequenceDepth == 0) { - if (actions[currentAction].at != startAction) { + if (actions[currentAction].at != ActionType::start) { currentAction++; - actions[currentAction].Create(startAction); + actions[currentAction].Create(ActionType::start); maxAction = currentAction; } actions[currentAction].mayCoalesce = false; @@ -459,9 +481,9 @@ void UndoHistory::EndUndoAction() { EnsureUndoRoom(); undoSequenceDepth--; if (0 == undoSequenceDepth) { - if (actions[currentAction].at != startAction) { + if (actions[currentAction].at != ActionType::start) { currentAction++; - actions[currentAction].Create(startAction); + actions[currentAction].Create(ActionType::start); maxAction = currentAction; } actions[currentAction].mayCoalesce = false; @@ -477,7 +499,7 @@ void UndoHistory::DeleteUndoHistory() { actions[i].Clear(); maxAction = 0; currentAction = 0; - actions[currentAction].Create(startAction); + actions[currentAction].Create(ActionType::start); savePoint = 0; tentativePoint = -1; } @@ -501,12 +523,12 @@ void UndoHistory::TentativeCommit() { } bool UndoHistory::TentativeActive() const noexcept { - return tentativePoint >= 0; + return tentativePoint >= 0; } int UndoHistory::TentativeSteps() noexcept { // Drop any trailing startAction - if (actions[currentAction].at == startAction && currentAction > 0) + if (actions[currentAction].at == ActionType::start && currentAction > 0) currentAction--; if (tentativePoint >= 0) return currentAction - tentativePoint; @@ -520,12 +542,12 @@ bool UndoHistory::CanUndo() const noexcept { int UndoHistory::StartUndo() { // Drop any trailing startAction - if (actions[currentAction].at == startAction && currentAction > 0) + if (actions[currentAction].at == ActionType::start && currentAction > 0) currentAction--; // Count the steps in this action int act = currentAction; - while (actions[act].at != startAction && act > 0) { + while (actions[act].at != ActionType::start && act > 0) { act--; } return currentAction - act; @@ -545,12 +567,12 @@ bool UndoHistory::CanRedo() const noexcept { int UndoHistory::StartRedo() { // Drop any leading startAction - if (currentAction < maxAction && actions[currentAction].at == startAction) + if (currentAction < maxAction && actions[currentAction].at == ActionType::start) currentAction++; // Count the steps in this action int act = currentAction; - while (act < maxAction && actions[act].at != startAction) { + while (act < maxAction && actions[act].at != ActionType::start) { act++; } return act - currentAction; @@ -568,12 +590,12 @@ CellBuffer::CellBuffer(bool hasStyles_, bool largeDocument_) : hasStyles(hasStyles_), largeDocument(largeDocument_) { readOnly = false; utf8Substance = false; - utf8LineEnds = 0; + utf8LineEnds = LineEndType::Default; collectingUndo = true; if (largeDocument) - plv = Sci::make_unique>(); + plv = std::make_unique>(); else - plv = Sci::make_unique>(); + plv = std::make_unique>(); } CellBuffer::~CellBuffer() { @@ -637,6 +659,21 @@ Sci::Position CellBuffer::GapPosition() const noexcept { return substance.GapPosition(); } +SplitView CellBuffer::AllView() const noexcept { + const size_t length = substance.Length(); + size_t length1 = substance.GapPosition(); + if (length1 == 0) { + // Assign segment2 to segment1 / length1 to avoid useless test against 0 length1 + length1 = length; + } + return SplitView { + substance.ElementPointer(0), + length1, + substance.ElementPointer(length1) - length1, + length + }; +} + // The char* returned is to an allocation owned by the undo history const char *CellBuffer::InsertString(Sci::Position position, const char *s, Sci::Position insertLength, bool &startSequence) { // InsertString and DeleteChars are the bottleneck though which all changes occur @@ -645,7 +682,7 @@ const char *CellBuffer::InsertString(Sci::Position position, const char *s, Sci: if (collectingUndo) { // Save into the undo/redo stack, but only the characters - not the formatting // This takes up about half load time - data = uh.AppendAction(insertAction, position, s, insertLength, startSequence); + data = uh.AppendAction(ActionType::insert, position, s, insertLength, startSequence); } BasicInsertString(position, s, insertLength); @@ -694,7 +731,7 @@ const char *CellBuffer::DeleteChars(Sci::Position position, Sci::Position delete // Save into the undo/redo stack, but only the characters - not the formatting // The gap would be moved to position anyway for the deletion so this doesn't cost extra data = substance.RangePointer(position, deleteLength); - data = uh.AppendAction(removeAction, position, data, deleteLength, startSequence); + data = uh.AppendAction(ActionType::remove, position, data, deleteLength, startSequence); } BasicDeleteChars(position, deleteLength); @@ -717,9 +754,9 @@ void CellBuffer::SetUTF8Substance(bool utf8Substance_) noexcept { utf8Substance = utf8Substance_; } -void CellBuffer::SetLineEndTypes(int utf8LineEnds_) { +void CellBuffer::SetLineEndTypes(LineEndType utf8LineEnds_) { if (utf8LineEnds != utf8LineEnds_) { - const int indexes = plv->LineCharacterIndex(); + const LineCharacterIndexType indexes = plv->LineCharacterIndex(); utf8LineEnds = utf8LineEnds_; ResetLineEnds(); AllocateLineCharacterIndex(indexes); @@ -733,7 +770,7 @@ bool CellBuffer::ContainsLineEnd(const char *s, Sci::Position length) const noex const unsigned char ch = s[i]; if ((ch == '\r') || (ch == '\n')) { return true; - } else if (utf8LineEnds) { + } else if (utf8LineEnds == LineEndType::Unicode) { if (UTF8IsMultibyteLineEnd(chBeforePrev, chPrev, ch)) { return true; } @@ -748,11 +785,11 @@ void CellBuffer::SetPerLine(PerLine *pl) noexcept { plv->SetPerLine(pl); } -int CellBuffer::LineCharacterIndex() const noexcept { +LineCharacterIndexType CellBuffer::LineCharacterIndex() const noexcept { return plv->LineCharacterIndex(); } -void CellBuffer::AllocateLineCharacterIndex(int lineCharacterIndex) { +void CellBuffer::AllocateLineCharacterIndex(LineCharacterIndexType lineCharacterIndex) { if (utf8Substance) { if (plv->AllocateLineCharacterIndex(lineCharacterIndex, Lines())) { // Changed so recalculate whole file @@ -761,7 +798,7 @@ void CellBuffer::AllocateLineCharacterIndex(int lineCharacterIndex) { } } -void CellBuffer::ReleaseLineCharacterIndex(int lineCharacterIndex) { +void CellBuffer::ReleaseLineCharacterIndex(LineCharacterIndexType lineCharacterIndex) { plv->ReleaseLineCharacterIndex(lineCharacterIndex); } @@ -769,6 +806,10 @@ Sci::Line CellBuffer::Lines() const noexcept { return plv->Lines(); } +void CellBuffer::AllocateLines(Sci::Line lines) { + plv->AllocateLines(lines); +} + Sci::Position CellBuffer::LineStart(Sci::Line line) const noexcept { if (line < 0) return 0; @@ -782,11 +823,11 @@ Sci::Line CellBuffer::LineFromPosition(Sci::Position pos) const noexcept { return plv->LineFromPosition(pos); } -Sci::Position CellBuffer::IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept { +Sci::Position CellBuffer::IndexLineStart(Sci::Line line, LineCharacterIndexType lineCharacterIndex) const noexcept { return plv->IndexLineStart(line, lineCharacterIndex); } -Sci::Line CellBuffer::LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const noexcept { +Sci::Line CellBuffer::LineFromPositionIndex(Sci::Position pos, LineCharacterIndexType lineCharacterIndex) const noexcept { return plv->LineFromPositionIndex(pos, lineCharacterIndex); } @@ -863,7 +904,7 @@ bool CellBuffer::UTF8IsCharacterBoundary(Sci::Position position) const { if (!UTF8IsTrailByte(back.front())) { if (i > 0) { // Have reached a non-trail - const int cla = UTF8Classify(reinterpret_cast(back.data()), back.size()); + const int cla = UTF8Classify(back); if ((cla & UTF8MaskInvalid) || (cla != i)) { return false; } @@ -883,13 +924,15 @@ bool CellBuffer::UTF8IsCharacterBoundary(Sci::Position position) const { void CellBuffer::ResetLineEnds() { // Reinitialize line data -- too much work to preserve + const Sci::Line lines = plv->Lines(); plv->Init(); + plv->AllocateLines(lines); - const Sci::Position position = 0; + constexpr Sci::Position position = 0; const Sci::Position length = Length(); + plv->InsertText(0, length); Sci::Line lineInsert = 1; - const bool atLineStart = true; - plv->InsertText(lineInsert-1, length); + constexpr bool atLineStart = true; unsigned char chBeforePrev = 0; unsigned char chPrev = 0; for (Sci::Position i = 0; i < length; i++) { @@ -905,7 +948,7 @@ void CellBuffer::ResetLineEnds() { InsertLine(lineInsert, (position + i) + 1, atLineStart); lineInsert++; } - } else if (utf8LineEnds) { + } else if (utf8LineEnds == LineEndType::Unicode) { if (UTF8IsMultibyteLineEnd(chBeforePrev, chPrev, ch)) { InsertLine(lineInsert, (position + i) + 1, atLineStart); lineInsert++; @@ -918,14 +961,14 @@ void CellBuffer::ResetLineEnds() { namespace { -CountWidths CountCharacterWidthsUTF8(const char *s, size_t len) noexcept { +CountWidths CountCharacterWidthsUTF8(std::string_view sv) noexcept { CountWidths cw; - size_t remaining = len; + size_t remaining = sv.length(); while (remaining > 0) { - const int utf8Status = UTF8Classify(reinterpret_cast(s), len); + const int utf8Status = UTF8Classify(sv); const int lenChar = utf8Status & UTF8MaskWidth; cw.CountChar(lenChar); - s += lenChar; + sv.remove_prefix(lenChar); remaining -= lenChar; } return cw; @@ -934,7 +977,7 @@ CountWidths CountCharacterWidthsUTF8(const char *s, size_t len) noexcept { } bool CellBuffer::MaintainingLineCharacterIndex() const noexcept { - return plv->LineCharacterIndex() != SC_LINECHARACTERINDEX_NONE; + return plv->LineCharacterIndex() != LineCharacterIndexType::None; } void CellBuffer::RecalculateIndexLineStarts(Sci::Line lineFirst, Sci::Line lineLast) { @@ -946,8 +989,8 @@ void CellBuffer::RecalculateIndexLineStarts(Sci::Line lineFirst, Sci::Line lineL posLineEnd = LineStart(line+1); const Sci::Position width = posLineEnd - posLineStart; text.resize(width); - GetCharRange(const_cast(text.data()), posLineStart, width); - const CountWidths cw = CountCharacterWidthsUTF8(text.data(), text.size()); + GetCharRange(text.data(), posLineStart, width); + const CountWidths cw = CountCharacterWidthsUTF8(text); plv->SetLineCharactersWidth(line, cw); } } @@ -959,7 +1002,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P const unsigned char chAfter = substance.ValueAt(position); bool breakingUTF8LineEnd = false; - if (utf8LineEnds && UTF8IsTrailByte(chAfter)) { + if (utf8LineEnds == LineEndType::Unicode && UTF8IsTrailByte(chAfter)) { breakingUTF8LineEnd = UTF8LineEndOverlaps(position); } @@ -976,7 +1019,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P // Actually, don't need to check that whole insertion is valid just that there // are no potential fragments at ends. simpleInsertion = UTF8IsCharacterBoundary(position) && - UTF8IsValid(s, insertLength); + UTF8IsValid(std::string_view(s, insertLength)); } substance.InsertFromArray(position, s, 0, insertLength); @@ -1019,7 +1062,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P uint8_t eolTable[256]{}; eolTable[static_cast('\n')] = 1; eolTable[static_cast('\r')] = 2; - if (utf8LineEnds) { + if (utf8LineEnds == LineEndType::Unicode) { // see UniConversion.h for LS, PS and NEL eolTable[0x85] = 4; eolTable[0xa8] = 3; @@ -1040,6 +1083,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P if (*ptr == '\n') { ++ptr; } + [[fallthrough]]; case 1: // '\n' positions[nPositions++] = position + ptr - s; if (nPositions == PositionBlockSize) { @@ -1078,7 +1122,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P if (ch == '\r' || ch == '\n') { InsertLine(lineInsert, (position + ptr - s), atLineStart); lineInsert++; - } else if (utf8LineEnds && !UTF8IsAscii(ch)) { + } else if (utf8LineEnds == LineEndType::Unicode && !UTF8IsAscii(ch)) { if (UTF8IsMultibyteLineEnd(chBeforePrev, chPrev, ch)) { InsertLine(lineInsert, (position + ptr - s), atLineStart); lineInsert++; @@ -1093,7 +1137,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P RemoveLine(lineInsert - 1); simpleInsertion = false; } - } else if (utf8LineEnds && !UTF8IsAscii(chAfter)) { + } else if (utf8LineEnds == LineEndType::Unicode && !UTF8IsAscii(chAfter)) { chBeforePrev = chPrev; chPrev = ch; // May have end of UTF-8 line end in buffer and start in insertion @@ -1114,7 +1158,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P } if (maintainingIndex) { if (simpleInsertion && (lineInsert == lineStart)) { - const CountWidths cw = CountCharacterWidthsUTF8(s, insertLength); + const CountWidths cw = CountCharacterWidthsUTF8(std::string_view(s, insertLength)); plv->InsertCharacters(linePosition, cw); } else { RecalculateIndexLineStarts(linePosition, lineInsert - 1); @@ -1126,7 +1170,7 @@ void CellBuffer::BasicDeleteChars(Sci::Position position, Sci::Position deleteLe if (deleteLength == 0) return; - Sci::Line lineRecalculateStart = INVALID_POSITION; + Sci::Line lineRecalculateStart = Sci::invalidPosition; if ((position == 0) && (deleteLength == substance.Length())) { // If whole buffer is being deleted, faster to reinitialise lines data @@ -1154,10 +1198,10 @@ void CellBuffer::BasicDeleteChars(Sci::Position position, Sci::Position deleteLe UTF8IsCharacterBoundary(position) && UTF8IsCharacterBoundary(posEnd); if (simpleDeletion) { std::string text(deleteLength, '\0'); - GetCharRange(const_cast(text.data()), position, deleteLength); - if (UTF8IsValid(text.data(), text.size())) { + GetCharRange(text.data(), position, deleteLength); + if (UTF8IsValid(text)) { // Everything is good - const CountWidths cw = CountCharacterWidthsUTF8(text.data(), text.size()); + const CountWidths cw = CountCharacterWidthsUTF8(text); plv->InsertCharacters(linePosition, -cw); } else { lineRecalculateStart = linePosition; @@ -1174,7 +1218,7 @@ void CellBuffer::BasicDeleteChars(Sci::Position position, Sci::Position deleteLe lineRemove++; ignoreNL = true; // First \n is not real deletion } - if (utf8LineEnds && UTF8IsTrailByte(chNext)) { + if (utf8LineEnds == LineEndType::Unicode && UTF8IsTrailByte(chNext)) { if (UTF8LineEndOverlaps(position)) { RemoveLine(lineRemove); } @@ -1193,7 +1237,7 @@ void CellBuffer::BasicDeleteChars(Sci::Position position, Sci::Position deleteLe } else { RemoveLine(lineRemove); } - } else if (utf8LineEnds) { + } else if (utf8LineEnds == LineEndType::Unicode) { if (!UTF8IsAscii(ch)) { const unsigned char next3[3] = {ch, chNext, static_cast(substance.ValueAt(position + i + 2))}; @@ -1243,7 +1287,7 @@ void CellBuffer::EndUndoAction() { void CellBuffer::AddUndoAction(Sci::Position token, bool mayCoalesce) { bool startSequence; - uh.AppendAction(containerAction, token, nullptr, 0, startSequence, mayCoalesce); + uh.AppendAction(ActionType::container, token, nullptr, 0, startSequence, mayCoalesce); } void CellBuffer::DeleteUndoHistory() { @@ -1264,13 +1308,13 @@ const Action &CellBuffer::GetUndoStep() const { void CellBuffer::PerformUndoStep() { const Action &actionStep = uh.GetUndoStep(); - if (actionStep.at == insertAction) { + if (actionStep.at == ActionType::insert) { if (substance.Length() < actionStep.lenData) { throw std::runtime_error( "CellBuffer::PerformUndoStep: deletion must be less than document length."); } BasicDeleteChars(actionStep.position, actionStep.lenData); - } else if (actionStep.at == removeAction) { + } else if (actionStep.at == ActionType::remove) { BasicInsertString(actionStep.position, actionStep.data.get(), actionStep.lenData); } uh.CompletedUndoStep(); @@ -1290,9 +1334,9 @@ const Action &CellBuffer::GetRedoStep() const { void CellBuffer::PerformRedoStep() { const Action &actionStep = uh.GetRedoStep(); - if (actionStep.at == insertAction) { + if (actionStep.at == ActionType::insert) { BasicInsertString(actionStep.position, actionStep.data.get(), actionStep.lenData); - } else if (actionStep.at == removeAction) { + } else if (actionStep.at == ActionType::remove) { BasicDeleteChars(actionStep.position, actionStep.lenData); } uh.CompletedRedoStep(); diff --git a/scintilla/src/CellBuffer.h b/scintilla/src/CellBuffer.h index 599b6062f4..d8914d7baf 100644 --- a/scintilla/src/CellBuffer.h +++ b/scintilla/src/CellBuffer.h @@ -8,7 +8,7 @@ #ifndef CELLBUFFER_H #define CELLBUFFER_H -namespace Scintilla { +namespace Scintilla::Internal { // Interface to per-line data that wants to see each line insertion and deletion class PerLine { @@ -25,14 +25,14 @@ class PerLine { */ class ILineVector; -enum actionType { insertAction, removeAction, startAction, containerAction }; +enum class ActionType { insert, remove, start, container }; /** * Actions are used to store all the information required to perform one undo/redo step. */ class Action { public: - actionType at; + ActionType at; Sci::Position position; std::unique_ptr data; Sci::Position lenData; @@ -46,7 +46,7 @@ class Action { // Move constructor allows vector to be resized without reallocating. Action(Action &&other) noexcept = default; ~Action(); - void Create(actionType at_, Sci::Position position_=0, const char *data_=nullptr, Sci::Position lenData_=0, bool mayCoalesce_=true); + void Create(ActionType at_, Sci::Position position_=0, const char *data_=nullptr, Sci::Position lenData_=0, bool mayCoalesce_=true); void Clear() noexcept; }; @@ -72,7 +72,7 @@ class UndoHistory { void operator=(UndoHistory &&) = delete; ~UndoHistory(); - const char *AppendAction(actionType at, Sci::Position position, const char *data, Sci::Position lengthData, bool &startSequence, bool mayCoalesce=true); + const char *AppendAction(ActionType at, Sci::Position position, const char *data, Sci::Position lengthData, bool &startSequence, bool mayCoalesce=true); void BeginUndoAction(); void EndUndoAction(); @@ -102,6 +102,32 @@ class UndoHistory { void CompletedRedoStep(); }; +struct SplitView { + const char *segment1 = nullptr; + size_t length1 = 0; + const char *segment2 = nullptr; + size_t length = 0; + + bool operator==(const SplitView &other) const noexcept { + return segment1 == other.segment1 && length1 == other.length1 && + segment2 == other.segment2 && length == other.length; + } + bool operator!=(const SplitView &other) const noexcept { + return !(*this == other); + } + + char CharAt(size_t position) const noexcept { + if (position < length1) { + return segment1[position]; + } + if (position < length) { + return segment2[position]; + } + return 0; + } +}; + + /** * Holder for an expandable array of characters that supports undo and line markers. * Based on article "Data Structures in a Bit-Mapped Text Editor" @@ -115,7 +141,7 @@ class CellBuffer { SplitVector style; bool readOnly; bool utf8Substance; - int utf8LineEnds; + Scintilla::LineEndType utf8LineEnds; bool collectingUndo; UndoHistory uh; @@ -150,22 +176,24 @@ class CellBuffer { const char *BufferPointer(); const char *RangePointer(Sci::Position position, Sci::Position rangeLength) noexcept; Sci::Position GapPosition() const noexcept; + SplitView AllView() const noexcept; Sci::Position Length() const noexcept; void Allocate(Sci::Position newSize); void SetUTF8Substance(bool utf8Substance_) noexcept; - int GetLineEndTypes() const noexcept { return utf8LineEnds; } - void SetLineEndTypes(int utf8LineEnds_); + Scintilla::LineEndType GetLineEndTypes() const noexcept { return utf8LineEnds; } + void SetLineEndTypes(Scintilla::LineEndType utf8LineEnds_); bool ContainsLineEnd(const char *s, Sci::Position length) const noexcept; void SetPerLine(PerLine *pl) noexcept; - int LineCharacterIndex() const noexcept; - void AllocateLineCharacterIndex(int lineCharacterIndex); - void ReleaseLineCharacterIndex(int lineCharacterIndex); + Scintilla::LineCharacterIndexType LineCharacterIndex() const noexcept; + void AllocateLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); + void ReleaseLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); Sci::Line Lines() const noexcept; + void AllocateLines(Sci::Line lines); Sci::Position LineStart(Sci::Line line) const noexcept; - Sci::Position IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept; + Sci::Position IndexLineStart(Sci::Line line, Scintilla::LineCharacterIndexType lineCharacterIndex) const noexcept; Sci::Line LineFromPosition(Sci::Position pos) const noexcept; - Sci::Line LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const noexcept; + Sci::Line LineFromPositionIndex(Sci::Position pos, Scintilla::LineCharacterIndexType lineCharacterIndex) const noexcept; void InsertLine(Sci::Line line, Sci::Position position, bool lineStart); void RemoveLine(Sci::Line line); const char *InsertString(Sci::Position position, const char *s, Sci::Position insertLength, bool &startSequence); diff --git a/scintilla/src/CharClassify.cxx b/scintilla/src/CharClassify.cxx index b5e2870f36..caff785b08 100644 --- a/scintilla/src/CharClassify.cxx +++ b/scintilla/src/CharClassify.cxx @@ -10,10 +10,10 @@ #include -#include "CharacterSet.h" +#include "CharacterType.h" #include "CharClassify.h" -using namespace Scintilla; +using namespace Scintilla::Internal; CharClassify::CharClassify() : charClass{} { SetDefaultCharClasses(true); @@ -21,29 +21,29 @@ CharClassify::CharClassify() : charClass{} { void CharClassify::SetDefaultCharClasses(bool includeWordClass) { // Initialize all char classes to default values - for (int ch = 0; ch < 256; ch++) { + for (int ch = 0; ch < maxChar; ch++) { if (ch == '\r' || ch == '\n') - charClass[ch] = ccNewLine; + charClass[ch] = CharacterClass::newLine; else if (ch < 0x20 || ch == ' ') - charClass[ch] = ccSpace; + charClass[ch] = CharacterClass::space; else if (includeWordClass && (ch >= 0x80 || IsAlphaNumeric(ch) || ch == '_')) - charClass[ch] = ccWord; + charClass[ch] = CharacterClass::word; else - charClass[ch] = ccPunctuation; + charClass[ch] = CharacterClass::punctuation; } } -void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) { +void CharClassify::SetCharClasses(const unsigned char *chars, CharacterClass newCharClass) { // Apply the newCharClass to the specified chars if (chars) { while (*chars) { - charClass[*chars] = static_cast(newCharClass); + charClass[*chars] = newCharClass; chars++; } } } -int CharClassify::GetCharsOfClass(cc characterClass, unsigned char *buffer) const noexcept { +int CharClassify::GetCharsOfClass(CharacterClass characterClass, unsigned char *buffer) const noexcept { // Get characters belonging to the given char class; return the number // of characters (if the buffer is NULL, don't write to it). int count = 0; diff --git a/scintilla/src/CharClassify.h b/scintilla/src/CharClassify.h index 36cc345586..9fc1be2980 100644 --- a/scintilla/src/CharClassify.h +++ b/scintilla/src/CharClassify.h @@ -8,22 +8,23 @@ #ifndef CHARCLASSIFY_H #define CHARCLASSIFY_H -namespace Scintilla { +namespace Scintilla::Internal { + +enum class CharacterClass : unsigned char { space, newLine, word, punctuation }; class CharClassify { public: CharClassify(); - enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation }; void SetDefaultCharClasses(bool includeWordClass); - void SetCharClasses(const unsigned char *chars, cc newCharClass); - int GetCharsOfClass(cc characterClass, unsigned char *buffer) const noexcept; - cc GetClass(unsigned char ch) const noexcept { return static_cast(charClass[ch]);} - bool IsWord(unsigned char ch) const noexcept { return static_cast(charClass[ch]) == ccWord;} + void SetCharClasses(const unsigned char *chars, CharacterClass newCharClass); + int GetCharsOfClass(CharacterClass characterClass, unsigned char *buffer) const noexcept; + CharacterClass GetClass(unsigned char ch) const noexcept { return charClass[ch];} + bool IsWord(unsigned char ch) const noexcept { return charClass[ch] == CharacterClass::word;} private: - enum { maxChar=256 }; - unsigned char charClass[maxChar]; // not type cc to save space + static constexpr int maxChar=256; + CharacterClass charClass[maxChar]; }; } diff --git a/scintilla/src/CharacterCategoryMap.cxx b/scintilla/src/CharacterCategoryMap.cxx new file mode 100644 index 0000000000..015b1de390 --- /dev/null +++ b/scintilla/src/CharacterCategoryMap.cxx @@ -0,0 +1,4105 @@ +// Scintilla source code edit control +/** @file CharacterCategoryMap.cxx + ** Returns the Unicode general category of a character. + ** Table automatically regenerated by scripts/GenerateCharacterCategory.py + ** Should only be rarely regenerated for new versions of Unicode. + ** Similar code to Lexilla's lexilla/lexlib/CharacterCategory.cxx but renamed + ** to avoid problems with builds that statically include both Scintilla and Lexilla. + **/ +// Copyright 2013 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include + +#include "CharacterCategoryMap.h" + +namespace Scintilla::Internal { + +namespace { + // Use an unnamed namespace to protect the declarations from name conflicts + +const int catRanges[] = { +//++Autogenerated -- start of section automatically generated +// Created with Python 3.9.4, Unicode 13.0.0 +25, +1046, +1073, +1171, +1201, +1293, +1326, +1361, +1394, +1425, +1452, +1489, +1544, +1873, +1938, +2033, +2080, +2925, +2961, +2990, +3028, +3051, +3092, +3105, +3949, +3986, +4014, +4050, +4089, +5142, +5169, +5203, +5333, +5361, +5396, +5429, +5444, +5487, +5522, +5562, +5589, +5620, +5653, +5682, +5706, +5780, +5793, +5841, +5908, +5930, +5956, +6000, +6026, +6129, +6144, +6898, +6912, +7137, +7922, +7937, +8192, +8225, +8256, +8289, +8320, +8353, +8384, +8417, +8448, +8481, +8512, +8545, +8576, +8609, +8640, +8673, +8704, +8737, +8768, +8801, +8832, +8865, +8896, +8929, +8960, +8993, +9024, +9057, +9088, +9121, +9152, +9185, +9216, +9249, +9280, +9313, +9344, +9377, +9408, +9441, +9472, +9505, +9536, +9569, +9600, +9633, +9664, +9697, +9728, +9761, +9792, +9825, +9856, +9889, +9920, +9953, +10016, +10049, +10080, +10113, +10144, +10177, +10208, +10241, +10272, +10305, +10336, +10369, +10400, +10433, +10464, +10497, +10560, +10593, +10624, +10657, +10688, +10721, +10752, +10785, +10816, +10849, +10880, +10913, +10944, +10977, +11008, +11041, +11072, +11105, +11136, +11169, +11200, +11233, +11264, +11297, +11328, +11361, +11392, +11425, +11456, +11489, +11520, +11553, +11584, +11617, +11648, +11681, +11712, +11745, +11776, +11809, +11840, +11873, +11904, +11937, +11968, +12001, +12032, +12097, +12128, +12161, +12192, +12225, +12320, +12385, +12416, +12449, +12480, +12545, +12576, +12673, +12736, +12865, +12896, +12961, +12992, +13089, +13184, +13249, +13280, +13345, +13376, +13409, +13440, +13473, +13504, +13569, +13600, +13633, +13696, +13729, +13760, +13825, +13856, +13953, +13984, +14017, +14048, +14113, +14180, +14208, +14241, +14340, +14464, +14498, +14529, +14560, +14594, +14625, +14656, +14690, +14721, +14752, +14785, +14816, +14849, +14880, +14913, +14944, +14977, +15008, +15041, +15072, +15105, +15136, +15169, +15200, +15233, +15296, +15329, +15360, +15393, +15424, +15457, +15488, +15521, +15552, +15585, +15616, +15649, +15680, +15713, +15744, +15777, +15808, +15841, +15904, +15938, +15969, +16000, +16033, +16064, +16161, +16192, +16225, +16256, +16289, +16320, +16353, +16384, +16417, +16448, +16481, +16512, +16545, +16576, +16609, +16640, +16673, +16704, +16737, +16768, +16801, +16832, +16865, +16896, +16929, +16960, +16993, +17024, +17057, +17088, +17121, +17152, +17185, +17216, +17249, +17280, +17313, +17344, +17377, +17408, +17441, +17472, +17505, +17536, +17569, +17600, +17633, +17664, +17697, +17728, +17761, +17792, +17825, +17856, +17889, +17920, +17953, +17984, +18017, +18240, +18305, +18336, +18401, +18464, +18497, +18528, +18657, +18688, +18721, +18752, +18785, +18816, +18849, +18880, +18913, +21124, +21153, +22019, +22612, +22723, +23124, +23555, +23732, +23939, +23988, +24003, +24052, +24581, +28160, +28193, +28224, +28257, +28291, +28340, +28352, +28385, +28445, +28483, +28513, +28625, +28640, +28701, +28820, +28864, +28913, +28928, +29053, +29056, +29117, +29120, +29185, +29216, +29789, +29792, +30081, +31200, +31233, +31296, +31393, +31488, +31521, +31552, +31585, +31616, +31649, +31680, +31713, +31744, +31777, +31808, +31841, +31872, +31905, +31936, +31969, +32000, +32033, +32064, +32097, +32128, +32161, +32192, +32225, +32384, +32417, +32466, +32480, +32513, +32544, +32609, +32672, +34305, +35840, +35873, +35904, +35937, +35968, +36001, +36032, +36065, +36096, +36129, +36160, +36193, +36224, +36257, +36288, +36321, +36352, +36385, +36416, +36449, +36480, +36513, +36544, +36577, +36608, +36641, +36672, +36705, +36736, +36769, +36800, +36833, +36864, +36897, +36949, +36965, +37127, +37184, +37217, +37248, +37281, +37312, +37345, +37376, +37409, +37440, +37473, +37504, +37537, +37568, +37601, +37632, +37665, +37696, +37729, +37760, +37793, +37824, +37857, +37888, +37921, +37952, +37985, +38016, +38049, +38080, +38113, +38144, +38177, +38208, +38241, +38272, +38305, +38336, +38369, +38400, +38433, +38464, +38497, +38528, +38561, +38592, +38625, +38656, +38689, +38720, +38753, +38784, +38817, +38848, +38881, +38912, +38977, +39008, +39041, +39072, +39105, +39136, +39169, +39200, +39233, +39264, +39297, +39328, +39361, +39424, +39457, +39488, +39521, +39552, +39585, +39616, +39649, +39680, +39713, +39744, +39777, +39808, +39841, +39872, +39905, +39936, +39969, +40000, +40033, +40064, +40097, +40128, +40161, +40192, +40225, +40256, +40289, +40320, +40353, +40384, +40417, +40448, +40481, +40512, +40545, +40576, +40609, +40640, +40673, +40704, +40737, +40768, +40801, +40832, +40865, +40896, +40929, +40960, +40993, +41024, +41057, +41088, +41121, +41152, +41185, +41216, +41249, +41280, +41313, +41344, +41377, +41408, +41441, +41472, +41505, +41536, +41569, +41600, +41633, +41664, +41697, +41728, +41761, +41792, +41825, +41856, +41889, +41920, +41953, +41984, +42017, +42048, +42081, +42112, +42145, +42176, +42209, +42240, +42273, +42304, +42337, +42368, +42401, +42432, +42465, +42525, +42528, +43773, +43811, +43857, +44033, +45361, +45388, +45437, +45493, +45555, +45597, +45605, +47052, +47077, +47121, +47141, +47217, +47237, +47313, +47333, +47389, +47620, +48509, +48612, +48753, +48829, +49178, +49362, +49457, +49523, +49553, +49621, +49669, +50033, +50074, +50109, +50129, +50180, +51203, +51236, +51557, +52232, +52561, +52676, +52741, +52772, +55953, +55972, +56005, +56250, +56277, +56293, +56483, +56549, +56629, +56645, +56772, +56840, +57156, +57269, +57316, +57361, +57821, +57850, +57860, +57893, +57924, +58885, +59773, +59812, +62661, +63012, +63069, +63496, +63812, +64869, +65155, +65237, +65265, +65347, +65405, +65445, +65491, +65540, +66245, +66371, +66405, +66691, +66725, +66819, +66853, +67037, +67089, +67581, +67588, +68389, +68509, +68561, +68605, +68612, +68989, +70660, +71357, +71364, +71965, +72293, +72794, +72805, +73830, +73860, +75589, +75622, +75653, +75684, +75718, +75813, +76070, +76197, +76230, +76292, +76325, +76548, +76869, +76945, +77000, +77329, +77347, +77380, +77861, +77894, +77981, +77988, +78269, +78308, +78397, +78436, +79165, +79172, +79421, +79428, +79485, +79556, +79709, +79749, +79780, +79814, +79909, +80061, +80102, +80189, +80230, +80293, +80324, +80381, +80614, +80669, +80772, +80861, +80868, +80965, +81053, +81096, +81412, +81491, +81546, +81749, +81779, +81796, +81841, +81861, +81917, +81957, +82022, +82077, +82084, +82301, +82404, +82493, +82532, +83261, +83268, +83517, +83524, +83613, +83620, +83709, +83716, +83805, +83845, +83901, +83910, +84005, +84093, +84197, +84285, +84325, +84445, +84517, +84573, +84772, +84925, +84932, +84989, +85192, +85509, +85572, +85669, +85713, +85757, +86053, +86118, +86173, +86180, +86493, +86500, +86621, +86628, +87357, +87364, +87613, +87620, +87709, +87716, +87901, +87941, +87972, +88006, +88101, +88285, +88293, +88358, +88413, +88422, +88485, +88541, +88580, +88637, +89092, +89157, +89245, +89288, +89617, +89651, +89693, +89892, +89925, +90141, +90149, +90182, +90269, +90276, +90557, +90596, +90685, +90724, +91453, +91460, +91709, +91716, +91805, +91812, +91997, +92037, +92068, +92102, +92133, +92166, +92197, +92349, +92390, +92477, +92518, +92581, +92637, +92837, +92902, +92957, +93060, +93149, +93156, +93253, +93341, +93384, +93717, +93732, +93770, +93981, +94277, +94308, +94365, +94372, +94589, +94660, +94781, +94788, +94941, +95012, +95101, +95108, +95165, +95172, +95261, +95332, +95421, +95492, +95613, +95684, +96093, +96198, +96261, +96294, +96381, +96454, +96573, +96582, +96677, +96733, +96772, +96829, +96998, +97053, +97480, +97802, +97909, +98099, +98133, +98173, +98309, +98342, +98437, +98468, +98749, +98756, +98877, +98884, +99645, +99652, +100189, +100260, +100293, +100390, +100541, +100549, +100669, +100677, +100829, +101029, +101117, +101124, +101245, +101380, +101445, +101533, +101576, +101917, +102129, +102154, +102389, +102404, +102437, +102470, +102545, +102564, +102845, +102852, +102973, +102980, +103741, +103748, +104093, +104100, +104285, +104325, +104356, +104390, +104421, +104454, +104637, +104645, +104678, +104765, +104774, +104837, +104925, +105126, +105213, +105412, +105469, +105476, +105541, +105629, +105672, +106013, +106020, +106109, +106501, +106566, +106628, +106941, +106948, +107069, +107076, +108389, +108452, +108486, +108581, +108733, +108742, +108861, +108870, +108965, +108996, +109045, +109085, +109188, +109286, +109322, +109540, +109637, +109725, +109768, +110090, +110389, +110404, +110621, +110629, +110662, +110749, +110756, +111357, +111428, +112221, +112228, +112541, +112548, +112605, +112644, +112893, +112965, +113021, +113126, +113221, +113341, +113349, +113405, +113414, +113693, +113864, +114205, +114246, +114321, +114365, +114724, +116261, +116292, +116357, +116605, +116723, +116740, +116931, +116965, +117233, +117256, +117585, +117661, +118820, +118909, +118916, +118973, +118980, +119165, +119172, +119965, +119972, +120029, +120036, +120357, +120388, +120453, +120740, +120797, +120836, +121021, +121027, +121085, +121093, +121309, +121352, +121693, +121732, +121885, +122884, +122933, +123025, +123509, +123537, +123573, +123653, +123733, +123912, +124234, +124565, +124581, +124629, +124645, +124693, +124709, +124749, +124782, +124813, +124846, +124870, +124932, +125213, +125220, +126397, +126501, +126950, +126981, +127153, +127173, +127236, +127397, +127773, +127781, +128957, +128981, +129221, +129269, +129469, +129493, +129553, +129717, +129841, +129917, +131076, +132454, +132517, +132646, +132677, +132870, +132901, +132966, +133029, +133092, +133128, +133457, +133636, +133830, +133893, +133956, +134085, +134180, +134214, +134308, +134374, +134596, +134693, +134820, +135237, +135270, +135333, +135398, +135589, +135620, +135654, +135688, +136006, +136101, +136149, +136192, +137437, +137440, +137501, +137632, +137693, +137729, +139121, +139139, +139169, +139268, +149821, +149828, +149981, +150020, +150269, +150276, +150333, +150340, +150493, +150532, +151869, +151876, +152029, +152068, +153149, +153156, +153309, +153348, +153597, +153604, +153661, +153668, +153821, +153860, +154365, +154372, +156221, +156228, +156381, +156420, +158589, +158629, +158737, +159018, +159677, +159748, +160277, +160605, +160768, +163549, +163585, +163805, +163852, +163876, +183733, +183761, +183780, +184342, +184356, +185197, +185230, +185277, +185348, +187761, +187849, +187940, +188221, +188420, +188861, +188868, +188997, +189117, +189444, +190021, +190129, +190205, +190468, +191045, +191133, +191492, +191933, +191940, +192061, +192069, +192157, +192516, +194181, +194246, +194277, +194502, +194757, +194790, +194853, +195217, +195299, +195345, +195443, +195460, +195493, +195549, +195592, +195933, +196106, +196445, +196625, +196812, +196849, +196965, +197082, +197117, +197128, +197469, +197636, +198755, +198788, +200509, +200708, +200869, +200932, +202021, +202052, +202109, +202244, +204509, +204804, +205821, +205829, +205926, +206053, +206118, +206237, +206342, +206405, +206438, +206629, +206749, +206869, +206909, +206993, +207048, +207364, +208349, +208388, +208573, +208900, +210333, +210436, +211293, +211464, +211786, +211837, +211925, +212996, +213733, +213798, +213861, +213917, +213969, +214020, +215718, +215749, +215782, +215813, +216061, +216069, +216102, +216133, +216166, +216229, +216486, +216677, +217021, +217061, +217096, +217437, +217608, +217949, +218129, +218339, +218385, +218589, +218629, +219079, +219109, +219197, +221189, +221318, +221348, +222853, +222886, +222917, +223078, +223109, +223142, +223301, +223334, +223396, +223645, +223752, +224081, +224309, +224613, +224917, +225213, +225285, +225350, +225380, +226342, +226373, +226502, +226565, +226630, +226661, +226756, +226824, +227140, +228549, +228582, +228613, +228678, +228773, +228806, +228837, +228934, +229021, +229265, +229380, +230534, +230789, +231046, +231109, +231197, +231281, +231432, +231773, +231844, +231944, +232260, +233219, +233425, +233473, +233789, +233984, +235389, +235424, +235537, +235805, +236037, +236145, +236165, +236582, +236613, +236836, +236965, +236996, +237189, +237220, +237286, +237317, +237380, +237437, +237569, +238979, +240993, +241411, +241441, +242531, +243717, +245597, +245605, +245760, +245793, +245824, +245857, +245888, +245921, +245952, +245985, +246016, +246049, +246080, +246113, +246144, +246177, +246208, +246241, +246272, +246305, +246336, +246369, +246400, +246433, +246464, +246497, +246528, +246561, +246592, +246625, +246656, +246689, +246720, +246753, +246784, +246817, +246848, +246881, +246912, +246945, +246976, +247009, +247040, +247073, +247104, +247137, +247168, +247201, +247232, +247265, +247296, +247329, +247360, +247393, +247424, +247457, +247488, +247521, +247552, +247585, +247616, +247649, +247680, +247713, +247744, +247777, +247808, +247841, +247872, +247905, +247936, +247969, +248000, +248033, +248064, +248097, +248128, +248161, +248192, +248225, +248256, +248289, +248320, +248353, +248384, +248417, +248448, +248481, +248512, +248545, +248576, +248609, +248640, +248673, +248704, +248737, +248768, +248801, +248832, +248865, +248896, +248929, +248960, +248993, +249024, +249057, +249088, +249121, +249152, +249185, +249216, +249249, +249280, +249313, +249344, +249377, +249408, +249441, +249472, +249505, +249536, +249569, +249600, +249633, +249664, +249697, +249728, +249761, +249792, +249825, +249856, +249889, +249920, +249953, +249984, +250017, +250048, +250081, +250112, +250145, +250176, +250209, +250240, +250273, +250304, +250337, +250368, +250401, +250432, +250465, +250496, +250529, +250816, +250849, +250880, +250913, +250944, +250977, +251008, +251041, +251072, +251105, +251136, +251169, +251200, +251233, +251264, +251297, +251328, +251361, +251392, +251425, +251456, +251489, +251520, +251553, +251584, +251617, +251648, +251681, +251712, +251745, +251776, +251809, +251840, +251873, +251904, +251937, +251968, +252001, +252032, +252065, +252096, +252129, +252160, +252193, +252224, +252257, +252288, +252321, +252352, +252385, +252416, +252449, +252480, +252513, +252544, +252577, +252608, +252641, +252672, +252705, +252736, +252769, +252800, +252833, +252864, +252897, +252928, +252961, +252992, +253025, +253056, +253089, +253120, +253153, +253184, +253217, +253248, +253281, +253312, +253345, +253376, +253409, +253440, +253473, +253504, +253537, +253568, +253601, +253632, +253665, +253696, +253729, +253760, +253793, +253824, +253857, +253888, +253921, +254208, +254465, +254685, +254720, +254941, +254977, +255232, +255489, +255744, +256001, +256221, +256256, +256477, +256513, +256797, +256800, +256861, +256864, +256925, +256928, +256989, +256992, +257025, +257280, +257537, +258013, +258049, +258306, +258561, +258818, +259073, +259330, +259585, +259773, +259777, +259840, +259970, +260020, +260033, +260084, +260161, +260285, +260289, +260352, +260482, +260532, +260609, +260765, +260801, +260864, +261021, +261044, +261121, +261376, +261556, +261661, +261697, +261821, +261825, +261888, +262018, +262068, +262141, +262166, +262522, +262668, +262865, +262927, +262960, +262989, +263023, +263088, +263117, +263151, +263185, +263447, +263480, +263514, +263670, +263697, +263983, +264016, +264049, +264171, +264241, +264338, +264365, +264398, +264433, +264786, +264817, +264843, +264881, +265206, +265242, +265405, +265434, +265738, +265763, +265821, +265866, +266066, +266157, +266190, +266211, +266250, +266578, +266669, +266702, +266749, +266755, +267197, +267283, +268317, +268805, +269223, +269349, +269383, +269477, +269885, +270357, +270400, +270453, +270560, +270613, +270657, +270688, +270785, +270848, +270945, +270997, +271008, +271061, +271122, +271136, +271317, +271488, +271541, +271552, +271605, +271616, +271669, +271680, +271829, +271841, +271872, +272001, +272036, +272161, +272213, +272257, +272320, +272402, +272544, +272577, +272725, +272754, +272789, +272833, +272885, +272906, +273417, +274528, +274561, +274601, +274730, +274773, +274845, +274962, +275125, +275282, +275349, +275474, +275509, +275570, +275605, +275666, +275701, +275922, +275957, +276946, +277013, +277074, +277109, +277138, +277173, +278162, +286741, +286989, +287022, +287053, +287086, +287125, +287762, +287829, +288045, +288078, +288117, +290706, +290741, +291698, +292501, +293778, +293973, +296189, +296981, +297341, +297994, +299925, +302410, +303125, +308978, +309013, +309298, +309333, +311058, +311317, +314866, +314901, +322829, +322862, +322893, +322926, +322957, +322990, +323021, +323054, +323085, +323118, +323149, +323182, +323213, +323246, +323274, +324245, +325650, +325805, +325838, +325874, +326861, +326894, +326925, +326958, +326989, +327022, +327053, +327086, +327117, +327150, +327186, +327701, +335890, +340077, +340110, +340141, +340174, +340205, +340238, +340269, +340302, +340333, +340366, +340397, +340430, +340461, +340494, +340525, +340558, +340589, +340622, +340653, +340686, +340717, +340750, +340786, +342797, +342830, +342861, +342894, +342930, +343949, +343982, +344018, +352277, +353810, +354485, +354546, +354741, +355997, +356053, +357085, +357109, +360448, +361981, +361985, +363517, +363520, +363553, +363584, +363681, +363744, +363777, +363808, +363841, +363872, +363905, +363936, +364065, +364096, +364129, +364192, +364225, +364419, +364480, +364577, +364608, +364641, +364672, +364705, +364736, +364769, +364800, +364833, +364864, +364897, +364928, +364961, +364992, +365025, +365056, +365089, +365120, +365153, +365184, +365217, +365248, +365281, +365312, +365345, +365376, +365409, +365440, +365473, +365504, +365537, +365568, +365601, +365632, +365665, +365696, +365729, +365760, +365793, +365824, +365857, +365888, +365921, +365952, +365985, +366016, +366049, +366080, +366113, +366144, +366177, +366208, +366241, +366272, +366305, +366336, +366369, +366400, +366433, +366464, +366497, +366528, +366561, +366592, +366625, +366656, +366689, +366720, +366753, +366784, +366817, +366848, +366881, +366912, +366945, +366976, +367009, +367040, +367073, +367104, +367137, +367168, +367201, +367232, +367265, +367296, +367329, +367360, +367393, +367424, +367457, +367488, +367521, +367552, +367585, +367616, +367649, +367680, +367713, +367797, +367968, +368001, +368032, +368065, +368101, +368192, +368225, +368285, +368433, +368554, +368593, +368641, +369885, +369889, +369949, +370081, +370141, +370180, +371997, +372195, +372241, +372285, +372709, +372740, +373501, +373764, +374013, +374020, +374269, +374276, +374525, +374532, +374781, +374788, +375037, +375044, +375293, +375300, +375549, +375556, +375805, +375813, +376849, +376911, +376944, +376975, +377008, +377041, +377135, +377168, +377201, +377231, +377264, +377297, +377580, +377617, +377676, +377713, +377743, +377776, +377809, +377871, +377904, +377933, +377966, +377997, +378030, +378061, +378094, +378125, +378158, +378193, +378339, +378385, +378700, +378769, +378892, +378929, +378957, +378993, +379413, +379473, +379517, +380949, +381789, +381813, +384669, +385045, +391901, +392725, +393117, +393238, +393265, +393365, +393379, +393412, +393449, +393485, +393518, +393549, +393582, +393613, +393646, +393677, +393710, +393741, +393774, +393813, +393869, +393902, +393933, +393966, +393997, +394030, +394061, +394094, +394124, +394157, +394190, +394261, +394281, +394565, +394694, +394764, +394787, +394965, +395017, +395107, +395140, +395185, +395221, +395293, +395300, +398077, +398117, +398196, +398243, +398308, +398348, +398372, +401265, +401283, +401380, +401437, +401572, +402973, +402980, +406013, +406037, +406090, +406229, +406532, +407573, +408733, +409092, +409621, +410621, +410634, +410965, +411914, +412181, +412202, +412693, +413706, +414037, +415274, +415765, +425988, +636949, +638980, +1310653, +1310724, +1311395, +1311428, +1348029, +1348117, +1349885, +1350148, +1351427, +1351633, +1351684, +1360259, +1360305, +1360388, +1360904, +1361220, +1361309, +1361920, +1361953, +1361984, +1362017, +1362048, +1362081, +1362112, +1362145, +1362176, +1362209, +1362240, +1362273, +1362304, +1362337, +1362368, +1362401, +1362432, +1362465, +1362496, +1362529, +1362560, +1362593, +1362624, +1362657, +1362688, +1362721, +1362752, +1362785, +1362816, +1362849, +1362880, +1362913, +1362944, +1362977, +1363008, +1363041, +1363072, +1363105, +1363136, +1363169, +1363200, +1363233, +1363264, +1363297, +1363328, +1363361, +1363396, +1363429, +1363463, +1363569, +1363589, +1363921, +1363939, +1363968, +1364001, +1364032, +1364065, +1364096, +1364129, +1364160, +1364193, +1364224, +1364257, +1364288, +1364321, +1364352, +1364385, +1364416, +1364449, +1364480, +1364513, +1364544, +1364577, +1364608, +1364641, +1364672, +1364705, +1364736, +1364769, +1364800, +1364833, +1364867, +1364933, +1364996, +1367241, +1367557, +1367633, +1367837, +1368084, +1368803, +1369108, +1369152, +1369185, +1369216, +1369249, +1369280, +1369313, +1369344, +1369377, +1369408, +1369441, +1369472, +1369505, +1369536, +1369569, +1369664, +1369697, +1369728, +1369761, +1369792, +1369825, +1369856, +1369889, +1369920, +1369953, +1369984, +1370017, +1370048, +1370081, +1370112, +1370145, +1370176, +1370209, +1370240, +1370273, +1370304, +1370337, +1370368, +1370401, +1370432, +1370465, +1370496, +1370529, +1370560, +1370593, +1370624, +1370657, +1370688, +1370721, +1370752, +1370785, +1370816, +1370849, +1370880, +1370913, +1370944, +1370977, +1371008, +1371041, +1371072, +1371105, +1371136, +1371169, +1371200, +1371233, +1371264, +1371297, +1371328, +1371361, +1371392, +1371425, +1371456, +1371489, +1371520, +1371553, +1371584, +1371617, +1371651, +1371681, +1371936, +1371969, +1372000, +1372033, +1372064, +1372129, +1372160, +1372193, +1372224, +1372257, +1372288, +1372321, +1372352, +1372385, +1372419, +1372468, +1372512, +1372545, +1372576, +1372609, +1372644, +1372672, +1372705, +1372736, +1372769, +1372864, +1372897, +1372928, +1372961, +1372992, +1373025, +1373056, +1373089, +1373120, +1373153, +1373184, +1373217, +1373248, +1373281, +1373312, +1373345, +1373376, +1373409, +1373440, +1373473, +1373504, +1373665, +1373696, +1373857, +1373888, +1373921, +1373952, +1373985, +1374016, +1374049, +1374080, +1374113, +1374144, +1374177, +1374237, +1374272, +1374305, +1374336, +1374465, +1374496, +1374529, +1374589, +1375904, +1375937, +1375972, +1376003, +1376065, +1376100, +1376325, +1376356, +1376453, +1376484, +1376613, +1376644, +1377382, +1377445, +1377510, +1377557, +1377669, +1377725, +1377802, +1378005, +1378067, +1378101, +1378141, +1378308, +1379985, +1380125, +1380358, +1380420, +1382022, +1382533, +1382621, +1382865, +1382920, +1383261, +1383429, +1384004, +1384209, +1384292, +1384337, +1384356, +1384421, +1384456, +1384772, +1385669, +1385937, +1385988, +1386725, +1387078, +1387165, +1387505, +1387524, +1388477, +1388549, +1388646, +1388676, +1390181, +1390214, +1390277, +1390406, +1390469, +1390534, +1390641, +1391069, +1391075, +1391112, +1391453, +1391569, +1391620, +1391781, +1391811, +1391844, +1392136, +1392452, +1392637, +1392644, +1393957, +1394150, +1394213, +1394278, +1394341, +1394429, +1394692, +1394789, +1394820, +1395077, +1395110, +1395165, +1395208, +1395549, +1395601, +1395716, +1396227, +1396260, +1396469, +1396548, +1396582, +1396613, +1396646, +1396676, +1398277, +1398308, +1398341, +1398436, +1398501, +1398564, +1398725, +1398788, +1398821, +1398852, +1398909, +1399652, +1399715, +1399761, +1399812, +1400166, +1400197, +1400262, +1400337, +1400388, +1400419, +1400486, +1400517, +1400573, +1400868, +1401085, +1401124, +1401341, +1401380, +1401597, +1401860, +1402109, +1402116, +1402365, +1402369, +1403764, +1403779, +1403905, +1404195, +1404244, +1404317, +1404417, +1406980, +1408102, +1408165, +1408198, +1408261, +1408294, +1408369, +1408390, +1408421, +1408477, +1408520, +1408861, +1409028, +1766557, +1766916, +1767677, +1767780, +1769373, +1769499, +1835036, +2039812, +2051549, +2051588, +2055005, +2056193, +2056445, +2056801, +2056989, +2057124, +2057157, +2057188, +2057522, +2057540, +2057981, +2057988, +2058173, +2058180, +2058237, +2058244, +2058333, +2058340, +2058429, +2058436, +2061908, +2062429, +2062948, +2074574, +2074605, +2074653, +2075140, +2077213, +2077252, +2079005, +2080260, +2080659, +2080693, +2080733, +2080773, +2081297, +2081517, +2081550, +2081585, +2081629, +2081797, +2082321, +2082348, +2082411, +2082477, +2082510, +2082541, +2082574, +2082605, +2082638, +2082669, +2082702, +2082733, +2082766, +2082797, +2082830, +2082861, +2082894, +2082925, +2082958, +2082993, +2083053, +2083086, +2083121, +2083243, +2083345, +2083453, +2083473, +2083596, +2083629, +2083662, +2083693, +2083726, +2083757, +2083790, +2083825, +2083922, +2083948, +2083986, +2084093, +2084113, +2084147, +2084177, +2084253, +2084356, +2084541, +2084548, +2088893, +2088954, +2088989, +2089009, +2089107, +2089137, +2089229, +2089262, +2089297, +2089330, +2089361, +2089388, +2089425, +2089480, +2089809, +2089874, +2089969, +2090016, +2090861, +2090897, +2090926, +2090964, +2090987, +2091028, +2091041, +2091885, +2091922, +2091950, +2091986, +2092013, +2092046, +2092081, +2092109, +2092142, +2092177, +2092228, +2092547, +2092580, +2094019, +2094084, +2095101, +2095172, +2095389, +2095428, +2095645, +2095684, +2095901, +2095940, +2096061, +2096147, +2096210, +2096244, +2096277, +2096307, +2096381, +2096405, +2096434, +2096565, +2096637, +2096954, +2097045, +2097117, +2097156, +2097565, +2097572, +2098429, +2098436, +2099069, +2099076, +2099165, +2099172, +2099677, +2099716, +2100189, +2101252, +2105213, +2105361, +2105469, +2105578, +2107037, +2107125, +2107401, +2109098, +2109237, +2109770, +2109845, +2109949, +2109973, +2110397, +2110485, +2110525, +2112021, +2113445, +2113501, +2117636, +2118589, +2118660, +2120253, +2120709, +2120746, +2121629, +2121732, +2122762, +2122909, +2123172, +2123817, +2123844, +2124105, +2124157, +2124292, +2125509, +2125693, +2125828, +2126813, +2126833, +2126852, +2128029, +2128132, +2128401, +2128425, +2128605, +2129920, +2131201, +2132484, +2135005, +2135048, +2135389, +2135552, +2136733, +2136833, +2138013, +2138116, +2139421, +2139652, +2141341, +2141681, +2141725, +2146308, +2156285, +2156548, +2157277, +2157572, +2157853, +2162692, +2162909, +2162948, +2163005, +2163012, +2164445, +2164452, +2164541, +2164612, +2164669, +2164708, +2165469, +2165489, +2165514, +2165764, +2166517, +2166570, +2166788, +2167805, +2168042, +2168349, +2169860, +2170493, +2170500, +2170589, +2170730, +2170884, +2171594, +2171805, +2171889, +2171908, +2172765, +2172913, +2172957, +2174980, +2176797, +2176906, +2176964, +2177034, +2177565, +2177610, +2179076, +2179109, +2179229, +2179237, +2179325, +2179461, +2179588, +2179741, +2179748, +2179869, +2179876, +2180829, +2180869, +2180989, +2181093, +2181130, +2181437, +2181649, +2181949, +2182148, +2183082, +2183153, +2183172, +2184106, +2184221, +2185220, +2185493, +2185508, +2186405, +2186493, +2186602, +2186769, +2187005, +2187268, +2189021, +2189105, +2189316, +2190045, +2190090, +2190340, +2190973, +2191114, +2191364, +2191965, +2192177, +2192317, +2192682, +2192925, +2195460, +2197821, +2199552, +2201213, +2201601, +2203261, +2203466, +2203652, +2204805, +2204957, +2205192, +2205533, +2214922, +2215933, +2215940, +2217309, +2217317, +2217388, +2217437, +2217476, +2217565, +2220036, +2220970, +2221284, +2221341, +2221572, +2222277, +2222634, +2222769, +2222941, +2225668, +2226346, +2226589, +2227204, +2227965, +2228230, +2228261, +2228294, +2228324, +2230021, +2230513, +2230749, +2230858, +2231496, +2231837, +2232293, +2232390, +2232420, +2233862, +2233957, +2234086, +2234149, +2234225, +2234298, +2234321, +2234461, +2234810, +2234845, +2234884, +2235709, +2235912, +2236253, +2236421, +2236516, +2237669, +2237830, +2237861, +2238141, +2238152, +2238481, +2238596, +2238630, +2238692, +2238749, +2238980, +2240101, +2240145, +2240196, +2240253, +2240517, +2240582, +2240612, +2242150, +2242245, +2242534, +2242596, +2242737, +2242853, +2242993, +2243014, +2243045, +2243080, +2243396, +2243441, +2243460, +2243505, +2243613, +2243626, +2244285, +2244612, +2245213, +2245220, +2246022, +2246117, +2246214, +2246277, +2246310, +2246341, +2246417, +2246597, +2246653, +2248708, +2248957, +2248964, +2249021, +2249028, +2249181, +2249188, +2249693, +2249700, +2250033, +2250077, +2250244, +2251749, +2251782, +2251877, +2252157, +2252296, +2252637, +2252805, +2252870, +2252957, +2252964, +2253245, +2253284, +2253373, +2253412, +2254141, +2254148, +2254397, +2254404, +2254493, +2254500, +2254685, +2254693, +2254756, +2254790, +2254853, +2254886, +2255037, +2255078, +2255165, +2255206, +2255325, +2255364, +2255421, +2255590, +2255645, +2255780, +2255942, +2256029, +2256069, +2256317, +2256389, +2256573, +2260996, +2262694, +2262789, +2263046, +2263109, +2263206, +2263237, +2263268, +2263409, +2263560, +2263889, +2263965, +2263985, +2264005, +2264036, +2264157, +2265092, +2266630, +2266725, +2266918, +2266949, +2266982, +2267109, +2267174, +2267205, +2267268, +2267345, +2267364, +2267421, +2267656, +2267997, +2273284, +2274790, +2274885, +2275037, +2275078, +2275205, +2275270, +2275301, +2275377, +2276100, +2276229, +2276317, +2277380, +2278918, +2279013, +2279270, +2279333, +2279366, +2279397, +2279473, +2279556, +2279613, +2279944, +2280285, +2280465, +2280893, +2281476, +2282853, +2282886, +2282917, +2282950, +2283013, +2283206, +2283237, +2283268, +2283325, +2283528, +2283869, +2285572, +2286461, +2286501, +2286598, +2286661, +2286790, +2286821, +2287005, +2287112, +2287434, +2287505, +2287605, +2287645, +2293764, +2295174, +2295269, +2295558, +2295589, +2295665, +2295709, +2298880, +2299905, +2300936, +2301258, +2301565, +2301924, +2302205, +2302244, +2302301, +2302340, +2302621, +2302628, +2302717, +2302724, +2303494, +2303709, +2303718, +2303805, +2303845, +2303910, +2303941, +2303972, +2304006, +2304036, +2304070, +2304101, +2304145, +2304253, +2304520, +2304861, +2307076, +2307357, +2307396, +2308646, +2308741, +2308893, +2308933, +2308998, +2309125, +2309156, +2309201, +2309220, +2309254, +2309309, +2310148, +2310181, +2310500, +2311781, +2311974, +2312004, +2312037, +2312177, +2312421, +2312477, +2312708, +2312741, +2312934, +2312997, +2313092, +2314565, +2314982, +2315013, +2315089, +2315172, +2315217, +2315389, +2316292, +2318141, +2326532, +2326845, +2326852, +2328038, +2328069, +2328317, +2328325, +2328518, +2328549, +2328580, +2328625, +2328797, +2329096, +2329418, +2330045, +2330129, +2330180, +2331165, +2331205, +2331933, +2331942, +2331973, +2332198, +2332229, +2332294, +2332325, +2332413, +2334724, +2334973, +2334980, +2335069, +2335076, +2336293, +2336509, +2336581, +2336637, +2336645, +2336733, +2336741, +2336964, +2336997, +2337053, +2337288, +2337629, +2337796, +2338013, +2338020, +2338109, +2338116, +2339142, +2339325, +2339333, +2339421, +2339430, +2339493, +2339526, +2339557, +2339588, +2339645, +2339848, +2340189, +2350084, +2350693, +2350758, +2350833, +2350909, +2356740, +2356797, +2357258, +2357941, +2358195, +2358325, +2358877, +2359281, +2359300, +2388829, +2392073, +2395645, +2395665, +2395837, +2396164, +2402461, +2490372, +2524669, +2524698, +2524989, +2654212, +2672893, +2949124, +2967357, +2967556, +2968573, +2968584, +2968925, +2969041, +2969117, +2972164, +2973149, +2973189, +2973361, +2973405, +2973700, +2975237, +2975473, +2975637, +2975747, +2975889, +2975925, +2975965, +2976264, +2976605, +2976618, +2976861, +2976868, +2977565, +2977700, +2978333, +3000320, +3001345, +3002378, +3003121, +3003261, +3006468, +3008893, +3008997, +3009028, +3009062, +3010845, +3011045, +3011171, +3011613, +3013635, +3013713, +3013731, +3013765, +3013821, +3014150, +3014237, +3014660, +3211037, +3211268, +3250909, +3252228, +3252541, +3538948, +3548157, +3549700, +3549821, +3550340, +3550493, +3550724, +3563421, +3637252, +3640701, +3640836, +3641277, +3641348, +3641661, +3641860, +3642205, +3642261, +3642277, +3642353, +3642394, +3642525, +3801109, +3808989, +3809301, +3810557, +3810613, +3812518, +3812581, +3812693, +3812774, +3812986, +3813221, +3813493, +3813541, +3813781, +3814725, +3814869, +3816765, +3817493, +3819589, +3819701, +3819741, +3824650, +3825309, +3825685, +3828477, +3828746, +3829565, +3833856, +3834689, +3835520, +3836353, +3836605, +3836609, +3837184, +3838017, +3838848, +3838909, +3838912, +3839005, +3839040, +3839101, +3839136, +3839229, +3839264, +3839421, +3839424, +3839681, +3839837, +3839841, +3839901, +3839905, +3840157, +3840161, +3840512, +3841345, +3842176, +3842269, +3842272, +3842429, +3842464, +3842749, +3842752, +3843005, +3843009, +3843840, +3843933, +3843936, +3844093, +3844096, +3844285, +3844288, +3844349, +3844416, +3844669, +3844673, +3845504, +3846337, +3847168, +3848001, +3848832, +3849665, +3850496, +3851329, +3852160, +3852993, +3853824, +3854657, +3855581, +3855616, +3856434, +3856449, +3857266, +3857281, +3857472, +3858290, +3858305, +3859122, +3859137, +3859328, +3860146, +3860161, +3860978, +3860993, +3861184, +3862002, +3862017, +3862834, +3862849, +3863040, +3863858, +3863873, +3864690, +3864705, +3864896, +3864929, +3864989, +3865032, +3866645, +3883013, +3884789, +3884901, +3886517, +3886757, +3886805, +3887237, +3887285, +3887345, +3887517, +3887973, +3888157, +3888165, +3888669, +3932165, +3932413, +3932421, +3932989, +3933029, +3933277, +3933285, +3933373, +3933381, +3933565, +3940356, +3941821, +3941893, +3942115, +3942365, +3942408, +3942749, +3942852, +3942901, +3942941, +3954692, +3956101, +3956232, +3956573, +3956723, +3956765, +3997700, +4004029, +4004074, +4004357, +4004605, +4005888, +4006977, +4008069, +4008291, +4008349, +4008456, +4008797, +4008913, +4008989, +4034090, +4035989, +4036010, +4036115, +4036138, +4036285, +4038698, +4040149, +4040170, +4040669, +4046852, +4047005, +4047012, +4047901, +4047908, +4047997, +4048004, +4048061, +4048100, +4048157, +4048164, +4048509, +4048516, +4048669, +4048676, +4048733, +4048740, +4048797, +4048964, +4049021, +4049124, +4049181, +4049188, +4049245, +4049252, +4049309, +4049316, +4049437, +4049444, +4049533, +4049540, +4049597, +4049636, +4049693, +4049700, +4049757, +4049764, +4049821, +4049828, +4049885, +4049892, +4049949, +4049956, +4050045, +4050052, +4050109, +4050148, +4050301, +4050308, +4050557, +4050564, +4050717, +4050724, +4050877, +4050884, +4050941, +4050948, +4051293, +4051300, +4051869, +4052004, +4052125, +4052132, +4052317, +4052324, +4052893, +4054546, +4054621, +4063253, +4064669, +4064789, +4067997, +4068373, +4068861, +4068917, +4069405, +4069429, +4069917, +4069941, +4071133, +4071434, +4071861, +4077021, +4078805, +4079741, +4080149, +4081565, +4081685, +4081981, +4082197, +4082269, +4082709, +4082909, +4087829, +4095860, +4096021, +4119325, +4119573, +4119997, +4120085, +4120509, +4120597, +4124317, +4124693, +4127549, +4127765, +4128157, +4128789, +4129181, +4129301, +4131101, +4131349, +4131677, +4131861, +4133149, +4133397, +4134365, +4134421, +4134493, +4136981, +4140861, +4140885, +4143517, +4143541, +4147869, +4148245, +4148701, +4148757, +4148925, +4149013, +4149117, +4149269, +4149501, +4149781, +4150589, +4150805, +4151037, +4151317, +4151421, +4151829, +4152061, +4153365, +4158077, +4158101, +4159869, +4161032, +4161373, +4194308, +5561309, +5562372, +5695165, +5695492, +5702621, +5702660, +5887069, +5887492, +6126653, +6225924, +6243293, +6291460, +6449533, +29360186, +29360221, +29361178, +29364253, +29368325, +29376029, +31457308, +33554397, +33554460, +35651549, +35651613, +//--Autogenerated -- end of section automatically generated +}; + +constexpr int maxUnicode = 0x10ffff; +constexpr int maskCategory = 0x1F; + +} + +// Each element in catRanges is the start of a range of Unicode characters in +// one general category. +// The value is comprised of a 21-bit character value shifted 5 bits and a 5 bit +// category matching the CharacterCategory enumeration. +// Initial version has 3249 entries and adds about 13K to the executable. +// The array is in ascending order so can be searched using binary search. +// Therefore the average call takes log2(3249) = 12 comparisons. +// For speed, it may be useful to make a linear table for the common values, +// possibly for 0..0xff for most Western European text or 0..0xfff for most +// alphabetic languages. + +CharacterCategory CategoriseCharacter(int character) { + if (character < 0 || character > maxUnicode) + return ccCn; + const int baseValue = character * (maskCategory+1) + maskCategory; + const int *placeAfter = std::lower_bound(catRanges, std::end(catRanges), baseValue); + return static_cast(*(placeAfter-1) & maskCategory); +} + +// Implementation of character sets recommended for identifiers in Unicode Standard Annex #31. +// http://unicode.org/reports/tr31/ + +namespace { + +enum class OtherID { oidNone, oidStart, oidContinue }; + +// Some characters are treated as valid for identifiers even +// though most characters from their category are not. +// Values copied from http://www.unicode.org/Public/9.0.0/ucd/PropList.txt +OtherID OtherIDOfCharacter(int character) noexcept { + if ( + (character == 0x1885) || // MONGOLIAN LETTER ALI GALI BALUDA + (character == 0x1886) || // MONGOLIAN LETTER ALI GALI THREE BALUDA + (character == 0x2118) || // SCRIPT CAPITAL P + (character == 0x212E) || // ESTIMATED SYMBOL + (character == 0x309B) || // KATAKANA-HIRAGANA VOICED SOUND MARK + (character == 0x309C)) { // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + return OtherID::oidStart; + } else if ( + (character == 0x00B7) || // MIDDLE DOT + (character == 0x0387) || // GREEK ANO TELEIA + ((character >= 0x1369) && (character <= 0x1371)) || // ETHIOPIC DIGIT ONE..ETHIOPIC DIGIT NINE + (character == 0x19DA)) { // NEW TAI LUE THAM DIGIT ONE + return OtherID::oidContinue; + } else { + return OtherID::oidNone; + } +} + +// Determine if a character is in Ll|Lu|Lt|Lm|Lo|Nl|Mn|Mc|Nd|Pc and has +// Pattern_Syntax|Pattern_White_Space. +// As of Unicode 9, only VERTICAL TILDE which is in Lm and has Pattern_Syntax matches. +// Should really generate from PropList.txt a list of Pattern_Syntax and Pattern_White_Space. +constexpr bool IsIdPattern(int character) noexcept { + return character == 0x2E2F; +} + +bool OmitXidStart(int character) noexcept { + switch (character) { + case 0x037A: // GREEK YPOGEGRAMMENI + case 0x0E33: // THAI CHARACTER SARA AM + case 0x0EB3: // LAO VOWEL SIGN AM + case 0x309B: // KATAKANA-HIRAGANA VOICED SOUND MARK + case 0x309C: // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + case 0xFC5E: // ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM + case 0xFC5F: // ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM + case 0xFC60: // ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM + case 0xFC61: // ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM + case 0xFC62: // ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM + case 0xFC63: // ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM + case 0xFDFA: // ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM + case 0xFDFB: // ARABIC LIGATURE JALLAJALALOUHOU + case 0xFE70: // ARABIC FATHATAN ISOLATED FORM + case 0xFE72: // ARABIC DAMMATAN ISOLATED FORM + case 0xFE74: // ARABIC KASRATAN ISOLATED FORM + case 0xFE76: // ARABIC FATHA ISOLATED FORM + case 0xFE78: // ARABIC DAMMA ISOLATED FORM + case 0xFE7A: // ARABIC KASRA ISOLATED FORM + case 0xFE7C: // ARABIC SHADDA ISOLATED FORM + case 0xFE7E: // ARABIC SUKUN ISOLATED FORM + case 0xFF9E: // HALFWIDTH KATAKANA VOICED SOUND MARK + case 0xFF9F: // HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + return true; + default: + return false; + } +} + +bool OmitXidContinue(int character) noexcept { + switch (character) { + case 0x037A: // GREEK YPOGEGRAMMENI + case 0x309B: // KATAKANA-HIRAGANA VOICED SOUND MARK + case 0x309C: // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + case 0xFC5E: // ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM + case 0xFC5F: // ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM + case 0xFC60: // ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM + case 0xFC61: // ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM + case 0xFC62: // ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM + case 0xFC63: // ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM + case 0xFDFA: // ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM + case 0xFDFB: // ARABIC LIGATURE JALLAJALALOUHOU + case 0xFE70: // ARABIC FATHATAN ISOLATED FORM + case 0xFE72: // ARABIC DAMMATAN ISOLATED FORM + case 0xFE74: // ARABIC KASRATAN ISOLATED FORM + case 0xFE76: // ARABIC FATHA ISOLATED FORM + case 0xFE78: // ARABIC DAMMA ISOLATED FORM + case 0xFE7A: // ARABIC KASRA ISOLATED FORM + case 0xFE7C: // ARABIC SHADDA ISOLATED FORM + case 0xFE7E: // ARABIC SUKUN ISOLATED FORM + return true; + default: + return false; + } +} + +} + +// UAX #31 defines ID_Start as +// [[:L:][:Nl:][:Other_ID_Start:]--[:Pattern_Syntax:]--[:Pattern_White_Space:]] +bool IsIdStart(int character) { + if (IsIdPattern(character)) { + return false; + } + const OtherID oid = OtherIDOfCharacter(character); + if (oid == OtherID::oidStart) { + return true; + } + const CharacterCategory c = CategoriseCharacter(character); + return (c == ccLl || c == ccLu || c == ccLt || c == ccLm || c == ccLo + || c == ccNl); +} + +// UAX #31 defines ID_Continue as +// [[:ID_Start:][:Mn:][:Mc:][:Nd:][:Pc:][:Other_ID_Continue:]--[:Pattern_Syntax:]--[:Pattern_White_Space:]] +bool IsIdContinue(int character) { + if (IsIdPattern(character)) { + return false; + } + const OtherID oid = OtherIDOfCharacter(character); + if (oid != OtherID::oidNone) { + return true; + } + const CharacterCategory c = CategoriseCharacter(character); + return (c == ccLl || c == ccLu || c == ccLt || c == ccLm || c == ccLo + || c == ccNl || c == ccMn || c == ccMc || c == ccNd || c == ccPc); +} + +// XID_Start is ID_Start modified for Normalization Form KC in UAX #31 +bool IsXidStart(int character) { + if (OmitXidStart(character)) { + return false; + } else { + return IsIdStart(character); + } +} + +// XID_Continue is ID_Continue modified for Normalization Form KC in UAX #31 +bool IsXidContinue(int character) { + if (OmitXidContinue(character)) { + return false; + } else { + return IsIdContinue(character); + } +} + +CharacterCategoryMap::CharacterCategoryMap() { + Optimize(256); +} + +int CharacterCategoryMap::Size() const noexcept { + return static_cast(dense.size()); +} + +void CharacterCategoryMap::Optimize(int countCharacters) { + const int characters = std::clamp(countCharacters, 256, maxUnicode + 1); + dense.resize(characters); + + int end = 0; + int index = 0; + int current = catRanges[index]; + ++index; + do { + const int next = catRanges[index]; + const unsigned char category = current & maskCategory; + current >>= 5; + end = std::min(characters, next >> 5); + while (current < end) { + dense[current++] = category; + } + current = next; + ++index; + } while (characters > end); +} + +} diff --git a/scintilla/src/CharacterCategoryMap.h b/scintilla/src/CharacterCategoryMap.h new file mode 100644 index 0000000000..b3b03eb5a3 --- /dev/null +++ b/scintilla/src/CharacterCategoryMap.h @@ -0,0 +1,52 @@ +// Scintilla source code edit control +/** @file CharacterCategoryMap.h + ** Returns the Unicode general category of a character. + ** Similar code to Lexilla's lexilla/lexlib/CharacterCategory.h but renamed + ** to avoid problems with builds that statically include both Scintilla and Lexilla. + **/ +// Copyright 2013 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef CHARACTERCATEGORYMAP_H +#define CHARACTERCATEGORYMAP_H + +namespace Scintilla::Internal { + +enum CharacterCategory { + ccLu, ccLl, ccLt, ccLm, ccLo, + ccMn, ccMc, ccMe, + ccNd, ccNl, ccNo, + ccPc, ccPd, ccPs, ccPe, ccPi, ccPf, ccPo, + ccSm, ccSc, ccSk, ccSo, + ccZs, ccZl, ccZp, + ccCc, ccCf, ccCs, ccCo, ccCn +}; + +CharacterCategory CategoriseCharacter(int character); + +// Common definitions of allowable characters in identifiers from UAX #31. +bool IsIdStart(int character); +bool IsIdContinue(int character); +bool IsXidStart(int character); +bool IsXidContinue(int character); + +class CharacterCategoryMap { +private: + std::vector dense; +public: + CharacterCategoryMap(); + CharacterCategory CategoryFor(int character) const { + if (static_cast(character) < dense.size()) { + return static_cast(dense[character]); + } else { + // binary search through ranges + return CategoriseCharacter(character); + } + } + int Size() const noexcept; + void Optimize(int countCharacters); +}; + +} + +#endif diff --git a/scintilla/src/CharacterType.cxx b/scintilla/src/CharacterType.cxx new file mode 100644 index 0000000000..2991ac3c4e --- /dev/null +++ b/scintilla/src/CharacterType.cxx @@ -0,0 +1,51 @@ +// Scintilla source code edit control +/** @file CharacterType.cxx + ** Tests for character type and case-insensitive comparisons. + **/ +// Copyright 1998-2010 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include + +#include "CharacterType.h" + +using namespace Scintilla::Internal; + +namespace Scintilla::Internal { + +int CompareCaseInsensitive(const char *a, const char *b) noexcept { + while (*a && *b) { + if (*a != *b) { + const char upperA = MakeUpperCase(*a); + const char upperB = MakeUpperCase(*b); + if (upperA != upperB) + return upperA - upperB; + } + a++; + b++; + } + // Either *a or *b is nul + return *a - *b; +} + +int CompareNCaseInsensitive(const char *a, const char *b, size_t len) noexcept { + while (*a && *b && len) { + if (*a != *b) { + const char upperA = MakeUpperCase(*a); + const char upperB = MakeUpperCase(*b); + if (upperA != upperB) + return upperA - upperB; + } + a++; + b++; + len--; + } + if (len == 0) + return 0; + else + // Either *a or *b is nul + return *a - *b; +} + +} diff --git a/scintilla/src/CharacterType.h b/scintilla/src/CharacterType.h new file mode 100644 index 0000000000..dcef6aa782 --- /dev/null +++ b/scintilla/src/CharacterType.h @@ -0,0 +1,112 @@ +// Scintilla source code edit control +/** @file CharacterType.h + ** Tests for character type and case-insensitive comparisons. + **/ +// Copyright 2007 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef CHARACTERTYPE_H +#define CHARACTERTYPE_H + +namespace Scintilla::Internal { + +// Functions for classifying characters + +constexpr bool IsASpace(int ch) noexcept { + return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); +} + +constexpr bool IsASpaceOrTab(int ch) noexcept { + return (ch == ' ') || (ch == '\t'); +} + +constexpr bool IsADigit(int ch) noexcept { + return (ch >= '0') && (ch <= '9'); +} + +constexpr bool IsADigit(int ch, int base) noexcept { + if (base <= 10) { + return (ch >= '0') && (ch < '0' + base); + } else { + return ((ch >= '0') && (ch <= '9')) || + ((ch >= 'A') && (ch < 'A' + base - 10)) || + ((ch >= 'a') && (ch < 'a' + base - 10)); + } +} + +constexpr bool IsASCII(int ch) noexcept { + return (ch >= 0) && (ch < 0x80); +} + +constexpr bool IsLowerCase(int ch) noexcept { + return (ch >= 'a') && (ch <= 'z'); +} + +constexpr bool IsUpperCase(int ch) noexcept { + return (ch >= 'A') && (ch <= 'Z'); +} + +constexpr bool IsUpperOrLowerCase(int ch) noexcept { + return IsUpperCase(ch) || IsLowerCase(ch); +} + +constexpr bool IsAlphaNumeric(int ch) noexcept { + return + ((ch >= '0') && (ch <= '9')) || + ((ch >= 'a') && (ch <= 'z')) || + ((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 == '~') + return true; + return false; +} + +// Simple case functions for ASCII supersets. + +template +constexpr T MakeUpperCase(T ch) noexcept { + if (ch < 'a' || ch > 'z') + return ch; + else + return ch - 'a' + 'A'; +} + +template +constexpr T MakeLowerCase(T ch) noexcept { + if (ch < 'A' || ch > 'Z') + return ch; + else + return ch - 'A' + 'a'; +} + +int CompareCaseInsensitive(const char *a, const char *b) noexcept; +int CompareNCaseInsensitive(const char *a, const char *b, size_t len) noexcept; + +} + +#endif diff --git a/scintilla/src/ContractionState.cxx b/scintilla/src/ContractionState.cxx index 8897f3d957..199b3cb78e 100644 --- a/scintilla/src/ContractionState.cxx +++ b/scintilla/src/ContractionState.cxx @@ -10,11 +10,13 @@ #include #include +#include #include +#include #include #include -#include "Platform.h" +#include "Debugging.h" #include "Position.h" #include "UniqueString.h" @@ -24,7 +26,7 @@ #include "SparseVector.h" #include "ContractionState.h" -using namespace Scintilla; +using namespace Scintilla::Internal; namespace { @@ -100,11 +102,11 @@ ContractionState::~ContractionState() { template void ContractionState::EnsureData() { if (OneToOne()) { - visible = Sci::make_unique>(); - expanded = Sci::make_unique>(); - heights = Sci::make_unique>(); - foldDisplayTexts = Sci::make_unique>(); - displayLines = Sci::make_unique>(4); + visible = std::make_unique>(); + expanded = std::make_unique>(); + heights = std::make_unique>(); + foldDisplayTexts = std::make_unique>(); + displayLines = std::make_unique>(4); InsertLines(0, linesInDocument); } } @@ -408,13 +410,13 @@ void ContractionState::Check() const noexcept { } -namespace Scintilla { +namespace Scintilla::Internal { std::unique_ptr ContractionStateCreate(bool largeDocument) { if (largeDocument) - return Sci::make_unique>(); + return std::make_unique>(); else - return Sci::make_unique>(); + return std::make_unique>(); } } diff --git a/scintilla/src/ContractionState.h b/scintilla/src/ContractionState.h index b30d071b4c..55c390c556 100644 --- a/scintilla/src/ContractionState.h +++ b/scintilla/src/ContractionState.h @@ -8,7 +8,7 @@ #ifndef CONTRACTIONSTATE_H #define CONTRACTIONSTATE_H -namespace Scintilla { +namespace Scintilla::Internal { /** */ diff --git a/scintilla/src/DBCS.cxx b/scintilla/src/DBCS.cxx index 148c9818e8..e3ae3d75ff 100644 --- a/scintilla/src/DBCS.cxx +++ b/scintilla/src/DBCS.cxx @@ -7,9 +7,9 @@ #include "DBCS.h" -using namespace Scintilla; +using namespace Scintilla::Internal; -namespace Scintilla { +namespace Scintilla::Internal { bool DBCSIsLeadByte(int codePage, char ch) noexcept { // Byte ranges found in Wikipedia articles with relevant search strings in each case @@ -39,4 +39,16 @@ bool DBCSIsLeadByte(int codePage, char ch) noexcept { return false; } +bool IsDBCSValidSingleByte(int codePage, int ch) noexcept { + switch (codePage) { + case 932: + return ch == 0x80 + || (ch >= 0xA0 && ch <= 0xDF) + || (ch >= 0xFD); + + default: + return false; + } +} + } diff --git a/scintilla/src/DBCS.h b/scintilla/src/DBCS.h index 58659ee3ee..ceeb75929e 100644 --- a/scintilla/src/DBCS.h +++ b/scintilla/src/DBCS.h @@ -8,7 +8,7 @@ #ifndef DBCS_H #define DBCS_H -namespace Scintilla { +namespace Scintilla::Internal { constexpr bool IsDBCSCodePage(int codePage) noexcept { return codePage == 932 @@ -19,6 +19,7 @@ constexpr bool IsDBCSCodePage(int codePage) noexcept { } bool DBCSIsLeadByte(int codePage, char ch) noexcept; +bool IsDBCSValidSingleByte(int codePage, int ch) noexcept; } diff --git a/scintilla/src/Debugging.h b/scintilla/src/Debugging.h new file mode 100644 index 0000000000..5221ff8e34 --- /dev/null +++ b/scintilla/src/Debugging.h @@ -0,0 +1,44 @@ +// Scintilla source code edit control +/** @file Debugging.h + ** Assert and debug trace functions. + ** Implemented in each platform layer. + **/ +// Copyright 1998-2009 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef DEBUGGING_H +#define DEBUGGING_H + +namespace Scintilla::Internal { + +#if defined(__clang__) +# if __has_feature(attribute_analyzer_noreturn) +# define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) +# else +# define CLANG_ANALYZER_NORETURN +# endif +#else +# define CLANG_ANALYZER_NORETURN +#endif + +/** + * Platform namespace used to segregate debugging functions. + */ +namespace Platform { + +void DebugDisplay(const char *s) noexcept; +void DebugPrintf(const char *format, ...) noexcept; +bool ShowAssertionPopUps(bool assertionPopUps_) noexcept; +void Assert(const char *c, const char *file, int line) noexcept CLANG_ANALYZER_NORETURN; + +} + +#ifdef NDEBUG +#define PLATFORM_ASSERT(c) ((void)0) +#else +#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Internal::Platform::Assert(#c, __FILE__, __LINE__)) +#endif + +} + +#endif diff --git a/scintilla/src/Decoration.cxx b/scintilla/src/Decoration.cxx index 4bfff2d01f..77b2894b22 100644 --- a/scintilla/src/Decoration.cxx +++ b/scintilla/src/Decoration.cxx @@ -11,20 +11,23 @@ #include #include +#include #include +#include #include #include -#include "Platform.h" +#include "ScintillaTypes.h" + +#include "Debugging.h" -#include "Scintilla.h" #include "Position.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "Decoration.h" -using namespace Scintilla; +using namespace Scintilla::Internal; namespace { @@ -143,7 +146,7 @@ Decoration *DecorationList::DecorationFromIndicator(int indicator) noe template Decoration *DecorationList::Create(int indicator, Sci::Position length) { currentIndicator = indicator; - std::unique_ptr> decoNew = Sci::make_unique>(indicator); + std::unique_ptr> decoNew = std::make_unique>(indicator); decoNew->rs.InsertSpace(0, static_cast(length)); typename std::vector>>::iterator it = std::lower_bound( @@ -192,7 +195,7 @@ FillResult DecorationList::FillRange(Sci::Position position, // Converting result from POS to Sci::Position as callers not polymorphic. const FillResult frInPOS = current->rs.FillRange(static_cast(position), value, static_cast(fillLength)); const FillResult fr { frInPOS.changed, frInPOS.position, frInPOS.fillLength }; - if (current->Empty()) { + if (current->Empty()) { Delete(currentIndicator); } return fr; @@ -228,7 +231,7 @@ template void DecorationList::DeleteLexerDecorations() { decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), [](const std::unique_ptr> &deco) noexcept { - return deco->Indicator() < INDICATOR_CONTAINER ; + return deco->Indicator() < static_cast(Scintilla::IndicatorNumbers::Container); }), decorationList.end()); current = nullptr; SetView(); @@ -259,7 +262,7 @@ int DecorationList::AllOnFor(Sci::Position position) const noexcept { int mask = 0; for (const std::unique_ptr> &deco : decorationList) { if (deco->rs.ValueAt(static_cast(position))) { - if (deco->Indicator() < INDICATOR_IME) { + if (deco->Indicator() < static_cast(Scintilla::IndicatorNumbers::Ime)) { mask |= 1 << deco->Indicator(); } } @@ -296,20 +299,20 @@ Sci::Position DecorationList::End(int indicator, Sci::Position position) no } -namespace Scintilla { +namespace Scintilla::Internal { std::unique_ptr DecorationCreate(bool largeDocument, int indicator) { if (largeDocument) - return Sci::make_unique>(indicator); + return std::make_unique>(indicator); else - return Sci::make_unique>(indicator); + return std::make_unique>(indicator); } std::unique_ptr DecorationListCreate(bool largeDocument) { if (largeDocument) - return Sci::make_unique>(); + return std::make_unique>(); else - return Sci::make_unique>(); + return std::make_unique>(); } } diff --git a/scintilla/src/Decoration.h b/scintilla/src/Decoration.h index bab8e2500f..c8faafec92 100644 --- a/scintilla/src/Decoration.h +++ b/scintilla/src/Decoration.h @@ -7,7 +7,7 @@ #ifndef DECORATION_H #define DECORATION_H -namespace Scintilla { +namespace Scintilla::Internal { class IDecoration { public: diff --git a/scintilla/src/Document.cxx b/scintilla/src/Document.cxx index f4681a5eda..b5ec9a275d 100644 --- a/scintilla/src/Document.cxx +++ b/scintilla/src/Document.cxx @@ -14,8 +14,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -24,14 +26,14 @@ #include #endif -#include "Platform.h" - +#include "ScintillaTypes.h" #include "ILoader.h" #include "ILexer.h" -#include "Scintilla.h" -#include "CharacterSet.h" -#include "CharacterCategory.h" +#include "Debugging.h" + +#include "CharacterType.h" +#include "CharacterCategoryMap.h" #include "Position.h" #include "SplitVector.h" #include "Partitioning.h" @@ -47,6 +49,7 @@ #include "ElapsedPeriod.h" using namespace Scintilla; +using namespace Scintilla::Internal; void LexInterface::Colourise(Sci::Position start, Sci::Position end) { if (pdoc && instance && !performingStyle) { @@ -76,15 +79,11 @@ void LexInterface::Colourise(Sci::Position start, Sci::Position end) { } } -int LexInterface::LineEndTypesSupported() { +LineEndType LexInterface::LineEndTypesSupported() { if (instance) { - const int interfaceVersion = instance->Version(); - if (interfaceVersion >= lvSubStyles) { - ILexerWithSubStyles *ssinstance = static_cast(instance); - return ssinstance->LineEndTypesSupported(); - } + return static_cast(instance->LineEndTypesSupported()); } - return 0; + return LineEndType::Default; } ActionDuration::ActionDuration(double duration_, double minDuration_, double maxDuration_) noexcept : @@ -101,7 +100,7 @@ void ActionDuration::AddSample(size_t numberActions, double durationOfActions) n constexpr double alpha = 0.25; const double durationOne = durationOfActions / numberActions; - duration = Sci::clamp(alpha * durationOne + (1.0 - alpha) * duration, + duration = std::clamp(alpha * durationOne + (1.0 - alpha) * duration, minDuration, maxDuration); } @@ -109,17 +108,21 @@ double ActionDuration::Duration() const noexcept { return duration; } -Document::Document(int options) : - cb((options & SC_DOCUMENTOPTION_STYLES_NONE) == 0, (options & SC_DOCUMENTOPTION_TEXT_LARGE) != 0), - durationStyleOneLine(0.00001, 0.000001, 0.0001) { +size_t ActionDuration::ActionsInAllowedTime(double secondsAllowed) const noexcept { + return std::lround(secondsAllowed / Duration()); +} + +Document::Document(DocumentOption options) : + cb(!FlagSet(options, DocumentOption::StylesNone), FlagSet(options, DocumentOption::TextLarge)), + durationStyleOneByte(0.000001, 0.0000001, 0.00001) { refCount = 0; #ifdef _WIN32 - eolMode = SC_EOL_CRLF; + eolMode = EndOfLine::CrLf; #else - eolMode = SC_EOL_LF; + eolMode = EndOfLine::Lf; #endif - dbcsCodePage = SC_CP_UTF8; - lineEndBitSet = SC_LINE_END_TYPE_DEFAULT; + dbcsCodePage = CpUtf8; + lineEndBitSet = LineEndType::Default; endStyled = 0; styleClock = 0; enteredModification = 0; @@ -135,17 +138,17 @@ Document::Document(int options) : matchesValid = false; - perLineData[ldMarkers] = Sci::make_unique(); - perLineData[ldLevels] = Sci::make_unique(); - perLineData[ldState] = Sci::make_unique(); - perLineData[ldMargin] = Sci::make_unique(); - perLineData[ldAnnotation] = Sci::make_unique(); - perLineData[ldEOLAnnotation] = Sci::make_unique(); + perLineData[ldMarkers] = std::make_unique(); + perLineData[ldLevels] = std::make_unique(); + perLineData[ldState] = std::make_unique(); + perLineData[ldMargin] = std::make_unique(); + perLineData[ldAnnotation] = std::make_unique(); + perLineData[ldEOLAnnotation] = std::make_unique(); decorations = DecorationListCreate(IsLarge()); cb.SetPerLine(this); - cb.SetUTF8Substance(SC_CP_UTF8 == dbcsCodePage); + cb.SetUTF8Substance(CpUtf8 == dbcsCodePage); } Document::~Document() { @@ -220,11 +223,11 @@ LineAnnotation *Document::EOLAnnotations() const noexcept { return dynamic_cast(perLineData[ldEOLAnnotation].get()); } -int Document::LineEndTypesSupported() const { - if ((SC_CP_UTF8 == dbcsCodePage) && pli) +LineEndType Document::LineEndTypesSupported() const { + if ((CpUtf8 == dbcsCodePage) && pli) return pli->LineEndTypesSupported(); else - return 0; + return LineEndType::Default; } bool Document::SetDBCSCodePage(int dbcsCodePage_) { @@ -232,7 +235,7 @@ bool Document::SetDBCSCodePage(int dbcsCodePage_) { dbcsCodePage = dbcsCodePage_; SetCaseFolder(nullptr); cb.SetLineEndTypes(lineEndBitSet & LineEndTypesSupported()); - cb.SetUTF8Substance(SC_CP_UTF8 == dbcsCodePage); + cb.SetUTF8Substance(CpUtf8 == dbcsCodePage); ModifiedAt(0); // Need to restyle whole document return true; } else { @@ -240,10 +243,10 @@ bool Document::SetDBCSCodePage(int dbcsCodePage_) { } } -bool Document::SetLineEndTypesAllowed(int lineEndBitSet_) { +bool Document::SetLineEndTypesAllowed(LineEndType lineEndBitSet_) { if (lineEndBitSet != lineEndBitSet_) { lineEndBitSet = lineEndBitSet_; - const int lineEndBitSetActive = lineEndBitSet & LineEndTypesSupported(); + const LineEndType lineEndBitSetActive = lineEndBitSet & LineEndTypesSupported(); if (lineEndBitSetActive != cb.GetLineEndTypes()) { ModifiedAt(0); cb.SetLineEndTypes(lineEndBitSetActive); @@ -275,38 +278,38 @@ void Document::TentativeUndo() { for (int step = 0; step < steps; step++) { const Sci::Line prevLinesTotal = LinesTotal(); const Action &action = cb.GetUndoStep(); - if (action.at == removeAction) { + if (action.at == ActionType::remove) { NotifyModified(DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action)); - } else if (action.at == containerAction) { - DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO); + ModificationFlags::BeforeInsert | ModificationFlags::Undo, action)); + } else if (action.at == ActionType::container) { + DocModification dm(ModificationFlags::Container | ModificationFlags::Undo); dm.token = action.position; NotifyModified(dm); } else { NotifyModified(DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action)); + ModificationFlags::BeforeDelete | ModificationFlags::Undo, action)); } cb.PerformUndoStep(); - if (action.at != containerAction) { + if (action.at != ActionType::container) { ModifiedAt(action.position); } - int modFlags = SC_PERFORMED_UNDO; + ModificationFlags modFlags = ModificationFlags::Undo; // With undo, an insertion action becomes a deletion notification - if (action.at == removeAction) { - modFlags |= SC_MOD_INSERTTEXT; - } else if (action.at == insertAction) { - modFlags |= SC_MOD_DELETETEXT; + if (action.at == ActionType::remove) { + modFlags |= ModificationFlags::InsertText; + } else if (action.at == ActionType::insert) { + modFlags |= ModificationFlags::DeleteText; } if (steps > 1) - modFlags |= SC_MULTISTEPUNDOREDO; + modFlags |= ModificationFlags::MultiStepUndoRedo; const Sci::Line linesAdded = LinesTotal() - prevLinesTotal; if (linesAdded != 0) multiLine = true; if (step == steps - 1) { - modFlags |= SC_LASTSTEPINUNDOREDO; + modFlags |= ModificationFlags::LastStepInUndoRedo; if (multiLine) - modFlags |= SC_MULTILINEUNDOREDO; + modFlags |= ModificationFlags::MultilineUndoRedo; } NotifyModified(DocModification(modFlags, action.position, action.lenData, linesAdded, action.data.get())); @@ -333,7 +336,7 @@ Sci::Line Document::MarkerNext(Sci::Line lineStart, int mask) const noexcept { int Document::AddMark(Sci::Line line, int markerNum) { if (line >= 0 && line <= LinesTotal()) { const int prev = Markers()->AddMark(line, markerNum, LinesTotal()); - const DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, nullptr, line); + const DocModification mh(ModificationFlags::ChangeMarker, LineStart(line), 0, 0, nullptr, line); NotifyModified(mh); return prev; } else { @@ -350,19 +353,19 @@ void Document::AddMarkSet(Sci::Line line, int valueSet) { if (m & 1) Markers()->AddMark(line, i, LinesTotal()); } - const DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, nullptr, line); + const DocModification mh(ModificationFlags::ChangeMarker, LineStart(line), 0, 0, nullptr, line); NotifyModified(mh); } void Document::DeleteMark(Sci::Line line, int markerNum) { Markers()->DeleteMark(line, markerNum, false); - const DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, nullptr, line); + const DocModification mh(ModificationFlags::ChangeMarker, LineStart(line), 0, 0, nullptr, line); NotifyModified(mh); } void Document::DeleteMarkFromHandle(int markerHandle) { Markers()->DeleteMarkFromHandle(markerHandle); - DocModification mh(SC_MOD_CHANGEMARKER); + DocModification mh(ModificationFlags::ChangeMarker); mh.line = -1; NotifyModified(mh); } @@ -374,7 +377,7 @@ void Document::DeleteAllMarks(int markerNum) { someChanges = true; } if (someChanges) { - DocModification mh(SC_MOD_CHANGEMARKER); + DocModification mh(ModificationFlags::ChangeMarker); mh.line = -1; NotifyModified(mh); } @@ -405,7 +408,7 @@ Sci_Position SCI_METHOD Document::LineEnd(Sci_Position line) const { return LineStart(line + 1); } else { Sci::Position position = LineStart(line + 1); - if (SC_LINE_END_TYPE_UNICODE == cb.GetLineEndTypes()) { + if (LineEndType::Unicode == cb.GetLineEndTypes()) { const unsigned char bytes[] = { cb.UCharAt(position-3), cb.UCharAt(position-2), @@ -430,7 +433,7 @@ Sci_Position SCI_METHOD Document::LineEnd(Sci_Position line) const { void SCI_METHOD Document::SetErrorStatus(int status) { // Tell the watchers an error has occurred. for (const WatcherWithUserData &watcher : watchers) { - watcher.watcher->NotifyErrorOccurred(this, watcher.userData, status); + watcher.watcher->NotifyErrorOccurred(this, watcher.userData, static_cast(status)); } } @@ -468,21 +471,35 @@ Sci::Position Document::VCHomePosition(Sci::Position position) const { return startText; } -Sci::Position Document::IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept { +Sci::Position Document::IndexLineStart(Sci::Line line, LineCharacterIndexType lineCharacterIndex) const noexcept { return cb.IndexLineStart(line, lineCharacterIndex); } -Sci::Line Document::LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const noexcept { +Sci::Line Document::LineFromPositionIndex(Sci::Position pos, LineCharacterIndexType lineCharacterIndex) const noexcept { return cb.LineFromPositionIndex(pos, lineCharacterIndex); } +Sci::Line Document::LineFromPositionAfter(Sci::Line line, Sci::Position length) const noexcept { + const Sci::Position posAfter = cb.LineStart(line) + length; + if (posAfter >= LengthNoExcept()) { + return LinesTotal(); + } + const Sci::Line lineAfter = SciLineFromPosition(posAfter); + if (lineAfter > line) { + return lineAfter; + } else { + // Want to make some progress so return next line + return lineAfter + 1; + } +} + int SCI_METHOD Document::SetLevel(Sci_Position line, int level) { const int prev = Levels()->SetLevel(line, level, LinesTotal()); if (prev != level) { - DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER, + DocModification mh(ModificationFlags::ChangeFold | ModificationFlags::ChangeMarker, LineStart(line), 0, 0, nullptr, line); - mh.foldLevelNow = level; - mh.foldLevelPrev = prev; + mh.foldLevelNow = static_cast(level); + mh.foldLevelPrev = static_cast(prev); NotifyModified(mh); } return prev; @@ -492,35 +509,38 @@ int SCI_METHOD Document::GetLevel(Sci_Position line) const { return Levels()->GetLevel(line); } +FoldLevel Document::GetFoldLevel(Sci_Position line) const { + return static_cast(Levels()->GetLevel(line)); +} + void Document::ClearLevels() { Levels()->ClearLevels(); } -static bool IsSubordinate(int levelStart, int levelTry) noexcept { - if (levelTry & SC_FOLDLEVELWHITEFLAG) +static bool IsSubordinate(FoldLevel levelStart, FoldLevel levelTry) noexcept { + if (LevelIsWhitespace(levelTry)) return true; else return LevelNumber(levelStart) < LevelNumber(levelTry); } -Sci::Line Document::GetLastChild(Sci::Line lineParent, int level, Sci::Line lastLine) { - if (level == -1) - level = LevelNumber(GetLevel(lineParent)); +Sci::Line Document::GetLastChild(Sci::Line lineParent, std::optional level, Sci::Line lastLine) { + const FoldLevel levelStart = LevelNumberPart(level ? *level : GetFoldLevel(lineParent)); const Sci::Line maxLine = LinesTotal(); const Sci::Line lookLastLine = (lastLine != -1) ? std::min(LinesTotal() - 1, lastLine) : -1; Sci::Line lineMaxSubord = lineParent; while (lineMaxSubord < maxLine - 1) { EnsureStyledTo(LineStart(lineMaxSubord + 2)); - if (!IsSubordinate(level, GetLevel(lineMaxSubord + 1))) + if (!IsSubordinate(levelStart, GetFoldLevel(lineMaxSubord + 1))) break; - if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !(GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG)) + if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !LevelIsWhitespace(GetFoldLevel(lineMaxSubord))) break; lineMaxSubord++; } if (lineMaxSubord > lineParent) { - if (level > LevelNumber(GetLevel(lineMaxSubord + 1))) { + if (levelStart > LevelNumberPart(GetFoldLevel(lineMaxSubord + 1))) { // Have chewed up some whitespace that belongs to a parent so seek back - if (GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG) { + if (LevelIsWhitespace(GetFoldLevel(lineMaxSubord))) { lineMaxSubord--; } } @@ -529,16 +549,16 @@ Sci::Line Document::GetLastChild(Sci::Line lineParent, int level, Sci::Line last } Sci::Line Document::GetFoldParent(Sci::Line line) const { - const int level = LevelNumber(GetLevel(line)); + const FoldLevel level = LevelNumberPart(GetFoldLevel(line)); Sci::Line lineLook = line - 1; while ((lineLook > 0) && ( - (!(GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG)) || - (LevelNumber(GetLevel(lineLook)) >= level)) + (!LevelIsHeader(GetFoldLevel(lineLook))) || + (LevelNumberPart(GetFoldLevel(lineLook)) >= level)) ) { lineLook--; } - if ((GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG) && - (LevelNumber(GetLevel(lineLook)) < level)) { + if (LevelIsHeader(GetFoldLevel(lineLook)) && + (LevelNumberPart(GetFoldLevel(lineLook)) < level)) { return lineLook; } else { return -1; @@ -546,49 +566,49 @@ Sci::Line Document::GetFoldParent(Sci::Line line) const { } void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sci::Line line, Sci::Line lastLine) { - const int level = GetLevel(line); + const FoldLevel level = GetFoldLevel(line); const Sci::Line lookLastLine = std::max(line, lastLine) + 1; Sci::Line lookLine = line; - int lookLineLevel = level; - int lookLineLevelNum = LevelNumber(lookLineLevel); - while ((lookLine > 0) && ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || - ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum >= LevelNumber(GetLevel(lookLine + 1)))))) { - lookLineLevel = GetLevel(--lookLine); - lookLineLevelNum = LevelNumber(lookLineLevel); + FoldLevel lookLineLevel = level; + FoldLevel lookLineLevelNum = LevelNumberPart(lookLineLevel); + while ((lookLine > 0) && (LevelIsWhitespace(lookLineLevel) || + (LevelIsHeader(lookLineLevel) && (lookLineLevelNum >= LevelNumberPart(GetFoldLevel(lookLine + 1)))))) { + lookLineLevel = GetFoldLevel(--lookLine); + lookLineLevelNum = LevelNumberPart(lookLineLevel); } - Sci::Line beginFoldBlock = (lookLineLevel & SC_FOLDLEVELHEADERFLAG) ? lookLine : GetFoldParent(lookLine); + Sci::Line beginFoldBlock = LevelIsHeader(lookLineLevel) ? lookLine : GetFoldParent(lookLine); if (beginFoldBlock == -1) { highlightDelimiter.Clear(); return; } - Sci::Line endFoldBlock = GetLastChild(beginFoldBlock, -1, lookLastLine); + Sci::Line endFoldBlock = GetLastChild(beginFoldBlock, {}, lookLastLine); Sci::Line firstChangeableLineBefore = -1; if (endFoldBlock < line) { lookLine = beginFoldBlock - 1; - lookLineLevel = GetLevel(lookLine); - lookLineLevelNum = LevelNumber(lookLineLevel); - while ((lookLine >= 0) && (lookLineLevelNum >= SC_FOLDLEVELBASE)) { - if (lookLineLevel & SC_FOLDLEVELHEADERFLAG) { - if (GetLastChild(lookLine, -1, lookLastLine) == line) { + lookLineLevel = GetFoldLevel(lookLine); + lookLineLevelNum = LevelNumberPart(lookLineLevel); + while ((lookLine >= 0) && (lookLineLevelNum >= FoldLevel::Base)) { + if (LevelIsHeader(lookLineLevel)) { + if (GetLastChild(lookLine, {}, lookLastLine) == line) { beginFoldBlock = lookLine; endFoldBlock = line; firstChangeableLineBefore = line - 1; } } - if ((lookLine > 0) && (lookLineLevelNum == SC_FOLDLEVELBASE) && (LevelNumber(GetLevel(lookLine - 1)) > lookLineLevelNum)) + if ((lookLine > 0) && (lookLineLevelNum == FoldLevel::Base) && (LevelNumberPart(GetFoldLevel(lookLine - 1)) > lookLineLevelNum)) break; - lookLineLevel = GetLevel(--lookLine); - lookLineLevelNum = LevelNumber(lookLineLevel); + lookLineLevel = GetFoldLevel(--lookLine); + lookLineLevelNum = LevelNumberPart(lookLineLevel); } } if (firstChangeableLineBefore == -1) { - for (lookLine = line - 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = LevelNumber(lookLineLevel); + for (lookLine = line - 1, lookLineLevel = GetFoldLevel(lookLine), lookLineLevelNum = LevelNumberPart(lookLineLevel); lookLine >= beginFoldBlock; - lookLineLevel = GetLevel(--lookLine), lookLineLevelNum = LevelNumber(lookLineLevel)) { - if ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || (lookLineLevelNum > LevelNumber(level))) { + lookLineLevel = GetFoldLevel(--lookLine), lookLineLevelNum = LevelNumberPart(lookLineLevel)) { + if (LevelIsWhitespace(lookLineLevel) || (lookLineLevelNum > LevelNumberPart(level))) { firstChangeableLineBefore = lookLine; break; } @@ -598,10 +618,10 @@ void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sc firstChangeableLineBefore = beginFoldBlock - 1; Sci::Line firstChangeableLineAfter = -1; - for (lookLine = line + 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = LevelNumber(lookLineLevel); + for (lookLine = line + 1, lookLineLevel = GetFoldLevel(lookLine), lookLineLevelNum = LevelNumberPart(lookLineLevel); lookLine <= endFoldBlock; - lookLineLevel = GetLevel(++lookLine), lookLineLevelNum = LevelNumber(lookLineLevel)) { - if ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum < LevelNumber(GetLevel(lookLine + 1)))) { + lookLineLevel = GetFoldLevel(++lookLine), lookLineLevelNum = LevelNumberPart(lookLineLevel)) { + if (LevelIsHeader(lookLineLevel) && (lookLineLevelNum < LevelNumberPart(GetFoldLevel(lookLine + 1)))) { firstChangeableLineAfter = lookLine; break; } @@ -616,7 +636,7 @@ void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sc } Sci::Position Document::ClampPositionIntoDocument(Sci::Position pos) const noexcept { - return Sci::clamp(pos, static_cast(0), static_cast(Length())); + return std::clamp(pos, 0, LengthNoExcept()); } bool Document::IsCrLf(Sci::Position pos) const noexcept { @@ -640,7 +660,7 @@ int Document::LenChar(Sci::Position pos) const noexcept { // Common case: ASCII character return 1; } - if (SC_CP_UTF8 == dbcsCodePage) { + if (CpUtf8 == dbcsCodePage) { const int widthCharBytes = UTF8BytesOfLead[leadByte]; unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 }; for (int b = 1; b < widthCharBytes; b++) { @@ -654,7 +674,7 @@ int Document::LenChar(Sci::Position pos) const noexcept { return utf8status & UTF8MaskWidth; } } else { - if (IsDBCSLeadByteNoExcept(leadByte) && ((pos + 1) < LengthNoExcept())) { + if (IsDBCSLeadByteNoExcept(leadByte) && IsDBCSTrailByteNoExcept(cb.CharAt(pos + 1))) { return 2; } else { return 1; @@ -689,7 +709,7 @@ bool Document::InGoodUTF8(Sci::Position pos, Sci::Position &start, Sci::Position } } -// Normalise a position so that it is not halfway through a two byte character. +// Normalise a position so that it is not part way through a multi-byte character. // This can occur in two situations - // When lines are terminated with \r\n pairs which should be treated as one character. // When displaying DBCS text such as Japanese. @@ -711,7 +731,7 @@ Sci::Position Document::MovePositionOutsideChar(Sci::Position pos, Sci::Position } if (dbcsCodePage) { - if (SC_CP_UTF8 == dbcsCodePage) { + if (CpUtf8 == dbcsCodePage) { const unsigned char ch = cb.UCharAt(pos); // If ch is not a trail byte then pos is valid intercharacter position if (UTF8IsTrailByte(ch)) { @@ -740,7 +760,7 @@ Sci::Position Document::MovePositionOutsideChar(Sci::Position pos, Sci::Position // Check from known start of character. while (posCheck < pos) { - const int mbsize = IsDBCSLeadByteNoExcept(cb.CharAt(posCheck)) ? 2 : 1; + const int mbsize = IsDBCSDualByteAt(posCheck) ? 2 : 1; if (posCheck + mbsize == pos) { return pos; } else if (posCheck + mbsize > pos) { @@ -770,7 +790,7 @@ Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const noexc return cb.Length(); if (dbcsCodePage) { - if (SC_CP_UTF8 == dbcsCodePage) { + if (CpUtf8 == dbcsCodePage) { if (increment == 1) { // Simple forward movement case so can avoid some checks const unsigned char leadByte = cb.UCharAt(pos); @@ -805,7 +825,7 @@ Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const noexc } } else { if (moveDir > 0) { - const int mbsize = IsDBCSLeadByteNoExcept(cb.CharAt(pos)) ? 2 : 1; + const int mbsize = IsDBCSDualByteAt(pos) ? 2 : 1; pos += mbsize; if (pos > cb.Length()) pos = cb.Length(); @@ -818,8 +838,13 @@ Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const noexc if ((pos - 1) <= posStartLine) { return pos - 1; } else if (IsDBCSLeadByteNoExcept(cb.CharAt(pos - 1))) { - // Must actually be trail byte - return pos - 2; + // Should actually be trail byte + if (IsDBCSDualByteAt(pos - 2)) { + return pos - 2; + } else { + // Invalid byte pair so treat as one byte wide + return pos - 1; + } } else { // Otherwise, step back until a non-lead-byte is found. Sci::Position posTemp = pos - 1; @@ -828,7 +853,12 @@ Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const noexc // Now posTemp+1 must point to the beginning of a character, // so figure out whether we went back an even or an odd // number of bytes and go back 1 or 2 bytes, respectively. - return (pos - 1 - ((pos - posTemp) & 1)); + const Sci::Position widthLast = ((pos - posTemp) & 1) + 1; + if ((widthLast == 2) && (IsDBCSDualByteAt(pos - widthLast))) { + return pos - widthLast; + } + // Byte before pos may be valid character or may be an invalid second byte + return pos - 1; } } } @@ -859,7 +889,7 @@ Document::CharacterExtracted Document::CharacterAfter(Sci::Position position) co // Common case: ASCII character return CharacterExtracted(leadByte, 1); } - if (SC_CP_UTF8 == dbcsCodePage) { + if (CpUtf8 == dbcsCodePage) { const int widthCharBytes = UTF8BytesOfLead[leadByte]; unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 }; for (int b = 1; b Length())) - return INVALID_POSITION; + return Sci::invalidPosition; } return pos; } @@ -948,7 +980,7 @@ Sci::Position Document::GetRelativePositionUTF16(Sci::Position positionStart, Sc while (characterOffset != 0) { const Sci::Position posNext = NextPosition(pos, increment); if (posNext == pos) - return INVALID_POSITION; + return Sci::invalidPosition; if (std::abs(pos-posNext) > 3) // 4 byte character = 2*UTF16. characterOffset -= increment; pos = posNext; @@ -957,44 +989,38 @@ Sci::Position Document::GetRelativePositionUTF16(Sci::Position positionStart, Sc } else { pos = positionStart + characterOffset; if ((pos < 0) || (pos > LengthNoExcept())) - return INVALID_POSITION; + return Sci::invalidPosition; } return pos; } int SCI_METHOD Document::GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const { - int character; int bytesInCharacter = 1; const unsigned char leadByte = cb.UCharAt(position); - if (dbcsCodePage) { - if (SC_CP_UTF8 == dbcsCodePage) { - if (UTF8IsAscii(leadByte)) { - // Single byte character or invalid - character = leadByte; + int character = leadByte; + if (dbcsCodePage && !UTF8IsAscii(leadByte)) { + if (CpUtf8 == dbcsCodePage) { + const int widthCharBytes = UTF8BytesOfLead[leadByte]; + unsigned char charBytes[UTF8MaxBytes] = {leadByte,0,0,0}; + for (int b=1; b= 0xFE); - case 950: - // Big5 - return - ((lead >= 0x80) && (lead <= 0xA0)) || - (lead == 0xC8) || - (lead >= 0xFA); - case 1361: - // Korean Johab KS C-5601-1992 - return - ((lead >= 0x80) && (lead <= 0x83)) || - ((lead >= 0xD4) && (lead <= 0xD8)) || - (lead == 0xDF) || - (lead >= 0xFA); - } - return false; -} - -bool Document::IsDBCSTrailByteInvalid(char ch) const noexcept { +bool Document::IsDBCSTrailByteNoExcept(char ch) const noexcept { const unsigned char trail = ch; switch (dbcsCodePage) { case 932: // Shift_jis - return - (trail <= 0x3F) || - (trail == 0x7F) || - (trail >= 0xFD); + return (trail != 0x7F) && + ((trail >= 0x40) && (trail <= 0xFC)); case 936: // GBK - return - (trail <= 0x3F) || - (trail == 0x7F) || - (trail == 0xFF); + return (trail != 0x7F) && + ((trail >= 0x40) && (trail <= 0xFE)); case 949: // Korean Wansung KS C-5601-1987 return - (trail <= 0x40) || - ((trail >= 0x5B) && (trail <= 0x60)) || - ((trail >= 0x7B) && (trail <= 0x80)) || - (trail == 0xFF); + ((trail >= 0x41) && (trail <= 0x5A)) || + ((trail >= 0x61) && (trail <= 0x7A)) || + ((trail >= 0x81) && (trail <= 0xFE)); case 950: // Big5 return - (trail <= 0x3F) || - ((trail >= 0x7F) && (trail <= 0xA0)) || - (trail == 0xFF); + ((trail >= 0x40) && (trail <= 0x7E)) || + ((trail >= 0xA1) && (trail <= 0xFE)); case 1361: // Korean Johab KS C-5601-1992 return - (trail <= 0x30) || - (trail == 0x7F) || - (trail == 0x80) || - (trail == 0xFF); + ((trail >= 0x31) && (trail <= 0x7E)) || + ((trail >= 0x81) && (trail <= 0xFE)); } return false; } -int Document::DBCSDrawBytes(const char *text, int len) const noexcept { - if (len <= 1) { - return len; +int Document::DBCSDrawBytes(std::string_view text) const noexcept { + if (text.length() <= 1) { + return static_cast(text.length()); } if (IsDBCSLeadByteNoExcept(text[0])) { - return IsDBCSTrailByteInvalid(text[1]) ? 1 : 2; + return IsDBCSTrailByteNoExcept(text[1]) ? 2 : 1; } else { return 1; } } +bool Document::IsDBCSDualByteAt(Sci::Position pos) const noexcept { + return IsDBCSLeadByteNoExcept(cb.CharAt(pos)) + && IsDBCSTrailByteNoExcept(cb.CharAt(pos + 1)); +} + static constexpr bool IsSpaceOrTab(int ch) noexcept { return ch == ' ' || ch == '\t'; } @@ -1160,7 +1146,7 @@ int Document::SafeSegment(const char *text, int length, int lengthSegment) const } lastEncodingAllowedBreak = j; - if (dbcsCodePage == SC_CP_UTF8) { + if (dbcsCodePage == CpUtf8) { j += UTF8BytesOfLead[ch]; } else if (dbcsCodePage) { j += IsDBCSLeadByteNoExcept(ch) ? 2 : 1; @@ -1177,7 +1163,7 @@ int Document::SafeSegment(const char *text, int length, int lengthSegment) const } EncodingFamily Document::CodePageFamily() const noexcept { - if (SC_CP_UTF8 == dbcsCodePage) + if (CpUtf8 == dbcsCodePage) return EncodingFamily::unicode; else if (dbcsCodePage) return EncodingFamily::dbcs; @@ -1216,7 +1202,7 @@ bool Document::DeleteChars(Sci::Position pos, Sci::Position len) { if (!cb.IsReadOnly()) { NotifyModified( DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_USER, + ModificationFlags::BeforeDelete | ModificationFlags::User, pos, len, 0, 0)); const Sci::Line prevLinesTotal = LinesTotal(); @@ -1231,7 +1217,8 @@ bool Document::DeleteChars(Sci::Position pos, Sci::Position len) { ModifiedAt(pos-1); NotifyModified( DocModification( - SC_MOD_DELETETEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), + ModificationFlags::DeleteText | ModificationFlags::User | + (startSequence?ModificationFlags::StartAction:ModificationFlags::None), pos, len, LinesTotal() - prevLinesTotal, text)); } @@ -1259,7 +1246,7 @@ Sci::Position Document::InsertString(Sci::Position position, const char *s, Sci: insertion.clear(); NotifyModified( DocModification( - SC_MOD_INSERTCHECK, + ModificationFlags::InsertCheck, position, insertLength, 0, s)); if (insertionSet) { @@ -1268,7 +1255,7 @@ Sci::Position Document::InsertString(Sci::Position position, const char *s, Sci: } NotifyModified( DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_USER, + ModificationFlags::BeforeInsert | ModificationFlags::User, position, insertLength, 0, s)); const Sci::Line prevLinesTotal = LinesTotal(); @@ -1280,7 +1267,8 @@ Sci::Position Document::InsertString(Sci::Position position, const char *s, Sci: ModifiedAt(position); NotifyModified( DocModification( - SC_MOD_INSERTTEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), + ModificationFlags::InsertText | ModificationFlags::User | + (startSequence?ModificationFlags::StartAction:ModificationFlags::None), position, insertLength, LinesTotal() - prevLinesTotal, text)); if (insertionSet) { // Free memory as could be large @@ -1300,11 +1288,11 @@ int SCI_METHOD Document::AddData(const char *data, Sci_Position length) { const Sci::Position position = Length(); InsertString(position, data, length); } catch (std::bad_alloc &) { - return SC_STATUS_BADALLOC; + return static_cast(Status::BadAlloc); } catch (...) { - return SC_STATUS_FAILURE; + return static_cast(Status::Failure); } - return 0; + return static_cast(Status::Ok); } void * SCI_METHOD Document::ConvertToDocument() { @@ -1328,11 +1316,11 @@ Sci::Position Document::Undo() { for (int step = 0; step < steps; step++) { const Sci::Line prevLinesTotal = LinesTotal(); const Action &action = cb.GetUndoStep(); - if (action.at == removeAction) { + if (action.at == ActionType::remove) { NotifyModified(DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action)); - } else if (action.at == containerAction) { - DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO); + ModificationFlags::BeforeInsert | ModificationFlags::Undo, action)); + } else if (action.at == ActionType::container) { + DocModification dm(ModificationFlags::Container | ModificationFlags::Undo); dm.token = action.position; NotifyModified(dm); if (!action.mayCoalesce) { @@ -1343,19 +1331,19 @@ Sci::Position Document::Undo() { } } else { NotifyModified(DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action)); + ModificationFlags::BeforeDelete | ModificationFlags::Undo, action)); } cb.PerformUndoStep(); - if (action.at != containerAction) { + if (action.at != ActionType::container) { ModifiedAt(action.position); newPos = action.position; } - int modFlags = SC_PERFORMED_UNDO; + ModificationFlags modFlags = ModificationFlags::Undo; // With undo, an insertion action becomes a deletion notification - if (action.at == removeAction) { + if (action.at == ActionType::remove) { newPos += action.lenData; - modFlags |= SC_MOD_INSERTTEXT; + modFlags |= ModificationFlags::InsertText; if ((coalescedRemoveLen > 0) && (action.position == prevRemoveActionPos || action.position == (prevRemoveActionPos + prevRemoveActionLen))) { coalescedRemoveLen += action.lenData; @@ -1366,22 +1354,22 @@ Sci::Position Document::Undo() { } prevRemoveActionPos = action.position; prevRemoveActionLen = action.lenData; - } else if (action.at == insertAction) { - modFlags |= SC_MOD_DELETETEXT; + } else if (action.at == ActionType::insert) { + modFlags |= ModificationFlags::DeleteText; coalescedRemovePos = -1; coalescedRemoveLen = 0; prevRemoveActionPos = -1; prevRemoveActionLen = 0; } if (steps > 1) - modFlags |= SC_MULTISTEPUNDOREDO; + modFlags |= ModificationFlags::MultiStepUndoRedo; const Sci::Line linesAdded = LinesTotal() - prevLinesTotal; if (linesAdded != 0) multiLine = true; if (step == steps - 1) { - modFlags |= SC_LASTSTEPINUNDOREDO; + modFlags |= ModificationFlags::LastStepInUndoRedo; if (multiLine) - modFlags |= SC_MULTILINEUNDOREDO; + modFlags |= ModificationFlags::MultilineUndoRedo; } NotifyModified(DocModification(modFlags, action.position, action.lenData, linesAdded, action.data.get())); @@ -1408,39 +1396,39 @@ Sci::Position Document::Redo() { for (int step = 0; step < steps; step++) { const Sci::Line prevLinesTotal = LinesTotal(); const Action &action = cb.GetRedoStep(); - if (action.at == insertAction) { + if (action.at == ActionType::insert) { NotifyModified(DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action)); - } else if (action.at == containerAction) { - DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_REDO); + ModificationFlags::BeforeInsert | ModificationFlags::Redo, action)); + } else if (action.at == ActionType::container) { + DocModification dm(ModificationFlags::Container | ModificationFlags::Redo); dm.token = action.position; NotifyModified(dm); } else { NotifyModified(DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action)); + ModificationFlags::BeforeDelete | ModificationFlags::Redo, action)); } cb.PerformRedoStep(); - if (action.at != containerAction) { + if (action.at != ActionType::container) { ModifiedAt(action.position); newPos = action.position; } - int modFlags = SC_PERFORMED_REDO; - if (action.at == insertAction) { + ModificationFlags modFlags = ModificationFlags::Redo; + if (action.at == ActionType::insert) { newPos += action.lenData; - modFlags |= SC_MOD_INSERTTEXT; - } else if (action.at == removeAction) { - modFlags |= SC_MOD_DELETETEXT; + modFlags |= ModificationFlags::InsertText; + } else if (action.at == ActionType::remove) { + modFlags |= ModificationFlags::DeleteText; } if (steps > 1) - modFlags |= SC_MULTISTEPUNDOREDO; + modFlags |= ModificationFlags::MultiStepUndoRedo; const Sci::Line linesAdded = LinesTotal() - prevLinesTotal; if (linesAdded != 0) multiLine = true; if (step == steps - 1) { - modFlags |= SC_LASTSTEPINUNDOREDO; + modFlags |= ModificationFlags::LastStepInUndoRedo; if (multiLine) - modFlags |= SC_MULTILINEUNDOREDO; + modFlags |= ModificationFlags::MultilineUndoRedo; } NotifyModified( DocModification(modFlags, action.position, action.lenData, @@ -1629,15 +1617,15 @@ void Document::Indent(bool forwards, Sci::Line lineBottom, Sci::Line lineTop) { // Convert line endings for a piece of text to a particular mode. // Stop at len or when a NUL is found. -std::string Document::TransformLineEnds(const char *s, size_t len, int eolModeWanted) { +std::string Document::TransformLineEnds(const char *s, size_t len, EndOfLine eolModeWanted) { std::string dest; for (size_t i = 0; (i < len) && (s[i]); i++) { if (s[i] == '\n' || s[i] == '\r') { - if (eolModeWanted == SC_EOL_CR) { + if (eolModeWanted == EndOfLine::Cr) { dest.push_back('\r'); - } else if (eolModeWanted == SC_EOL_LF) { + } else if (eolModeWanted == EndOfLine::Lf) { dest.push_back('\n'); - } else { // eolModeWanted == SC_EOL_CRLF + } else { // eolModeWanted == EndOfLine::CrLf dest.push_back('\r'); dest.push_back('\n'); } @@ -1651,25 +1639,25 @@ std::string Document::TransformLineEnds(const char *s, size_t len, int eolModeWa return dest; } -void Document::ConvertLineEnds(int eolModeSet) { +void Document::ConvertLineEnds(EndOfLine eolModeSet) { UndoGroup ug(this); for (Sci::Position pos = 0; pos < Length(); pos++) { if (cb.CharAt(pos) == '\r') { if (cb.CharAt(pos + 1) == '\n') { // CRLF - if (eolModeSet == SC_EOL_CR) { + if (eolModeSet == EndOfLine::Cr) { DeleteChars(pos + 1, 1); // Delete the LF - } else if (eolModeSet == SC_EOL_LF) { + } else if (eolModeSet == EndOfLine::Lf) { DeleteChars(pos, 1); // Delete the CR } else { pos++; } } else { // CR - if (eolModeSet == SC_EOL_CRLF) { + if (eolModeSet == EndOfLine::CrLf) { pos += InsertString(pos + 1, "\n", 1); // Insert LF - } else if (eolModeSet == SC_EOL_LF) { + } else if (eolModeSet == EndOfLine::Lf) { pos += InsertString(pos, "\n", 1); // Insert LF DeleteChars(pos, 1); // Delete CR pos--; @@ -1677,9 +1665,9 @@ void Document::ConvertLineEnds(int eolModeSet) { } } else if (cb.CharAt(pos) == '\n') { // LF - if (eolModeSet == SC_EOL_CRLF) { + if (eolModeSet == EndOfLine::CrLf) { pos += InsertString(pos, "\r", 1); // Insert CR - } else if (eolModeSet == SC_EOL_CR) { + } else if (eolModeSet == EndOfLine::Cr) { pos += InsertString(pos, "\r", 1); // Insert CR DeleteChars(pos, 1); // Delete LF pos--; @@ -1689,9 +1677,9 @@ void Document::ConvertLineEnds(int eolModeSet) { } -int Document::Options() const noexcept { - return (IsLarge() ? SC_DOCUMENTOPTION_TEXT_LARGE : 0) | - (cb.HasStyles() ? 0 : SC_DOCUMENTOPTION_STYLES_NONE); +DocumentOption Document::Options() const noexcept { + return (IsLarge() ? DocumentOption::TextLarge : DocumentOption::Default) | + (cb.HasStyles() ? DocumentOption::Default : DocumentOption::StylesNone); } bool Document::IsWhiteLine(Sci::Line line) const { @@ -1733,9 +1721,9 @@ Sci::Position Document::ParaDown(Sci::Position pos) const { return LineEnd(line-1); } -CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { - if (dbcsCodePage && (!UTF8IsAscii(ch))) { - if (SC_CP_UTF8 == dbcsCodePage) { +CharacterClass Document::WordCharacterClass(unsigned int ch) const { + if (dbcsCodePage && (ch >= 0x80)) { + if (CpUtf8 == dbcsCodePage) { // Use hard coded Unicode class const CharacterCategory cc = charMap.CategoryFor(ch); switch (cc) { @@ -1743,7 +1731,7 @@ CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { // Separator, Line/Paragraph case ccZl: case ccZp: - return CharClassify::ccNewLine; + return CharacterClass::newLine; // Separator, Space case ccZs: @@ -1753,7 +1741,7 @@ CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { case ccCs: case ccCo: case ccCn: - return CharClassify::ccSpace; + return CharacterClass::space; // Letter case ccLu: @@ -1769,7 +1757,7 @@ CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { case ccMn: case ccMc: case ccMe: - return CharClassify::ccWord; + return CharacterClass::word; // Punctuation case ccPc: @@ -1784,12 +1772,12 @@ CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { case ccSc: case ccSk: case ccSo: - return CharClassify::ccPunctuation; + return CharacterClass::punctuation; } } else { // Asian DBCS - return CharClassify::ccWord; + return CharacterClass::word; } } return charClass.GetClass(static_cast(ch)); @@ -1800,7 +1788,7 @@ CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { * Finds the start of word at pos when delta < 0 or the end of the word when delta >= 0. */ Sci::Position Document::ExtendWordSelect(Sci::Position pos, int delta, bool onlyWordCharacters) const { - CharClassify::cc ccStart = CharClassify::ccWord; + CharacterClass ccStart = CharacterClass::word; if (delta < 0) { if (!onlyWordCharacters) { const CharacterExtracted ce = CharacterBefore(pos); @@ -1838,13 +1826,13 @@ Sci::Position Document::NextWordStart(Sci::Position pos, int delta) const { if (delta < 0) { while (pos > 0) { const CharacterExtracted ce = CharacterBefore(pos); - if (WordCharacterClass(ce.character) != CharClassify::ccSpace) + if (WordCharacterClass(ce.character) != CharacterClass::space) break; pos -= ce.widthBytes; } if (pos > 0) { CharacterExtracted ce = CharacterBefore(pos); - const CharClassify::cc ccStart = WordCharacterClass(ce.character); + const CharacterClass ccStart = WordCharacterClass(ce.character); while (pos > 0) { ce = CharacterBefore(pos); if (WordCharacterClass(ce.character) != ccStart) @@ -1854,7 +1842,7 @@ Sci::Position Document::NextWordStart(Sci::Position pos, int delta) const { } } else { CharacterExtracted ce = CharacterAfter(pos); - const CharClassify::cc ccStart = WordCharacterClass(ce.character); + const CharacterClass ccStart = WordCharacterClass(ce.character); while (pos < LengthNoExcept()) { ce = CharacterAfter(pos); if (WordCharacterClass(ce.character) != ccStart) @@ -1863,7 +1851,7 @@ Sci::Position Document::NextWordStart(Sci::Position pos, int delta) const { } while (pos < LengthNoExcept()) { ce = CharacterAfter(pos); - if (WordCharacterClass(ce.character) != CharClassify::ccSpace) + if (WordCharacterClass(ce.character) != CharacterClass::space) break; pos += ce.widthBytes; } @@ -1882,8 +1870,8 @@ Sci::Position Document::NextWordEnd(Sci::Position pos, int delta) const { if (delta < 0) { if (pos > 0) { CharacterExtracted ce = CharacterBefore(pos); - const CharClassify::cc ccStart = WordCharacterClass(ce.character); - if (ccStart != CharClassify::ccSpace) { + const CharacterClass ccStart = WordCharacterClass(ce.character); + if (ccStart != CharacterClass::space) { while (pos > 0) { ce = CharacterBefore(pos); if (WordCharacterClass(ce.character) != ccStart) @@ -1893,7 +1881,7 @@ Sci::Position Document::NextWordEnd(Sci::Position pos, int delta) const { } while (pos > 0) { ce = CharacterBefore(pos); - if (WordCharacterClass(ce.character) != CharClassify::ccSpace) + if (WordCharacterClass(ce.character) != CharacterClass::space) break; pos -= ce.widthBytes; } @@ -1901,13 +1889,13 @@ Sci::Position Document::NextWordEnd(Sci::Position pos, int delta) const { } else { while (pos < LengthNoExcept()) { const CharacterExtracted ce = CharacterAfter(pos); - if (WordCharacterClass(ce.character) != CharClassify::ccSpace) + if (WordCharacterClass(ce.character) != CharacterClass::space) break; pos += ce.widthBytes; } if (pos < LengthNoExcept()) { CharacterExtracted ce = CharacterAfter(pos); - const CharClassify::cc ccStart = WordCharacterClass(ce.character); + const CharacterClass ccStart = WordCharacterClass(ce.character); while (pos < LengthNoExcept()) { ce = CharacterAfter(pos); if (WordCharacterClass(ce.character) != ccStart) @@ -1919,6 +1907,15 @@ Sci::Position Document::NextWordEnd(Sci::Position pos, int delta) const { return pos; } +namespace { + +constexpr bool IsWordEdge(CharacterClass cc, CharacterClass ccNext) noexcept { + return (cc != ccNext) && + (cc == CharacterClass::word || cc == CharacterClass::punctuation); +} + +} + /** * Check that the character at the given position is a word or punctuation character and that * the previous character is of a different character class. @@ -1926,31 +1923,29 @@ Sci::Position Document::NextWordEnd(Sci::Position pos, int delta) const { bool Document::IsWordStartAt(Sci::Position pos) const { if (pos >= LengthNoExcept()) return false; - if (pos > 0) { + if (pos >= 0) { const CharacterExtracted cePos = CharacterAfter(pos); - const CharClassify::cc ccPos = WordCharacterClass(cePos.character); - const CharacterExtracted cePrev = CharacterBefore(pos); - const CharClassify::cc ccPrev = WordCharacterClass(cePrev.character); - return (ccPos == CharClassify::ccWord || ccPos == CharClassify::ccPunctuation) && - (ccPos != ccPrev); + // At start of document, treat as if space before so can be word start + const CharacterExtracted cePrev = (pos > 0) ? + CharacterBefore(pos) : CharacterExtracted(' ', 1); + return IsWordEdge(WordCharacterClass(cePos.character), WordCharacterClass(cePrev.character)); } return true; } /** - * Check that the character at the given position is a word or punctuation character and that + * Check that the character before the given position is a word or punctuation character and that * the next character is of a different character class. */ bool Document::IsWordEndAt(Sci::Position pos) const { if (pos <= 0) return false; - if (pos < LengthNoExcept()) { - const CharacterExtracted cePos = CharacterAfter(pos); - const CharClassify::cc ccPos = WordCharacterClass(cePos.character); + if (pos <= LengthNoExcept()) { + // At end of document, treat as if space after so can be word end + const CharacterExtracted cePos = (pos < LengthNoExcept()) ? + CharacterAfter(pos) : CharacterExtracted(' ', 1); const CharacterExtracted cePrev = CharacterBefore(pos); - const CharClassify::cc ccPrev = WordCharacterClass(cePrev.character); - return (ccPrev == CharClassify::ccWord || ccPrev == CharClassify::ccPunctuation) && - (ccPrev != ccPos); + return IsWordEdge(WordCharacterClass(cePrev.character), WordCharacterClass(cePos.character)); } return true; } @@ -1973,8 +1968,8 @@ bool Document::HasCaseFolder() const noexcept { return pcf != nullptr; } -void Document::SetCaseFolder(CaseFolder *pcf_) noexcept { - pcf.reset(pcf_); +void Document::SetCaseFolder(std::unique_ptr pcf_) noexcept { + pcf = std::move(pcf_); } Document::CharacterExtracted Document::ExtractCharacter(Sci::Position position) const noexcept { @@ -1996,19 +1991,53 @@ Document::CharacterExtracted Document::ExtractCharacter(Sci::Position position) } } +namespace { + +// Equivalent of memchr over the split view +ptrdiff_t SplitFindChar(const SplitView &view, size_t start, size_t length, int ch) noexcept { + size_t range1Length = 0; + if (start < view.length1) { + range1Length = std::min(length, view.length1 - start); + const char *match = static_cast(memchr(view.segment1 + start, ch, range1Length)); + if (match) { + return match - view.segment1; + } + start += range1Length; + } + const char *match2 = static_cast(memchr(view.segment2 + start, ch, length - range1Length)); + if (match2) { + return match2 - view.segment2; + } + return -1; +} + +// Equivalent of memcmp over the split view +// This does not call memcmp as search texts are commonly too short to overcome the +// call overhead. +bool SplitMatch(const SplitView &view, size_t start, std::string_view text) noexcept { + for (size_t i = 0; i < text.length(); i++) { + if (view.CharAt(i + start) != text[i]) { + return false; + } + } + return true; +} + +} + /** * Find text in document, supporting both forward and backward * searches (just pass minPos > maxPos to do a backward search) * Has not been tested with backwards DBCS searches yet. */ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, const char *search, - int flags, Sci::Position *length) { + FindOption flags, Sci::Position *length) { if (*length <= 0) return minPos; - const bool caseSensitive = (flags & SCFIND_MATCHCASE) != 0; - const bool word = (flags & SCFIND_WHOLEWORD) != 0; - const bool wordStart = (flags & SCFIND_WORDSTART) != 0; - const bool regExp = (flags & SCFIND_REGEXP) != 0; + const bool caseSensitive = FlagSet(flags, FindOption::MatchCase); + const bool word = FlagSet(flags, FindOption::WholeWord); + const bool wordStart = FlagSet(flags, FindOption::WordStart); + const bool regExp = FlagSet(flags, FindOption::RegExp); if (regExp) { if (!regex) regex = std::unique_ptr(CreateRegexSearch(&charClass)); @@ -2032,60 +2061,98 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con // Back all of a character pos = NextPosition(pos, increment); } + const SplitView cbView = cb.AllView(); if (caseSensitive) { const Sci::Position endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos; - const char charStartSearch = search[0]; - while (forward ? (pos < endSearch) : (pos >= endSearch)) { - if (CharAt(pos) == charStartSearch) { - bool found = (pos + lengthFind) <= limitPos; - for (int indexSearch = 1; (indexSearch < lengthFind) && found; indexSearch++) { - found = CharAt(pos + indexSearch) == search[indexSearch]; + const unsigned char charStartSearch = search[0]; + if (forward && ((0 == dbcsCodePage) || (CpUtf8 == dbcsCodePage && !UTF8IsTrailByte(charStartSearch)))) { + // This is a fast case where there is no need to test byte values to iterate + // so becomes the equivalent of a memchr+memcmp loop. + // UTF-8 search will not be self-synchronizing when starts with trail byte + const std::string_view suffix(search + 1, lengthFind - 1); + while (pos < endSearch) { + pos = SplitFindChar(cbView, pos, limitPos - pos, charStartSearch); + if (pos < 0) { + break; } - if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { + if (SplitMatch(cbView, pos + 1, suffix) && MatchesWordOptions(word, wordStart, pos, lengthFind)) { return pos; } + pos++; + } + } else { + while (forward ? (pos < endSearch) : (pos >= endSearch)) { + const unsigned char leadByte = cbView.CharAt(pos); + if (leadByte == charStartSearch) { + bool found = (pos + lengthFind) <= limitPos; + // SplitMatch could be called here but it is slower with g++ -O2 + for (int indexSearch = 1; (indexSearch < lengthFind) && found; indexSearch++) { + found = cbView.CharAt(pos + indexSearch) == search[indexSearch]; + } + if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { + return pos; + } + } + if (forward && UTF8IsAscii(leadByte)) { + pos++; + } else { + if (dbcsCodePage) { + if (!NextCharacter(pos, increment)) { + break; + } + } else { + pos += increment; + } + } } - if (!NextCharacter(pos, increment)) - break; } - } else if (SC_CP_UTF8 == dbcsCodePage) { + } else if (CpUtf8 == dbcsCodePage) { constexpr size_t maxFoldingExpansion = 4; std::vector searchThing((lengthFind+1) * UTF8MaxBytes * maxFoldingExpansion + 1); const size_t lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); - char bytes[UTF8MaxBytes + 1] = ""; - char folded[UTF8MaxBytes * maxFoldingExpansion + 1] = ""; while (forward ? (pos < endPos) : (pos >= endPos)) { int widthFirstCharacter = 0; Sci::Position posIndexDocument = pos; size_t indexSearch = 0; bool characterMatches = true; for (;;) { - const unsigned char leadByte = cb.UCharAt(posIndexDocument); - bytes[0] = leadByte; + const unsigned char leadByte = cbView.CharAt(posIndexDocument); + char bytes[UTF8MaxBytes + 1]; int widthChar = 1; if (!UTF8IsAscii(leadByte)) { const int widthCharBytes = UTF8BytesOfLead[leadByte]; + bytes[0] = leadByte; for (int b=1; b(bytes), widthCharBytes) & UTF8MaskWidth; } - if (!widthFirstCharacter) + if (!widthFirstCharacter) { widthFirstCharacter = widthChar; - if ((posIndexDocument + widthChar) > limitPos) + } + if ((posIndexDocument + widthChar) > limitPos) { break; - const size_t lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar); - // memcmp may examine lenFlat bytes in both arguments so assert it doesn't read past end of searchThing - assert((indexSearch + lenFlat) <= searchThing.size()); - // Does folded match the buffer - characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); - if (!characterMatches) + } + size_t lenFlat = 1; + if (widthChar == 1) { + characterMatches = searchThing[indexSearch] == MakeLowerCase(leadByte); + } else { + char folded[UTF8MaxBytes * maxFoldingExpansion + 1]; + lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar); + // memcmp may examine lenFlat bytes in both arguments so assert it doesn't read past end of searchThing + assert((indexSearch + lenFlat) <= searchThing.size()); + // Does folded match the buffer + characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); + } + if (!characterMatches) { break; + } posIndexDocument += widthChar; indexSearch += lenFlat; - if (indexSearch >= lenSearch) + if (indexSearch >= lenSearch) { break; + } } if (characterMatches && (indexSearch == lenSearch)) { if (MatchesWordOptions(word, wordStart, pos, posIndexDocument - pos)) { @@ -2096,8 +2163,9 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con if (forward) { pos += widthFirstCharacter; } else { - if (!NextCharacter(pos, increment)) + if (!NextCharacter(pos, increment)) { break; + } } } } else if (dbcsCodePage) { @@ -2106,25 +2174,37 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con std::vector searchThing((lengthFind+1) * maxBytesCharacter * maxFoldingExpansion + 1); const size_t lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); while (forward ? (pos < endPos) : (pos >= endPos)) { + int widthFirstCharacter = 0; Sci::Position indexDocument = 0; size_t indexSearch = 0; bool characterMatches = true; - while (characterMatches && - ((pos + indexDocument) < limitPos) && + while (((pos + indexDocument) < limitPos) && (indexSearch < lenSearch)) { - char bytes[maxBytesCharacter + 1]; - bytes[0] = cb.CharAt(pos + indexDocument); - const Sci::Position widthChar = IsDBCSLeadByteNoExcept(bytes[0]) ? 2 : 1; - if (widthChar == 2) - bytes[1] = cb.CharAt(pos + indexDocument + 1); - if ((pos + indexDocument + widthChar) > limitPos) + const unsigned char leadByte = cbView.CharAt(pos + indexDocument); + const int widthChar = (!UTF8IsAscii(leadByte) && IsDBCSLeadByteNoExcept(leadByte)) ? 2 : 1; + if (!widthFirstCharacter) { + widthFirstCharacter = widthChar; + } + if ((pos + indexDocument + widthChar) > limitPos) { break; - char folded[maxBytesCharacter * maxFoldingExpansion + 1]; - const size_t lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar); - // memcmp may examine lenFlat bytes in both arguments so assert it doesn't read past end of searchThing - assert((indexSearch + lenFlat) <= searchThing.size()); - // Does folded match the buffer - characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); + } + size_t lenFlat = 1; + if (widthChar == 1) { + characterMatches = searchThing[indexSearch] == MakeLowerCase(leadByte); + } else { + char bytes[maxBytesCharacter + 1]; + bytes[0] = leadByte; + bytes[1] = cbView.CharAt(pos + indexDocument + 1); + char folded[maxBytesCharacter * maxFoldingExpansion + 1]; + lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar); + // memcmp may examine lenFlat bytes in both arguments so assert it doesn't read past end of searchThing + assert((indexSearch + lenFlat) <= searchThing.size()); + // Does folded match the buffer + characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); + } + if (!characterMatches) { + break; + } indexDocument += widthChar; indexSearch += lenFlat; } @@ -2134,8 +2214,13 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con return pos; } } - if (!NextCharacter(pos, increment)) - break; + if (forward) { + pos += widthFirstCharacter; + } else { + if (!NextCharacter(pos, increment)) { + break; + } + } } } else { const Sci::Position endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos; @@ -2144,16 +2229,20 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con while (forward ? (pos < endSearch) : (pos >= endSearch)) { bool found = (pos + lengthFind) <= limitPos; for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) { - const char ch = CharAt(pos + indexSearch); - char folded[2]; - pcf->Fold(folded, sizeof(folded), &ch, 1); - found = folded[0] == searchThing[indexSearch]; + const char ch = cbView.CharAt(pos + indexSearch); + const char chTest = searchThing[indexSearch]; + if (UTF8IsAscii(ch)) { + found = chTest == MakeLowerCase(ch); + } else { + char folded[2]; + pcf->Fold(folded, sizeof(folded), &ch, 1); + found = folded[0] == chTest; + } } if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { return pos; } - if (!NextCharacter(pos, increment)) - break; + pos += increment; } } } @@ -2168,15 +2257,15 @@ const char *Document::SubstituteByPosition(const char *text, Sci::Position *leng return nullptr; } -int Document::LineCharacterIndex() const noexcept { +LineCharacterIndexType Document::LineCharacterIndex() const noexcept { return cb.LineCharacterIndex(); } -void Document::AllocateLineCharacterIndex(int lineCharacterIndex) { +void Document::AllocateLineCharacterIndex(LineCharacterIndexType lineCharacterIndex) { return cb.AllocateLineCharacterIndex(lineCharacterIndex); } -void Document::ReleaseLineCharacterIndex(int lineCharacterIndex) { +void Document::ReleaseLineCharacterIndex(LineCharacterIndexType lineCharacterIndex) { return cb.ReleaseLineCharacterIndex(lineCharacterIndex); } @@ -2184,15 +2273,19 @@ Sci::Line Document::LinesTotal() const noexcept { return cb.Lines(); } +void Document::AllocateLines(Sci::Line lines) { + cb.AllocateLines(lines); +} + void Document::SetDefaultCharClasses(bool includeWordClass) { charClass.SetDefaultCharClasses(includeWordClass); } -void Document::SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass) { +void Document::SetCharClasses(const unsigned char *chars, CharacterClass newCharClass) { charClass.SetCharClasses(chars, newCharClass); } -int Document::GetCharsOfClass(CharClassify::cc characterClass, unsigned char *buffer) const { +int Document::GetCharsOfClass(CharacterClass characterClass, unsigned char *buffer) const { return charClass.GetCharsOfClass(characterClass, buffer); } @@ -2204,7 +2297,7 @@ int Document::CharacterCategoryOptimization() const noexcept { return charMap.Size(); } -void SCI_METHOD Document::StartStyling(Sci_Position position, char) { +void SCI_METHOD Document::StartStyling(Sci_Position position) { endStyled = position; } @@ -2215,7 +2308,7 @@ bool SCI_METHOD Document::SetStyleFor(Sci_Position length, char style) { enteredStyling++; const Sci::Position prevEndStyled = endStyled; if (cb.SetStyleFor(endStyled, length, style)) { - const DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER, + const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User, prevEndStyled, length); NotifyModified(mh); } @@ -2244,7 +2337,7 @@ bool SCI_METHOD Document::SetStyles(Sci_Position length, const char *styles) { } } if (didChange) { - const DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER, + const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User, startMod, endMod - startMod + 1); NotifyModified(mh); } @@ -2271,11 +2364,10 @@ void Document::EnsureStyledTo(Sci::Position pos) { } void Document::StyleToAdjustingLineDuration(Sci::Position pos) { - const Sci::Line lineFirst = SciLineFromPosition(GetEndStyled()); + const Sci::Position stylingStart = GetEndStyled(); ElapsedPeriod epStyling; EnsureStyledTo(pos); - const Sci::Line lineLast = SciLineFromPosition(GetEndStyled()); - durationStyleOneLine.AddSample(lineLast - lineFirst, epStyling.Duration()); + durationStyleOneByte.AddSample(pos - stylingStart, epStyling.Duration()); } void Document::LexerChanged() { @@ -2296,7 +2388,7 @@ void Document::SetLexInterface(std::unique_ptr pLexInterface) noex int SCI_METHOD Document::SetLineState(Sci_Position line, int state) { const int statePrevious = States()->SetLineState(line, state); if (state != statePrevious) { - const DocModification mh(SC_MOD_CHANGELINESTATE, LineStart(line), 0, 0, nullptr, + const DocModification mh(ModificationFlags::ChangeLineState, LineStart(line), 0, 0, nullptr, static_cast(line)); NotifyModified(mh); } @@ -2312,7 +2404,7 @@ Sci::Line Document::GetMaxLineState() const noexcept { } void SCI_METHOD Document::ChangeLexerState(Sci_Position start, Sci_Position end) { - const DocModification mh(SC_MOD_LEXERSTATE, start, + const DocModification mh(ModificationFlags::LexerState, start, end-start, 0, 0, 0); NotifyModified(mh); } @@ -2325,20 +2417,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(SC_MOD_CHANGEMARGIN, LineStart(line), + const DocModification mh(ModificationFlags::ChangeMargin, LineStart(line), 0, 0, 0, line); NotifyModified(mh); } void Document::MarginSetStyle(Sci::Line line, int style) { Margins()->SetStyle(line, style); - NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), + NotifyModified(DocModification(ModificationFlags::ChangeMargin, LineStart(line), 0, 0, 0, line)); } void Document::MarginSetStyles(Sci::Line line, const unsigned char *styles) { Margins()->SetStyles(line, styles); - NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), + NotifyModified(DocModification(ModificationFlags::ChangeMargin, LineStart(line), 0, 0, 0, line)); } @@ -2361,7 +2453,7 @@ void Document::AnnotationSetText(Sci::Line line, const char *text) { const Sci::Line linesBefore = AnnotationLines(line); Annotations()->SetText(line, text); const int linesAfter = AnnotationLines(line); - DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), + DocModification mh(ModificationFlags::ChangeAnnotation, LineStart(line), 0, 0, 0, line); mh.annotationLinesAdded = linesAfter - linesBefore; NotifyModified(mh); @@ -2371,7 +2463,7 @@ void Document::AnnotationSetText(Sci::Line line, const char *text) { void Document::AnnotationSetStyle(Sci::Line line, int style) { if (line >= 0 && line < LinesTotal()) { Annotations()->SetStyle(line, style); - const DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), + const DocModification mh(ModificationFlags::ChangeAnnotation, LineStart(line), 0, 0, 0, line); NotifyModified(mh); } @@ -2404,7 +2496,7 @@ StyledText Document::EOLAnnotationStyledText(Sci::Line line) const noexcept { void Document::EOLAnnotationSetText(Sci::Line line, const char *text) { if (line >= 0 && line < LinesTotal()) { EOLAnnotations()->SetText(line, text); - const DocModification mh(SC_MOD_CHANGEEOLANNOTATION, LineStart(line), + const DocModification mh(ModificationFlags::ChangeEOLAnnotation, LineStart(line), 0, 0, 0, line); NotifyModified(mh); } @@ -2413,7 +2505,7 @@ void Document::EOLAnnotationSetText(Sci::Line line, const char *text) { void Document::EOLAnnotationSetStyle(Sci::Line line, int style) { if (line >= 0 && line < LinesTotal()) { EOLAnnotations()->SetStyle(line, style); - const DocModification mh(SC_MOD_CHANGEEOLANNOTATION, LineStart(line), + const DocModification mh(ModificationFlags::ChangeEOLAnnotation, LineStart(line), 0, 0, 0, line); NotifyModified(mh); } @@ -2439,7 +2531,7 @@ void SCI_METHOD Document::DecorationFillRange(Sci_Position position, int value, const FillResult fr = decorations->FillRange( position, value, fillLength); if (fr.changed) { - const DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER, + const DocModification mh(ModificationFlags::ChangeIndicator | ModificationFlags::User, fr.position, fr.fillLength); NotifyModified(mh); } @@ -2455,12 +2547,18 @@ bool Document::AddWatcher(DocWatcher *watcher, void *userData) { return true; } -bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) { - std::vector::iterator it = - std::find(watchers.begin(), watchers.end(), WatcherWithUserData(watcher, userData)); - if (it != watchers.end()) { - watchers.erase(it); - return true; +bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) noexcept { + try { + // This can never fail as WatcherWithUserData constructor and == are noexcept + // but std::find is not noexcept. + std::vector::iterator it = + std::find(watchers.begin(), watchers.end(), WatcherWithUserData(watcher, userData)); + if (it != watchers.end()) { + watchers.erase(it); + return true; + } + } catch (...) { + // Ignore any exception } return false; } @@ -2478,9 +2576,9 @@ void Document::NotifySavePoint(bool atSavePoint) { } void Document::NotifyModified(DocModification mh) { - if (mh.modificationType & SC_MOD_INSERTTEXT) { + if (FlagSet(mh.modificationType, ModificationFlags::InsertText)) { decorations->InsertSpace(mh.position, mh.length); - } else if (mh.modificationType & SC_MOD_DELETETEXT) { + } else if (FlagSet(mh.modificationType, ModificationFlags::DeleteText)) { decorations->DeleteRange(mh.position, mh.length); } for (const WatcherWithUserData &watcher : watchers) { @@ -2530,7 +2628,7 @@ static bool IsASCIIPunctuationCharacter(unsigned int ch) noexcept { } bool Document::IsWordPartSeparator(unsigned int ch) const { - return (WordCharacterClass(ch) == CharClassify::ccWord) && IsASCIIPunctuationCharacter(ch); + return (WordCharacterClass(ch) == CharacterClass::word) && IsASCIIPunctuationCharacter(ch); } Sci::Position Document::WordPartLeft(Sci::Position pos) const { @@ -2707,7 +2805,7 @@ class BuiltinRegex : public RegexSearchBase { ~BuiltinRegex() override = default; Sci::Position FindText(Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s, - bool caseSensitive, bool word, bool wordStart, int flags, + bool caseSensitive, bool word, bool wordStart, FindOption flags, Sci::Position *length) override; const char *SubstituteByPosition(Document *doc, const char *text, Sci::Position *length) override; @@ -3129,8 +3227,8 @@ Sci::Position Cxx11RegexFindText(const Document *doc, Sci::Position minPos, Sci: search.Clear(); bool matched = false; - if (SC_CP_UTF8 == doc->dbcsCodePage) { - const std::wstring ws = WStringFromUTF8(s, strlen(s)); + if (CpUtf8 == doc->dbcsCodePage) { + const std::wstring ws = WStringFromUTF8(s); std::wregex regexp; regexp.assign(ws, flagsRe); matched = MatchOnLines(doc, regexp, resr, search); @@ -3166,11 +3264,11 @@ Sci::Position Cxx11RegexFindText(const Document *doc, Sci::Position minPos, Sci: } Sci::Position BuiltinRegex::FindText(Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s, - bool caseSensitive, bool, bool, int flags, + bool caseSensitive, bool, bool, FindOption flags, Sci::Position *length) { #ifndef NO_CXX11_REGEX - if (flags & SCFIND_CXX11REGEX) { + if (FlagSet(flags, FindOption::Cxx11RegEx)) { return Cxx11RegexFindText(doc, minPos, maxPos, s, caseSensitive, length, search); } @@ -3178,7 +3276,7 @@ Sci::Position BuiltinRegex::FindText(Document *doc, Sci::Position minPos, Sci::P const RESearchRange resr(doc, minPos, maxPos); - const bool posix = (flags & SCFIND_POSIX) != 0; + const bool posix = FlagSet(flags, FindOption::Posix); const char *errmsg = search.Compile(s, *length, caseSensitive, posix); if (errmsg) { @@ -3305,7 +3403,7 @@ const char *BuiltinRegex::SubstituteByPosition(Document *doc, const char *text, #ifndef SCI_OWNREGEX -RegexSearchBase *Scintilla::CreateRegexSearch(CharClassify *charClassTable) { +RegexSearchBase *Scintilla::Internal::CreateRegexSearch(CharClassify *charClassTable) { return new BuiltinRegex(charClassTable); } diff --git a/scintilla/src/Document.h b/scintilla/src/Document.h index a314247394..7984ad0180 100644 --- a/scintilla/src/Document.h +++ b/scintilla/src/Document.h @@ -8,7 +8,7 @@ #ifndef DOCUMENT_H #define DOCUMENT_H -namespace Scintilla { +namespace Scintilla::Internal { class DocWatcher; class DocModification; @@ -93,7 +93,7 @@ class RegexSearchBase { virtual ~RegexSearchBase() {} virtual Sci::Position FindText(Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s, - bool caseSensitive, bool word, bool wordStart, int flags, Sci::Position *length) = 0; + bool caseSensitive, bool word, bool wordStart, Scintilla::FindOption flags, Sci::Position *length) = 0; ///@return String with the substitutions, must remain valid until the next call or destruction virtual const char *SubstituteByPosition(Document *doc, const char *text, Sci::Position *length) = 0; @@ -164,14 +164,10 @@ class HighlightDelimiter { bool isEnabled; }; -constexpr int LevelNumber(int level) noexcept { - return level & SC_FOLDLEVELNUMBERMASK; -} - class LexInterface { protected: Document *pdoc; - ILexer *instance; + Scintilla::ILexer5 *instance; bool performingStyle; ///< Prevent reentrance public: explicit LexInterface(Document *pdoc_) noexcept : pdoc(pdoc_), instance(nullptr), performingStyle(false) { @@ -179,7 +175,7 @@ class LexInterface { virtual ~LexInterface() { } void Colourise(Sci::Position start, Sci::Position end); - virtual int LineEndTypesSupported(); + virtual Scintilla::LineEndType LineEndTypesSupported(); bool UseContainerLexing() const noexcept { return instance == nullptr; } @@ -207,11 +203,12 @@ class ActionDuration { ActionDuration(double duration_, double minDuration_, double maxDuration_) noexcept; void AddSample(size_t numberActions, double durationOfActions) noexcept; double Duration() const noexcept; + size_t ActionsInAllowedTime(double secondsAllowed) const noexcept; }; /** */ -class Document : PerLine, public IDocumentWithLineEnd, public ILoader { +class Document : PerLine, public Scintilla::IDocument, public Scintilla::ILoader { public: /** Used to pair watcher pointer with user data. */ @@ -271,21 +268,21 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { } }; - int eolMode; + Scintilla::EndOfLine eolMode; /// Can also be SC_CP_UTF8 to enable UTF-8 mode int dbcsCodePage; - int lineEndBitSet; + Scintilla::LineEndType lineEndBitSet; int tabInChars; int indentInChars; int actualIndentInChars; bool useTabs; bool tabIndents; bool backspaceUnindents; - ActionDuration durationStyleOneLine; + ActionDuration durationStyleOneByte; std::unique_ptr decorations; - Document(int options); + Document(Scintilla::DocumentOption options); // Deleted so Document objects can not be copied. Document(const Document &) = delete; Document(Document &&) = delete; @@ -302,14 +299,14 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { void InsertLines(Sci::Line line, Sci::Line lines) override; void RemoveLine(Sci::Line line) override; - int LineEndTypesSupported() const; + Scintilla::LineEndType LineEndTypesSupported() const; bool SetDBCSCodePage(int dbcsCodePage_); - int GetLineEndTypesAllowed() const noexcept { return cb.GetLineEndTypes(); } - bool SetLineEndTypesAllowed(int lineEndBitSet_); - int GetLineEndTypesActive() const noexcept { return cb.GetLineEndTypes(); } + Scintilla::LineEndType GetLineEndTypesAllowed() const noexcept { return cb.GetLineEndTypes(); } + bool SetLineEndTypesAllowed(Scintilla::LineEndType lineEndBitSet_); + Scintilla::LineEndType GetLineEndTypesActive() const noexcept { return cb.GetLineEndTypes(); } int SCI_METHOD Version() const override { - return dvLineEnd; + return Scintilla::dvRelease4; } void SCI_METHOD SetErrorStatus(int status) override; @@ -332,9 +329,9 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { int SCI_METHOD CodePage() const override; bool SCI_METHOD IsDBCSLeadByte(char ch) const override; bool IsDBCSLeadByteNoExcept(char ch) const noexcept; - bool IsDBCSLeadByteInvalid(char ch) const noexcept; - bool IsDBCSTrailByteInvalid(char ch) const noexcept; - int DBCSDrawBytes(const char *text, int len) const noexcept; + 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; EncodingFamily CodePageFamily() const noexcept; @@ -378,12 +375,12 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { Sci::Position CountUTF16(Sci::Position startPos, Sci::Position endPos) const noexcept; Sci::Position FindColumn(Sci::Line line, Sci::Position column); void Indent(bool forwards, Sci::Line lineBottom, Sci::Line lineTop); - static std::string TransformLineEnds(const char *s, size_t len, int eolModeWanted); - void ConvertLineEnds(int eolModeSet); + static std::string TransformLineEnds(const char *s, size_t len, Scintilla::EndOfLine eolModeWanted); + void ConvertLineEnds(Scintilla::EndOfLine eolModeSet); void SetReadOnly(bool set) { cb.SetReadOnly(set); } bool IsReadOnly() const noexcept { return cb.IsReadOnly(); } bool IsLarge() const noexcept { return cb.IsLarge(); } - int Options() const noexcept; + Scintilla::DocumentOption Options() const noexcept; void DelChar(Sci::Position pos); void DelCharBack(Sci::Position pos); @@ -414,13 +411,15 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { bool IsLineEndPosition(Sci::Position position) const; bool IsPositionInLineEnd(Sci::Position position) const; Sci::Position VCHomePosition(Sci::Position position) const; - Sci::Position IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept; - Sci::Line LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const noexcept; + Sci::Position IndexLineStart(Sci::Line line, Scintilla::LineCharacterIndexType lineCharacterIndex) const noexcept; + Sci::Line LineFromPositionIndex(Sci::Position pos, Scintilla::LineCharacterIndexType lineCharacterIndex) const noexcept; + Sci::Line LineFromPositionAfter(Sci::Line line, Sci::Position length) const noexcept; int SCI_METHOD SetLevel(Sci_Position line, int level) override; int SCI_METHOD GetLevel(Sci_Position line) const override; + Scintilla::FoldLevel GetFoldLevel(Sci_Position line) const; void ClearLevels(); - Sci::Line GetLastChild(Sci::Line lineParent, int level=-1, Sci::Line lastLine=-1); + Sci::Line GetLastChild(Sci::Line lineParent, std::optional level = {}, Sci::Line lastLine = -1); Sci::Line GetFoldParent(Sci::Line line) const; void GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sci::Line line, Sci::Line lastLine); @@ -439,20 +438,21 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { bool MatchesWordOptions(bool word, bool wordStart, Sci::Position pos, Sci::Position length) const; bool HasCaseFolder() const noexcept; - void SetCaseFolder(CaseFolder *pcf_) noexcept; - Sci::Position FindText(Sci::Position minPos, Sci::Position maxPos, const char *search, int flags, Sci::Position *length); + void SetCaseFolder(std::unique_ptr pcf_) noexcept; + Sci::Position FindText(Sci::Position minPos, Sci::Position maxPos, const char *search, Scintilla::FindOption flags, Sci::Position *length); const char *SubstituteByPosition(const char *text, Sci::Position *length); - int LineCharacterIndex() const noexcept; - void AllocateLineCharacterIndex(int lineCharacterIndex); - void ReleaseLineCharacterIndex(int lineCharacterIndex); + Scintilla::LineCharacterIndexType LineCharacterIndex() const noexcept; + void AllocateLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); + void ReleaseLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex); Sci::Line LinesTotal() const noexcept; + void AllocateLines(Sci::Line lines); void SetDefaultCharClasses(bool includeWordClass); - void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass); - int GetCharsOfClass(CharClassify::cc characterClass, unsigned char *buffer) const; + void SetCharClasses(const unsigned char *chars, CharacterClass newCharClass); + int GetCharsOfClass(CharacterClass characterClass, unsigned char *buffer) const; void SetCharacterCategoryOptimization(int countCharacters); int CharacterCategoryOptimization() const noexcept; - void SCI_METHOD StartStyling(Sci_Position position, char mask) override; + void SCI_METHOD StartStyling(Sci_Position position) override; bool SCI_METHOD SetStyleFor(Sci_Position length, char style) override; bool SCI_METHOD SetStyles(Sci_Position length, const char *styles) override; Sci::Position GetEndStyled() const noexcept { return endStyled; } @@ -490,9 +490,9 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { void EOLAnnotationClearAll(); bool AddWatcher(DocWatcher *watcher, void *userData); - bool RemoveWatcher(DocWatcher *watcher, void *userData); + bool RemoveWatcher(DocWatcher *watcher, void *userData) noexcept; - CharClassify::cc WordCharacterClass(unsigned int ch) const; + CharacterClass WordCharacterClass(unsigned int ch) const; bool IsWordPartSeparator(unsigned int ch) const; Sci::Position WordPartLeft(Sci::Position pos) const; Sci::Position WordPartRight(Sci::Position pos) const; @@ -526,6 +526,9 @@ class UndoGroup { UndoGroup &operator=(UndoGroup &&) = delete; ~UndoGroup() { if (groupNeeded) { + // EndUndoAction can throw as it allocates but throw in destructor is fatal. + // To fix this UndoHistory should allocate any memory needed by EndUndoAction + // beforehand or change EndUndoAction to not require allocation. pdoc->EndUndoAction(); } } @@ -542,18 +545,18 @@ class UndoGroup { */ class DocModification { public: - int modificationType; + Scintilla::ModificationFlags modificationType; Sci::Position position; Sci::Position length; Sci::Line linesAdded; /**< Negative if lines deleted. */ const char *text; /**< Only valid for changes to text, not for changes to style. */ Sci::Line line; - int foldLevelNow; - int foldLevelPrev; + Scintilla::FoldLevel foldLevelNow; + Scintilla::FoldLevel foldLevelPrev; Sci::Line annotationLinesAdded; Sci::Position token; - DocModification(int modificationType_, Sci::Position position_=0, Sci::Position length_=0, + DocModification(Scintilla::ModificationFlags modificationType_, Sci::Position position_=0, Sci::Position length_=0, Sci::Line linesAdded_=0, const char *text_=nullptr, Sci::Line line_=0) noexcept : modificationType(modificationType_), position(position_), @@ -561,20 +564,20 @@ class DocModification { linesAdded(linesAdded_), text(text_), line(line_), - foldLevelNow(0), - foldLevelPrev(0), + foldLevelNow(Scintilla::FoldLevel::None), + foldLevelPrev(Scintilla::FoldLevel::None), annotationLinesAdded(0), token(0) {} - DocModification(int modificationType_, const Action &act, Sci::Line linesAdded_=0) noexcept : + DocModification(Scintilla::ModificationFlags modificationType_, const Action &act, Sci::Line linesAdded_=0) noexcept : modificationType(modificationType_), position(act.position), length(act.lenData), linesAdded(linesAdded_), text(act.data.get()), line(0), - foldLevelNow(0), - foldLevelPrev(0), + foldLevelNow(Scintilla::FoldLevel::None), + foldLevelPrev(Scintilla::FoldLevel::None), annotationLinesAdded(0), token(0) {} }; @@ -593,7 +596,7 @@ class DocWatcher { virtual void NotifyDeleted(Document *doc, void *userData) noexcept = 0; virtual void NotifyStyleNeeded(Document *doc, void *userData, Sci::Position endPos) = 0; virtual void NotifyLexerChanged(Document *doc, void *userData) = 0; - virtual void NotifyErrorOccurred(Document *doc, void *userData, int status) = 0; + virtual void NotifyErrorOccurred(Document *doc, void *userData, Scintilla::Status status) = 0; }; } diff --git a/scintilla/src/EditModel.cxx b/scintilla/src/EditModel.cxx index f43ae2aed6..5dd3cc87d0 100644 --- a/scintilla/src/EditModel.cxx +++ b/scintilla/src/EditModel.cxx @@ -13,18 +13,23 @@ #include #include +#include #include #include +#include +#include #include #include -#include "Platform.h" - +#include "ScintillaTypes.h" #include "ILoader.h" #include "ILexer.h" -#include "Scintilla.h" -#include "CharacterCategory.h" +#include "Debugging.h" +#include "Geometry.h" +#include "Platform.h" + +#include "CharacterCategoryMap.h" #include "Position.h" #include "UniqueString.h" @@ -33,7 +38,6 @@ #include "RunStyles.h" #include "ContractionState.h" #include "CellBuffer.h" -#include "KeyMap.h" #include "Indicator.h" #include "LineMarker.h" #include "Style.h" @@ -48,6 +52,7 @@ #include "EditModel.h" using namespace Scintilla; +using namespace Scintilla::Internal; Caret::Caret() noexcept : active(false), on(false), period(500) {} @@ -59,25 +64,42 @@ EditModel::EditModel() : braces{} { posDrag = SelectionPosition(Sci::invalidPosition); braces[0] = Sci::invalidPosition; braces[1] = Sci::invalidPosition; - bracesMatchStyle = STYLE_BRACEBAD; + bracesMatchStyle = StyleBraceBad; highlightGuideColumn = 0; + hasFocus = false; primarySelection = true; - imeInteraction = imeWindowed; - foldFlags = 0; - foldDisplayTextStyle = SC_FOLDDISPLAYTEXT_HIDDEN; + imeInteraction = IMEInteraction::Windowed; + bidirectional = Bidirectional::Disabled; + foldFlags = FoldFlag::None; + foldDisplayTextStyle = FoldDisplayTextStyle::Hidden; hotspot = Range(Sci::invalidPosition); + hotspotSingleLine = true; hoverIndicatorPos = Sci::invalidPosition; wrapWidth = LineLayout::wrapWidthInfinite; - pdoc = new Document(SC_DOCUMENTOPTION_DEFAULT); + pdoc = new Document(DocumentOption::Default); pdoc->AddRef(); pcs = ContractionStateCreate(pdoc->IsLarge()); } EditModel::~EditModel() { - pdoc->Release(); + try { + // This never throws but isn't marked noexcept for compatibility + pdoc->Release(); + } catch (...) { + // Ignore any exception + } pdoc = nullptr; } +bool EditModel::BidirectionalEnabled() const noexcept { + return (bidirectional != Bidirectional::Disabled) && + (CpUtf8 == pdoc->dbcsCodePage); +} + +bool EditModel::BidirectionalR2L() const noexcept { + return bidirectional == Bidirectional::R2L; +} + void EditModel::SetDefaultFoldDisplayText(const char *text) { defaultFoldDisplayText = IsNullOrEmpty(text) ? UniqueString() : UniqueStringCopy(text); } @@ -87,10 +109,15 @@ const char *EditModel::GetDefaultFoldDisplayText() const noexcept { } const char *EditModel::GetFoldDisplayText(Sci::Line lineDoc) const noexcept { - if (foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_HIDDEN || pcs->GetExpanded(lineDoc)) { + if (foldDisplayTextStyle == FoldDisplayTextStyle::Hidden || pcs->GetExpanded(lineDoc)) { return nullptr; } const char *text = pcs->GetFoldDisplayText(lineDoc); return text ? text : defaultFoldDisplayText.get(); } + +InSelection EditModel::LineEndInSelection(Sci::Line lineDoc) const { + const Sci::Position posAfterLineEnd = pdoc->LineStart(lineDoc + 1); + return sel.InSelectionForEOL(posAfterLineEnd); +} diff --git a/scintilla/src/EditModel.h b/scintilla/src/EditModel.h index cb6ea28399..16a3d1c9fd 100644 --- a/scintilla/src/EditModel.h +++ b/scintilla/src/EditModel.h @@ -8,7 +8,7 @@ #ifndef EDITMODEL_H #define EDITMODEL_H -namespace Scintilla { +namespace Scintilla::Internal { /** */ @@ -33,18 +33,20 @@ class EditModel { Sci::Position braces[2]; int bracesMatchStyle; int highlightGuideColumn; + bool hasFocus; Selection sel; bool primarySelection; - enum IMEInteraction { imeWindowed, imeInline } imeInteraction; - enum class CharacterSource { directInput, tentativeInput, imeResult }; + Scintilla::IMEInteraction imeInteraction; + Scintilla::Bidirectional bidirectional; - int foldFlags; - int foldDisplayTextStyle; + Scintilla::FoldFlag foldFlags; + Scintilla::FoldDisplayTextStyle foldDisplayTextStyle; UniqueString defaultFoldDisplayText; std::unique_ptr pcs; // Hotspot support Range hotspot; + bool hotspotSingleLine; Sci::Position hoverIndicatorPos; // Wrapping support @@ -63,9 +65,12 @@ class EditModel { virtual Point GetVisibleOriginInMain() const = 0; virtual Sci::Line LinesOnScreen() const = 0; virtual Range GetHotSpotRange() const noexcept = 0; + bool BidirectionalEnabled() const noexcept; + bool BidirectionalR2L() const noexcept; void SetDefaultFoldDisplayText(const char *text); const char *GetDefaultFoldDisplayText() const noexcept; const char *GetFoldDisplayText(Sci::Line lineDoc) const noexcept; + InSelection LineEndInSelection(Sci::Line lineDoc) const; }; } diff --git a/scintilla/src/EditView.cxx b/scintilla/src/EditView.cxx index cae02ef5c9..e4b0fa5d91 100644 --- a/scintilla/src/EditView.cxx +++ b/scintilla/src/EditView.cxx @@ -14,24 +14,30 @@ #include #include +#include #include #include +#include #include +#include #include #include #include #include -#include "Platform.h" - +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" +#include "ScintillaStructures.h" #include "ILoader.h" #include "ILexer.h" -#include "Scintilla.h" -#include "CharacterSet.h" -#include "CharacterCategory.h" +#include "Debugging.h" +#include "Geometry.h" +#include "Platform.h" + +#include "CharacterType.h" +#include "CharacterCategoryMap.h" #include "Position.h" -#include "IntegerRectangle.h" #include "UniqueString.h" #include "SplitVector.h" #include "Partitioning.h" @@ -57,14 +63,15 @@ #include "ElapsedPeriod.h" using namespace Scintilla; +using namespace Scintilla::Internal; PrintParameters::PrintParameters() noexcept { magnification = 0; - colourMode = SC_PRINT_NORMAL; - wrapState = WrapMode::word; + colourMode = PrintOption::Normal; + wrapState = Wrap::Word; } -namespace Scintilla { +namespace Scintilla::Internal { bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st) noexcept { if (st.multipleStyles) { @@ -88,9 +95,9 @@ static int WidthStyledText(Surface *surface, const ViewStyle &vs, int styleOffse size_t endSegment = start; while ((endSegment + 1 < len) && (styles[endSegment + 1] == style)) endSegment++; - FontAlias fontText = vs.styles[style + styleOffset].font; - width += static_cast(surface->WidthText(fontText, text + start, - static_cast(endSegment - start + 1))); + const Font *fontText = vs.styles[style + styleOffset].font.get(); + const std::string_view sv(text + start, endSegment - start + 1); + width += static_cast(surface->WidthText(fontText, sv)); start = endSegment + 1; } return width; @@ -105,9 +112,9 @@ int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, cons if (st.multipleStyles) { widthSubLine = WidthStyledText(surface, vs, styleOffset, st.text + start, st.styles + start, lenLine); } else { - FontAlias fontText = vs.styles[styleOffset + st.style].font; - widthSubLine = static_cast(surface->WidthText(fontText, - st.text + start, static_cast(lenLine))); + const Font *fontText = vs.styles[styleOffset + st.style].font.get(); + const std::string_view text(st.text + start, lenLine); + widthSubLine = static_cast(surface->WidthText(fontText, text)); } if (widthSubLine > widthMax) widthMax = widthSubLine; @@ -117,18 +124,18 @@ int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, cons } void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XYPOSITION ybase, - const char *s, int len, DrawPhase phase) { - FontAlias fontText = style.font; - if (phase & drawBack) { - if (phase & drawText) { + std::string_view text, DrawPhase phase) { + const Font *fontText = style.font.get(); + if (FlagSet(phase, DrawPhase::back)) { + if (FlagSet(phase, DrawPhase::text)) { // Drawing both - surface->DrawTextNoClip(rc, fontText, ybase, s, len, + surface->DrawTextNoClip(rc, fontText, ybase, text, style.fore, style.back); } else { - surface->FillRectangle(rc, style.back); + surface->FillRectangleAligned(rc, Fill(style.back)); } - } else if (phase & drawText) { - surface->DrawTextTransparent(rc, fontText, ybase, s, len, style.fore); + } else if (FlagSet(phase, DrawPhase::text)) { + surface->DrawTextTransparent(rc, fontText, ybase, text, style.fore); } } @@ -144,26 +151,32 @@ void DrawStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, PRec while (end < length - 1 && st.styles[start + end + 1] == style) end++; style += styleOffset; - FontAlias fontText = vs.styles[style].font; - const int width = static_cast(surface->WidthText(fontText, - st.text + start + i, static_cast(end - i + 1))); + const Font *fontText = vs.styles[style].font.get(); + const std::string_view text(st.text + start + i, end - i + 1); + const int width = static_cast(surface->WidthText(fontText, text)); PRectangle rcSegment = rcText; rcSegment.left = static_cast(x); rcSegment.right = static_cast(x + width + 1); DrawTextNoClipPhase(surface, rcSegment, vs.styles[style], - rcText.top + vs.maxAscent, st.text + start + i, - static_cast(end - i + 1), phase); + rcText.top + vs.maxAscent, text, phase); x += width; i = end + 1; } } else { const size_t style = st.style + styleOffset; DrawTextNoClipPhase(surface, rcText, vs.styles[style], - rcText.top + vs.maxAscent, st.text + start, - static_cast(length), phase); + rcText.top + vs.maxAscent, + std::string_view(st.text + start, length), phase); } } +void Hexits(char *hexits, int ch) noexcept { + hexits[0] = 'x'; + hexits[1] = "0123456789ABCDEF"[ch / 0x10]; + hexits[2] = "0123456789ABCDEF"[ch % 0x10]; + hexits[3] = 0; +} + } EditView::EditView() { @@ -171,23 +184,22 @@ EditView::EditView() { hideSelection = false; drawOverstrikeCaret = true; bufferedDraw = true; - phasesDraw = phasesTwo; + phasesDraw = PhasesDraw::Two; lineWidthMaxSeen = 0; additionalCaretsBlink = true; additionalCaretsVisible = true; imeCaretBlockOverride = false; - llc.SetLevel(LineLayoutCache::llcCaret); + llc.SetLevel(LineCache::Caret); posCache.SetSize(0x400); tabArrowHeight = 4; customDrawTabArrow = nullptr; customDrawWrapMarker = nullptr; } -EditView::~EditView() { -} +EditView::~EditView() = default; bool EditView::SetTwoPhaseDraw(bool twoPhaseDraw) noexcept { - const PhasesDraw phasesDrawNew = twoPhaseDraw ? phasesTwo : phasesOne; + const PhasesDraw phasesDrawNew = twoPhaseDraw ? PhasesDraw::Two : PhasesDraw::One; const bool redraw = phasesDraw != phasesDrawNew; phasesDraw = phasesDrawNew; return redraw; @@ -201,7 +213,7 @@ bool EditView::SetPhasesDraw(int phases) noexcept { } bool EditView::LinesOverlap() const noexcept { - return phasesDraw == phasesMultiple; + return phasesDraw == PhasesDraw::Multiple; } void EditView::ClearAllTabstops() noexcept { @@ -221,7 +233,7 @@ bool EditView::ClearTabstops(Sci::Line line) noexcept { bool EditView::AddTabstop(Sci::Line line, int x) { if (!ldTabstops) { - ldTabstops = Sci::make_unique(); + ldTabstops = std::make_unique(); } return ldTabstops && ldTabstops->AddTabstop(line, x); } @@ -248,28 +260,10 @@ void EditView::LinesAddedOrRemoved(Sci::Line lineOfPos, Sci::Line linesAdded) { } } -void EditView::DropGraphics(bool freeObjects) { - if (freeObjects) { - pixmapLine.reset(); - pixmapIndentGuide.reset(); - pixmapIndentGuideHighlight.reset(); - } else { - if (pixmapLine) - pixmapLine->Release(); - if (pixmapIndentGuide) - pixmapIndentGuide->Release(); - if (pixmapIndentGuideHighlight) - pixmapIndentGuideHighlight->Release(); - } -} - -void EditView::AllocateGraphics(const ViewStyle &vsDraw) { - if (!pixmapLine) - pixmapLine.reset(Surface::Allocate(vsDraw.technology)); - if (!pixmapIndentGuide) - pixmapIndentGuide.reset(Surface::Allocate(vsDraw.technology)); - if (!pixmapIndentGuideHighlight) - pixmapIndentGuideHighlight.reset(Surface::Allocate(vsDraw.technology)); +void EditView::DropGraphics() noexcept { + pixmapLine.reset(); + pixmapIndentGuide.reset(); + pixmapIndentGuideHighlight.reset(); } static const char *ControlCharacterString(unsigned char ch) noexcept { @@ -279,52 +273,63 @@ static const char *ControlCharacterString(unsigned char ch) noexcept { "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" }; - if (ch < Sci::size(reps)) { + if (ch < std::size(reps)) { return reps[ch]; } else { return "BAD"; } } -static void DrawTabArrow(Surface *surface, PRectangle rcTab, int ymid, const ViewStyle &vsDraw) { - const IntegerRectangle ircTab(rcTab); - if ((rcTab.left + 2) < (rcTab.right - 1)) - surface->MoveTo(ircTab.left + 2, ymid); - else - surface->MoveTo(ircTab.right - 1, ymid); - surface->LineTo(ircTab.right - 1, ymid); +static void DrawTabArrow(Surface *surface, PRectangle rcTab, int ymid, + const ViewStyle &vsDraw, Stroke stroke) { + + const XYPOSITION halfWidth = stroke.width / 2.0; + + const XYPOSITION leftStroke = std::round(std::min(rcTab.left + 2, rcTab.right - 1)) + halfWidth; + const XYPOSITION rightStroke = std::max(leftStroke, std::round(rcTab.right) - 1.0f - halfWidth); + const XYPOSITION yMidAligned = ymid + halfWidth; + const Point arrowPoint(rightStroke, yMidAligned); + if (rightStroke > leftStroke) { + // When not enough room, don't draw the arrow shaft + surface->LineDraw(Point(leftStroke, yMidAligned), arrowPoint, stroke); + } // Draw the arrow head if needed - if (vsDraw.tabDrawMode == tdLongArrow) { - int ydiff = (ircTab.bottom - ircTab.top) / 2; - int xhead = ircTab.right - 1 - ydiff; + if (vsDraw.tabDrawMode == TabDrawMode::LongArrow) { + XYPOSITION ydiff = std::floor(rcTab.Height() / 2.0f); + XYPOSITION xhead = rightStroke - ydiff; if (xhead <= rcTab.left) { - ydiff -= ircTab.left - xhead - 1; - xhead = ircTab.left - 1; + ydiff -= rcTab.left - xhead; + xhead = rcTab.left; } - surface->LineTo(xhead, ymid - ydiff); - surface->MoveTo(ircTab.right - 1, ymid); - surface->LineTo(xhead, ymid + ydiff); + const Point ptsHead[] = { + Point(xhead, yMidAligned - ydiff), + arrowPoint, + Point(xhead, yMidAligned + ydiff) + }; + surface->PolyLine(ptsHead, std::size(ptsHead), stroke); } } -void EditView::RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw) { - if (!pixmapIndentGuide->Initialised()) { +void EditView::RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw) { + if (!pixmapIndentGuide) { // 1 extra pixel in height so can handle odd/even positions and so produce a continuous line - pixmapIndentGuide->InitPixMap(1, vsDraw.lineHeight + 1, surfaceWindow, wid); - pixmapIndentGuideHighlight->InitPixMap(1, vsDraw.lineHeight + 1, surfaceWindow, wid); + pixmapIndentGuide = surfaceWindow->AllocatePixMap(1, vsDraw.lineHeight + 1); + pixmapIndentGuideHighlight = surfaceWindow->AllocatePixMap(1, vsDraw.lineHeight + 1); const PRectangle rcIG = PRectangle::FromInts(0, 0, 1, vsDraw.lineHeight); - pixmapIndentGuide->FillRectangle(rcIG, vsDraw.styles[STYLE_INDENTGUIDE].back); - pixmapIndentGuideHighlight->FillRectangle(rcIG, vsDraw.styles[STYLE_BRACELIGHT].back); + pixmapIndentGuide->FillRectangle(rcIG, vsDraw.styles[StyleIndentGuide].back); + pixmapIndentGuideHighlight->FillRectangle(rcIG, vsDraw.styles[StyleBraceLight].back); for (int stripe = 1; stripe < vsDraw.lineHeight + 1; stripe += 2) { const PRectangle rcPixel = PRectangle::FromInts(0, stripe, 1, stripe + 1); - pixmapIndentGuide->FillRectangle(rcPixel, vsDraw.styles[STYLE_INDENTGUIDE].fore); - pixmapIndentGuideHighlight->FillRectangle(rcPixel, vsDraw.styles[STYLE_BRACELIGHT].fore); + pixmapIndentGuide->FillRectangle(rcPixel, vsDraw.styles[StyleIndentGuide].fore); + pixmapIndentGuideHighlight->FillRectangle(rcPixel, vsDraw.styles[StyleBraceLight].fore); } + pixmapIndentGuide->FlushDrawing(); + pixmapIndentGuideHighlight->FlushDrawing(); } } -LineLayout *EditView::RetrieveLineLayout(Sci::Line lineNumber, const EditModel &model) { +std::shared_ptr EditView::RetrieveLineLayout(Sci::Line lineNumber, const EditModel &model) { const Sci::Position posLineStart = model.pdoc->LineStart(lineNumber); const Sci::Position posLineEnd = model.pdoc->LineStart(lineNumber + 1); PLATFORM_ASSERT(posLineEnd >= posLineStart); @@ -344,15 +349,15 @@ constexpr XYPOSITION epsilon = 0.0001f; // A small nudge to avoid floating point * This only affects ASCII characters and is provided for languages with case-insensitive * ASCII keywords where the user wishes to view keywords in a preferred case. */ -inline char CaseForce(Style::ecaseForced caseForce, char chDoc, char chPrevious) { +inline char CaseForce(Style::CaseForce caseForce, char chDoc, char chPrevious) noexcept { switch (caseForce) { - case Style::caseMixed: + case Style::CaseForce::mixed: return chDoc; - case Style::caseLower: + case Style::CaseForce::lower: return MakeLowerCase(chDoc); - case Style::caseUpper: + case Style::CaseForce::upper: return MakeUpperCase(chDoc); - case Style::caseCamel: + case Style::CaseForce::camel: default: // default should not occur, included to avoid warnings if (IsUpperOrLowerCase(chDoc) && !IsUpperOrLowerCase(chPrevious)) { return MakeUpperCase(chDoc); @@ -368,6 +373,10 @@ constexpr bool IsControlCharacter(int ch) noexcept { return (ch >= 0 && ch < ' ') || (ch == 127); } +bool ViewIsASCII(std::string_view text) { + return std::all_of(text.cbegin(), text.cend(), IsASCII); +} + } /** @@ -375,12 +384,13 @@ constexpr bool IsControlCharacter(int ch) noexcept { * Copy the given @a line and its styles from the document into local arrays. * Also determine the x position at which each character starts. */ -void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surface, const ViewStyle &vstyle, LineLayout *ll, int width) { +void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewStyle &vstyle, LineLayout *ll, int width) { if (!ll) return; + const Sci::Line line = ll->LineNumber(); PLATFORM_ASSERT(line < model.pdoc->LinesTotal()); - PLATFORM_ASSERT(ll->chars != NULL); + PLATFORM_ASSERT(ll->chars); const Sci::Position posLineStart = model.pdoc->LineStart(line); Sci::Position posLineEnd = model.pdoc->LineStart(line + 1); // If the line is very long, limit the treatment to a length that should fit in the viewport @@ -424,7 +434,7 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa if (ll->validity == LineLayout::ValidLevel::invalid) { ll->widthLine = LineLayout::wrapWidthInfinite; ll->lines = 1; - if (vstyle.edgeState == EDGE_BACKGROUND) { + if (vstyle.edgeState == EdgeVisualStyle::Background) { Sci::Position edgePosition = model.pdoc->FindColumn(line, vstyle.theEdge.column); if (edgePosition >= posLineStart) { edgePosition -= posLineStart; @@ -474,10 +484,20 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa representationWidth = NextTabstopPos(line, x, vstyle.tabWidth) - ll->positions[ts.start]; } else { if (representationWidth <= 0.0) { - XYPOSITION positionsRepr[256]; // Should expand when needed - posCache.MeasureWidths(surface, vstyle, STYLE_CONTROLCHAR, ts.representation->stringRep.c_str(), - static_cast(ts.representation->stringRep.length()), positionsRepr, model.pdoc); - representationWidth = positionsRepr[ts.representation->stringRep.length() - 1] + vstyle.ctrlCharPadding; + assert(ts.representation->stringRep.length() <= Representation::maxLength); + XYPOSITION positionsRepr[Representation::maxLength+1]; + // ts.representation->stringRep is UTF-8 which only matches cache if document is UTF-8 + // or it only contains ASCII which is a subset of all currently supported encodings. + if ((CpUtf8 == model.pdoc->dbcsCodePage) || ViewIsASCII(ts.representation->stringRep)) { + posCache.MeasureWidths(surface, vstyle, StyleControlChar, ts.representation->stringRep, + positionsRepr); + } else { + surface->MeasureWidthsUTF8(vstyle.styles[StyleControlChar].font.get(), ts.representation->stringRep, positionsRepr); + } + representationWidth = positionsRepr[ts.representation->stringRep.length() - 1]; + if (FlagSet(ts.representation->appearance, RepresentationAppearance::Blob)) { + representationWidth += vstyle.ctrlCharPadding; + } } } for (int ii = 0; ii < ts.length; ii++) @@ -487,8 +507,8 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa // Over half the segments are single characters and of these about half are space characters. ll->positions[ts.start + 1] = vstyle.styles[ll->styles[ts.start]].spaceWidth; } else { - posCache.MeasureWidths(surface, vstyle, ll->styles[ts.start], &ll->chars[ts.start], - ts.length, &ll->positions[ts.start + 1], model.pdoc); + posCache.MeasureWidths(surface, vstyle, ll->styles[ts.start], + std::string_view(&ll->chars[ts.start], ts.length), &ll->positions[ts.start + 1]); } } lastSegItalics = (!ts.representation) && ((ll->chars[ts.end() - 1] != ' ') && vstyle.styles[ll->styles[ts.start]].italic); @@ -515,23 +535,25 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa // Simple common case where line does not need wrapping. ll->lines = 1; } else { - if (vstyle.wrapVisualFlags & SC_WRAPVISUALFLAG_END) { + if (FlagSet(vstyle.wrap.visualFlags, WrapVisualFlag::End)) { width -= static_cast(vstyle.aveCharWidth); // take into account the space for end wrap mark } XYPOSITION wrapAddIndent = 0; // This will be added to initial indent of line - switch (vstyle.wrapIndentMode) { - case SC_WRAPINDENT_FIXED: - wrapAddIndent = vstyle.wrapVisualStartIndent * vstyle.aveCharWidth; + switch (vstyle.wrap.indentMode) { + case WrapIndentMode::Fixed: + wrapAddIndent = vstyle.wrap.visualStartIndent * vstyle.aveCharWidth; break; - case SC_WRAPINDENT_INDENT: + case WrapIndentMode::Indent: wrapAddIndent = model.pdoc->IndentSize() * vstyle.spaceWidth; break; - case SC_WRAPINDENT_DEEPINDENT: + case WrapIndentMode::DeepIndent: wrapAddIndent = model.pdoc->IndentSize() * 2 * vstyle.spaceWidth; break; + default: // No additional indent for WrapIndentMode::Fixed + break; } ll->wrapIndent = wrapAddIndent; - if (vstyle.wrapIndentMode != SC_WRAPINDENT_FIXED) { + if (vstyle.wrap.indentMode != WrapIndentMode::Fixed) { for (int i = 0; i < ll->numCharsInLine; i++) { if (!IsSpaceOrTab(ll->chars[i])) { ll->wrapIndent += ll->positions[i]; // Add line indent @@ -543,7 +565,7 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa if (ll->wrapIndent > width - static_cast(vstyle.aveCharWidth) * 15) ll->wrapIndent = wrapAddIndent; // Check for wrapIndent minimum - if ((vstyle.wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (ll->wrapIndent < vstyle.aveCharWidth)) + if ((FlagSet(vstyle.wrap.visualFlags, WrapVisualFlag::Start)) && (ll->wrapIndent < vstyle.aveCharWidth)) ll->wrapIndent = vstyle.aveCharWidth; // Indent to show start visual ll->lines = 0; // Calculate line start positions based upon width. @@ -575,12 +597,12 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa continue; } if (p > 0) { - if (vstyle.wrapState == WrapMode::character) { + 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.wrapState == WrapMode::word) && (ll->styles[p] != ll->styles[p - 1])) { + } 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; @@ -594,26 +616,78 @@ void EditView::LayoutLine(const EditModel &model, Sci::Line line, Surface *surfa } } +// Fill the LineLayout bidirectional data fields according to each char style + +void EditView::UpdateBidiData(const EditModel &model, const ViewStyle &vstyle, LineLayout *ll) { + if (model.BidirectionalEnabled()) { + ll->EnsureBidiData(); + for (int stylesInLine = 0; stylesInLine < ll->numCharsInLine; stylesInLine++) { + ll->bidiData->stylesFonts[stylesInLine] = vstyle.styles[ll->styles[stylesInLine]].font; + } + ll->bidiData->stylesFonts[ll->numCharsInLine].reset(); + + for (int charsInLine = 0; charsInLine < ll->numCharsInLine; charsInLine++) { + const int charWidth = UTF8DrawBytes(reinterpret_cast(&ll->chars[charsInLine]), ll->numCharsInLine - charsInLine); + const Representation *repr = model.reprs.RepresentationFromCharacter(std::string_view(&ll->chars[charsInLine], charWidth)); + + ll->bidiData->widthReprs[charsInLine] = 0.0f; + if (repr && ll->chars[charsInLine] != '\t') { + ll->bidiData->widthReprs[charsInLine] = ll->positions[charsInLine + charWidth] - ll->positions[charsInLine]; + } + if (charWidth > 1) { + for (int c = 1; c < charWidth; c++) { + charsInLine++; + ll->bidiData->widthReprs[charsInLine] = 0.0f; + } + } + } + ll->bidiData->widthReprs[ll->numCharsInLine] = 0.0f; + } else { + ll->bidiData.reset(); + } +} + Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, Sci::Line topLine, - const ViewStyle &vs, PointEnd pe) { + const ViewStyle &vs, PointEnd pe, const PRectangle rcClient) { Point pt; - if (pos.Position() == INVALID_POSITION) + if (pos.Position() == Sci::invalidPosition) return pt; Sci::Line lineDoc = model.pdoc->SciLineFromPosition(pos.Position()); Sci::Position posLineStart = model.pdoc->LineStart(lineDoc); - if ((pe & peLineEnd) && (lineDoc > 0) && (pos.Position() == posLineStart)) { + if (FlagSet(pe, PointEnd::lineEnd) && (lineDoc > 0) && (pos.Position() == posLineStart)) { // Want point at end of first line lineDoc--; posLineStart = model.pdoc->LineStart(lineDoc); } const Sci::Line lineVisible = model.pcs->DisplayFromDoc(lineDoc); - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); + std::shared_ptr ll = RetrieveLineLayout(lineDoc, model); if (surface && ll) { - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); + LayoutLine(model, surface, vs, ll.get(), model.wrapWidth); const int posInLine = static_cast(pos.Position() - posLineStart); pt = ll->PointFromPosition(posInLine, vs.lineHeight, pe); - pt.y += (lineVisible - topLine) * vs.lineHeight; pt.x += vs.textStart - model.xOffset; + + if (model.BidirectionalEnabled()) { + // Fill the line bidi data + UpdateBidiData(model, vs, ll.get()); + + // Find subLine + const int subLine = ll->SubLineFromPosition(posInLine, pe); + const int caretPosition = posInLine - ll->LineStart(subLine); + + // Get the point from current position + const ScreenLine screenLine(ll.get(), subLine, vs, rcClient.right, tabWidthMinimumPixels); + std::unique_ptr slLayout = surface->Layout(&screenLine); + pt.x = slLayout->XFromPosition(caretPosition); + + pt.x += vs.textStart - model.xOffset; + + pt.y = 0; + if (posInLine >= ll->LineStart(subLine)) { + pt.y = static_cast(subLine*vs.lineHeight); + } + } + pt.y += (lineVisible - topLine) * vs.lineHeight; } pt.x += pos.VirtualSpace() * vs.styles[ll->EndLineStyle()].spaceWidth; return pt; @@ -626,9 +700,9 @@ Range EditView::RangeDisplayLine(Surface *surface, const EditModel &model, Sci:: } const Sci::Line lineDoc = model.pcs->DocFromDisplay(lineVisible); const Sci::Position positionLineStart = model.pdoc->LineStart(lineDoc); - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); + std::shared_ptr ll = RetrieveLineLayout(lineDoc, model); if (surface && ll) { - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); + LayoutLine(model, surface, vs, ll.get(), model.wrapWidth); const Sci::Line lineStartSet = model.pcs->DisplayFromDoc(lineDoc); const int subLine = static_cast(lineVisible - lineStartSet); if (subLine < ll->lines) { @@ -644,21 +718,22 @@ Range EditView::RangeDisplayLine(Surface *surface, const EditModel &model, Sci:: return rangeSubLine; } -SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditModel &model, PointDocument pt, bool canReturnInvalid, bool charPosition, bool virtualSpace, const ViewStyle &vs) { +SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditModel &model, PointDocument pt, bool canReturnInvalid, + bool charPosition, bool virtualSpace, const ViewStyle &vs, const PRectangle rcClient) { pt.x = pt.x - vs.textStart; Sci::Line visibleLine = static_cast(std::floor(pt.y / vs.lineHeight)); if (!canReturnInvalid && (visibleLine < 0)) visibleLine = 0; const Sci::Line lineDoc = model.pcs->DocFromDisplay(visibleLine); if (canReturnInvalid && (lineDoc < 0)) - return SelectionPosition(INVALID_POSITION); + return SelectionPosition(Sci::invalidPosition); if (lineDoc >= model.pdoc->LinesTotal()) - return SelectionPosition(canReturnInvalid ? INVALID_POSITION : + return SelectionPosition(canReturnInvalid ? Sci::invalidPosition : model.pdoc->Length()); const Sci::Position posLineStart = model.pdoc->LineStart(lineDoc); - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); + std::shared_ptr ll = RetrieveLineLayout(lineDoc, model); if (surface && ll) { - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); + LayoutLine(model, surface, vs, ll.get(), model.wrapWidth); const Sci::Line lineStartSet = model.pcs->DisplayFromDoc(lineDoc); const int subLine = static_cast(visibleLine - lineStartSet); if (subLine < ll->lines) { @@ -666,8 +741,19 @@ SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditMo const XYPOSITION subLineStart = ll->positions[rangeSubLine.start]; if (subLine > 0) // Wrapped pt.x -= ll->wrapIndent; - const Sci::Position positionInLine = ll->FindPositionFromX(static_cast(pt.x + subLineStart), - rangeSubLine, charPosition); + Sci::Position positionInLine = 0; + if (model.BidirectionalEnabled()) { + // Fill the line bidi data + UpdateBidiData(model, vs, ll.get()); + + const ScreenLine screenLine(ll.get(), subLine, vs, rcClient.right, tabWidthMinimumPixels); + std::unique_ptr slLayout = surface->Layout(&screenLine); + positionInLine = slLayout->PositionFromX(static_cast(pt.x), charPosition) + + rangeSubLine.start; + } else { + positionInLine = ll->FindPositionFromX(static_cast(pt.x + subLineStart), + rangeSubLine, charPosition); + } if (positionInLine < rangeSubLine.end) { return SelectionPosition(model.pdoc->MovePositionOutsideChar(positionInLine + posLineStart, 1)); } @@ -687,7 +773,7 @@ SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditMo if (!canReturnInvalid) return SelectionPosition(ll->numCharsInLine + posLineStart); } - return SelectionPosition(canReturnInvalid ? INVALID_POSITION : posLineStart); + return SelectionPosition(canReturnInvalid ? Sci::invalidPosition : posLineStart); } /** @@ -696,10 +782,10 @@ SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditMo * This method is used for rectangular selections and does not work on wrapped lines. */ SelectionPosition EditView::SPositionFromLineX(Surface *surface, const EditModel &model, Sci::Line lineDoc, int x, const ViewStyle &vs) { - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); + std::shared_ptr ll = RetrieveLineLayout(lineDoc, model); if (surface && ll) { const Sci::Position posLineStart = model.pdoc->LineStart(lineDoc); - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); + LayoutLine(model, surface, vs, ll.get(), model.wrapWidth); const Range rangeSubLine = ll->SubLineRange(0, LineLayout::Scope::visibleOnly); const XYPOSITION subLineStart = ll->positions[rangeSubLine.start]; const Sci::Position positionInLine = ll->FindPositionFromX(x + subLineStart, rangeSubLine, false); @@ -717,9 +803,9 @@ SelectionPosition EditView::SPositionFromLineX(Surface *surface, const EditModel Sci::Line EditView::DisplayFromPosition(Surface *surface, const EditModel &model, Sci::Position pos, const ViewStyle &vs) { const Sci::Line lineDoc = model.pdoc->SciLineFromPosition(pos); Sci::Line lineDisplay = model.pcs->DisplayFromDoc(lineDoc); - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); + std::shared_ptr ll = RetrieveLineLayout(lineDoc, model); if (surface && ll) { - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); + LayoutLine(model, surface, vs, ll.get(), model.wrapWidth); const Sci::Position posLineStart = model.pdoc->LineStart(lineDoc); const Sci::Position posInLine = pos - posLineStart; lineDisplay--; // To make up for first increment ahead. @@ -734,11 +820,11 @@ Sci::Line EditView::DisplayFromPosition(Surface *surface, const EditModel &model Sci::Position EditView::StartEndDisplayLine(Surface *surface, const EditModel &model, Sci::Position pos, bool start, const ViewStyle &vs) { const Sci::Line line = model.pdoc->SciLineFromPosition(pos); - AutoLineLayout ll(llc, RetrieveLineLayout(line, model)); - Sci::Position posRet = INVALID_POSITION; + std::shared_ptr ll = RetrieveLineLayout(line, model); + Sci::Position posRet = Sci::invalidPosition; if (surface && ll) { const Sci::Position posLineStart = model.pdoc->LineStart(line); - LayoutLine(model, line, surface, vs, ll, model.wrapWidth); + LayoutLine(model, surface, vs, ll.get(), model.wrapWidth); const Sci::Position posInLine = pos - posLineStart; if (posInLine <= ll->maxLineLength) { for (int subLine = 0; subLine < ll->lines; subLine++) { @@ -751,7 +837,7 @@ Sci::Position EditView::StartEndDisplayLine(Surface *surface, const EditModel &m if (subLine == ll->lines - 1) posRet = ll->numCharsBeforeEOL + posLineStart; else - posRet = ll->LineStart(subLine + 1) + posLineStart - 1; + posRet = model.pdoc->MovePositionOutsideChar(ll->LineStart(subLine + 1) + posLineStart - 1, -1, false); } } } @@ -760,32 +846,59 @@ Sci::Position EditView::StartEndDisplayLine(Surface *surface, const EditModel &m return posRet; } -static ColourDesired SelectionBackground(const ViewStyle &vsDraw, bool main, bool primarySelection) noexcept { - return main ? - (primarySelection ? vsDraw.selColours.back : vsDraw.selBackground2) : - vsDraw.selAdditionalBackground; -} +namespace { -static ColourDesired TextBackground(const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - ColourOptional background, int inSelection, bool inHotspot, int styleMain, Sci::Position i) noexcept { - if (inSelection == 1) { - if (vsDraw.selColours.back.isSet && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) { - return SelectionBackground(vsDraw, true, model.primarySelection); - } - } else if (inSelection == 2) { - if (vsDraw.selColours.back.isSet && (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA)) { - return SelectionBackground(vsDraw, false, model.primarySelection); +constexpr ColourRGBA bugColour = ColourRGBA(0xff, 0, 0xff, 0xf0); + +// Selection background colours are always defined, the value_or is to show if bug + +ColourRGBA SelectionBackground(const EditModel &model, const ViewStyle &vsDraw, InSelection inSelection) { + if (inSelection == InSelection::inNone) + return bugColour; // Not selected is a bug + + Element element = Element::SelectionBack; + if (inSelection == InSelection::inAdditional) + element = Element::SelectionAdditionalBack; + if (!model.primarySelection) + element = Element::SelectionSecondaryBack; + if (!model.hasFocus && vsDraw.ElementColour(Element::SelectionInactiveBack)) + element = Element::SelectionInactiveBack; + return vsDraw.ElementColour(element).value_or(bugColour); +} + +std::optional SelectionForeground(const EditModel &model, const ViewStyle &vsDraw, InSelection inSelection) { + if (inSelection == InSelection::inNone) + return {}; + Element element = Element::SelectionText; + if (inSelection == InSelection::inAdditional) + element = Element::SelectionAdditionalText; + if (!model.primarySelection) // Secondary selection + element = Element::SelectionSecondaryText; + if (!model.hasFocus) { + if (vsDraw.ElementColour(Element::SelectionInactiveText)) { + element = Element::SelectionInactiveText; + } else { + return {}; } - } else { - if ((vsDraw.edgeState == EDGE_BACKGROUND) && - (i >= ll->edgeColumn) && - (i < ll->numCharsBeforeEOL)) - return vsDraw.theEdge.colour; - if (inHotspot && vsDraw.hotspotColours.back.isSet) - return vsDraw.hotspotColours.back; - } - if (background.isSet && (styleMain != STYLE_BRACELIGHT) && (styleMain != STYLE_BRACEBAD)) { - return background; + } + return vsDraw.ElementColour(element); +} + +} + +static ColourRGBA TextBackground(const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + std::optional background, InSelection inSelection, bool inHotspot, int styleMain, Sci::Position i) { + if (inSelection && (vsDraw.selection.layer == Layer::Base)) { + return SelectionBackground(model, vsDraw, inSelection).Opaque(); + } + if ((vsDraw.edgeState == EdgeVisualStyle::Background) && + (i >= ll->edgeColumn) && + (i < ll->numCharsBeforeEOL)) + return vsDraw.theEdge.colour; + if (inHotspot && vsDraw.ElementColour(Element::HotSpotActiveBack)) + return vsDraw.ElementColour(Element::HotSpotActiveBack)->Opaque(); + if (background && (styleMain != StyleBraceLight) && (styleMain != StyleBraceBad)) { + return *background; } else { return vsDraw.styles[styleMain].back; } @@ -799,21 +912,15 @@ void EditView::DrawIndentGuide(Surface *surface, Sci::Line lineVisible, int line highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide); } -static void SimpleAlphaRectangle(Surface *surface, PRectangle rc, ColourDesired fill, int alpha) { - if (alpha != SC_ALPHA_NOALPHA) { - surface->AlphaRectangle(rc, 0, fill, alpha, fill, alpha, 0); - } -} - static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle rcSegment, - const char *s, ColourDesired textBack, ColourDesired textFore, bool fillBackground) { + std::string_view text, ColourRGBA textBack, ColourRGBA textFore, bool fillBackground) { if (rcSegment.Empty()) return; if (fillBackground) { - surface->FillRectangle(rcSegment, textBack); + surface->FillRectangleAligned(rcSegment, Fill(textBack)); } - FontAlias ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font; - const int normalCharHeight = static_cast(std::ceil(vsDraw.styles[STYLE_CONTROLCHAR].capitalHeight)); + const Font *ctrlCharsFont = vsDraw.styles[StyleControlChar].font.get(); + const int normalCharHeight = static_cast(std::ceil(vsDraw.styles[StyleControlChar].capitalHeight)); PRectangle rcCChar = rcSegment; rcCChar.left = rcCChar.left + 1; rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight; @@ -821,49 +928,50 @@ static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle r PRectangle rcCentral = rcCChar; rcCentral.top++; rcCentral.bottom--; - surface->FillRectangle(rcCentral, textFore); + surface->FillRectangleAligned(rcCentral, Fill(textFore)); PRectangle rcChar = rcCChar; rcChar.left++; rcChar.right--; - surface->DrawTextClipped(rcChar, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, s, static_cast(s ? strlen(s) : 0), + surface->DrawTextClippedUTF8(rcChar, ctrlCharsFont, + rcSegment.top + vsDraw.maxAscent, text, textBack, textFore); } -static void DrawFrame(Surface *surface, ColourDesired colour, int alpha, PRectangle rcFrame) { - if (alpha != SC_ALPHA_NOALPHA) - surface->AlphaRectangle(rcFrame, 0, colour, alpha, colour, alpha, 0); - else - surface->FillRectangle(rcFrame, colour); -} - static void DrawCaretLineFramed(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, int subLine) { + const std::optional caretlineBack = vsDraw.ElementColour(Element::CaretLineBack); + if (!caretlineBack) { + return; + } + + const ColourRGBA colourFrame = (vsDraw.caretLine.layer == Layer::Base) ? + caretlineBack->Opaque() : *caretlineBack; + const int width = vsDraw.GetFrameWidth(); - if (subLine == 0 || ll->wrapIndent == 0 || vsDraw.caretLineAlpha != SC_ALPHA_NOALPHA) { + + // Avoid double drawing the corners by removing the left and right sides when drawing top and bottom borders + const PRectangle rcWithoutLeftRight = rcLine.Inset(Point(width, 0.0)); + + if (subLine == 0 || ll->wrapIndent == 0 || vsDraw.caretLine.layer != Layer::Base) { // Left - DrawFrame(surface, vsDraw.caretLineBackground, vsDraw.caretLineAlpha, - PRectangle(rcLine.left, rcLine.top, rcLine.left + width, rcLine.bottom)); + surface->FillRectangleAligned(Side(rcLine, Edge::left, width), colourFrame); } if (subLine == 0) { // Top - DrawFrame(surface, vsDraw.caretLineBackground, vsDraw.caretLineAlpha, - PRectangle(rcLine.left + width, rcLine.top, rcLine.right - width, rcLine.top + width)); + surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::top, width), colourFrame); } - if (subLine == ll->lines - 1 || vsDraw.caretLineAlpha != SC_ALPHA_NOALPHA) { + if (subLine == ll->lines - 1 || vsDraw.caretLine.layer != Layer::Base) { // Right - DrawFrame(surface, vsDraw.caretLineBackground, vsDraw.caretLineAlpha, - PRectangle(rcLine.right - width, rcLine.top, rcLine.right, rcLine.bottom)); + surface->FillRectangleAligned(Side(rcLine, Edge::right, width), colourFrame); } if (subLine == ll->lines - 1) { // Bottom - DrawFrame(surface, vsDraw.caretLineBackground, vsDraw.caretLineAlpha, - PRectangle(rcLine.left + width, rcLine.bottom - width, rcLine.right - width, rcLine.bottom)); + surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::bottom, width), colourFrame); } } void EditView::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) { + std::optional background) { const Sci::Position posLineStart = model.pdoc->LineStart(line); PRectangle rcSegment = rcLine; @@ -880,79 +988,99 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle if (virtualSpace > 0.0f) { rcSegment.left = xEol + xStart; rcSegment.right = xEol + xStart + virtualSpace; - surface->FillRectangle(rcSegment, background.isSet ? background : vsDraw.styles[ll->styles[ll->numCharsInLine]].back); - if (!hideSelection && ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA))) { + const ColourRGBA backgroundFill = background.value_or(vsDraw.styles[ll->styles[ll->numCharsInLine]].back); + surface->FillRectangleAligned(rcSegment, backgroundFill); + if (!hideSelection && (vsDraw.selection.layer == Layer::Base)) { const SelectionSegment virtualSpaceRange(SelectionPosition(model.pdoc->LineEnd(line)), SelectionPosition(model.pdoc->LineEnd(line), model.sel.VirtualSpaceFor(model.pdoc->LineEnd(line)))); for (size_t r = 0; rEndLineStyle()].spaceWidth; - rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - - static_cast(subLineStart)+portion.start.VirtualSpace() * spaceWidth; - rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - - static_cast(subLineStart)+portion.end.VirtualSpace() * spaceWidth; - rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left; - rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right; - surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, r == model.sel.Main(), model.primarySelection)); - } + const SelectionSegment portion = model.sel.Range(r).Intersect(virtualSpaceRange); + if (!portion.Empty()) { + const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; + rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - + static_cast(subLineStart)+portion.start.VirtualSpace() * spaceWidth; + rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - + static_cast(subLineStart)+portion.end.VirtualSpace() * spaceWidth; + rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left; + rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right; + surface->FillRectangleAligned(rcSegment, Fill( + SelectionBackground(model, vsDraw, model.sel.RangeType(r)).Opaque())); } } } } - int eolInSelection = 0; - int alpha = SC_ALPHA_NOALPHA; - if (!hideSelection) { - const Sci::Position posAfterLineEnd = model.pdoc->LineStart(line + 1); - eolInSelection = lastSubLine ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0; - alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; + InSelection eolInSelection = InSelection::inNone; + if (!hideSelection && lastSubLine) { + eolInSelection = model.LineEndInSelection(line); } + const ColourRGBA selectionBack = SelectionBackground(model, vsDraw, eolInSelection); + // Draw the [CR], [LF], or [CR][LF] blobs if visible line ends are on XYPOSITION blobsWidth = 0; if (lastSubLine) { - for (Sci::Position eolPos = ll->numCharsBeforeEOL; eolPosnumCharsInLine; eolPos++) { - rcSegment.left = xStart + ll->positions[eolPos] - static_cast(subLineStart)+virtualSpace; - rcSegment.right = xStart + ll->positions[eolPos + 1] - static_cast(subLineStart)+virtualSpace; - blobsWidth += rcSegment.Width(); - char hexits[4] = ""; - const char *ctrlChar; - const unsigned char chEOL = ll->chars[eolPos]; + for (Sci::Position eolPos = ll->numCharsBeforeEOL; eolPosnumCharsInLine;) { const int styleMain = ll->styles[eolPos]; - const ColourDesired textBack = TextBackground(model, vsDraw, ll, background, eolInSelection, false, styleMain, eolPos); - if (UTF8IsAscii(chEOL)) { - ctrlChar = ControlCharacterString(chEOL); + const std::optional selectionFore = SelectionForeground(model, vsDraw, eolInSelection); + ColourRGBA textFore = selectionFore.value_or(vsDraw.styles[styleMain].fore); + char hexits[4] = ""; + std::string_view ctrlChar; + Sci::Position widthBytes = 1; + RepresentationAppearance appearance = RepresentationAppearance::Blob; + const Representation *repr = model.reprs.RepresentationFromCharacter(std::string_view(&ll->chars[eolPos], ll->numCharsInLine - eolPos)); + if (repr) { + // Representation of whole text + widthBytes = ll->numCharsInLine - eolPos; + } else { + repr = model.reprs.RepresentationFromCharacter(std::string_view(&ll->chars[eolPos], 1)); + } + if (repr) { + ctrlChar = repr->stringRep; + appearance = repr->appearance; + if (FlagSet(appearance, RepresentationAppearance::Colour)) { + textFore = repr->colour; + } } else { - const Representation *repr = model.reprs.RepresentationFromCharacter(&ll->chars[eolPos], ll->numCharsInLine - eolPos); - if (repr) { - ctrlChar = repr->stringRep.c_str(); - eolPos = ll->numCharsInLine; + const unsigned char chEOL = ll->chars[eolPos]; + if (UTF8IsAscii(chEOL)) { + ctrlChar = ControlCharacterString(chEOL); } else { - sprintf(hexits, "x%2X", chEOL); + Hexits(hexits, chEOL); ctrlChar = hexits; } } - ColourDesired textFore = vsDraw.styles[styleMain].fore; - if (eolInSelection && vsDraw.selColours.fore.isSet) { - textFore = (eolInSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground; - } - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1)) { - if (alpha == SC_ALPHA_NOALPHA) { - surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection)); + + rcSegment.left = xStart + ll->positions[eolPos] - static_cast(subLineStart)+virtualSpace; + rcSegment.right = xStart + ll->positions[eolPos + widthBytes] - static_cast(subLineStart)+virtualSpace; + blobsWidth += rcSegment.Width(); + const ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, eolInSelection, false, styleMain, eolPos); + if (eolInSelection && (line < model.pdoc->LinesTotal() - 1)) { + if (vsDraw.selection.layer == Layer::Base) { + surface->FillRectangleAligned(rcSegment, Fill(selectionBack.Opaque())); } else { - surface->FillRectangle(rcSegment, textBack); + surface->FillRectangleAligned(rcSegment, Fill(textBack)); } } else { - surface->FillRectangle(rcSegment, textBack); + surface->FillRectangleAligned(rcSegment, Fill(textBack)); } - DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, textBack, textFore, phasesDraw == phasesOne); - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { - SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); + const bool drawEOLSelection = eolInSelection && (line < model.pdoc->LinesTotal() - 1); + ColourRGBA blobText = textBack; + if (drawEOLSelection && (vsDraw.selection.layer == Layer::UnderText)) { + surface->FillRectangleAligned(rcSegment, selectionBack); + blobText = textBack.MixedWith(selectionBack, selectionBack.GetAlphaComponent()); } + if (FlagSet(appearance, RepresentationAppearance::Blob)) { + DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, blobText, textFore, phasesDraw == PhasesDraw::One); + } else { + surface->DrawTextTransparentUTF8(rcSegment, vsDraw.styles[StyleControlChar].font.get(), + rcSegment.top + vsDraw.maxAscent, ctrlChar, textFore); + } + if (drawEOLSelection && (vsDraw.selection.layer == Layer::OverText)) { + surface->FillRectangleAligned(rcSegment, selectionBack); + } + eolPos += widthBytes; } } @@ -960,20 +1088,20 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle rcSegment.left = xEol + xStart + virtualSpace + blobsWidth; rcSegment.right = rcSegment.left + vsDraw.aveCharWidth; - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) { - surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection)); + if (eolInSelection && (line < model.pdoc->LinesTotal() - 1) && (vsDraw.selection.layer == Layer::Base)) { + surface->FillRectangleAligned(rcSegment, Fill(selectionBack.Opaque())); } else { - if (background.isSet) { - surface->FillRectangle(rcSegment, background); + if (background) { + surface->FillRectangleAligned(rcSegment, Fill(*background)); } else if (line < model.pdoc->LinesTotal() - 1) { - surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine]].back); + surface->FillRectangleAligned(rcSegment, Fill(vsDraw.styles[ll->styles[ll->numCharsInLine]].back)); } else if (vsDraw.styles[ll->styles[ll->numCharsInLine]].eolFilled) { - surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine]].back); + surface->FillRectangleAligned(rcSegment, Fill(vsDraw.styles[ll->styles[ll->numCharsInLine]].back)); } else { - surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back); + surface->FillRectangleAligned(rcSegment, Fill(vsDraw.styles[StyleDefault].back)); } - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { - SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); + if (eolInSelection && (line < model.pdoc->LinesTotal() - 1) && (vsDraw.selection.layer != Layer::Base)) { + surface->FillRectangleAligned(rcSegment, selectionBack); } } @@ -982,7 +1110,7 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle rcSegment.left = rcLine.left; rcSegment.right = rcLine.right; - const bool drawEOLAnnotationStyledText = (vsDraw.eolAnnotationVisible != EOLANNOTATION_HIDDEN) && model.pdoc->EOLAnnotationStyledText(line).text; + const bool drawEOLAnnotationStyledText = (vsDraw.eolAnnotationVisible != EOLAnnotationVisible::Hidden) && model.pdoc->EOLAnnotationStyledText(line).text; const bool fillRemainder = (!lastSubLine || (!model.GetFoldDisplayText(line) && !drawEOLAnnotationStyledText)); if (fillRemainder) { // Fill the remainder of the line @@ -992,21 +1120,20 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle bool drawWrapMarkEnd = false; if (subLine + 1 < ll->lines) { - if (vsDraw.wrapVisualFlags & SC_WRAPVISUALFLAG_END) { + if (FlagSet(vsDraw.wrap.visualFlags, WrapVisualFlag::End)) { drawWrapMarkEnd = ll->LineStart(subLine + 1) != 0; } if (vsDraw.IsLineFrameOpaque(model.caret.active, ll->containsCaret)) { - const int width = vsDraw.GetFrameWidth(); // Draw right of frame under marker - DrawFrame(surface, vsDraw.caretLineBackground, vsDraw.caretLineAlpha, - PRectangle(rcLine.right - width, rcLine.top, rcLine.right, rcLine.bottom)); + surface->FillRectangleAligned(Side(rcLine, Edge::right, vsDraw.GetFrameWidth()), + vsDraw.ElementColour(Element::CaretLineBack)->Opaque()); } } if (drawWrapMarkEnd) { PRectangle rcPlace = rcSegment; - if (vsDraw.wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_END_BY_TEXT) { + if (FlagSet(vsDraw.wrap.visualFlagsLocation, WrapVisualLocation::EndByText)) { rcPlace.left = xEol + xStart + virtualSpace; rcPlace.right = rcPlace.left + vsDraw.aveCharWidth; } else { @@ -1023,27 +1150,52 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle } static void DrawIndicator(int indicNum, Sci::Position startPos, Sci::Position endPos, Surface *surface, const ViewStyle &vsDraw, - const LineLayout *ll, int xStart, PRectangle rcLine, Sci::Position secondCharacter, int subLine, Indicator::State state, int value) { + const LineLayout *ll, int xStart, PRectangle rcLine, Sci::Position secondCharacter, int subLine, Indicator::State state, + int value, bool bidiEnabled, int tabWidthMinimumPixels) { + const XYPOSITION subLineStart = ll->positions[ll->LineStart(subLine)]; + + std::vector rectangles; + const PRectangle rcIndic( ll->positions[startPos] + xStart - subLineStart, rcLine.top + vsDraw.maxAscent, ll->positions[endPos] + xStart - subLineStart, rcLine.top + vsDraw.maxAscent + 3); - PRectangle rcFirstCharacter = rcIndic; - // Allow full descent space for character indicators - rcFirstCharacter.bottom = rcLine.top + vsDraw.maxAscent + vsDraw.maxDescent; - if (secondCharacter >= 0) { - rcFirstCharacter.right = ll->positions[secondCharacter] + xStart - subLineStart; + + if (bidiEnabled) { + ScreenLine screenLine(ll, subLine, vsDraw, rcLine.right - xStart, tabWidthMinimumPixels); + const Range lineRange = ll->SubLineRange(subLine, LineLayout::Scope::visibleOnly); + + std::unique_ptr slLayout = surface->Layout(&screenLine); + std::vector intervals = slLayout->FindRangeIntervals( + startPos - lineRange.start, endPos - lineRange.start); + for (const Interval &interval : intervals) { + PRectangle rcInterval = rcIndic; + rcInterval.left = interval.left + xStart; + rcInterval.right = interval.right + xStart; + rectangles.push_back(rcInterval); + } } else { - // Indicator continued from earlier line so make an empty box and don't draw - rcFirstCharacter.right = rcFirstCharacter.left; + rectangles.push_back(rcIndic); + } + + for (const PRectangle &rc : rectangles) { + PRectangle rcFirstCharacter = rc; + // Allow full descent space for character indicators + rcFirstCharacter.bottom = rcLine.top + vsDraw.maxAscent + vsDraw.maxDescent; + if (secondCharacter >= 0) { + rcFirstCharacter.right = ll->positions[secondCharacter] + xStart - subLineStart; + } else { + // Indicator continued from earlier line so make an empty box and don't draw + rcFirstCharacter.right = rcFirstCharacter.left; + } + vsDraw.indicators[indicNum].Draw(surface, rc, rcLine, rcFirstCharacter, state, value); } - vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine, rcFirstCharacter, state, value); } static void DrawIndicators(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Position lineEnd, bool under, Sci::Position hoverIndicatorPos) { + Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Position lineEnd, bool under, int tabWidthMinimumPixels) { // Draw decorators const Sci::Position posLineStart = model.pdoc->LineStart(line); const Sci::Position lineStart = ll->LineStart(subLine); @@ -1059,12 +1211,13 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS const Range rangeRun(deco->StartRun(startPos), deco->EndRun(startPos)); const Sci::Position endPos = std::min(rangeRun.end, posLineEnd); const bool hover = vsDraw.indicators[deco->Indicator()].IsDynamic() && - rangeRun.ContainsCharacter(hoverIndicatorPos); + rangeRun.ContainsCharacter(model.hoverIndicatorPos); const int value = deco->ValueAt(startPos); const Indicator::State state = hover ? Indicator::State::hover : Indicator::State::normal; const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1); DrawIndicator(deco->Indicator(), startPos - posLineStart, endPos - posLineStart, - surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, state, value); + surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, state, + value, model.BidirectionalEnabled(), tabWidthMinimumPixels); startPos = endPos; if (!deco->ValueAt(startPos)) { startPos = deco->EndRun(startPos); @@ -1074,23 +1227,25 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS } // Use indicators to highlight matching braces - if ((vsDraw.braceHighlightIndicatorSet && (model.bracesMatchStyle == STYLE_BRACELIGHT)) || - (vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == STYLE_BRACEBAD))) { - const int braceIndicator = (model.bracesMatchStyle == STYLE_BRACELIGHT) ? vsDraw.braceHighlightIndicator : vsDraw.braceBadLightIndicator; + if ((vsDraw.braceHighlightIndicatorSet && (model.bracesMatchStyle == StyleBraceLight)) || + (vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == StyleBraceBad))) { + const int braceIndicator = (model.bracesMatchStyle == StyleBraceLight) ? vsDraw.braceHighlightIndicator : vsDraw.braceBadLightIndicator; if (under == vsDraw.indicators[braceIndicator].under) { const Range rangeLine(posLineStart + lineStart, posLineEnd); if (rangeLine.ContainsCharacter(model.braces[0])) { const Sci::Position braceOffset = model.braces[0] - posLineStart; if (braceOffset < ll->numCharsInLine) { const Sci::Position secondOffset = model.pdoc->MovePositionOutsideChar(model.braces[0] + 1, 1) - posLineStart; - DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::State::normal, 1); + DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, + subLine, Indicator::State::normal, 1, model.BidirectionalEnabled(), tabWidthMinimumPixels); } } if (rangeLine.ContainsCharacter(model.braces[1])) { const Sci::Position braceOffset = model.braces[1] - posLineStart; if (braceOffset < ll->numCharsInLine) { const Sci::Position secondOffset = model.pdoc->MovePositionOutsideChar(model.braces[1] + 1, 1) - posLineStart; - DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::State::normal, 1); + DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, + subLine, Indicator::State::normal, 1, model.BidirectionalEnabled(), tabWidthMinimumPixels); } } } @@ -1108,17 +1263,13 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con return; PRectangle rcSegment = rcLine; - const char *foldDisplayText = text; - const int lengthFoldDisplayText = static_cast(strlen(foldDisplayText)); - FontAlias fontText = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].font; - const int widthFoldDisplayText = static_cast(surface->WidthText(fontText, foldDisplayText, lengthFoldDisplayText)); + const std::string_view foldDisplayText(text); + const Font *fontText = vsDraw.styles[StyleFoldDisplayText].font.get(); + const int widthFoldDisplayText = static_cast(surface->WidthText(fontText, foldDisplayText)); - int eolInSelection = 0; - int alpha = SC_ALPHA_NOALPHA; + InSelection eolInSelection = InSelection::inNone; if (!hideSelection) { - const Sci::Position posAfterLineEnd = model.pdoc->LineStart(line + 1); - eolInSelection = (subLine == (ll->lines - 1)) ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0; - alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; + eolInSelection = model.LineEndInSelection(line); } const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; @@ -1127,13 +1278,11 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con rcSegment.left = xStart + static_cast(ll->positions[ll->numCharsInLine] - subLineStart) + virtualSpace + vsDraw.aveCharWidth; rcSegment.right = rcSegment.left + static_cast(widthFoldDisplayText); - const ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); - ColourDesired textFore = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].fore; - if (eolInSelection && (vsDraw.selColours.fore.isSet)) { - textFore = (eolInSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground; - } - const ColourDesired textBack = TextBackground(model, vsDraw, ll, background, eolInSelection, - false, STYLE_FOLDDISPLAYTEXT, -1); + const std::optional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); + const std::optional selectionFore = SelectionForeground(model, vsDraw, eolInSelection); + const ColourRGBA textFore = selectionFore.value_or(vsDraw.styles[StyleFoldDisplayText].fore); + const ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, eolInSelection, + false, StyleFoldDisplayText, -1); if (model.trackLineWidth) { if (rcSegment.right + 1> lineWidthMaxSeen) { @@ -1142,8 +1291,8 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con } } - if (phase & drawBack) { - surface->FillRectangle(rcSegment, textBack); + if (FlagSet(phase, DrawPhase::back)) { + surface->FillRectangleAligned(rcSegment, Fill(textBack)); // Fill Remainder of the line PRectangle rcRemainder = rcSegment; @@ -1154,39 +1303,30 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con FillLineRemainder(surface, model, vsDraw, ll, line, rcRemainder, subLine); } - if (phase & drawText) { - if (phasesDraw != phasesOne) { + if (FlagSet(phase, DrawPhase::text)) { + if (phasesDraw != PhasesDraw::One) { surface->DrawTextTransparent(rcSegment, fontText, rcSegment.top + vsDraw.maxAscent, foldDisplayText, - lengthFoldDisplayText, textFore); + textFore); } else { surface->DrawTextNoClip(rcSegment, fontText, rcSegment.top + vsDraw.maxAscent, foldDisplayText, - lengthFoldDisplayText, textFore, textBack); + textFore, textBack); } } - if (phase & drawIndicatorsFore) { - if (model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_BOXED) { - surface->PenColour(textFore); + if (FlagSet(phase, DrawPhase::indicatorsFore)) { + if (model.foldDisplayTextStyle == FoldDisplayTextStyle::Boxed) { PRectangle rcBox = rcSegment; - rcBox.left = Sci::round(rcSegment.left); - rcBox.right = Sci::round(rcSegment.right); - const IntegerRectangle ircBox(rcBox); - surface->MoveTo(ircBox.left, ircBox.top); - surface->LineTo(ircBox.left, ircBox.bottom); - surface->MoveTo(ircBox.right, ircBox.top); - surface->LineTo(ircBox.right, ircBox.bottom); - surface->MoveTo(ircBox.left, ircBox.top); - surface->LineTo(ircBox.right, ircBox.top); - surface->MoveTo(ircBox.left, ircBox.bottom - 1); - surface->LineTo(ircBox.right, ircBox.bottom - 1); + rcBox.left = std::round(rcSegment.left); + rcBox.right = std::round(rcSegment.right); + surface->RectangleFrame(rcBox, Stroke(textFore)); } } - if (phase & drawSelectionTranslucent) { - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && alpha != SC_ALPHA_NOALPHA) { - SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); + if (FlagSet(phase, DrawPhase::selectionTranslucent)) { + if (eolInSelection && (line < model.pdoc->LinesTotal() - 1) && (vsDraw.selection.layer != Layer::Base)) { + surface->FillRectangleAligned(rcSegment, SelectionBackground(model, vsDraw, eolInSelection)); } } } @@ -1197,18 +1337,57 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c if (!lastSubLine) return; - if (vsDraw.eolAnnotationVisible == EOLANNOTATION_HIDDEN) { + if (vsDraw.eolAnnotationVisible == EOLAnnotationVisible::Hidden) { return; } const StyledText stEOLAnnotation = model.pdoc->EOLAnnotationStyledText(line); if (!stEOLAnnotation.text || !ValidStyledText(vsDraw, vsDraw.eolAnnotationStyleOffset, stEOLAnnotation)) { return; } + const std::string_view eolAnnotationText(stEOLAnnotation.text, stEOLAnnotation.length); const size_t style = stEOLAnnotation.style + vsDraw.eolAnnotationStyleOffset; PRectangle rcSegment = rcLine; - FontAlias fontText = vsDraw.styles[style].font; - const int widthEOLAnnotationText = static_cast(surface->WidthText(fontText, stEOLAnnotation.text, stEOLAnnotation.length)); + const Font *fontText = vsDraw.styles[style].font.get(); + + const Surface::Ends ends = static_cast(static_cast(vsDraw.eolAnnotationVisible) & 0xff); + const Surface::Ends leftSide = static_cast(static_cast(ends) & 0xf); + const Surface::Ends rightSide = static_cast(static_cast(ends) & 0xf0); + + XYPOSITION leftBoxSpace = 0; + XYPOSITION rightBoxSpace = 0; + if (vsDraw.eolAnnotationVisible >= EOLAnnotationVisible::Boxed) { + leftBoxSpace = 1; + rightBoxSpace = 1; + if (vsDraw.eolAnnotationVisible != EOLAnnotationVisible::Boxed) { + switch (leftSide) { + case Surface::Ends::leftFlat: + leftBoxSpace = 1; + break; + case Surface::Ends::leftAngle: + leftBoxSpace = rcLine.Height() / 2.0; + break; + case Surface::Ends::semiCircles: + default: + leftBoxSpace = rcLine.Height() / 3.0; + break; + } + switch (rightSide) { + case Surface::Ends::rightFlat: + rightBoxSpace = 1; + break; + case Surface::Ends::rightAngle: + rightBoxSpace = rcLine.Height() / 2.0; + break; + case Surface::Ends::semiCircles: + default: + rightBoxSpace = rcLine.Height() / 3.0; + break; + } + } + } + const int widthEOLAnnotationText = static_cast(surface->WidthTextUTF8(fontText, eolAnnotationText) + + leftBoxSpace + rightBoxSpace); const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; const XYPOSITION virtualSpace = model.sel.VirtualSpaceFor( @@ -1219,13 +1398,14 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c const char *textFoldDisplay = model.GetFoldDisplayText(line); if (textFoldDisplay) { - rcSegment.left += (static_cast(surface->WidthText(fontText, textFoldDisplay, static_cast(strlen(textFoldDisplay)))) + vsDraw.aveCharWidth); + const std::string_view foldDisplayText(textFoldDisplay); + rcSegment.left += (static_cast(surface->WidthText(fontText, foldDisplayText)) + vsDraw.aveCharWidth); } rcSegment.right = rcSegment.left + static_cast(widthEOLAnnotationText); - const ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); - ColourDesired textFore = vsDraw.styles[style].fore; - const ColourDesired textBack = TextBackground(model, vsDraw, ll, background, false, + const std::optional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); + const ColourRGBA textFore = vsDraw.styles[style].fore; + const ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, InSelection::inNone, false, static_cast(style), -1); if (model.trackLineWidth) { @@ -1235,51 +1415,61 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c } } - if (phase & drawBack) { - surface->FillRectangle(rcSegment, textBack); - - // Fill Remainder of the line + if (FlagSet(phase, DrawPhase::back)) { + // This fills in the whole remainder of the line even though + // it may be double drawing. This is to allow stadiums with + // curved or angled ends to have the area outside in the correct + // background colour. PRectangle rcRemainder = rcSegment; - rcRemainder.left = rcRemainder.right; - if (rcRemainder.left < rcLine.left) - rcRemainder.left = rcLine.left; rcRemainder.right = rcLine.right; FillLineRemainder(surface, model, vsDraw, ll, line, rcRemainder, subLine); } - if (phase & drawText) { - if (phasesDraw != phasesOne) { - surface->DrawTextTransparent(rcSegment, fontText, - rcSegment.top + vsDraw.maxAscent, stEOLAnnotation.text, stEOLAnnotation.length, - textFore); - } else { - surface->DrawTextNoClip(rcSegment, fontText, - rcSegment.top + vsDraw.maxAscent, stEOLAnnotation.text, stEOLAnnotation.length, + PRectangle rcText = rcSegment; + rcText.left += leftBoxSpace; + rcText.right -= rightBoxSpace; + + // For single phase drawing, draw the text then any box over it + if (FlagSet(phase, DrawPhase::text)) { + if (phasesDraw == PhasesDraw::One) { + surface->DrawTextNoClipUTF8(rcText, fontText, + rcText.top + vsDraw.maxAscent, eolAnnotationText, textFore, textBack); } } - if (phase & drawIndicatorsFore) { - if (vsDraw.eolAnnotationVisible == EOLANNOTATION_BOXED ) { - surface->PenColour(textFore); + // Draw any box or stadium shape + if (FlagSet(phase, DrawPhase::indicatorsBack)) { + if (vsDraw.eolAnnotationVisible >= EOLAnnotationVisible::Boxed) { PRectangle rcBox = rcSegment; - rcBox.left = Sci::round(rcSegment.left); - rcBox.right = Sci::round(rcSegment.right); - const IntegerRectangle ircBox(rcBox); - surface->MoveTo(ircBox.left, ircBox.top); - surface->LineTo(ircBox.left, ircBox.bottom); - surface->MoveTo(ircBox.right, ircBox.top); - surface->LineTo(ircBox.right, ircBox.bottom); - surface->MoveTo(ircBox.left, ircBox.top); - surface->LineTo(ircBox.right, ircBox.top); - surface->MoveTo(ircBox.left, ircBox.bottom - 1); - surface->LineTo(ircBox.right, ircBox.bottom - 1); + rcBox.left = std::round(rcSegment.left); + rcBox.right = std::round(rcSegment.right); + if (vsDraw.eolAnnotationVisible == EOLAnnotationVisible::Boxed) { + surface->RectangleFrame(rcBox, Stroke(textFore)); + } else { + if (phasesDraw == PhasesDraw::One) { + // Draw an outline around the text + surface->Stadium(rcBox, FillStroke(ColourRGBA(textBack, 0), textFore, 1.0), ends); + } else { + // Draw with a fill to fill the edges of the shape. + surface->Stadium(rcBox, FillStroke(textBack, textFore, 1.0), ends); + } + } + } + } + + // For multi-phase drawing draw the text last as transparent over any box + if (FlagSet(phase, DrawPhase::text)) { + if (phasesDraw != PhasesDraw::One) { + surface->DrawTextTransparentUTF8(rcText, fontText, + rcText.top + vsDraw.maxAscent, eolAnnotationText, + textFore); } } } -static constexpr bool AnnotationBoxedOrIndented(int annotationVisible) noexcept { - return annotationVisible == ANNOTATION_BOXED || annotationVisible == ANNOTATION_INDENTED; +static constexpr bool AnnotationBoxedOrIndented(AnnotationVisible annotationVisible) noexcept { + return annotationVisible == AnnotationVisible::Boxed || annotationVisible == AnnotationVisible::Indented; } void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, @@ -1289,8 +1479,8 @@ void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const Vi const int annotationLine = subLine - ll->lines; const StyledText stAnnotation = model.pdoc->AnnotationStyledText(line); if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) { - if (phase & drawBack) { - surface->FillRectangle(rcSegment, vsDraw.styles[0].back); + if (FlagSet(phase, DrawPhase::back)) { + surface->FillRectangleAligned(rcSegment, Fill(vsDraw.styles[0].back)); } rcSegment.left = static_cast(xStart); if (model.trackLineWidth || AnnotationBoxedOrIndented(vsDraw.annotationVisible)) { @@ -1314,34 +1504,30 @@ void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const Vi lineInAnnotation++; } PRectangle rcText = rcSegment; - if ((phase & drawBack) && AnnotationBoxedOrIndented(vsDraw.annotationVisible)) { - surface->FillRectangle(rcText, - vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back); + if ((FlagSet(phase, DrawPhase::back)) && AnnotationBoxedOrIndented(vsDraw.annotationVisible)) { + surface->FillRectangleAligned(rcText, + Fill(vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back)); rcText.left += vsDraw.spaceWidth; } DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, stAnnotation, start, lengthAnnotation, phase); - if ((phase & drawBack) && (vsDraw.annotationVisible == ANNOTATION_BOXED)) { - surface->PenColour(vsDraw.styles[vsDraw.annotationStyleOffset].fore); - const IntegerRectangle ircSegment(rcSegment); - surface->MoveTo(ircSegment.left, ircSegment.top); - surface->LineTo(ircSegment.left, ircSegment.bottom); - surface->MoveTo(ircSegment.right, ircSegment.top); - surface->LineTo(ircSegment.right, ircSegment.bottom); + if ((FlagSet(phase, DrawPhase::back)) && (vsDraw.annotationVisible == AnnotationVisible::Boxed)) { + const ColourRGBA colourBorder = vsDraw.styles[vsDraw.annotationStyleOffset].fore; + const PRectangle rcBorder = PixelAlignOutside(rcSegment, surface->PixelDivisions()); + surface->FillRectangle(Side(rcBorder, Edge::left, 1), colourBorder); + surface->FillRectangle(Side(rcBorder, Edge::right, 1), colourBorder); if (subLine == ll->lines) { - surface->MoveTo(ircSegment.left, ircSegment.top); - surface->LineTo(ircSegment.right, ircSegment.top); + surface->FillRectangle(Side(rcBorder, Edge::top, 1), colourBorder); } if (subLine == ll->lines + annotationLines - 1) { - surface->MoveTo(ircSegment.left, ircSegment.bottom - 1); - surface->LineTo(ircSegment.right, ircSegment.bottom - 1); + surface->FillRectangle(Side(rcBorder, Edge::bottom, 1), colourBorder); } } } } static void DrawBlockCaret(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int subLine, int xStart, Sci::Position offset, Sci::Position posCaret, PRectangle rcCaret, ColourDesired caretColour) { + int subLine, int xStart, Sci::Position offset, Sci::Position posCaret, PRectangle rcCaret, ColourRGBA caretColour) { const Sci::Position lineStart = ll->LineStart(subLine); Sci::Position posBefore = posCaret; @@ -1399,10 +1585,10 @@ static void DrawBlockCaret(Surface *surface, const EditModel &model, const ViewS // This character is where the caret block is, we override the colours // (inversed) for drawing the caret here. const int styleMain = ll->styles[offsetFirstChar]; - FontAlias fontText = vsDraw.styles[styleMain].font; + const Font *fontText = vsDraw.styles[styleMain].font.get(); + const std::string_view text(&ll->chars[offsetFirstChar], numCharsToDraw); surface->DrawTextClipped(rcCaret, fontText, - rcCaret.top + vsDraw.maxAscent, &ll->chars[offsetFirstChar], - static_cast(numCharsToDraw), vsDraw.styles[styleMain].back, + rcCaret.top + vsDraw.maxAscent, text, vsDraw.styles[styleMain].back, caretColour); } @@ -1417,7 +1603,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt for (size_t r = 0; (r model.sel.Range(r).anchor) { if (posCaret.VirtualSpace() > 0) @@ -1430,6 +1616,18 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt const XYPOSITION virtualOffset = posCaret.VirtualSpace() * spaceWidth; if (ll->InLine(offset, subLine) && offset <= ll->numCharsBeforeEOL) { XYPOSITION xposCaret = ll->positions[offset] + virtualOffset - ll->positions[ll->LineStart(subLine)]; + if (model.BidirectionalEnabled() && (posCaret.VirtualSpace() == 0)) { + // Get caret point + const ScreenLine screenLine(ll, subLine, vsDraw, rcLine.right, tabWidthMinimumPixels); + + const int caretPosition = offset - ll->LineStart(subLine); + + std::unique_ptr slLayout = surface->Layout(&screenLine); + const XYPOSITION caretLeft = slLayout->XFromPosition(caretPosition); + + // In case of start of line, the cursor should be at the right + xposCaret = caretLeft + virtualOffset; + } if (ll->wrapIndent != 0) { const Sci::Position lineStart = ll->LineStart(subLine); if (lineStart != 0) // Wrapped @@ -1464,10 +1662,10 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt const ViewStyle::CaretShape caretShape = drawDrag ? ViewStyle::CaretShape::line : vsDraw.CaretShapeForMode(model.inOverstrike); if (drawDrag) { /* Dragging text, use a line caret */ - rcCaret.left = Sci::round(xposCaret - caretWidthOffset); - rcCaret.right = rcCaret.left + vsDraw.caretWidth; + rcCaret.left = std::round(xposCaret - caretWidthOffset); + rcCaret.right = rcCaret.left + vsDraw.caret.width; } else if ((caretShape == ViewStyle::CaretShape::bar) && drawOverstrikeCaret) { - /* Overstrike (insert mode), use a modified bar caret */ + /* Over-strike (insert mode), use a modified bar caret */ rcCaret.top = rcCaret.bottom - 2; rcCaret.left = xposCaret + 1; rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1; @@ -1482,14 +1680,16 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt } } else { /* Line caret */ - rcCaret.left = Sci::round(xposCaret - caretWidthOffset); - rcCaret.right = rcCaret.left + vsDraw.caretWidth; + rcCaret.left = std::round(xposCaret - caretWidthOffset); + rcCaret.right = rcCaret.left + vsDraw.caret.width; } - const ColourDesired caretColour = mainCaret ? vsDraw.caretcolour : vsDraw.additionalCaretColour; + const Element elementCaret = mainCaret ? Element::Caret : Element::CaretAdditional; + const ColourRGBA caretColour = *vsDraw.ElementColour(elementCaret); + //assert(caretColour.IsOpaque()); if (drawBlockCaret) { DrawBlockCaret(surface, model, vsDraw, ll, subLine, xStart, offset, posCaret.Position(), rcCaret, caretColour); } else { - surface->FillRectangle(rcCaret, caretColour); + surface->FillRectangleAligned(rcCaret, Fill(caretColour)); } } } @@ -1499,20 +1699,19 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt } static void DrawWrapIndentAndMarker(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, - int xStart, PRectangle rcLine, ColourOptional background, DrawWrapMarkerFn customDrawWrapMarker, + int xStart, PRectangle rcLine, std::optional background, DrawWrapMarkerFn customDrawWrapMarker, bool caretActive) { // default bgnd here.. - surface->FillRectangle(rcLine, background.isSet ? background : - vsDraw.styles[STYLE_DEFAULT].back); + surface->FillRectangleAligned(rcLine, Fill(background ? *background : + vsDraw.styles[StyleDefault].back)); if (vsDraw.IsLineFrameOpaque(caretActive, ll->containsCaret)) { - const int width = vsDraw.GetFrameWidth(); // Draw left of frame under marker - DrawFrame(surface, vsDraw.caretLineBackground, vsDraw.caretLineAlpha, - PRectangle(rcLine.left, rcLine.top, rcLine.left + width, rcLine.bottom)); + surface->FillRectangleAligned(Side(rcLine, Edge::left, vsDraw.GetFrameWidth()), + vsDraw.ElementColour(Element::CaretLineBack)->Opaque()); } - if (vsDraw.wrapVisualFlags & SC_WRAPVISUALFLAG_START) { + if (FlagSet(vsDraw.wrap.visualFlags, WrapVisualFlag::Start)) { // draw continuation rect PRectangle rcPlace = rcLine; @@ -1520,7 +1719,7 @@ static void DrawWrapIndentAndMarker(Surface *surface, const ViewStyle &vsDraw, c rcPlace.left = static_cast(xStart); rcPlace.right = rcPlace.left + ll->wrapIndent; - if (vsDraw.wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_START_BY_TEXT) + if (FlagSet(vsDraw.wrap.visualFlagsLocation, WrapVisualLocation::StartByText)) rcPlace.left = rcPlace.right - vsDraw.aveCharWidth; else rcPlace.right = rcPlace.left + vsDraw.aveCharWidth; @@ -1535,17 +1734,17 @@ static void DrawWrapIndentAndMarker(Surface *surface, const ViewStyle &vsDraw, c 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, ColourOptional background) const { + int subLine, std::optional background) const { const bool selBackDrawn = vsDraw.SelectionBackgroundDrawn(); bool inIndentation = subLine == 0; // Do not handle indentation except on first subline. const XYACCUMULATOR subLineStart = ll->positions[lineRange.start]; // Does not take margin into account but not significant - const int xStartVisible = static_cast(subLineStart)-xStart; + const XYPOSITION xStartVisible = static_cast(subLineStart-xStart); BreakFinder bfBack(ll, &model.sel, lineRange, posLineStart, xStartVisible, selBackDrawn, model.pdoc, &model.reprs, nullptr); - const bool drawWhitespaceBackground = vsDraw.WhitespaceBackgroundDrawn() && !background.isSet; + const bool drawWhitespaceBackground = vsDraw.WhitespaceBackgroundDrawn() && !background; // Background drawing loop while (bfBack.More()) { @@ -1566,24 +1765,25 @@ void EditView::DrawBackground(Surface *surface, const EditModel &model, const Vi if (rcSegment.right > rcLine.right) rcSegment.right = rcLine.right; - const int inSelection = hideSelection ? 0 : model.sel.CharacterInSelection(iDoc); + const InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); const bool inHotspot = (ll->hotspot.Valid()) && ll->hotspot.ContainsCharacter(iDoc); - ColourDesired textBack = TextBackground(model, vsDraw, ll, background, inSelection, + ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, inSelection, inHotspot, ll->styles[i], i); if (ts.representation) { if (ll->chars[i] == '\t') { // Tab display - if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) - textBack = vsDraw.whitespaceColours.back; + if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) { + textBack = vsDraw.ElementColour(Element::WhiteSpaceBack)->Opaque(); + } } else { // Blob display inIndentation = false; } - surface->FillRectangle(rcSegment, textBack); + surface->FillRectangleAligned(rcSegment, Fill(textBack)); } else { // Normal text display - surface->FillRectangle(rcSegment, textBack); - if (vsDraw.viewWhitespace != wsInvisible) { + surface->FillRectangleAligned(rcSegment, Fill(textBack)); + if (vsDraw.viewWhitespace != WhiteSpace::Invisible) { for (int cpos = 0; cpos <= i - ts.start; cpos++) { if (ll->chars[cpos + ts.start] == ' ') { if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) { @@ -1592,7 +1792,8 @@ void EditView::DrawBackground(Surface *surface, const EditModel &model, const Vi rcSegment.top, ll->positions[cpos + ts.start + 1] + xStart - static_cast(subLineStart), rcSegment.bottom); - surface->FillRectangle(rcSpace, vsDraw.whitespaceColours.back); + surface->FillRectangleAligned(rcSpace, + vsDraw.ElementColour(Element::WhiteSpaceBack)->Opaque()); } } else { inIndentation = false; @@ -1608,15 +1809,15 @@ void EditView::DrawBackground(Surface *surface, const EditModel &model, const Vi static void DrawEdgeLine(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, Range lineRange, int xStart) { - if (vsDraw.edgeState == EDGE_LINE) { + if (vsDraw.edgeState == EdgeVisualStyle::Line) { PRectangle rcSegment = rcLine; const int edgeX = static_cast(vsDraw.theEdge.column * vsDraw.spaceWidth); rcSegment.left = static_cast(edgeX + xStart); if ((ll->wrapIndent != 0) && (lineRange.start != 0)) rcSegment.left -= ll->wrapIndent; rcSegment.right = rcSegment.left + 1; - surface->FillRectangle(rcSegment, vsDraw.theEdge.colour); - } else if (vsDraw.edgeState == EDGE_MULTILINE) { + surface->FillRectangleAligned(rcSegment, Fill(vsDraw.theEdge.colour)); + } else if (vsDraw.edgeState == EdgeVisualStyle::MultiLine) { for (size_t edge = 0; edge < vsDraw.theMultiEdge.size(); edge++) { if (vsDraw.theMultiEdge[edge].column >= 0) { PRectangle rcSegment = rcLine; @@ -1625,30 +1826,30 @@ static void DrawEdgeLine(Surface *surface, const ViewStyle &vsDraw, const LineLa if ((ll->wrapIndent != 0) && (lineRange.start != 0)) rcSegment.left -= ll->wrapIndent; rcSegment.right = rcSegment.left + 1; - surface->FillRectangle(rcSegment, vsDraw.theMultiEdge[edge].colour); + surface->FillRectangleAligned(rcSegment, Fill(vsDraw.theMultiEdge[edge].colour)); } } } } -// Draw underline mark as part of background if not transparent +// Draw underline mark as part of background if on base layer static void DrawMarkUnderline(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, Sci::Line line, PRectangle rcLine) { int marks = model.pdoc->GetMark(line); for (int markBit = 0; (markBit < 32) && marks; markBit++) { - if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE) && - (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) { + if ((marks & 1) && (vsDraw.markers[markBit].markType == MarkerSymbol::Underline) && + (vsDraw.markers[markBit].layer == Layer::Base)) { PRectangle rcUnderline = rcLine; rcUnderline.top = rcUnderline.bottom - 2; - surface->FillRectangle(rcUnderline, vsDraw.markers[markBit].back); + surface->FillRectangleAligned(rcUnderline, Fill(vsDraw.markers[markBit].back)); } marks >>= 1; } } static void DrawTranslucentSelection(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, PRectangle rcLine, int subLine, Range lineRange, int xStart) { - if ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha != SC_ALPHA_NOALPHA)) { + Sci::Line line, PRectangle rcLine, int subLine, Range lineRange, int xStart, int tabWidthMinimumPixels, Layer layer) { + if (vsDraw.selection.layer == layer) { const Sci::Position posLineStart = model.pdoc->LineStart(line); const XYACCUMULATOR subLineStart = ll->positions[lineRange.start]; // For each selection draw @@ -1660,16 +1861,40 @@ static void DrawTranslucentSelection(Surface *surface, const EditModel &model, c const SelectionPosition posEnd(posLineStart + lineRange.end, virtualSpaces); const SelectionSegment virtualSpaceRange(posStart, posEnd); for (size_t r = 0; r < model.sel.Count(); r++) { - const int alpha = (r == model.sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; - if (alpha != SC_ALPHA_NOALPHA) { - const SelectionSegment portion = model.sel.Range(r).Intersect(virtualSpaceRange); - if (!portion.Empty()) { - const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; + const SelectionSegment portion = model.sel.Range(r).Intersect(virtualSpaceRange); + if (!portion.Empty()) { + const ColourRGBA selectionBack = SelectionBackground( + model, vsDraw, model.sel.RangeType(r)); + const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; + if (model.BidirectionalEnabled()) { + const int selectionStart = static_cast(portion.start.Position() - posLineStart - lineRange.start); + const int selectionEnd = static_cast(portion.end.Position() - posLineStart - lineRange.start); + + const ScreenLine screenLine(ll, subLine, vsDraw, rcLine.right, tabWidthMinimumPixels); + std::unique_ptr slLayout = surface->Layout(&screenLine); + + const std::vector intervals = slLayout->FindRangeIntervals(selectionStart, selectionEnd); + for (const Interval &interval : intervals) { + const XYPOSITION rcRight = interval.right + xStart; + const XYPOSITION rcLeft = interval.left + xStart; + const PRectangle rcSelection(rcLeft, rcLine.top, rcRight, rcLine.bottom); + surface->FillRectangleAligned(rcSelection, selectionBack); + } + + if (portion.end.VirtualSpace()) { + const XYPOSITION xStartVirtual = ll->positions[lineRange.end] - + static_cast(subLineStart) + xStart; + PRectangle rcSegment = rcLine; + rcSegment.left = xStartVirtual + portion.start.VirtualSpace() * spaceWidth; + rcSegment.right = xStartVirtual + portion.end.VirtualSpace() * spaceWidth; + surface->FillRectangleAligned(rcSegment, selectionBack); + } + } else { PRectangle rcSegment = rcLine; rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - - static_cast(subLineStart)+portion.start.VirtualSpace() * spaceWidth; + static_cast(subLineStart) + portion.start.VirtualSpace() * spaceWidth; rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - - static_cast(subLineStart)+portion.end.VirtualSpace() * spaceWidth; + static_cast(subLineStart) + portion.end.VirtualSpace() * spaceWidth; if ((ll->wrapIndent != 0) && (lineRange.start != 0)) { if ((portion.start.Position() - posLineStart) == lineRange.start && model.sel.Range(r).ContainsCharacter(portion.start.Position() - 1)) rcSegment.left -= static_cast(ll->wrapIndent); // indentation added to xStart was truncated to int, so we do the same here @@ -1677,7 +1902,7 @@ static void DrawTranslucentSelection(Surface *surface, const EditModel &model, c rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left; rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right; if (rcSegment.right > rcLine.left) - SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, r == model.sel.Main(), model.primarySelection), alpha); + surface->FillRectangleAligned(rcSegment, selectionBack); } } } @@ -1686,33 +1911,33 @@ static void DrawTranslucentSelection(Surface *surface, const EditModel &model, c // Draw any translucent whole line states static void DrawTranslucentLineState(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, PRectangle rcLine, int subLine) { - if ((model.caret.active || vsDraw.alwaysShowCaretLineBackground) && vsDraw.showCaretLineBackground && ll->containsCaret && - vsDraw.caretLineAlpha != SC_ALPHA_NOALPHA) { - if (vsDraw.caretLineFrame) { + Sci::Line line, PRectangle rcLine, int subLine, Layer layer) { + if ((model.caret.active || vsDraw.caretLine.alwaysShow) && vsDraw.ElementColour(Element::CaretLineBack) && ll->containsCaret && + vsDraw.caretLine.layer == layer) { + if (vsDraw.caretLine.frame) { DrawCaretLineFramed(surface, vsDraw, ll, rcLine, subLine); } else { - SimpleAlphaRectangle(surface, rcLine, vsDraw.caretLineBackground, vsDraw.caretLineAlpha); + surface->FillRectangleAligned(rcLine, *vsDraw.ElementColour(Element::CaretLineBack)); } } const int marksOfLine = model.pdoc->GetMark(line); int marksDrawnInText = marksOfLine & vsDraw.maskDrawInText; for (int markBit = 0; (markBit < 32) && marksDrawnInText; markBit++) { - if (marksDrawnInText & 1) { - if (vsDraw.markers[markBit].markType == SC_MARK_BACKGROUND) { - SimpleAlphaRectangle(surface, rcLine, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha); - } else if (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE) { + if ((marksDrawnInText & 1) && (vsDraw.markers[markBit].layer == layer)) { + if (vsDraw.markers[markBit].markType == MarkerSymbol::Background) { + surface->FillRectangleAligned(rcLine, vsDraw.markers[markBit].BackWithAlpha()); + } else if (vsDraw.markers[markBit].markType == MarkerSymbol::Underline) { PRectangle rcUnderline = rcLine; rcUnderline.top = rcUnderline.bottom - 2; - SimpleAlphaRectangle(surface, rcUnderline, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha); + surface->FillRectangleAligned(rcUnderline, vsDraw.markers[markBit].BackWithAlpha()); } } marksDrawnInText >>= 1; } int marksDrawnInLine = marksOfLine & vsDraw.maskInLine; for (int markBit = 0; (markBit < 32) && marksDrawnInLine; markBit++) { - if (marksDrawnInLine & 1) { - SimpleAlphaRectangle(surface, rcLine, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha); + if ((marksDrawnInLine & 1) && (vsDraw.markers[markBit].layer == layer)) { + surface->FillRectangleAligned(rcLine, vsDraw.markers[markBit].BackWithAlpha()); } marksDrawnInLine >>= 1; } @@ -1720,21 +1945,21 @@ static void DrawTranslucentLineState(Surface *surface, const EditModel &model, c void EditView::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) { + int subLine, std::optional background) { const bool selBackDrawn = vsDraw.SelectionBackgroundDrawn(); - const bool drawWhitespaceBackground = vsDraw.WhitespaceBackgroundDrawn() && !background.isSet; + const bool drawWhitespaceBackground = vsDraw.WhitespaceBackgroundDrawn() && !background; bool inIndentation = subLine == 0; // Do not handle indentation except on first subline. const XYACCUMULATOR subLineStart = ll->positions[lineRange.start]; const XYPOSITION indentWidth = model.pdoc->IndentSize() * vsDraw.spaceWidth; // Does not take margin into account but not significant - const int xStartVisible = static_cast(subLineStart)-xStart; + const XYPOSITION xStartVisible = static_cast(subLineStart-xStart); // Foreground drawing loop BreakFinder bfFore(ll, &model.sel, lineRange, posLineStart, xStartVisible, - (((phasesDraw == phasesOne) && selBackDrawn) || vsDraw.selColours.fore.isSet), model.pdoc, &model.reprs, &vsDraw); + (((phasesDraw == PhasesDraw::One) && selBackDrawn) || vsDraw.SelectionTextDrawn()), model.pdoc, &model.reprs, &vsDraw); while (bfFore.More()) { @@ -1749,13 +1974,13 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi // draw strings that are completely past the right side of the window. if (rcSegment.Intersects(rcLine)) { const int styleMain = ll->styles[i]; - ColourDesired textFore = vsDraw.styles[styleMain].fore; - FontAlias textFont = vsDraw.styles[styleMain].font; - //hotspot foreground + ColourRGBA textFore = vsDraw.styles[styleMain].fore; + const Font *textFont = vsDraw.styles[styleMain].font.get(); + // Hot-spot foreground const bool inHotspot = (ll->hotspot.Valid()) && ll->hotspot.ContainsCharacter(iDoc); if (inHotspot) { - if (vsDraw.hotspotColours.fore.isSet) - textFore = vsDraw.hotspotColours.fore; + if (vsDraw.ElementColour(Element::HotSpotActive)) + textFore = *vsDraw.ElementColour(Element::HotSpotActive); } if (vsDraw.indicatorsSetFore) { // At least one indicator sets the text colour so see if it applies to this segment @@ -1770,13 +1995,13 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi hover = rangeRun.ContainsCharacter(model.hoverIndicatorPos); } if (hover) { - if (indicator.sacHover.style == INDIC_TEXTFORE) { + if (indicator.sacHover.style == IndicatorStyle::TextFore) { textFore = indicator.sacHover.fore; } } else { - if (indicator.sacNormal.style == INDIC_TEXTFORE) { - if (indicator.Flags() & SC_INDICFLAG_VALUEFORE) - textFore = ColourDesired(indicatorValue & SC_INDICVALUEMASK); + if (indicator.sacNormal.style == IndicatorStyle::TextFore) { + if (FlagSet(indicator.Flags(), IndicFlag::ValueFore)) + textFore = ColourRGBA::FromRGB(indicatorValue & static_cast(IndicValue::Mask)); else textFore = indicator.sacNormal.fore; } @@ -1784,20 +2009,21 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi } } } - const int inSelection = hideSelection ? 0 : model.sel.CharacterInSelection(iDoc); - if (inSelection && (vsDraw.selColours.fore.isSet)) { - textFore = (inSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground; + const InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); + const std::optional selectionFore = SelectionForeground(model, vsDraw, inSelection); + if (selectionFore) { + textFore = *selectionFore; } - ColourDesired textBack = TextBackground(model, vsDraw, ll, background, inSelection, inHotspot, styleMain, i); + ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, inSelection, inHotspot, styleMain, i); if (ts.representation) { if (ll->chars[i] == '\t') { // Tab display - if (phasesDraw == phasesOne) { + if (phasesDraw == PhasesDraw::One) { if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) - textBack = vsDraw.whitespaceColours.back; - surface->FillRectangle(rcSegment, textBack); + textBack = vsDraw.ElementColour(Element::WhiteSpaceBack)->Opaque(); + surface->FillRectangleAligned(rcSegment, Fill(textBack)); } - if (inIndentation && vsDraw.viewIndentationGuides == ivReal) { + if (inIndentation && vsDraw.viewIndentationGuides == IndentView::Real) { for (int indentCount = static_cast((ll->positions[i] + epsilon) / indentWidth); indentCount <= (ll->positions[i + 1] - epsilon) / indentWidth; indentCount++) { @@ -1808,18 +2034,16 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi } } } - if (vsDraw.viewWhitespace != wsInvisible) { + if (vsDraw.viewWhitespace != WhiteSpace::Invisible) { if (vsDraw.WhiteSpaceVisible(inIndentation)) { - if (vsDraw.whitespaceColours.fore.isSet) - textFore = vsDraw.whitespaceColours.fore; - surface->PenColour(textFore); const PRectangle rcTab(rcSegment.left + 1, rcSegment.top + tabArrowHeight, rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); - const int segmentTop = static_cast(rcSegment.top + vsDraw.lineHeight / 2); + const int segmentTop = static_cast(rcSegment.top) + vsDraw.lineHeight / 2; + const ColourRGBA whiteSpaceFore = vsDraw.ElementColour(Element::WhiteSpace).value_or(textFore); if (!customDrawTabArrow) - DrawTabArrow(surface, rcTab, segmentTop, vsDraw); + DrawTabArrow(surface, rcTab, segmentTop, vsDraw, Stroke(whiteSpaceFore, 1.0f)); else - customDrawTabArrow(surface, rcTab, segmentTop); + customDrawTabArrow(surface, rcTab, segmentTop, vsDraw, Stroke(whiteSpaceFore, 1.0f)); } } } else { @@ -1828,56 +2052,62 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi // Using one font for all control characters so it can be controlled independently to ensure // the box goes around the characters tightly. Seems to be no way to work out what height // is taken by an individual character - internal leading gives varying results. - FontAlias ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font; + const Font *ctrlCharsFont = vsDraw.styles[StyleControlChar].font.get(); const char cc[2] = { static_cast(vsDraw.controlCharSymbol), '\0' }; surface->DrawTextNoClip(rcSegment, ctrlCharsFont, rcSegment.top + vsDraw.maxAscent, - cc, 1, textBack, textFore); + cc, textBack, textFore); } else { - DrawTextBlob(surface, vsDraw, rcSegment, ts.representation->stringRep.c_str(), - textBack, textFore, phasesDraw == phasesOne); + if (FlagSet(ts.representation->appearance, RepresentationAppearance::Colour)) { + textFore = ts.representation->colour; + } + if (FlagSet(ts.representation->appearance, RepresentationAppearance::Blob)) { + DrawTextBlob(surface, vsDraw, rcSegment, ts.representation->stringRep, + textBack, textFore, phasesDraw == PhasesDraw::One); + } else { + surface->DrawTextTransparentUTF8(rcSegment, vsDraw.styles[StyleControlChar].font.get(), + rcSegment.top + vsDraw.maxAscent, ts.representation->stringRep, textFore); + } } } } else { // Normal text display if (vsDraw.styles[styleMain].visible) { - if (phasesDraw != phasesOne) { + const std::string_view text(&ll->chars[ts.start], i - ts.start + 1); + if (phasesDraw != PhasesDraw::One) { surface->DrawTextTransparent(rcSegment, textFont, - rcSegment.top + vsDraw.maxAscent, &ll->chars[ts.start], - static_cast(i - ts.start + 1), textFore); + rcSegment.top + vsDraw.maxAscent, text, textFore); } else { surface->DrawTextNoClip(rcSegment, textFont, - rcSegment.top + vsDraw.maxAscent, &ll->chars[ts.start], - static_cast(i - ts.start + 1), textFore, textBack); + rcSegment.top + vsDraw.maxAscent, text, textFore, textBack); } } - if (vsDraw.viewWhitespace != wsInvisible || - (inIndentation && vsDraw.viewIndentationGuides != ivNone)) { + if (vsDraw.viewWhitespace != WhiteSpace::Invisible || + (inIndentation && vsDraw.viewIndentationGuides != IndentView::None)) { for (int cpos = 0; cpos <= i - ts.start; cpos++) { if (ll->chars[cpos + ts.start] == ' ') { - if (vsDraw.viewWhitespace != wsInvisible) { - if (vsDraw.whitespaceColours.fore.isSet) - textFore = vsDraw.whitespaceColours.fore; + if (vsDraw.viewWhitespace != WhiteSpace::Invisible) { if (vsDraw.WhiteSpaceVisible(inIndentation)) { const XYPOSITION xmid = (ll->positions[cpos + ts.start] + ll->positions[cpos + ts.start + 1]) / 2; - if ((phasesDraw == phasesOne) && drawWhitespaceBackground) { - textBack = vsDraw.whitespaceColours.back; + if ((phasesDraw == PhasesDraw::One) && drawWhitespaceBackground) { + textBack = vsDraw.ElementColour(Element::WhiteSpaceBack)->Opaque(); const PRectangle rcSpace( ll->positions[cpos + ts.start] + xStart - static_cast(subLineStart), rcSegment.top, ll->positions[cpos + ts.start + 1] + xStart - static_cast(subLineStart), rcSegment.bottom); - surface->FillRectangle(rcSpace, textBack); + surface->FillRectangleAligned(rcSpace, Fill(textBack)); } const int halfDotWidth = vsDraw.whitespaceSize / 2; PRectangle rcDot(xmid + xStart - halfDotWidth - static_cast(subLineStart), rcSegment.top + vsDraw.lineHeight / 2, 0.0f, 0.0f); rcDot.right = rcDot.left + vsDraw.whitespaceSize; rcDot.bottom = rcDot.top + vsDraw.whitespaceSize; - surface->FillRectangle(rcDot, textFore); + const ColourRGBA whiteSpaceFore = vsDraw.ElementColour(Element::WhiteSpace).value_or(textFore); + surface->FillRectangleAligned(rcDot, Fill(whiteSpaceFore)); } } - if (inIndentation && vsDraw.viewIndentationGuides == ivReal) { + if (inIndentation && vsDraw.viewIndentationGuides == IndentView::Real) { for (int indentCount = static_cast((ll->positions[cpos + ts.start] + epsilon) / indentWidth); indentCount <= (ll->positions[cpos + ts.start + 1] - epsilon) / indentWidth; indentCount++) { @@ -1898,15 +2128,15 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi PRectangle rcUL = rcSegment; rcUL.top = rcUL.top + vsDraw.maxAscent + 1; rcUL.bottom = rcUL.top + 1; - if (vsDraw.hotspotColours.fore.isSet) - surface->FillRectangle(rcUL, vsDraw.hotspotColours.fore); + if (vsDraw.ElementColour(Element::HotSpotActive)) + surface->FillRectangleAligned(rcUL, Fill(*vsDraw.ElementColour(Element::HotSpotActive))); else - surface->FillRectangle(rcUL, textFore); + surface->FillRectangleAligned(rcUL, Fill(textFore)); } else if (vsDraw.styles[styleMain].underline) { PRectangle rcUL = rcSegment; rcUL.top = rcUL.top + vsDraw.maxAscent + 1; rcUL.bottom = rcUL.top + 1; - surface->FillRectangle(rcUL, textFore); + surface->FillRectangleAligned(rcUL, Fill(textFore)); } } else if (rcSegment.left > rcLine.right) { break; @@ -1916,7 +2146,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi void EditView::DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, Sci::Line lineVisible, PRectangle rcLine, int xStart, int subLine) { - if ((vsDraw.viewIndentationGuides == ivLookForward || vsDraw.viewIndentationGuides == ivLookBoth) + if ((vsDraw.viewIndentationGuides == IndentView::LookForward || vsDraw.viewIndentationGuides == IndentView::LookBoth) && (subLine == 0)) { const Sci::Position posLineStart = model.pdoc->LineStart(line); int indentSpace = model.pdoc->GetLineIndentation(line); @@ -1932,12 +2162,12 @@ void EditView::DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &mode xStartText = 100000; // Don't limit to visible indentation on empty line // This line is empty, so use indentation of last line with text int indentLastWithText = model.pdoc->GetLineIndentation(lineLastWithText); - const int isFoldHeader = model.pdoc->GetLevel(lineLastWithText) & SC_FOLDLEVELHEADERFLAG; + const int isFoldHeader = LevelIsHeader(model.pdoc->GetFoldLevel(lineLastWithText)); if (isFoldHeader) { // Level is one more level than parent indentLastWithText += model.pdoc->IndentSize(); } - if (vsDraw.viewIndentationGuides == ivLookForward) { + if (vsDraw.viewIndentationGuides == IndentView::LookForward) { // In viLookForward mode, previous line only used if it is a fold header if (isFoldHeader) { indentSpace = std::max(indentSpace, indentLastWithText); @@ -1977,7 +2207,7 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl } // See if something overrides the line background colour. - const ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); + const std::optional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); const Sci::Position posLineStart = model.pdoc->LineStart(line); @@ -1986,49 +2216,54 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl const XYACCUMULATOR subLineStart = ll->positions[lineRange.start]; if ((ll->wrapIndent != 0) && (subLine > 0)) { - if (phase & drawBack) { + if (FlagSet(phase, DrawPhase::back)) { DrawWrapIndentAndMarker(surface, vsDraw, ll, xStart, rcLine, background, customDrawWrapMarker, model.caret.active); } xStart += static_cast(ll->wrapIndent); } - if (phasesDraw != phasesOne) { - if (phase & drawBack) { + if (phasesDraw != PhasesDraw::One) { + if (FlagSet(phase, DrawPhase::back)) { DrawBackground(surface, model, vsDraw, ll, rcLine, lineRange, posLineStart, xStart, subLine, background); - DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, drawBack); - DrawEOLAnnotationText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, drawBack); - phase = static_cast(phase & ~drawBack); // Remove drawBack to not draw again in DrawFoldDisplayText + DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, DrawPhase::back); + DrawEOLAnnotationText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, DrawPhase::back); + // Remove drawBack to not draw again in DrawFoldDisplayText + phase = static_cast(static_cast(phase) & ~static_cast(DrawPhase::back)); DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, xStart, subLine, subLineStart, background); if (vsDraw.IsLineFrameOpaque(model.caret.active, ll->containsCaret)) DrawCaretLineFramed(surface, vsDraw, ll, rcLine, subLine); } - if (phase & drawIndicatorsBack) { - DrawIndicators(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, lineRangeIncludingEnd.end, true, model.hoverIndicatorPos); + if (FlagSet(phase, DrawPhase::indicatorsBack)) { + DrawIndicators(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, + lineRangeIncludingEnd.end, true, tabWidthMinimumPixels); DrawEdgeLine(surface, vsDraw, ll, rcLine, lineRange, xStart); DrawMarkUnderline(surface, model, vsDraw, line, rcLine); } } - if (phase & drawText) { + if (FlagSet(phase, DrawPhase::text)) { + DrawTranslucentSelection(surface, model, vsDraw, ll, line, rcLine, subLine, lineRange, xStart, tabWidthMinimumPixels, Layer::UnderText); + DrawTranslucentLineState(surface, model, vsDraw, ll, line, rcLine, subLine, Layer::UnderText); DrawForeground(surface, model, vsDraw, ll, lineVisible, rcLine, lineRange, posLineStart, xStart, subLine, background); } - if (phase & drawIndentationGuides) { + if (FlagSet(phase, DrawPhase::indentationGuides)) { DrawIndentGuidesOverEmpty(surface, model, vsDraw, ll, line, lineVisible, rcLine, xStart, subLine); } - if (phase & drawIndicatorsFore) { - DrawIndicators(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, lineRangeIncludingEnd.end, false, model.hoverIndicatorPos); + if (FlagSet(phase, DrawPhase::indicatorsFore)) { + DrawIndicators(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, + lineRangeIncludingEnd.end, false, tabWidthMinimumPixels); } DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, phase); DrawEOLAnnotationText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, phase); - if (phasesDraw == phasesOne) { + if (phasesDraw == PhasesDraw::One) { DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, xStart, subLine, subLineStart, background); if (vsDraw.IsLineFrameOpaque(model.caret.active, ll->containsCaret)) @@ -2037,36 +2272,36 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl DrawMarkUnderline(surface, model, vsDraw, line, rcLine); } - if (!hideSelection && (phase & drawSelectionTranslucent)) { - DrawTranslucentSelection(surface, model, vsDraw, ll, line, rcLine, subLine, lineRange, xStart); + if (!hideSelection && FlagSet(phase, DrawPhase::selectionTranslucent)) { + DrawTranslucentSelection(surface, model, vsDraw, ll, line, rcLine, subLine, lineRange, xStart, tabWidthMinimumPixels, Layer::OverText); } - if (phase & drawLineTranslucent) { - DrawTranslucentLineState(surface, model, vsDraw, ll, line, rcLine, subLine); + if (FlagSet(phase, DrawPhase::lineTranslucent)) { + DrawTranslucentLineState(surface, model, vsDraw, ll, line, rcLine, subLine, Layer::OverText); } } static void DrawFoldLines(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, Sci::Line line, PRectangle rcLine) { const bool expanded = model.pcs->GetExpanded(line); - const int level = model.pdoc->GetLevel(line); - const int levelNext = model.pdoc->GetLevel(line + 1); - if ((level & SC_FOLDLEVELHEADERFLAG) && + const FoldLevel level = model.pdoc->GetFoldLevel(line); + const FoldLevel levelNext = model.pdoc->GetFoldLevel(line + 1); + if (LevelIsHeader(level) && (LevelNumber(level) < LevelNumber(levelNext))) { // Paint the line above the fold - if ((expanded && (model.foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED)) + if ((expanded && (FlagSet(model.foldFlags, FoldFlag::LineBeforeExpanded))) || - (!expanded && (model.foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) { + (!expanded && (FlagSet(model.foldFlags, FoldFlag::LineBeforeContracted)))) { PRectangle rcFoldLine = rcLine; rcFoldLine.bottom = rcFoldLine.top + 1; - surface->FillRectangle(rcFoldLine, vsDraw.styles[STYLE_DEFAULT].fore); + surface->FillRectangleAligned(rcFoldLine, Fill(vsDraw.styles[StyleDefault].fore)); } // Paint the line below the fold - if ((expanded && (model.foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED)) + if ((expanded && (FlagSet(model.foldFlags, FoldFlag::LineAfterExpanded))) || - (!expanded && (model.foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) { + (!expanded && (FlagSet(model.foldFlags, FoldFlag::LineAfterContracted)))) { PRectangle rcFoldLine = rcLine; rcFoldLine.top = rcFoldLine.bottom - 1; - surface->FillRectangle(rcFoldLine, vsDraw.styles[STYLE_DEFAULT].fore); + surface->FillRectangleAligned(rcFoldLine, Fill(vsDraw.styles[StyleDefault].fore)); } } } @@ -2085,8 +2320,7 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan surface = pixmapLine.get(); PLATFORM_ASSERT(pixmapLine->Initialised()); } - surface->SetUnicodeMode(SC_CP_UTF8 == model.pdoc->dbcsCodePage); - surface->SetDBCSMode(model.pdoc->dbcsCodePage); + surface->SetMode(SurfaceMode(model.pdoc->dbcsCodePage, model.BidirectionalR2L())); const Point ptOrigin = model.GetVisibleOriginInMain(); @@ -2108,7 +2342,8 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan // Remove selection margin from drawing area so text will not be drawn // on it in unbuffered mode. - if (!bufferedDraw && vsDraw.marginInside) { + const bool clipping = !bufferedDraw && vsDraw.marginInside; + if (clipping) { PRectangle rcClipText = rcTextArea; rcClipText.left -= leftTextOverlap; surfaceWindow->SetClip(rcClipText); @@ -2121,18 +2356,18 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan double durCopy = 0.0; ElapsedPeriod epWhole; #endif - const bool bracesIgnoreStyle = ((vsDraw.braceHighlightIndicatorSet && (model.bracesMatchStyle == STYLE_BRACELIGHT)) || - (vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == STYLE_BRACEBAD))); + const bool bracesIgnoreStyle = ((vsDraw.braceHighlightIndicatorSet && (model.bracesMatchStyle == StyleBraceLight)) || + (vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == StyleBraceBad))); Sci::Line lineDocPrevious = -1; // Used to avoid laying out one document line multiple times - AutoLineLayout ll(llc, nullptr); + std::shared_ptr ll; std::vector phases; - if ((phasesDraw == phasesMultiple) && !bufferedDraw) { - for (DrawPhase phase = drawBack; phase <= drawCarets; phase = static_cast(phase * 2)) { + if ((phasesDraw == PhasesDraw::Multiple) && !bufferedDraw) { + for (DrawPhase phase = DrawPhase::back; phase <= DrawPhase::carets; phase = static_cast(static_cast(phase) * 2)) { phases.push_back(phase); } } else { - phases.push_back(drawAll); + phases.push_back(DrawPhase::all); } for (const DrawPhase &phase : phases) { int ypos = 0; @@ -2154,9 +2389,8 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan ElapsedPeriod ep; #endif if (lineDoc != lineDocPrevious) { - ll.Set(nullptr); - ll.Set(RetrieveLineLayout(lineDoc, model)); - LayoutLine(model, lineDoc, surface, vsDraw, ll, model.wrapWidth); + ll = RetrieveLineLayout(lineDoc, model); + LayoutLine(model, surface, vsDraw, ll.get(), model.wrapWidth); lineDocPrevious = lineDoc; } #if defined(TIME_PAINTING) @@ -2177,27 +2411,32 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan ll->SetBracesHighlight(rangeLine, model.braces, static_cast(model.bracesMatchStyle), static_cast(model.highlightGuideColumn * vsDraw.spaceWidth), bracesIgnoreStyle); - if (leftTextOverlap && (bufferedDraw || ((phasesDraw < phasesMultiple) && (phase & drawBack)))) { + if (leftTextOverlap && (bufferedDraw || ((phasesDraw < PhasesDraw::Multiple) && (FlagSet(phase, DrawPhase::back))))) { // Clear the left margin PRectangle rcSpacer = rcLine; rcSpacer.right = rcSpacer.left; rcSpacer.left -= 1; - surface->FillRectangle(rcSpacer, vsDraw.styles[STYLE_DEFAULT].back); + surface->FillRectangleAligned(rcSpacer, Fill(vsDraw.styles[StyleDefault].back)); + } + + if (model.BidirectionalEnabled()) { + // Fill the line bidi data + UpdateBidiData(model, vsDraw, ll.get()); } - DrawLine(surface, model, vsDraw, ll, lineDoc, visibleLine, xStart, rcLine, subLine, phase); + DrawLine(surface, model, vsDraw, ll.get(), lineDoc, visibleLine, xStart, rcLine, subLine, phase); #if defined(TIME_PAINTING) durPaint += ep.Duration(true); #endif // Restore the previous styles for the brace highlights in case layout is in cache. ll->RestoreBracesHighlight(rangeLine, model.braces, bracesIgnoreStyle); - if (phase & drawFoldLines) { + if (FlagSet(phase, DrawPhase::foldLines)) { DrawFoldLines(surface, model, vsDraw, lineDoc, rcLine); } - if (phase & drawCarets) { - DrawCarets(surface, model, vsDraw, ll, lineDoc, xStart, rcLine, subLine); + if (FlagSet(phase, DrawPhase::carets)) { + DrawCarets(surface, model, vsDraw, ll.get(), lineDoc, xStart, rcLine, subLine); } if (bufferedDraw) { @@ -2205,6 +2444,7 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan const PRectangle rcCopyArea = PRectangle::FromInts(vsDraw.textStart - leftTextOverlap, yposScreen, static_cast(rcClient.right - vsDraw.rightMarginWidth), yposScreen + vsDraw.lineHeight); + pixmapLine->FlushDrawing(); surfaceWindow->Copy(rcCopyArea, from, *pixmapLine); } @@ -2223,7 +2463,7 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan visibleLine++; } } - ll.Set(nullptr); + ll.reset(); #if defined(TIME_PAINTING) if (durPaint < 0.00000001) durPaint = 0.00000001; @@ -2234,23 +2474,27 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan rcBeyondEOF.right = rcBeyondEOF.right - ((vsDraw.marginInside) ? vsDraw.rightMarginWidth : 0); rcBeyondEOF.top = static_cast((model.pcs->LinesDisplayed() - model.TopLineOfMain()) * vsDraw.lineHeight); if (rcBeyondEOF.top < rcBeyondEOF.bottom) { - surfaceWindow->FillRectangle(rcBeyondEOF, vsDraw.styles[STYLE_DEFAULT].back); - if (vsDraw.edgeState == EDGE_LINE) { + surfaceWindow->FillRectangleAligned(rcBeyondEOF, Fill(vsDraw.styles[StyleDefault].back)); + if (vsDraw.edgeState == EdgeVisualStyle::Line) { const int edgeX = static_cast(vsDraw.theEdge.column * vsDraw.spaceWidth); rcBeyondEOF.left = static_cast(edgeX + xStart); rcBeyondEOF.right = rcBeyondEOF.left + 1; - surfaceWindow->FillRectangle(rcBeyondEOF, vsDraw.theEdge.colour); - } else if (vsDraw.edgeState == EDGE_MULTILINE) { + surfaceWindow->FillRectangleAligned(rcBeyondEOF, Fill(vsDraw.theEdge.colour)); + } else if (vsDraw.edgeState == EdgeVisualStyle::MultiLine) { for (size_t edge = 0; edge < vsDraw.theMultiEdge.size(); edge++) { if (vsDraw.theMultiEdge[edge].column >= 0) { const int edgeX = static_cast(vsDraw.theMultiEdge[edge].column * vsDraw.spaceWidth); rcBeyondEOF.left = static_cast(edgeX + xStart); rcBeyondEOF.right = rcBeyondEOF.left + 1; - surfaceWindow->FillRectangle(rcBeyondEOF, vsDraw.theMultiEdge[edge].colour); + surfaceWindow->FillRectangleAligned(rcBeyondEOF, Fill(vsDraw.theMultiEdge[edge].colour)); } } } } + + if (clipping) + surfaceWindow->PopClip(); + //Platform::DebugPrintf("start display %d, offset = %d\n", model.pdoc->Length(), model.xOffset); #if defined(TIME_PAINTING) Platform::DebugPrintf( @@ -2262,62 +2506,59 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan void EditView::FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, PRectangle rcArea, int subLine) const { - int eolInSelection = 0; - int alpha = SC_ALPHA_NOALPHA; - if (!hideSelection) { - const Sci::Position posAfterLineEnd = model.pdoc->LineStart(line + 1); - eolInSelection = (subLine == (ll->lines - 1)) ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0; - alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; - } + InSelection eolInSelection = InSelection::inNone; + if ((!hideSelection) && (subLine == (ll->lines - 1))) { + eolInSelection = model.LineEndInSelection(line); + } - const ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); + const std::optional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); - if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) { - surface->FillRectangle(rcArea, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection)); + if (eolInSelection && vsDraw.selection.eolFilled && (line < model.pdoc->LinesTotal() - 1) && (vsDraw.selection.layer == Layer::Base)) { + surface->FillRectangleAligned(rcArea, Fill(SelectionBackground(model, vsDraw, eolInSelection).Opaque())); + } else { + if (background) { + surface->FillRectangleAligned(rcArea, Fill(*background)); + } else if (vsDraw.styles[ll->styles[ll->numCharsInLine]].eolFilled) { + surface->FillRectangleAligned(rcArea, Fill(vsDraw.styles[ll->styles[ll->numCharsInLine]].back)); } else { - if (background.isSet) { - surface->FillRectangle(rcArea, background); - } else if (vsDraw.styles[ll->styles[ll->numCharsInLine]].eolFilled) { - surface->FillRectangle(rcArea, vsDraw.styles[ll->styles[ll->numCharsInLine]].back); - } else { - surface->FillRectangle(rcArea, vsDraw.styles[STYLE_DEFAULT].back); - } - if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { - SimpleAlphaRectangle(surface, rcArea, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); - } + surface->FillRectangleAligned(rcArea, Fill(vsDraw.styles[StyleDefault].back)); } + if (eolInSelection && vsDraw.selection.eolFilled && (line < model.pdoc->LinesTotal() - 1) && (vsDraw.selection.layer != Layer::Base)) { + surface->FillRectangleAligned(rcArea, SelectionBackground(model, vsDraw, eolInSelection)); + } + } } // Space (3 space characters) between line numbers and text when printing. #define lineNumberPrintSpace " " -static ColourDesired InvertedLight(ColourDesired orig) noexcept { +static ColourRGBA InvertedLight(ColourRGBA orig) noexcept { unsigned int r = orig.GetRed(); unsigned int g = orig.GetGreen(); unsigned int b = orig.GetBlue(); const unsigned int l = (r + g + b) / 3; // There is a better calculation for this that matches human eye const unsigned int il = 0xff - l; if (l == 0) - return ColourDesired(0xff, 0xff, 0xff); + return ColourRGBA(0xff, 0xff, 0xff); r = r * il / l; g = g * il / l; b = b * il / l; - return ColourDesired(std::min(r, 0xffu), std::min(g, 0xffu), std::min(b, 0xffu)); + return ColourRGBA(std::min(r, 0xffu), std::min(g, 0xffu), std::min(b, 0xffu)); } -Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure, +Sci::Position EditView::FormatRange(bool draw, const RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure, const EditModel &model, const ViewStyle &vs) { // Can't use measurements cached for screen posCache.Clear(); ViewStyle vsPrint(vs); - vsPrint.technology = SC_TECHNOLOGY_DEFAULT; + vsPrint.technology = Technology::Default; // Modify the view style for printing as do not normally want any of the transient features to be printed // Printing supports only the line number margin. int lineNumberIndex = -1; for (size_t margin = 0; margin < vs.ms.size(); margin++) { - if ((vsPrint.ms[margin].style == SC_MARGIN_NUMBER) && (vsPrint.ms[margin].width > 0)) { + if ((vsPrint.ms[margin].style == MarginType::Number) && (vsPrint.ms[margin].width > 0)) { lineNumberIndex = static_cast(margin); } else { vsPrint.ms[margin].width = 0; @@ -2326,40 +2567,35 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur vsPrint.fixedColumnWidth = 0; vsPrint.zoomLevel = printParameters.magnification; // Don't show indentation guides - // If this ever gets changed, cached pixmap would need to be recreated if technology != SC_TECHNOLOGY_DEFAULT - vsPrint.viewIndentationGuides = ivNone; + // If this ever gets changed, cached pixmap would need to be recreated if technology != Technology::Default + vsPrint.viewIndentationGuides = IndentView::None; // Don't show the selection when printing - vsPrint.selColours.back.isSet = false; - vsPrint.selColours.fore.isSet = false; - vsPrint.selAlpha = SC_ALPHA_NOALPHA; - vsPrint.selAdditionalAlpha = SC_ALPHA_NOALPHA; - vsPrint.whitespaceColours.back.isSet = false; - vsPrint.whitespaceColours.fore.isSet = false; - vsPrint.showCaretLineBackground = false; - vsPrint.alwaysShowCaretLineBackground = false; + vsPrint.elementColours.clear(); + vsPrint.elementBaseColours.clear(); + vsPrint.caretLine.alwaysShow = false; // Don't highlight matching braces using indicators vsPrint.braceHighlightIndicatorSet = false; vsPrint.braceBadLightIndicatorSet = false; // Set colours for printing according to users settings for (size_t sty = 0; sty < vsPrint.styles.size(); sty++) { - if (printParameters.colourMode == SC_PRINT_INVERTLIGHT) { + if (printParameters.colourMode == PrintOption::InvertLight) { vsPrint.styles[sty].fore = InvertedLight(vsPrint.styles[sty].fore); vsPrint.styles[sty].back = InvertedLight(vsPrint.styles[sty].back); - } else if (printParameters.colourMode == SC_PRINT_BLACKONWHITE) { - vsPrint.styles[sty].fore = ColourDesired(0, 0, 0); - vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff); - } else if (printParameters.colourMode == SC_PRINT_COLOURONWHITE) { - vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff); - } else if (printParameters.colourMode == SC_PRINT_COLOURONWHITEDEFAULTBG) { - if (sty <= STYLE_DEFAULT) { - vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff); + } else if (printParameters.colourMode == PrintOption::BlackOnWhite) { + vsPrint.styles[sty].fore = ColourRGBA(0, 0, 0); + vsPrint.styles[sty].back = ColourRGBA(0xff, 0xff, 0xff); + } else if (printParameters.colourMode == PrintOption::ColourOnWhite) { + vsPrint.styles[sty].back = ColourRGBA(0xff, 0xff, 0xff); + } else if (printParameters.colourMode == PrintOption::ColourOnWhiteDefaultBG) { + if (sty <= StyleDefault) { + vsPrint.styles[sty].back = ColourRGBA(0xff, 0xff, 0xff); } } } - // White background for the line numbers if SC_PRINT_SCREENCOLOURS isn't used - if (printParameters.colourMode != SC_PRINT_SCREENCOLOURS) - vsPrint.styles[STYLE_LINENUMBER].back = ColourDesired(0xff, 0xff, 0xff); + // White background for the line numbers if PrintOption::ScreenColours isn't used + if (printParameters.colourMode != PrintOption::ScreenColours) + vsPrint.styles[StyleLineNumber].back = ColourRGBA(0xff, 0xff, 0xff); // Printing uses different margins, so reset screen margins vsPrint.leftMarginWidth = 0; @@ -2369,8 +2605,8 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur // Determining width must happen after fonts have been realised in Refresh int lineNumberWidth = 0; if (lineNumberIndex >= 0) { - lineNumberWidth = static_cast(surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, - "99999" lineNumberPrintSpace, 5 + static_cast(strlen(lineNumberPrintSpace)))); + lineNumberWidth = static_cast(surfaceMeasure->WidthText(vsPrint.styles[StyleLineNumber].font.get(), + "99999" lineNumberPrintSpace)); vsPrint.ms[lineNumberIndex].width = lineNumberWidth; vsPrint.Refresh(*surfaceMeasure, model.pdoc->tabInChars); // Recalculate fixedColumnWidth } @@ -2384,7 +2620,7 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur linePrintLast = linePrintMax; //Platform::DebugPrintf("Formatting lines=[%0d,%0d,%0d] top=%0d bottom=%0d line=%0d %0d\n", // linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight, - // surfaceMeasure->Height(vsPrint.styles[STYLE_LINENUMBER].font)); + // surfaceMeasure->Height(vsPrint.styles[StyleLineNumber].font)); Sci::Position endPosPrint = model.pdoc->Length(); if (linePrintLast < model.pdoc->LinesTotal()) endPosPrint = model.pdoc->LineStart(linePrintLast + 1); @@ -2400,7 +2636,7 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur Sci::Position nPrintPos = pfr->chrg.cpMin; int visibleLine = 0; int widthPrint = pfr->rc.right - pfr->rc.left - vsPrint.fixedColumnWidth; - if (printParameters.wrapState == WrapMode::none) + if (printParameters.wrapState == Wrap::None) widthPrint = LineLayout::wrapWidthInfinite; while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) { @@ -2413,8 +2649,8 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur // Copy this line and its styles from the document into local arrays // and determine the x position at which each character starts. - LineLayout ll(static_cast(model.pdoc->LineStart(lineDoc + 1) - model.pdoc->LineStart(lineDoc) + 1)); - LayoutLine(model, lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint); + LineLayout ll(lineDoc, static_cast(model.pdoc->LineStart(lineDoc + 1) - model.pdoc->LineStart(lineDoc) + 1)); + LayoutLine(model, surfaceMeasure, vsPrint, &ll, widthPrint); ll.containsCaret = false; @@ -2449,12 +2685,12 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur rcNumber.right = rcNumber.left + lineNumberWidth; // Right justify rcNumber.left = rcNumber.right - surfaceMeasure->WidthText( - vsPrint.styles[STYLE_LINENUMBER].font, number.c_str(), static_cast(number.length())); + vsPrint.styles[StyleLineNumber].font.get(), number); surface->FlushCachedState(); - surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font, - static_cast(ypos + vsPrint.maxAscent), number.c_str(), static_cast(number.length()), - vsPrint.styles[STYLE_LINENUMBER].fore, - vsPrint.styles[STYLE_LINENUMBER].back); + surface->DrawTextNoClip(rcNumber, vsPrint.styles[StyleLineNumber].font.get(), + static_cast(ypos + vsPrint.maxAscent), number, + vsPrint.styles[StyleLineNumber].fore, + vsPrint.styles[StyleLineNumber].back); } // Draw the line @@ -2466,7 +2702,7 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur if (draw) { rcLine.top = static_cast(ypos); rcLine.bottom = static_cast(ypos + vsPrint.lineHeight); - DrawLine(surface, model, vsPrint, &ll, lineDoc, visibleLine, xStart, rcLine, iwl, drawAll); + DrawLine(surface, model, vsPrint, &ll, lineDoc, visibleLine, xStart, rcLine, iwl, DrawPhase::all); } ypos += vsPrint.lineHeight; } diff --git a/scintilla/src/EditView.h b/scintilla/src/EditView.h index 0ff5ef8349..bac59ed310 100644 --- a/scintilla/src/EditView.h +++ b/scintilla/src/EditView.h @@ -8,39 +8,42 @@ #ifndef EDITVIEW_H #define EDITVIEW_H -namespace Scintilla { +namespace Scintilla::Internal { struct PrintParameters { int magnification; - int colourMode; - WrapMode wrapState; + Scintilla::PrintOption colourMode; + Scintilla::Wrap wrapState; PrintParameters() noexcept; }; /** * The view may be drawn in separate phases. */ -enum DrawPhase { - drawBack = 0x1, - drawIndicatorsBack = 0x2, - drawText = 0x4, - drawIndentationGuides = 0x8, - drawIndicatorsFore = 0x10, - drawSelectionTranslucent = 0x20, - drawLineTranslucent = 0x40, - drawFoldLines = 0x80, - drawCarets = 0x100, - drawAll = 0x1FF +enum class DrawPhase { + none = 0x0, + back = 0x1, + indicatorsBack = 0x2, + text = 0x4, + indentationGuides = 0x8, + indicatorsFore = 0x10, + selectionTranslucent = 0x20, + lineTranslucent = 0x40, + foldLines = 0x80, + carets = 0x100, + all = 0x1FF }; bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st) noexcept; int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, const StyledText &st); void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XYPOSITION ybase, - const char *s, int len, DrawPhase phase); + 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); +typedef void (*DrawTabArrowFn)(Surface *surface, PRectangle rcTab, int ymid, + const ViewStyle &vsDraw, Stroke stroke); class LineTabstops; @@ -64,8 +67,7 @@ class EditView { * In multiPhaseDraw mode, drawing is performed in multiple phases with each phase drawing * one feature over the whole drawing area, instead of within one line. This allows text to * overlap from one line to the next. */ - enum PhasesDraw { phasesOne, phasesTwo, phasesMultiple }; - PhasesDraw phasesDraw; + Scintilla::PhasesDraw phasesDraw; int lineWidthMaxSeen; @@ -108,19 +110,20 @@ class EditView { int GetNextTabstop(Sci::Line line, int x) const noexcept; void LinesAddedOrRemoved(Sci::Line lineOfPos, Sci::Line linesAdded); - void DropGraphics(bool freeObjects); - void AllocateGraphics(const ViewStyle &vsDraw); - void RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw); + void DropGraphics() noexcept; + void RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw); - LineLayout *RetrieveLineLayout(Sci::Line lineNumber, const EditModel &model); - void LayoutLine(const EditModel &model, Sci::Line line, Surface *surface, const ViewStyle &vstyle, + std::shared_ptr RetrieveLineLayout(Sci::Line lineNumber, const EditModel &model); + void LayoutLine(const EditModel &model, Surface *surface, const ViewStyle &vstyle, LineLayout *ll, int width = LineLayout::wrapWidthInfinite); + static void UpdateBidiData(const EditModel &model, const ViewStyle &vstyle, LineLayout *ll); + Point LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, Sci::Line topLine, - const ViewStyle &vs, PointEnd pe); + const ViewStyle &vs, PointEnd pe, const PRectangle rcClient); Range RangeDisplayLine(Surface *surface, const EditModel &model, Sci::Line lineVisible, const ViewStyle &vs); SelectionPosition SPositionFromLocation(Surface *surface, const EditModel &model, PointDocument pt, bool canReturnInvalid, - bool charPosition, bool virtualSpace, const ViewStyle &vs); + bool charPosition, bool virtualSpace, const ViewStyle &vs, const PRectangle rcClient); SelectionPosition SPositionFromLineX(Surface *surface, const EditModel &model, Sci::Line lineDoc, int x, const ViewStyle &vs); 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); @@ -128,7 +131,7 @@ class EditView { 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); + std::optional 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); void DrawEOLAnnotationText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, @@ -139,10 +142,10 @@ class EditView { 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; + int subLine, std::optional 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); + int subLine, std::optional 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, @@ -151,38 +154,10 @@ class EditView { 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::Position FormatRange(bool draw, const Sci_RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure, + Sci::Position FormatRange(bool draw, const Scintilla::RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure, const EditModel &model, const ViewStyle &vs); }; -/** -* Convenience class to ensure LineLayout objects are always disposed. -*/ -class AutoLineLayout { - LineLayoutCache &llc; - LineLayout *ll; -public: - AutoLineLayout(LineLayoutCache &llc_, LineLayout *ll_) noexcept : llc(llc_), ll(ll_) {} - AutoLineLayout(const AutoLineLayout &) = delete; - AutoLineLayout(AutoLineLayout &&) = delete; - AutoLineLayout &operator=(const AutoLineLayout &) = delete; - AutoLineLayout &operator=(AutoLineLayout &&) = delete; - ~AutoLineLayout() noexcept { - llc.Dispose(ll); - ll = nullptr; - } - LineLayout *operator->() const noexcept { - return ll; - } - operator LineLayout *() const noexcept { - return ll; - } - void Set(LineLayout *ll_) noexcept { - llc.Dispose(ll); - ll = ll_; - } -}; - } #endif diff --git a/scintilla/src/Editor.cxx b/scintilla/src/Editor.cxx index 684d205e60..db7e2366e3 100644 --- a/scintilla/src/Editor.cxx +++ b/scintilla/src/Editor.cxx @@ -14,22 +14,29 @@ #include #include +#include #include #include +#include #include +#include #include #include #include #include -#include "Platform.h" - +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" +#include "ScintillaStructures.h" #include "ILoader.h" #include "ILexer.h" -#include "Scintilla.h" -#include "CharacterSet.h" -#include "CharacterCategory.h" +#include "Debugging.h" +#include "Geometry.h" +#include "Platform.h" + +#include "CharacterType.h" +#include "CharacterCategoryMap.h" #include "Position.h" #include "UniqueString.h" #include "SplitVector.h" @@ -48,6 +55,7 @@ #include "CaseFolder.h" #include "Document.h" #include "UniConversion.h" +#include "DBCS.h" #include "Selection.h" #include "PositionCache.h" #include "EditModel.h" @@ -57,6 +65,7 @@ #include "ElapsedPeriod.h" using namespace Scintilla; +using namespace Scintilla::Internal; namespace { @@ -64,19 +73,19 @@ namespace { return whether this modification represents an operation that may reasonably be deferred (not done now OR [possibly] at all) */ -bool CanDeferToLastStep(const DocModification &mh) noexcept { - if (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) +constexpr bool CanDeferToLastStep(const DocModification &mh) noexcept { + if (FlagSet(mh.modificationType, (ModificationFlags::BeforeInsert | ModificationFlags::BeforeDelete))) return true; // CAN skip - if (!(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO))) + if (!FlagSet(mh.modificationType, (ModificationFlags::Undo | ModificationFlags::Redo))) return false; // MUST do - if (mh.modificationType & SC_MULTISTEPUNDOREDO) + if (FlagSet(mh.modificationType, ModificationFlags::MultiStepUndoRedo)) return true; // CAN skip return false; // PRESUMABLY must do } constexpr bool CanEliminate(const DocModification &mh) noexcept { return - (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) != 0; + FlagSet(mh.modificationType, (ModificationFlags::BeforeInsert | ModificationFlags::BeforeDelete)); } /* @@ -85,10 +94,10 @@ constexpr bool CanEliminate(const DocModification &mh) noexcept { */ constexpr bool IsLastStep(const DocModification &mh) noexcept { return - (mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)) != 0 - && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0 - && (mh.modificationType & SC_LASTSTEPINUNDOREDO) != 0 - && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0; + FlagSet(mh.modificationType, (ModificationFlags::Undo | ModificationFlags::Redo)) + && (FlagSet(mh.modificationType, ModificationFlags::MultiStepUndoRedo)) + && (FlagSet(mh.modificationType, ModificationFlags::LastStepInUndoRedo)) + && (FlagSet(mh.modificationType, ModificationFlags::MultilineUndoRedo)); } } @@ -97,42 +106,41 @@ Timer::Timer() noexcept : ticking(false), ticksToWait(0), tickerID{} {} Idler::Idler() noexcept : - state(false), idlerID(0) {} + state(false), idlerID(nullptr) {} -static bool IsAllSpacesOrTabs(const char *s, unsigned int len) noexcept { - for (unsigned int i = 0; i < len; i++) { +static constexpr bool IsAllSpacesOrTabs(std::string_view sv) noexcept { + for (const char ch : sv) { // This is safe because IsSpaceOrTab() will return false for null terminators - if (!IsSpaceOrTab(s[i])) + if (!IsSpaceOrTab(ch)) return false; } return true; } -Editor::Editor() : durationWrapOneLine(0.00001, 0.000001, 0.0001) { +Editor::Editor() : durationWrapOneByte(0.000001, 0.0000001, 0.00001) { ctrlID = 0; stylesValid = false; - technology = SC_TECHNOLOGY_DEFAULT; + technology = Technology::Default; scaleRGBAImage = 100.0f; - cursorMode = SC_CURSORNORMAL; + cursorMode = CursorShape::Normal; - hasFocus = false; - errorStatus = 0; + errorStatus = Status::Ok; mouseDownCaptures = true; mouseWheelCaptures = true; lastClickTime = 0; doubleClickCloseThreshold = Point(3, 3); - dwellDelay = SC_TIME_FOREVER; - ticksToDwell = SC_TIME_FOREVER; + dwellDelay = TimeForever; + ticksToDwell = TimeForever; dwelling = false; ptMouseLast.x = 0; ptMouseLast.y = 0; - inDragDrop = ddNone; + inDragDrop = DragDrop::none; dropWentOutside = false; posDrop = SelectionPosition(Sci::invalidPosition); - hotSpotClickPos = INVALID_POSITION; + hotSpotClickPos = Sci::invalidPosition; selectionUnit = TextUnit::character; lastXChosen = 0; @@ -142,8 +150,8 @@ Editor::Editor() : durationWrapOneLine(0.00001, 0.000001, 0.0001) { wordSelectAnchorEndPos = 0; wordSelectInitialCaretPos = -1; - caretPolicies.x = { CARET_SLOP | CARET_EVEN, 50 }; - caretPolicies.y = { CARET_EVEN, 0 }; + caretPolicies.x = { CaretPolicy::Slop | CaretPolicy::Even, 50 }; + caretPolicies.y = { CaretPolicy::Even, 0 }; visiblePolicy = { 0, 0 }; @@ -154,39 +162,39 @@ Editor::Editor() : durationWrapOneLine(0.00001, 0.000001, 0.0001) { scrollWidth = 2000; verticalScrollBarVisible = true; endAtLastLine = true; - caretSticky = SC_CARETSTICKY_OFF; - marginOptions = SC_MARGINOPTION_NONE; + caretSticky = CaretSticky::Off; + marginOptions = MarginOption::None; mouseSelectionRectangularSwitch = false; multipleSelection = false; additionalSelectionTyping = false; - multiPasteMode = SC_MULTIPASTE_ONCE; - virtualSpaceOptions = SCVS_NONE; + multiPasteMode = MultiPaste::Once; + virtualSpaceOptions = VirtualSpace::None; targetRange = SelectionSegment(); - searchFlags = 0; + searchFlags = FindOption::None; topLine = 0; posTopLine = 0; lengthForEncode = -1; - needUpdateUI = 0; - ContainerNeedsUpdate(SC_UPDATE_CONTENT); + needUpdateUI = Update::None; + ContainerNeedsUpdate(Update::Content); - paintState = notPainting; + paintState = PaintState::notPainting; paintAbandonedByStyling = false; paintingAllText = false; willRedrawAll = false; - idleStyling = SC_IDLESTYLING_NONE; + idleStyling = IdleStyling::None; needIdleStyling = false; - modEventMask = SC_MODEVENTMASKALL; + modEventMask = ModificationFlags::EventMaskAll; commandEvents = true; - pdoc->AddWatcher(this, 0); + pdoc->AddWatcher(this, nullptr); recordingMacro = false; - foldAutomatic = 0; + foldAutomatic = AutomaticFold::None; convertPastes = true; @@ -194,8 +202,8 @@ Editor::Editor() : durationWrapOneLine(0.00001, 0.000001, 0.0001) { } Editor::~Editor() { - pdoc->RemoveWatcher(this, 0); - DropGraphics(true); + pdoc->RemoveWatcher(this, nullptr); + DropGraphics(); } void Editor::Finalise() { @@ -213,22 +221,23 @@ void Editor::SetRepresentations() { "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" }; - for (size_t j=0; j < Sci::size(reps); j++) { + for (size_t j=0; j < std::size(reps); j++) { const char c[2] = { static_cast(j), 0 }; - reprs.SetRepresentation(c, reps[j]); + 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 (IsUnicodeMode()) { + 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 < Sci::size(repsC1); j++) { + for (size_t j=0; j < std::size(repsC1); j++) { const char c1[3] = { '\xc2', static_cast(0x80+j), 0 }; reprs.SetRepresentation(c1, repsC1[j]); } @@ -236,43 +245,28 @@ void Editor::SetRepresentations() { reprs.SetRepresentation("\xe2\x80\xa9", "PS"); } - // UTF-8 invalid bytes - if (IsUnicodeMode()) { - for (int k=0x80; k < 0x100; k++) { - const char hiByte[2] = { static_cast(k), 0 }; - char hexits[5]; // Really only needs 4 but that causes warning from gcc 7.1 - sprintf(hexits, "x%2X", k); - reprs.SetRepresentation(hiByte, hexits); - } - } else if (pdoc->dbcsCodePage) { - // DBCS invalid single lead bytes + // Invalid as single bytes in multi-byte encodings + if (dbcsCodePage) { for (int k = 0x80; k < 0x100; k++) { - const char ch = static_cast(k); - if (pdoc->IsDBCSLeadByteNoExcept(ch) || pdoc->IsDBCSLeadByteInvalid(ch)) { - const char hiByte[2] = { ch, 0 }; - char hexits[5]; // Really only needs 4 but that causes warning from gcc 7.1 - sprintf(hexits, "x%2X", k); + if ((CpUtf8 == dbcsCodePage) || !IsDBCSValidSingleByte(dbcsCodePage, k)) { + const char hiByte[2] = { static_cast(k), 0 }; + char hexits[4]; + Hexits(hexits, k); reprs.SetRepresentation(hiByte, hexits); } } } } -void Editor::DropGraphics(bool freeObjects) { - marginView.DropGraphics(freeObjects); - view.DropGraphics(freeObjects); -} - -void Editor::AllocateGraphics() { - marginView.AllocateGraphics(vs); - view.AllocateGraphics(vs); +void Editor::DropGraphics() noexcept { + marginView.DropGraphics(); + view.DropGraphics(); } void Editor::InvalidateStyleData() { stylesValid = false; vs.technology = technology; - DropGraphics(false); - AllocateGraphics(); + DropGraphics(); view.llc.Invalidate(LineLayout::ValidLevel::invalid); view.posCache.Clear(); } @@ -379,9 +373,10 @@ SelectionPosition Editor::ClampPositionIntoDocument(SelectionPosition sp) const } Point Editor::LocationFromPosition(SelectionPosition pos, PointEnd pe) { + const PRectangle rcClient = GetTextRectangle(); RefreshStyleData(); AutoSurface surface(this); - return view.LocationFromPosition(surface, *this, pos, topLine, vs, pe); + return view.LocationFromPosition(surface, *this, pos, topLine, vs, pe, rcClient); } Point Editor::LocationFromPosition(Sci::Position pos, PointEnd pe) { @@ -397,20 +392,22 @@ SelectionPosition Editor::SPositionFromLocation(Point pt, bool canReturnInvalid, RefreshStyleData(); AutoSurface surface(this); + PRectangle rcClient = GetTextRectangle(); + // May be in scroll view coordinates so translate back to main view + const Point ptOrigin = GetVisibleOriginInMain(); + rcClient.Move(-ptOrigin.x, -ptOrigin.y); + if (canReturnInvalid) { - PRectangle rcClient = GetTextRectangle(); - // May be in scroll view coordinates so translate back to main view - const Point ptOrigin = GetVisibleOriginInMain(); - rcClient.Move(-ptOrigin.x, -ptOrigin.y); if (!rcClient.Contains(pt)) - return SelectionPosition(INVALID_POSITION); + return SelectionPosition(Sci::invalidPosition); if (pt.x < vs.textStart) - return SelectionPosition(INVALID_POSITION); + return SelectionPosition(Sci::invalidPosition); if (pt.y < 0) - return SelectionPosition(INVALID_POSITION); + return SelectionPosition(Sci::invalidPosition); } const PointDocument ptdoc = DocumentPointFromView(pt); - return view.SPositionFromLocation(surface, *this, ptdoc, canReturnInvalid, charPosition, virtualSpace, vs); + return view.SPositionFromLocation(surface, *this, ptdoc, canReturnInvalid, + charPosition, virtualSpace, vs, rcClient); } Sci::Position Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) { @@ -442,7 +439,7 @@ Sci::Line Editor::LineFromLocation(Point pt) const { void Editor::SetTopLine(Sci::Line topLineNew) { if ((topLine != topLineNew) && (topLineNew >= 0)) { topLine = topLineNew; - ContainerNeedsUpdate(SC_UPDATE_V_SCROLL); + ContainerNeedsUpdate(Update::VScroll); } posTopLine = pdoc->LineStart(pcs->DocFromDisplay(topLine)); } @@ -452,10 +449,10 @@ void Editor::SetTopLine(Sci::Line topLineNew) { * @return true if calling code should stop drawing. */ bool Editor::AbandonPaint() { - if ((paintState == painting) && !paintingAllText) { - paintState = paintAbandoned; + if ((paintState == PaintState::painting) && !paintingAllText) { + paintState = PaintState::abandoned; } - return paintState == paintAbandoned; + return paintState == PaintState::abandoned; } void Editor::RedrawRect(PRectangle rc) { @@ -578,7 +575,7 @@ void Editor::SetRectangularRange() { if (sel.IsRectangular()) { const int xAnchor = XFromPosition(sel.Rectangular().anchor); int xCaret = XFromPosition(sel.Rectangular().caret); - if (sel.selType == Selection::selThin) { + if (sel.selType == Selection::SelTypes::thin) { xCaret = xAnchor; } const Sci::Line lineAnchorRect = @@ -591,7 +588,7 @@ void Editor::SetRectangularRange() { SelectionRange range( view.SPositionFromLineX(surface, *this, line, xCaret, vs), view.SPositionFromLineX(surface, *this, line, xAnchor, vs)); - if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0) + if (!FlagSet(virtualSpaceOptions, VirtualSpace::RectangularSelection)) range.ClearVirtualSpace(); if (line == lineAnchorRect) sel.SetSelection(range); @@ -603,7 +600,7 @@ void Editor::SetRectangularRange() { void Editor::ThinRectangularRange() { if (sel.IsRectangular()) { - sel.selType = Selection::selThin; + sel.selType = Selection::SelTypes::thin; if (sel.Rectangular().caret < sel.Rectangular().anchor) { sel.Rectangular() = SelectionRange(sel.Range(sel.Count()-1).caret, sel.Range(0).anchor); } else { @@ -629,7 +626,7 @@ void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSel lastAffected = std::max(lastAffected, sel.Range(r).anchor.Position()); } } - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + ContainerNeedsUpdate(Update::Selection); InvalidateRange(firstAffected, lastAffected); } @@ -659,7 +656,7 @@ void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition ancho anchor_ = ClampPositionIntoDocument(anchor_); const Sci::Line currentLine = pdoc->SciLineFromPosition(currentPos_.Position()); SelectionRange rangeNew(currentPos_, anchor_); - if (sel.selType == Selection::selLines) { + if (sel.selType == Selection::SelTypes::lines) { rangeNew = LineSelectionRange(currentPos_, anchor_); } if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) { @@ -673,7 +670,7 @@ void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition ancho if (marginView.highlightDelimiter.NeedsDrawing(currentLine)) { RedrawSelMargin(); } - QueueIdleWork(WorkNeeded::workUpdateUI); + QueueIdleWork(WorkItems::updateUI); } void Editor::SetSelection(Sci::Position currentPos_, Sci::Position anchor_) { @@ -691,7 +688,7 @@ void Editor::SetSelection(SelectionPosition currentPos_) { sel.Rectangular() = SelectionRange(SelectionPosition(currentPos_), sel.Rectangular().anchor); SetRectangularRange(); - } else if (sel.selType == Selection::selLines) { + } else if (sel.selType == Selection::SelTypes::lines) { sel.RangeMain() = LineSelectionRange(currentPos_, sel.RangeMain().anchor); } else { sel.RangeMain() = @@ -703,11 +700,7 @@ void Editor::SetSelection(SelectionPosition currentPos_) { if (marginView.highlightDelimiter.NeedsDrawing(currentLine)) { RedrawSelMargin(); } - QueueIdleWork(WorkNeeded::workUpdateUI); -} - -void Editor::SetSelection(int currentPos_) { - SetSelection(SelectionPosition(currentPos_)); + QueueIdleWork(WorkItems::updateUI); } void Editor::SetEmptySelection(SelectionPosition currentPos_) { @@ -725,7 +718,7 @@ void Editor::SetEmptySelection(SelectionPosition currentPos_) { if (marginView.highlightDelimiter.NeedsDrawing(currentLine)) { RedrawSelMargin(); } - QueueIdleWork(WorkNeeded::workUpdateUI); + QueueIdleWork(WorkItems::updateUI); } void Editor::SetEmptySelection(Sci::Position currentPos_) { @@ -772,7 +765,7 @@ void Editor::MultipleSelectAdd(AddNumber addNumber) { selectedText.c_str(), searchFlags, &lengthFound); if (pos >= 0) { sel.AddSelection(SelectionRange(pos + lengthFound, pos)); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + ContainerNeedsUpdate(Update::Selection); ScrollRange(sel.RangeMain()); Redraw(); if (addNumber == AddNumber::one) @@ -851,7 +844,7 @@ void Editor::MovedCaret(SelectionPosition newPos, SelectionPosition previousPos, } } const XYScrollPosition newXY = XYScrollToMakeVisible( - SelectionRange(posDrag.IsValid() ? posDrag : newPos), xysDefault, policies); + SelectionRange(posDrag.IsValid() ? posDrag : newPos), XYScrollOptions::all, policies); if (previousPos.IsValid() && (newXY.xOffset == xOffset)) { // simple vertical scroll then invalidate ScrollTo(newXY.topLine); @@ -866,36 +859,36 @@ void Editor::MovedCaret(SelectionPosition newPos, SelectionPosition previousPos, ClaimSelection(); SetHoverIndicatorPosition(sel.MainCaret()); - QueueIdleWork(WorkNeeded::workUpdateUI); + QueueIdleWork(WorkItems::updateUI); if (marginView.highlightDelimiter.NeedsDrawing(currentLine)) { RedrawSelMargin(); } } -void Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, bool ensureVisible) { +void Editor::MovePositionTo(SelectionPosition newPos, Selection::SelTypes selt, bool ensureVisible) { const SelectionPosition spCaret = ((sel.Count() == 1) && sel.Empty()) ? - sel.Last() : SelectionPosition(INVALID_POSITION); + sel.Last() : SelectionPosition(Sci::invalidPosition); const Sci::Position delta = newPos.Position() - sel.MainCaret(); newPos = ClampPositionIntoDocument(newPos); newPos = MovePositionOutsideChar(newPos, delta); - if (!multipleSelection && sel.IsRectangular() && (selt == Selection::selStream)) { + if (!multipleSelection && sel.IsRectangular() && (selt == Selection::SelTypes::stream)) { // Can't turn into multiple selection so clear additional selections InvalidateSelection(SelectionRange(newPos), true); sel.DropAdditionalRanges(); } - if (!sel.IsRectangular() && (selt == Selection::selRectangle)) { + if (!sel.IsRectangular() && (selt == Selection::SelTypes::rectangle)) { // Switching to rectangular InvalidateSelection(sel.RangeMain(), false); SelectionRange rangeMain = sel.RangeMain(); sel.Clear(); sel.Rectangular() = rangeMain; } - if (selt != Selection::noSel) { + if (selt != Selection::SelTypes::none) { sel.selType = selt; } - if (selt != Selection::noSel || sel.MoveExtends()) { + if (selt != Selection::SelTypes::none || sel.MoveExtends()) { SetSelection(newPos); } else { SetEmptySelection(newPos); @@ -904,7 +897,7 @@ void Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, MovedCaret(newPos, spCaret, ensureVisible, caretPolicies); } -void Editor::MovePositionTo(Sci::Position newPos, Selection::selTypes selt, bool ensureVisible) { +void Editor::MovePositionTo(Sci::Position newPos, Selection::SelTypes selt, bool ensureVisible) { MovePositionTo(SelectionPosition(newPos), selt, ensureVisible); } @@ -918,11 +911,11 @@ SelectionPosition Editor::MovePositionSoVisible(SelectionPosition pos, int moveD Sci::Line lineDisplay = pcs->DisplayFromDoc(lineDoc); if (moveDir > 0) { // lineDisplay is already line before fold as lines in fold use display line of line after fold - lineDisplay = Sci::clamp(lineDisplay, static_cast(0), pcs->LinesDisplayed()); + lineDisplay = std::clamp(lineDisplay, 0, pcs->LinesDisplayed()); return SelectionPosition( pdoc->LineStart(pcs->DocFromDisplay(lineDisplay))); } else { - lineDisplay = Sci::clamp(lineDisplay - 1, static_cast(0), pcs->LinesDisplayed()); + lineDisplay = std::clamp(lineDisplay - 1, 0, pcs->LinesDisplayed()); return SelectionPosition( pdoc->LineEnd(pcs->DocFromDisplay(lineDisplay))); } @@ -947,12 +940,12 @@ void Editor::SetLastXChosen() { } void Editor::ScrollTo(Sci::Line line, bool moveThumb) { - const Sci::Line topLineNew = Sci::clamp(line, static_cast(0), MaxScrollPos()); + const Sci::Line topLineNew = std::clamp(line, 0, MaxScrollPos()); if (topLineNew != topLine) { // Try to optimise small scrolls #ifndef UNDER_CE const Sci::Line linesToMove = topLine - topLineNew; - const bool performBlit = (std::abs(linesToMove) <= 10) && (paintState == notPainting); + const bool performBlit = (std::abs(linesToMove) <= 10) && (paintState == PaintState::notPainting); willRedrawAll = !performBlit; #endif SetTopLine(topLineNew); @@ -987,7 +980,7 @@ void Editor::HorizontalScrollTo(int xPos) { xPos = 0; if (!Wrapping() && (xOffset != xPos)) { xOffset = xPos; - ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); + ContainerNeedsUpdate(Update::HScroll); SetHorizontalScrollPos(); RedrawRect(GetClientRectangle()); } @@ -1084,13 +1077,13 @@ void Editor::MoveCaretInsideView(bool ensureVisible) { MovePositionTo(SPositionFromLocation( Point::FromInts(lastXChosen - xOffset, static_cast(rcClient.top)), false, false, UserVirtualSpace()), - Selection::noSel, ensureVisible); + Selection::SelTypes::none, ensureVisible); } else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) { const ptrdiff_t yOfLastLineFullyDisplayed = static_cast(rcClient.top) + (LinesOnScreen() - 1) * vs.lineHeight; MovePositionTo(SPositionFromLocation( Point::FromInts(lastXChosen - xOffset, static_cast(rcClient.top + yOfLastLineFullyDisplayed)), false, false, UserVirtualSpace()), - Selection::noSel, ensureVisible); + Selection::SelTypes::none, ensureVisible); } } @@ -1159,14 +1152,15 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran } // Vertical positioning - if ((options & xysVertical) && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || (policies.y.policy & CARET_STRICT) != 0)) { + if (FlagSet(options, XYScrollOptions::vertical) && + (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || FlagSet(policies.y.policy, CaretPolicy::Strict))) { const Sci::Line lineCaret = DisplayFromPosition(range.caret.Position()); const Sci::Line linesOnScreen = LinesOnScreen(); const Sci::Line halfScreen = std::max(linesOnScreen - 1, static_cast(2)) / 2; - const bool bSlop = (policies.y.policy & CARET_SLOP) != 0; - const bool bStrict = (policies.y.policy & CARET_STRICT) != 0; - const bool bJump = (policies.y.policy & CARET_JUMPS) != 0; - const bool bEven = (policies.y.policy & CARET_EVEN) != 0; + const bool bSlop = FlagSet(policies.y.policy, CaretPolicy::Slop); + const bool bStrict = FlagSet(policies.y.policy, CaretPolicy::Strict); + const bool bJump = FlagSet(policies.y.policy, CaretPolicy::Jumps); + const bool bEven = FlagSet(policies.y.policy, CaretPolicy::Even); // It should be possible to scroll the window to show the caret, // but this fails to remove the caret on GTK+ @@ -1174,14 +1168,14 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran Sci::Line yMoveT, yMoveB; if (bStrict) { Sci::Line yMarginT, yMarginB; - if (!(options & xysUseMargin)) { + if (!FlagSet(options, XYScrollOptions::useMargin)) { // In drag mode, avoid moves // otherwise, a double click will select several lines. yMarginT = yMarginB = 0; } else { // yMarginT must equal to caretYSlop, with a minimum of 1 and // a maximum of slightly less than half the height of the text area. - yMarginT = Sci::clamp(static_cast(policies.y.slop), static_cast(1), halfScreen); + yMarginT = std::clamp(policies.y.slop, 1, halfScreen); if (bEven) { yMarginB = yMarginT; } else { @@ -1191,7 +1185,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran yMoveT = yMarginT; if (bEven) { if (bJump) { - yMoveT = Sci::clamp(static_cast(policies.y.slop * 3), static_cast(1), halfScreen); + yMoveT = std::clamp(policies.y.slop * 3, 1, halfScreen); } yMoveB = yMoveT; } else { @@ -1206,7 +1200,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran } } else { // Not strict yMoveT = bJump ? policies.y.slop * 3 : policies.y.slop; - yMoveT = Sci::clamp(yMoveT, static_cast(1), halfScreen); + yMoveT = std::clamp(yMoveT, 1, halfScreen); if (bEven) { yMoveB = yMoveT; } else { @@ -1256,29 +1250,29 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran newXY.topLine = std::min(newXY.topLine, lineCaret); } } - newXY.topLine = Sci::clamp(newXY.topLine, static_cast(0), MaxScrollPos()); + newXY.topLine = std::clamp(newXY.topLine, 0, MaxScrollPos()); } // Horizontal positioning - if ((options & xysHorizontal) && !Wrapping()) { + if (FlagSet(options, XYScrollOptions::horizontal) && !Wrapping()) { const int halfScreen = std::max(static_cast(rcClient.Width()) - 4, 4) / 2; - const bool bSlop = (policies.x.policy & CARET_SLOP) != 0; - const bool bStrict = (policies.x.policy & CARET_STRICT) != 0; - const bool bJump = (policies.x.policy & CARET_JUMPS) != 0; - const bool bEven = (policies.x.policy & CARET_EVEN) != 0; + const bool bSlop = FlagSet(policies.x.policy, CaretPolicy::Slop); + const bool bStrict = FlagSet(policies.x.policy, CaretPolicy::Strict); + const bool bJump = FlagSet(policies.x.policy, CaretPolicy::Jumps); + const bool bEven = FlagSet(policies.x.policy, CaretPolicy::Even); if (bSlop) { // A margin is defined int xMoveL, xMoveR; if (bStrict) { int xMarginL, xMarginR; - if (!(options & xysUseMargin)) { + if (!FlagSet(options, XYScrollOptions::useMargin)) { // In drag mode, avoid moves unless very near of the margin // otherwise, a simple click will select text. xMarginL = xMarginR = 2; } else { // xMargin must equal to caretXSlop, with a minimum of 2 and // a maximum of slightly less than half the width of the text area. - xMarginR = Sci::clamp(policies.x.slop, 2, halfScreen); + xMarginR = std::clamp(policies.x.slop, 2, halfScreen); if (bEven) { xMarginL = xMarginR; } else { @@ -1287,7 +1281,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran } if (bJump && bEven) { // Jump is used only in even mode - xMoveL = xMoveR = Sci::clamp(policies.x.slop * 3, 1, halfScreen); + xMoveL = xMoveR = std::clamp(policies.x.slop * 3, 1, halfScreen); } else { xMoveL = xMoveR = 0; // Not used, avoid a warning } @@ -1310,7 +1304,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran } } else { // Not strict xMoveR = bJump ? policies.x.slop * 3 : policies.x.slop; - xMoveR = Sci::clamp(xMoveR, 1, halfScreen); + xMoveR = std::clamp(xMoveR, 1, halfScreen); if (bEven) { xMoveL = xMoveR; } else { @@ -1391,7 +1385,7 @@ void Editor::SetXYScroll(XYScrollPosition newXY) { } if (newXY.xOffset != xOffset) { xOffset = newXY.xOffset; - ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); + ContainerNeedsUpdate(Update::HScroll); if (newXY.xOffset > 0) { const PRectangle rcText = GetTextRectangle(); if (horizontalScrollBarVisible && @@ -1408,12 +1402,14 @@ void Editor::SetXYScroll(XYScrollPosition newXY) { } void Editor::ScrollRange(SelectionRange range) { - SetXYScroll(XYScrollToMakeVisible(range, xysDefault, caretPolicies)); + SetXYScroll(XYScrollToMakeVisible(range, XYScrollOptions::all, caretPolicies)); } void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) { SetXYScroll(XYScrollToMakeVisible(SelectionRange(posDrag.IsValid() ? posDrag : sel.RangeMain().caret), - static_cast((useMargin?xysUseMargin:0)|(vert?xysVertical:0)|(horiz?xysHorizontal:0)), + (useMargin?XYScrollOptions::useMargin:XYScrollOptions::none)| + (vert?XYScrollOptions::vertical:XYScrollOptions::none)| + (horiz?XYScrollOptions::horizontal:XYScrollOptions::none), caretPolicies)); } @@ -1421,20 +1417,20 @@ void Editor::ShowCaretAtCurrentPosition() { if (hasFocus) { caret.active = true; caret.on = true; - FineTickerCancel(tickCaret); + FineTickerCancel(TickReason::caret); if (caret.period > 0) - FineTickerStart(tickCaret, caret.period, caret.period/10); + FineTickerStart(TickReason::caret, caret.period, caret.period/10); } else { caret.active = false; caret.on = false; - FineTickerCancel(tickCaret); + FineTickerCancel(TickReason::caret); } InvalidateCaret(); } void Editor::DropCaret() { caret.active = false; - FineTickerCancel(tickCaret); + FineTickerCancel(TickReason::caret); InvalidateCaret(); } @@ -1442,9 +1438,9 @@ void Editor::CaretSetPeriod(int period) { if (caret.period != period) { caret.period = period; caret.on = true; - FineTickerCancel(tickCaret); + FineTickerCancel(TickReason::caret); if ((caret.active) && (caret.period > 0)) - FineTickerStart(tickCaret, caret.period, caret.period/10); + FineTickerStart(TickReason::caret, caret.period, caret.period/10); InvalidateCaret(); } } @@ -1467,7 +1463,7 @@ void Editor::UpdateSystemCaret() { } bool Editor::Wrapping() const noexcept { - return vs.wrapState != WrapMode::none; + return vs.wrap.state != Wrap::None; } void Editor::NeedWrapping(Sci::Line docLineStart, Sci::Line docLineEnd) { @@ -1482,14 +1478,14 @@ void Editor::NeedWrapping(Sci::Line docLineStart, Sci::Line docLineEnd) { } bool Editor::WrapOneLine(Surface *surface, Sci::Line lineToWrap) { - AutoLineLayout ll(view.llc, view.RetrieveLineLayout(lineToWrap, *this)); + std::shared_ptr ll = view.RetrieveLineLayout(lineToWrap, *this); int linesWrapped = 1; if (ll) { - view.LayoutLine(*this, lineToWrap, surface, vs, ll, wrapWidth); + view.LayoutLine(*this, surface, vs, ll.get(), wrapWidth); linesWrapped = ll->lines; } return pcs->SetHeight(lineToWrap, linesWrapped + - (vs.annotationVisible ? pdoc->AnnotationLines(lineToWrap) : 0)); + ((vs.annotationVisible != AnnotationVisible::Hidden) ? pdoc->AnnotationLines(lineToWrap) : 0)); } // Perform wrapping for a subset of the lines needing wrapping. @@ -1505,7 +1501,7 @@ bool Editor::WrapLines(WrapScope ws) { wrapWidth = LineLayout::wrapWidthInfinite; for (Sci::Line lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) { pcs->SetHeight(lineDoc, 1 + - (vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0)); + ((vs.annotationVisible != AnnotationVisible::Hidden) ? pdoc->AnnotationLines(lineDoc) : 0)); } wrapOccurred = true; } @@ -1523,13 +1519,19 @@ bool Editor::WrapLines(WrapScope ws) { const Sci::Line lineDocTop = pcs->DocFromDisplay(topLine); const Sci::Line subLineTop = topLine - pcs->DisplayFromDoc(lineDocTop); if (ws == WrapScope::wsVisible) { - lineToWrap = Sci::clamp(lineDocTop-5, wrapPending.start, pdoc->LinesTotal()); + lineToWrap = std::clamp(lineDocTop-5, wrapPending.start, pdoc->LinesTotal()); // Priority wrap to just after visible area. // Since wrapping could reduce display lines, treat each // as taking only one display line. lineToWrapEnd = lineDocTop; Sci::Line lines = LinesOnScreen() + 1; - while ((lineToWrapEnd < pcs->LinesInDoc()) && (lines>0)) { + constexpr double secondsAllowed = 0.1; + const size_t actionsInAllowedTime = std::clamp( + durationWrapOneByte.ActionsInAllowedTime(secondsAllowed), + 0x2000, 0x200000); + const Sci::Line lineLast = pdoc->LineFromPositionAfter(lineToWrap, actionsInAllowedTime); + const Sci::Line maxLine = std::min(lineLast, pcs->LinesInDoc()); + while ((lineToWrapEnd < maxLine) && (lines>0)) { if (pcs->GetVisible(lineToWrapEnd)) lines--; lineToWrapEnd++; @@ -1542,10 +1544,10 @@ bool Editor::WrapLines(WrapScope ws) { } else if (ws == WrapScope::wsIdle) { // Try to keep time taken by wrapping reasonable so interaction remains smooth. constexpr double secondsAllowed = 0.01; - const Sci::Line linesInAllowedTime = Sci::clamp( - static_cast(secondsAllowed / durationWrapOneLine.Duration()), - LinesOnScreen() + 50, static_cast(0x10000)); - lineToWrapEnd = lineToWrap + linesInAllowedTime; + const size_t actionsInAllowedTime = std::clamp( + durationWrapOneByte.ActionsInAllowedTime(secondsAllowed), + 0x200, 0x20000); + lineToWrapEnd = pdoc->LineFromPositionAfter(lineToWrap, actionsInAllowedTime); } const Sci::Line lineEndNeedWrap = std::min(wrapPending.end, pdoc->LinesTotal()); lineToWrapEnd = std::min(lineToWrapEnd, lineEndNeedWrap); @@ -1564,7 +1566,7 @@ bool Editor::WrapLines(WrapScope ws) { if (surface) { //Platform::DebugPrintf("Wraplines: scope=%0d need=%0d..%0d perform=%0d..%0d\n", ws, wrapPending.start, wrapPending.end, lineToWrap, lineToWrapEnd); - const Sci::Line linesBeingWrapped = lineToWrapEnd - lineToWrap; + const size_t bytesBeingWrapped = pdoc->LineStart(lineToWrapEnd) - pdoc->LineStart(lineToWrap); ElapsedPeriod epWrapping; while (lineToWrap < lineToWrapEnd) { if (WrapOneLine(surface, lineToWrap)) { @@ -1573,7 +1575,7 @@ bool Editor::WrapLines(WrapScope ws) { wrapPending.Wrapped(lineToWrap); lineToWrap++; } - durationWrapOneLine.AddSample(linesBeingWrapped, epWrapping.Duration()); + durationWrapOneByte.AddSample(bytesBeingWrapped, epWrapping.Duration()); goodTopLine = pcs->DisplayFromDoc(lineDocTop) + std::min( subLineTop, static_cast(pcs->GetHeight(lineDocTop)-1)); @@ -1588,7 +1590,7 @@ bool Editor::WrapLines(WrapScope ws) { if (wrapOccurred) { SetScrollBars(); - SetTopLine(Sci::clamp(goodTopLine, static_cast(0), MaxScrollPos())); + SetTopLine(std::clamp(goodTopLine, 0, MaxScrollPos())); SetVerticalScrollPos(); } @@ -1615,10 +1617,10 @@ void Editor::LinesJoin() { } } -const char *Editor::StringFromEOLMode(int eolMode) noexcept { - if (eolMode == SC_EOL_CRLF) { +const char *Editor::StringFromEOLMode(EndOfLine eolMode) noexcept { + if (eolMode == EndOfLine::CrLf) { return "\r\n"; - } else if (eolMode == SC_EOL_CR) { + } else if (eolMode == EndOfLine::Cr) { return "\r"; } else { return "\n"; @@ -1637,10 +1639,10 @@ void Editor::LinesSplit(int pixelWidth) { UndoGroup ug(pdoc); for (Sci::Line line = lineStart; line <= lineEnd; line++) { AutoSurface surface(this); - AutoLineLayout ll(view.llc, view.RetrieveLineLayout(line, *this)); + std::shared_ptr ll = view.RetrieveLineLayout(line, *this); if (surface && ll) { const Sci::Position posLineStart = pdoc->LineStart(line); - view.LayoutLine(*this, line, surface, vs, ll, pixelWidth); + view.LayoutLine(*this, surface, vs, ll.get(), pixelWidth); Sci::Position lengthInsertedTotal = 0; for (int subLine = 1; subLine < ll->lines; subLine++) { const Sci::Position lengthInserted = pdoc->InsertString( @@ -1659,7 +1661,6 @@ void Editor::PaintSelMargin(Surface *surfaceWindow, const PRectangle &rc) { if (vs.fixedColumnWidth == 0) return; - AllocateGraphics(); RefreshStyleData(); RefreshPixMaps(surfaceWindow); @@ -1695,23 +1696,22 @@ void Editor::PaintSelMargin(Surface *surfaceWindow, const PRectangle &rc) { marginView.PaintMargin(surface, topLine, rc, rcMargin, *this, vs); if (view.bufferedDraw) { + marginView.pixmapSelMargin->FlushDrawing(); surfaceWindow->Copy(rcMargin, Point(rcMargin.left, rcMargin.top), *marginView.pixmapSelMargin); } } void Editor::RefreshPixMaps(Surface *surfaceWindow) { - view.RefreshPixMaps(surfaceWindow, wMain.GetID(), vs); - marginView.RefreshPixMaps(surfaceWindow, wMain.GetID(), vs); + view.RefreshPixMaps(surfaceWindow, vs); + marginView.RefreshPixMaps(surfaceWindow, vs); if (view.bufferedDraw) { const PRectangle rcClient = GetClientRectangle(); - if (!view.pixmapLine->Initialised()) { - - view.pixmapLine->InitPixMap(static_cast(rcClient.Width()), vs.lineHeight, - surfaceWindow, wMain.GetID()); + if (!view.pixmapLine) { + view.pixmapLine = surfaceWindow->AllocatePixMap(static_cast(rcClient.Width()), vs.lineHeight); } - if (!marginView.pixmapSelMargin->Initialised()) { - marginView.pixmapSelMargin->InitPixMap(vs.fixedColumnWidth, - static_cast(rcClient.Height()), surfaceWindow, wMain.GetID()); + if (!marginView.pixmapSelMargin) { + marginView.pixmapSelMargin = surfaceWindow->AllocatePixMap(vs.fixedColumnWidth, + static_cast(rcClient.Height())); } } } @@ -1719,10 +1719,9 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) { void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { //Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n", // paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom); - AllocateGraphics(); RefreshStyleData(); - if (paintState == paintAbandoned) + if (paintState == PaintState::abandoned) return; // Scroll bars may have changed so need redraw RefreshPixMaps(surfaceWindow); @@ -1759,25 +1758,25 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { if (!view.bufferedDraw) surfaceWindow->SetClip(rcArea); - if (paintState != paintAbandoned) { + if (paintState != PaintState::abandoned) { if (vs.marginInside) { PaintSelMargin(surfaceWindow, rcArea); PRectangle rcRightMargin = rcClient; rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth; if (rcArea.Intersects(rcRightMargin)) { - surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back); + surfaceWindow->FillRectangle(rcRightMargin, vs.styles[StyleDefault].back); } } else { // Else separate view so separate paint event but leftMargin included to allow overlap PRectangle rcLeftMargin = rcArea; rcLeftMargin.left = 0; rcLeftMargin.right = rcLeftMargin.left + vs.leftMarginWidth; if (rcArea.Intersects(rcLeftMargin)) { - surfaceWindow->FillRectangle(rcLeftMargin, vs.styles[STYLE_DEFAULT].back); + surfaceWindow->FillRectangle(rcLeftMargin, vs.styles[StyleDefault].back); } } } - if (paintState == paintAbandoned) { + if (paintState == PaintState::abandoned) { // Either styling or NotifyUpdateUI noticed that painting is needed // outside the current painting rectangle //Platform::DebugPrintf("Abandoning paint\n"); @@ -1788,6 +1787,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { NeedWrapping(pcs->DocFromDisplay(topLine)); } } + if (!view.bufferedDraw) + surfaceWindow->PopClip(); return; } @@ -1795,25 +1796,28 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { if (horizontalScrollBarVisible && trackLineWidth && (view.lineWidthMaxSeen > scrollWidth)) { scrollWidth = view.lineWidthMaxSeen; - if (!FineTickerRunning(tickWiden)) { - FineTickerStart(tickWiden, 50, 5); + if (!FineTickerRunning(TickReason::widen)) { + FineTickerStart(TickReason::widen, 50, 5); } } + if (!view.bufferedDraw) + surfaceWindow->PopClip(); + NotifyPainted(); } // This is mostly copied from the Paint method but with some things omitted // such as the margin markers, line numbers, selection and caret // Should be merged back into a combined Draw method. -Sci::Position Editor::FormatRange(bool draw, const Sci_RangeToFormat *pfr) { +Sci::Position Editor::FormatRange(bool draw, const RangeToFormat *pfr) { if (!pfr) return 0; - AutoSurface surface(pfr->hdc, this, SC_TECHNOLOGY_DEFAULT); + AutoSurface surface(pfr->hdc, this, Technology::Default); if (!surface) return 0; - AutoSurface surfaceMeasure(pfr->hdcTarget, this, SC_TECHNOLOGY_DEFAULT); + AutoSurface surfaceMeasure(pfr->hdcTarget, this, Technology::Default); if (!surfaceMeasure) { return 0; } @@ -1824,7 +1828,7 @@ long Editor::TextWidth(uptr_t style, const char *text) { RefreshStyleData(); AutoSurface surface(this); if (surface) { - return Sci::lround(surface->WidthText(vs.styles[style].font, text, static_cast(strlen(text)))); + return std::lround(surface->WidthText(vs.styles[style].font.get(), text)); } else { return 1; } @@ -1846,7 +1850,7 @@ void Editor::SetScrollBars() { // TODO: ensure always showing as many lines as possible // May not be, if, for example, window made larger if (topLine > MaxScrollPos()) { - SetTopLine(Sci::clamp(topLine, static_cast(0), MaxScrollPos())); + SetTopLine(std::clamp(topLine, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } @@ -1858,7 +1862,7 @@ void Editor::SetScrollBars() { } void Editor::ChangeSize() { - DropGraphics(false); + DropGraphics(); SetScrollBars(); if (Wrapping()) { PRectangle rcTextArea = GetClientRectangle(); @@ -1895,7 +1899,7 @@ void Editor::AddChar(char ch) { char s[2]; s[0] = ch; s[1] = '\0'; - InsertCharacter(s, 1, CharacterSource::directInput); + InsertCharacter(std::string_view(s, 1), CharacterSource::DirectInput); } void Editor::FilterSelections() { @@ -1906,8 +1910,8 @@ void Editor::FilterSelections() { } // InsertCharacter inserts a character encoded in document code page. -void Editor::InsertCharacter(const char *s, unsigned int len, CharacterSource charSource) { - if (len == 0) { +void Editor::InsertCharacter(std::string_view sv, CharacterSource charSource) { + if (sv.empty()) { return; } FilterSelections(); @@ -1947,7 +1951,7 @@ void Editor::InsertCharacter(const char *s, unsigned int len, CharacterSource ch } } positionInsert = RealizeVirtualSpace(positionInsert, currentSel->caret.VirtualSpace()); - const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, s, len); + const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, sv.data(), sv.length()); if (lengthInserted > 0) { currentSel->caret.SetPosition(positionInsert + lengthInserted); currentSel->anchor.SetPosition(positionInsert + lengthInserted); @@ -1975,34 +1979,34 @@ void Editor::InsertCharacter(const char *s, unsigned int len, CharacterSource ch EnsureCaretVisible(); // Avoid blinking during rapid typing: ShowCaretAtCurrentPosition(); - if ((caretSticky == SC_CARETSTICKY_OFF) || - ((caretSticky == SC_CARETSTICKY_WHITESPACE) && !IsAllSpacesOrTabs(s, len))) { + if ((caretSticky == CaretSticky::Off) || + ((caretSticky == CaretSticky::WhiteSpace) && !IsAllSpacesOrTabs(sv))) { SetLastXChosen(); } - int ch = static_cast(s[0]); - if (pdoc->dbcsCodePage != SC_CP_UTF8) { - if (len > 1) { + int ch = static_cast(sv[0]); + if (pdoc->dbcsCodePage != CpUtf8) { + if (sv.length() > 1) { // DBCS code page or DBCS font character set. - ch = (ch << 8) | static_cast(s[1]); + ch = (ch << 8) | static_cast(sv[1]); } } else { - if ((ch < 0xC0) || (1 == len)) { + if ((ch < 0xC0) || (1 == sv.length())) { // Handles UTF-8 characters between 0x01 and 0x7F and single byte // characters when not in UTF-8 mode. // Also treats \0 and naked trail bytes 0x80 to 0xBF as valid // characters representing themselves. } else { unsigned int utf32[1] = { 0 }; - UTF32FromUTF8(s, len, utf32, Sci::size(utf32)); + UTF32FromUTF8(sv, utf32, std::size(utf32)); ch = utf32[0]; } } NotifyChar(ch, charSource); - if (recordingMacro && charSource != CharacterSource::tentativeInput) { - std::string copy(s, len); // ensure NUL-terminated - NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast(copy.data())); + if (recordingMacro && charSource != CharacterSource::TentativeInput) { + std::string copy(sv); // ensure NUL-terminated + NotifyMacroRecord(Message::ReplaceSel, 0, reinterpret_cast(copy.data())); } } @@ -2030,7 +2034,7 @@ void Editor::ClearBeforeTentativeStart() { } void Editor::InsertPaste(const char *text, Sci::Position len) { - if (multiPasteMode == SC_MULTIPASTE_ONCE) { + if (multiPasteMode == MultiPaste::Once) { SelectionPosition selStart = sel.Start(); selStart = RealizeVirtualSpace(selStart); const Sci::Position lengthInserted = pdoc->InsertString(selStart.Position(), text, len); @@ -2038,7 +2042,7 @@ void Editor::InsertPaste(const char *text, Sci::Position len) { SetEmptySelection(selStart.Position() + lengthInserted); } } else { - // SC_MULTIPASTE_EACH + // MultiPaste::Each for (size_t r=0; rLineStart(pdoc->LineFromPosition(sel.MainCaret())); Sci::Position lengthInserted = pdoc->InsertString(insertPos, text, len); @@ -2138,7 +2142,7 @@ void Editor::ClearAll() { void Editor::ClearDocumentStyle() { pdoc->decorations->DeleteLexerDecorations(); - pdoc->StartStyling(0, '\377'); + pdoc->StartStyling(0); pdoc->SetStyleFor(pdoc->Length(), 0); pcs->ShowAll(); SetAnnotationHeights(0, pdoc->LinesTotal()); @@ -2177,9 +2181,9 @@ void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Posit if ((ptr[i] == '\r') || (!prevCr)) line++; if (line >= pdoc->LinesTotal()) { - if (pdoc->eolMode != SC_EOL_LF) + if (pdoc->eolMode != EndOfLine::Lf) pdoc->InsertString(pdoc->Length(), "\r", 1); - if (pdoc->eolMode != SC_EOL_CR) + if (pdoc->eolMode != EndOfLine::Cr) pdoc->InsertString(pdoc->Length(), "\n", 1); } // Pad the end of lines with spaces if required @@ -2305,23 +2309,23 @@ void Editor::DelCharBack(bool allowLineStartDeletion) { ClearSelection(); } sel.RemoveDuplicates(); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + ContainerNeedsUpdate(Update::Selection); // Avoid blinking during rapid typing: ShowCaretAtCurrentPosition(); } -int Editor::ModifierFlags(bool shift, bool ctrl, bool alt, bool meta, bool super) noexcept { +KeyMod Editor::ModifierFlags(bool shift, bool ctrl, bool alt, bool meta, bool super) noexcept { return - (shift ? SCI_SHIFT : 0) | - (ctrl ? SCI_CTRL : 0) | - (alt ? SCI_ALT : 0) | - (meta ? SCI_META : 0) | - (super ? SCI_SUPER : 0); + (shift ? KeyMod::Shift : KeyMod::Norm) | + (ctrl ? KeyMod::Ctrl : KeyMod::Norm) | + (alt ? KeyMod::Alt : KeyMod::Norm) | + (meta ? KeyMod::Meta : KeyMod::Norm) | + (super ? KeyMod::Super : KeyMod::Norm); } void Editor::NotifyFocus(bool focus) { - SCNotification scn = {}; - scn.nmhdr.code = focus ? SCN_FOCUSIN : SCN_FOCUSOUT; + NotificationData scn = {}; + scn.nmhdr.code = focus ? Notification::FocusIn : Notification::FocusOut; NotifyParent(scn); } @@ -2330,8 +2334,8 @@ void Editor::SetCtrlID(int identifier) { } void Editor::NotifyStyleToNeeded(Sci::Position endStyleNeeded) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_STYLENEEDED; + NotificationData scn = {}; + scn.nmhdr.code = Notification::StyleNeeded; scn.position = endStyleNeeded; NotifyParent(scn); } @@ -2343,125 +2347,125 @@ void Editor::NotifyStyleNeeded(Document *, void *, Sci::Position endStyleNeeded) void Editor::NotifyLexerChanged(Document *, void *) { } -void Editor::NotifyErrorOccurred(Document *, void *, int status) { +void Editor::NotifyErrorOccurred(Document *, void *, Status status) { errorStatus = status; } void Editor::NotifyChar(int ch, CharacterSource charSource) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_CHARADDED; + NotificationData scn = {}; + scn.nmhdr.code = Notification::CharAdded; scn.ch = ch; - scn.characterSource = static_cast(charSource); + scn.characterSource = charSource; NotifyParent(scn); } void Editor::NotifySavePoint(bool isSavePoint) { - SCNotification scn = {}; + NotificationData scn = {}; if (isSavePoint) { - scn.nmhdr.code = SCN_SAVEPOINTREACHED; + scn.nmhdr.code = Notification::SavePointReached; } else { - scn.nmhdr.code = SCN_SAVEPOINTLEFT; + scn.nmhdr.code = Notification::SavePointLeft; } NotifyParent(scn); } void Editor::NotifyModifyAttempt() { - SCNotification scn = {}; - scn.nmhdr.code = SCN_MODIFYATTEMPTRO; + NotificationData scn = {}; + scn.nmhdr.code = Notification::ModifyAttemptRO; NotifyParent(scn); } -void Editor::NotifyDoubleClick(Point pt, int modifiers) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_DOUBLECLICK; +void Editor::NotifyDoubleClick(Point pt, KeyMod modifiers) { + NotificationData scn = {}; + scn.nmhdr.code = Notification::DoubleClick; scn.line = LineFromLocation(pt); scn.position = PositionFromLocation(pt, true); scn.modifiers = modifiers; NotifyParent(scn); } -void Editor::NotifyHotSpotDoubleClicked(Sci::Position position, int modifiers) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK; +void Editor::NotifyHotSpotDoubleClicked(Sci::Position position, KeyMod modifiers) { + NotificationData scn = {}; + scn.nmhdr.code = Notification::HotSpotDoubleClick; scn.position = position; scn.modifiers = modifiers; NotifyParent(scn); } -void Editor::NotifyHotSpotClicked(Sci::Position position, int modifiers) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_HOTSPOTCLICK; +void Editor::NotifyHotSpotClicked(Sci::Position position, KeyMod modifiers) { + NotificationData scn = {}; + scn.nmhdr.code = Notification::HotSpotClick; scn.position = position; scn.modifiers = modifiers; NotifyParent(scn); } -void Editor::NotifyHotSpotReleaseClick(Sci::Position position, int modifiers) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK; +void Editor::NotifyHotSpotReleaseClick(Sci::Position position, KeyMod modifiers) { + NotificationData scn = {}; + scn.nmhdr.code = Notification::HotSpotReleaseClick; scn.position = position; scn.modifiers = modifiers; NotifyParent(scn); } bool Editor::NotifyUpdateUI() { - if (needUpdateUI) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_UPDATEUI; + if (needUpdateUI != Update::None) { + NotificationData scn = {}; + scn.nmhdr.code = Notification::UpdateUI; scn.updated = needUpdateUI; NotifyParent(scn); - needUpdateUI = 0; + needUpdateUI = Update::None; return true; } return false; } void Editor::NotifyPainted() { - SCNotification scn = {}; - scn.nmhdr.code = SCN_PAINTED; + NotificationData scn = {}; + scn.nmhdr.code = Notification::Painted; NotifyParent(scn); } -void Editor::NotifyIndicatorClick(bool click, Sci::Position position, int modifiers) { +void Editor::NotifyIndicatorClick(bool click, Sci::Position position, KeyMod modifiers) { const int mask = pdoc->decorations->AllOnFor(position); if ((click && mask) || pdoc->decorations->ClickNotified()) { - SCNotification scn = {}; + NotificationData scn = {}; pdoc->decorations->SetClickNotified(click); - scn.nmhdr.code = click ? SCN_INDICATORCLICK : SCN_INDICATORRELEASE; + scn.nmhdr.code = click ? Notification::IndicatorClick : Notification::IndicatorRelease; scn.modifiers = modifiers; scn.position = position; NotifyParent(scn); } } -bool Editor::NotifyMarginClick(Point pt, int modifiers) { +bool Editor::NotifyMarginClick(Point pt, KeyMod modifiers) { const int marginClicked = vs.MarginFromLocation(pt); if ((marginClicked >= 0) && vs.ms[marginClicked].sensitive) { const Sci::Position position = pdoc->LineStart(LineFromLocation(pt)); - if ((vs.ms[marginClicked].mask & SC_MASK_FOLDERS) && (foldAutomatic & SC_AUTOMATICFOLD_CLICK)) { - const bool ctrl = (modifiers & SCI_CTRL) != 0; - const bool shift = (modifiers & SCI_SHIFT) != 0; + if ((vs.ms[marginClicked].mask & MaskFolders) && (FlagSet(foldAutomatic, AutomaticFold::Click))) { + const bool ctrl = FlagSet(modifiers, KeyMod::Ctrl); + const bool shift = FlagSet(modifiers, KeyMod::Shift); const Sci::Line lineClick = pdoc->SciLineFromPosition(position); if (shift && ctrl) { - FoldAll(SC_FOLDACTION_TOGGLE); + FoldAll(FoldAction::Toggle); } else { - const int levelClick = pdoc->GetLevel(lineClick); - if (levelClick & SC_FOLDLEVELHEADERFLAG) { + const FoldLevel levelClick = pdoc->GetFoldLevel(lineClick); + if (LevelIsHeader(levelClick)) { if (shift) { // Ensure all children visible - FoldExpand(lineClick, SC_FOLDACTION_EXPAND, levelClick); + FoldExpand(lineClick, FoldAction::Expand, levelClick); } else if (ctrl) { - FoldExpand(lineClick, SC_FOLDACTION_TOGGLE, levelClick); + FoldExpand(lineClick, FoldAction::Toggle, levelClick); } else { // Toggle this line - FoldLine(lineClick, SC_FOLDACTION_TOGGLE); + FoldLine(lineClick, FoldAction::Toggle); } } } return true; } - SCNotification scn = {}; - scn.nmhdr.code = SCN_MARGINCLICK; + NotificationData scn = {}; + scn.nmhdr.code = Notification::MarginClick; scn.modifiers = modifiers; scn.position = position; scn.margin = marginClicked; @@ -2472,12 +2476,12 @@ bool Editor::NotifyMarginClick(Point pt, int modifiers) { } } -bool Editor::NotifyMarginRightClick(Point pt, int modifiers) { +bool Editor::NotifyMarginRightClick(Point pt, KeyMod modifiers) { const int marginRightClicked = vs.MarginFromLocation(pt); if ((marginRightClicked >= 0) && vs.ms[marginRightClicked].sensitive) { const Sci::Position position = pdoc->LineStart(LineFromLocation(pt)); - SCNotification scn = {}; - scn.nmhdr.code = SCN_MARGINRIGHTCLICK; + NotificationData scn = {}; + scn.nmhdr.code = Notification::MarginRightClick; scn.modifiers = modifiers; scn.position = position; scn.margin = marginRightClicked; @@ -2489,16 +2493,16 @@ bool Editor::NotifyMarginRightClick(Point pt, int modifiers) { } void Editor::NotifyNeedShown(Sci::Position pos, Sci::Position len) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_NEEDSHOWN; + NotificationData scn = {}; + scn.nmhdr.code = Notification::NeedShown; scn.position = pos; scn.length = len; NotifyParent(scn); } void Editor::NotifyDwelling(Point pt, bool state) { - SCNotification scn = {}; - scn.nmhdr.code = state ? SCN_DWELLSTART : SCN_DWELLEND; + NotificationData scn = {}; + scn.nmhdr.code = state ? Notification::DwellStart : Notification::DwellEnd; scn.position = PositionFromLocation(pt, true); scn.x = static_cast(pt.x + vs.ExternalMarginWidth()); scn.y = static_cast(pt.y); @@ -2506,8 +2510,8 @@ void Editor::NotifyDwelling(Point pt, bool state) { } void Editor::NotifyZoom() { - SCNotification scn = {}; - scn.nmhdr.code = SCN_ZOOM; + NotificationData scn = {}; + scn.nmhdr.code = Notification::Zoom; NotifyParent(scn); } @@ -2523,7 +2527,7 @@ void Editor::NotifySavePoint(Document *, void *, bool atSavePoint) { } void Editor::CheckModificationForWrap(DocModification mh) { - if (mh.modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) { + if (FlagSet(mh.modificationType, ModificationFlags::InsertText | ModificationFlags::DeleteText)) { view.llc.Invalidate(LineLayout::ValidLevel::checkTextAndStyle); const Sci::Line lineDoc = pdoc->SciLineFromPosition(mh.position); const Sci::Line lines = std::max(static_cast(0), mh.linesAdded); @@ -2539,7 +2543,7 @@ void Editor::CheckModificationForWrap(DocModification mh) { namespace { // Move a position so it is still after the same character as before the insertion. -Sci::Position MovePositionForInsertion(Sci::Position position, Sci::Position startInsertion, Sci::Position length) noexcept { +constexpr Sci::Position MovePositionForInsertion(Sci::Position position, Sci::Position startInsertion, Sci::Position length) noexcept { if (position > startInsertion) { return position + length; } @@ -2548,7 +2552,7 @@ Sci::Position MovePositionForInsertion(Sci::Position position, Sci::Position sta // Move a position so it is still after the same character as before the deletion if that // character is still present else after the previous surviving character. -Sci::Position MovePositionForDeletion(Sci::Position position, Sci::Position startDeletion, Sci::Position length) noexcept { +constexpr Sci::Position MovePositionForDeletion(Sci::Position position, Sci::Position startDeletion, Sci::Position length) noexcept { if (position > startDeletion) { const Sci::Position endDeletion = startDeletion + length; if (position > endDeletion) { @@ -2564,12 +2568,12 @@ Sci::Position MovePositionForDeletion(Sci::Position position, Sci::Position star } void Editor::NotifyModified(Document *, DocModification mh, void *) { - ContainerNeedsUpdate(SC_UPDATE_CONTENT); - if (paintState == painting) { + ContainerNeedsUpdate(Update::Content); + if (paintState == PaintState::painting) { CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length)); } - if (mh.modificationType & SC_MOD_CHANGELINESTATE) { - if (paintState == painting) { + if (FlagSet(mh.modificationType, ModificationFlags::ChangeLineState)) { + if (paintState == PaintState::painting) { CheckForChangeOutsidePaint( Range(pdoc->LineStart(mh.line), pdoc->LineStart(mh.line + 1))); @@ -2578,22 +2582,22 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { Redraw(); } } - if (mh.modificationType & SC_MOD_CHANGETABSTOPS) { + if (FlagSet(mh.modificationType, ModificationFlags::ChangeTabStops)) { Redraw(); } - if (mh.modificationType & SC_MOD_LEXERSTATE) { - if (paintState == painting) { + if (FlagSet(mh.modificationType, ModificationFlags::LexerState)) { + if (paintState == PaintState::painting) { CheckForChangeOutsidePaint( Range(mh.position, mh.position + mh.length)); } else { Redraw(); } } - if (mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) { - if (mh.modificationType & SC_MOD_CHANGESTYLE) { + if (FlagSet(mh.modificationType, ModificationFlags::ChangeStyle | ModificationFlags::ChangeIndicator)) { + if (FlagSet(mh.modificationType, ModificationFlags::ChangeStyle)) { pdoc->IncrementStyleClock(); } - if (paintState == notPainting) { + if (paintState == PaintState::notPainting) { const Sci::Line lineDocTop = pcs->DocFromDisplay(topLine); if (mh.position < pdoc->LineStart(lineDocTop)) { // Styling performed before this view @@ -2602,33 +2606,33 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { InvalidateRange(mh.position, mh.position + mh.length); } } - if (mh.modificationType & SC_MOD_CHANGESTYLE) { + if (FlagSet(mh.modificationType, ModificationFlags::ChangeStyle)) { view.llc.Invalidate(LineLayout::ValidLevel::checkTextAndStyle); } } else { // Move selection and brace highlights - if (mh.modificationType & SC_MOD_INSERTTEXT) { + if (FlagSet(mh.modificationType, ModificationFlags::InsertText)) { sel.MovePositions(true, mh.position, mh.length); braces[0] = MovePositionForInsertion(braces[0], mh.position, mh.length); braces[1] = MovePositionForInsertion(braces[1], mh.position, mh.length); - } else if (mh.modificationType & SC_MOD_DELETETEXT) { + } else if (FlagSet(mh.modificationType, ModificationFlags::DeleteText)) { sel.MovePositions(false, mh.position, mh.length); braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length); braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length); } - if ((mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) && pcs->HiddenLines()) { + if (FlagSet(mh.modificationType, ModificationFlags::BeforeInsert | ModificationFlags::BeforeDelete) && pcs->HiddenLines()) { // Some lines are hidden so may need shown. const Sci::Line lineOfPos = pdoc->SciLineFromPosition(mh.position); Sci::Position endNeedShown = mh.position; - if (mh.modificationType & SC_MOD_BEFOREINSERT) { + if (FlagSet(mh.modificationType, ModificationFlags::BeforeInsert)) { if (pdoc->ContainsLineEnd(mh.text, mh.length) && (mh.position != pdoc->LineStart(lineOfPos))) endNeedShown = pdoc->LineStart(lineOfPos+1); - } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { + } else if (FlagSet(mh.modificationType, ModificationFlags::BeforeDelete)) { // If the deletion includes any EOL then we extend the need shown area. endNeedShown = mh.position + mh.length; Sci::Line lineLast = pdoc->SciLineFromPosition(mh.position+mh.length); for (Sci::Line line = lineOfPos + 1; line <= lineLast; line++) { - const Sci::Line lineMaxSubord = pdoc->GetLastChild(line, -1, -1); + const Sci::Line lineMaxSubord = pdoc->GetLastChild(line, {}, -1); if (lineLast < lineMaxSubord) { lineLast = lineMaxSubord; endNeedShown = pdoc->LineEnd(lineLast); @@ -2650,17 +2654,17 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { } view.LinesAddedOrRemoved(lineOfPos, mh.linesAdded); } - if (mh.modificationType & SC_MOD_CHANGEANNOTATION) { + if (FlagSet(mh.modificationType, ModificationFlags::ChangeAnnotation)) { const Sci::Line lineDoc = pdoc->SciLineFromPosition(mh.position); - if (vs.annotationVisible) { + if (vs.annotationVisible != AnnotationVisible::Hidden) { if (pcs->SetHeight(lineDoc, pcs->GetHeight(lineDoc) + static_cast(mh.annotationLinesAdded))) { SetScrollBars(); } Redraw(); } } - if (mh.modificationType & SC_MOD_CHANGEEOLANNOTATION) { - if (vs.eolAnnotationVisible) { + if (FlagSet(mh.modificationType, ModificationFlags::ChangeEOLAnnotation)) { + if (vs.eolAnnotationVisible != EOLAnnotationVisible::Hidden) { Redraw(); } } @@ -2668,23 +2672,23 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { if (mh.linesAdded != 0) { // Avoid scrolling of display if change before current display if (mh.position < posTopLine && !CanDeferToLastStep(mh)) { - const Sci::Line newTop = Sci::clamp(topLine + mh.linesAdded, static_cast(0), MaxScrollPos()); + const Sci::Line newTop = std::clamp(topLine + mh.linesAdded, 0, MaxScrollPos()); if (newTop != topLine) { SetTopLine(newTop); SetVerticalScrollPos(); } } - if (paintState == notPainting && !CanDeferToLastStep(mh)) { + if (paintState == PaintState::notPainting && !CanDeferToLastStep(mh)) { if (SynchronousStylingToVisible()) { - QueueIdleWork(WorkNeeded::workStyle, pdoc->Length()); + QueueIdleWork(WorkItems::style, pdoc->Length()); } Redraw(); } } else { - if (paintState == notPainting && mh.length && !CanEliminate(mh)) { + if (paintState == PaintState::notPainting && mh.length && !CanEliminate(mh)) { if (SynchronousStylingToVisible()) { - QueueIdleWork(WorkNeeded::workStyle, mh.position + mh.length); + QueueIdleWork(WorkItems::style, mh.position + mh.length); } InvalidateRange(mh.position, mh.position + mh.length); } @@ -2695,9 +2699,9 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { SetScrollBars(); } - if ((mh.modificationType & SC_MOD_CHANGEMARKER) || (mh.modificationType & SC_MOD_CHANGEMARGIN)) { - if ((!willRedrawAll) && ((paintState == notPainting) || !PaintContainsMargin())) { - if (mh.modificationType & SC_MOD_CHANGEFOLD) { + if ((FlagSet(mh.modificationType, ModificationFlags::ChangeMarker)) || (FlagSet(mh.modificationType, ModificationFlags::ChangeMargin))) { + if ((!willRedrawAll) && ((paintState == PaintState::notPainting) || !PaintContainsMargin())) { + if (FlagSet(mh.modificationType, ModificationFlags::ChangeFold)) { // Fold changes can affect the drawing of following lines so redraw whole margin RedrawSelMargin(marginView.highlightDelimiter.isEnabled ? -1 : mh.line - 1, true); } else { @@ -2705,7 +2709,7 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { } } } - if ((mh.modificationType & SC_MOD_CHANGEFOLD) && (foldAutomatic & SC_AUTOMATICFOLD_CHANGE)) { + if ((FlagSet(mh.modificationType, ModificationFlags::ChangeFold)) && (FlagSet(foldAutomatic, AutomaticFold::Change))) { FoldChanged(mh.line, mh.foldLevelNow, mh.foldLevelPrev); } @@ -2716,16 +2720,16 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { } // If client wants to see this modification - if (mh.modificationType & modEventMask) { + if (FlagSet(mh.modificationType, modEventMask)) { if (commandEvents) { - if ((mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) == 0) { + if ((mh.modificationType & (ModificationFlags::ChangeStyle | ModificationFlags::ChangeIndicator)) == ModificationFlags::None) { // Real modification made to text of document. NotifyChange(); // Send EN_CHANGE } } - SCNotification scn = {}; - scn.nmhdr.code = SCN_MODIFIED; + NotificationData scn = {}; + scn.nmhdr.code = Notification::Modified; scn.position = mh.position; scn.modificationType = mh.modificationType; scn.text = mh.text; @@ -2744,131 +2748,131 @@ void Editor::NotifyDeleted(Document *, void *) noexcept { /* Do nothing */ } -void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { +void Editor::NotifyMacroRecord(Message iMessage, uptr_t wParam, sptr_t lParam) { // Enumerates all macroable messages switch (iMessage) { - case SCI_CUT: - case SCI_COPY: - case SCI_PASTE: - case SCI_CLEAR: - case SCI_REPLACESEL: - case SCI_ADDTEXT: - case SCI_INSERTTEXT: - case SCI_APPENDTEXT: - case SCI_CLEARALL: - case SCI_SELECTALL: - case SCI_GOTOLINE: - case SCI_GOTOPOS: - case SCI_SEARCHANCHOR: - case SCI_SEARCHNEXT: - case SCI_SEARCHPREV: - case SCI_LINEDOWN: - case SCI_LINEDOWNEXTEND: - case SCI_PARADOWN: - case SCI_PARADOWNEXTEND: - case SCI_LINEUP: - case SCI_LINEUPEXTEND: - case SCI_PARAUP: - case SCI_PARAUPEXTEND: - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: - case SCI_CHARRIGHT: - case SCI_CHARRIGHTEXTEND: - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: - case SCI_WORDRIGHT: - case SCI_WORDRIGHTEXTEND: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: - case SCI_WORDPARTRIGHT: - case SCI_WORDPARTRIGHTEXTEND: - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDRIGHTEND: - case SCI_WORDRIGHTENDEXTEND: - case SCI_HOME: - case SCI_HOMEEXTEND: - case SCI_LINEEND: - case SCI_LINEENDEXTEND: - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: - case SCI_LINEENDWRAP: - case SCI_LINEENDWRAPEXTEND: - case SCI_DOCUMENTSTART: - case SCI_DOCUMENTSTARTEXTEND: - case SCI_DOCUMENTEND: - case SCI_DOCUMENTENDEXTEND: - case SCI_STUTTEREDPAGEUP: - case SCI_STUTTEREDPAGEUPEXTEND: - case SCI_STUTTEREDPAGEDOWN: - case SCI_STUTTEREDPAGEDOWNEXTEND: - case SCI_PAGEUP: - case SCI_PAGEUPEXTEND: - case SCI_PAGEDOWN: - case SCI_PAGEDOWNEXTEND: - case SCI_EDITTOGGLEOVERTYPE: - case SCI_CANCEL: - case SCI_DELETEBACK: - case SCI_TAB: - case SCI_BACKTAB: - case SCI_FORMFEED: - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_DELWORDLEFT: - case SCI_DELWORDRIGHT: - case SCI_DELWORDRIGHTEND: - case SCI_DELLINELEFT: - case SCI_DELLINERIGHT: - case SCI_LINECOPY: - case SCI_LINECUT: - case SCI_LINEDELETE: - case SCI_LINETRANSPOSE: - case SCI_LINEREVERSE: - case SCI_LINEDUPLICATE: - case SCI_LOWERCASE: - case SCI_UPPERCASE: - case SCI_LINESCROLLDOWN: - case SCI_LINESCROLLUP: - case SCI_DELETEBACKNOTLINE: - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: - case SCI_LINEENDDISPLAY: - case SCI_LINEENDDISPLAYEXTEND: - case SCI_SETSELECTIONMODE: - case SCI_LINEDOWNRECTEXTEND: - case SCI_LINEUPRECTEXTEND: - case SCI_CHARLEFTRECTEXTEND: - case SCI_CHARRIGHTRECTEXTEND: - case SCI_HOMERECTEXTEND: - case SCI_VCHOMERECTEXTEND: - case SCI_LINEENDRECTEXTEND: - case SCI_PAGEUPRECTEXTEND: - case SCI_PAGEDOWNRECTEXTEND: - case SCI_SELECTIONDUPLICATE: - case SCI_COPYALLOWLINE: - case SCI_VERTICALCENTRECARET: - case SCI_MOVESELECTEDLINESUP: - case SCI_MOVESELECTEDLINESDOWN: - case SCI_SCROLLTOSTART: - case SCI_SCROLLTOEND: + case Message::Cut: + case Message::Copy: + case Message::Paste: + case Message::Clear: + case Message::ReplaceSel: + case Message::AddText: + case Message::InsertText: + case Message::AppendText: + case Message::ClearAll: + case Message::SelectAll: + case Message::GotoLine: + case Message::GotoPos: + case Message::SearchAnchor: + case Message::SearchNext: + case Message::SearchPrev: + case Message::LineDown: + case Message::LineDownExtend: + case Message::ParaDown: + case Message::ParaDownExtend: + case Message::LineUp: + case Message::LineUpExtend: + case Message::ParaUp: + case Message::ParaUpExtend: + case Message::CharLeft: + case Message::CharLeftExtend: + case Message::CharRight: + case Message::CharRightExtend: + case Message::WordLeft: + case Message::WordLeftExtend: + case Message::WordRight: + case Message::WordRightExtend: + case Message::WordPartLeft: + case Message::WordPartLeftExtend: + case Message::WordPartRight: + case Message::WordPartRightExtend: + case Message::WordLeftEnd: + case Message::WordLeftEndExtend: + case Message::WordRightEnd: + case Message::WordRightEndExtend: + case Message::Home: + case Message::HomeExtend: + case Message::LineEnd: + case Message::LineEndExtend: + case Message::HomeWrap: + case Message::HomeWrapExtend: + case Message::LineEndWrap: + case Message::LineEndWrapExtend: + case Message::DocumentStart: + case Message::DocumentStartExtend: + case Message::DocumentEnd: + case Message::DocumentEndExtend: + case Message::StutteredPageUp: + case Message::StutteredPageUpExtend: + case Message::StutteredPageDown: + case Message::StutteredPageDownExtend: + case Message::PageUp: + case Message::PageUpExtend: + case Message::PageDown: + case Message::PageDownExtend: + case Message::EditToggleOvertype: + case Message::Cancel: + case Message::DeleteBack: + case Message::Tab: + case Message::BackTab: + case Message::FormFeed: + case Message::VCHome: + case Message::VCHomeExtend: + case Message::VCHomeWrap: + case Message::VCHomeWrapExtend: + case Message::VCHomeDisplay: + case Message::VCHomeDisplayExtend: + case Message::DelWordLeft: + case Message::DelWordRight: + case Message::DelWordRightEnd: + case Message::DelLineLeft: + case Message::DelLineRight: + case Message::LineCopy: + case Message::LineCut: + case Message::LineDelete: + case Message::LineTranspose: + case Message::LineReverse: + case Message::LineDuplicate: + case Message::LowerCase: + case Message::UpperCase: + case Message::LineScrollDown: + case Message::LineScrollUp: + case Message::DeleteBackNotLine: + case Message::HomeDisplay: + case Message::HomeDisplayExtend: + case Message::LineEndDisplay: + case Message::LineEndDisplayExtend: + case Message::SetSelectionMode: + case Message::LineDownRectExtend: + case Message::LineUpRectExtend: + case Message::CharLeftRectExtend: + case Message::CharRightRectExtend: + case Message::HomeRectExtend: + case Message::VCHomeRectExtend: + case Message::LineEndRectExtend: + case Message::PageUpRectExtend: + case Message::PageDownRectExtend: + case Message::SelectionDuplicate: + case Message::CopyAllowLine: + case Message::VerticalCentreCaret: + case Message::MoveSelectedLinesUp: + case Message::MoveSelectedLinesDown: + case Message::ScrollToStart: + case Message::ScrollToEnd: break; // Filter out all others like display changes. Also, newlines are redundant // with char insert messages. - case SCI_NEWLINE: + case Message::NewLine: default: // printf("Filtered out %ld of macro recording\n", iMessage); return; } // Send notification - SCNotification scn = {}; - scn.nmhdr.code = SCN_MACRORECORD; + NotificationData scn = {}; + scn.nmhdr.code = Notification::MacroRecord; scn.message = iMessage; scn.wParam = wParam; scn.lParam = lParam; @@ -2876,8 +2880,8 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar } // Something has changed that the container should know about -void Editor::ContainerNeedsUpdate(int flags) noexcept { - needUpdateUI |= flags; +void Editor::ContainerNeedsUpdate(Update flags) noexcept { + needUpdateUI = needUpdateUI | flags; } /** @@ -2886,7 +2890,7 @@ void Editor::ContainerNeedsUpdate(int flags) noexcept { * If stuttered = true and not already at first/last row, move to first/last row of window. * If stuttered = true and already at first/last row, scroll as normal. */ -void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) { +void Editor::PageMove(int direction, Selection::SelTypes selt, bool stuttered) { Sci::Line topLineNew; SelectionPosition newPos; @@ -2910,8 +2914,8 @@ void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) { } else { const Point pt = LocationFromPosition(sel.MainCaret()); - topLineNew = Sci::clamp( - topLine + direction * LinesToScroll(), static_cast(0), MaxScrollPos()); + topLineNew = std::clamp( + topLine + direction * LinesToScroll(), 0, MaxScrollPos()); newPos = SPositionFromLocation( Point::FromInts(lastXChosen - xOffset, static_cast(pt.y) + direction * (vs.lineHeight * static_cast(LinesToScroll()))), @@ -2928,7 +2932,7 @@ void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) { } } -void Editor::ChangeCaseOfSelection(int caseMapping) { +void Editor::ChangeCaseOfSelection(CaseMapping caseMapping) { UndoGroup ug(pdoc); for (size_t r=0; reolMode); while (*eol) { - NotifyChar(*eol, CharacterSource::directInput); + NotifyChar(*eol, CharacterSource::DirectInput); if (recordingMacro) { char txt[2]; txt[0] = *eol; txt[1] = '\0'; - NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast(txt)); + NotifyMacroRecord(Message::ReplaceSel, 0, reinterpret_cast(txt)); } eol++; } @@ -3124,7 +3128,7 @@ SelectionPosition Editor::PositionUpOrDown(SelectionPosition spStart, int direct const Point pt = LocationFromPosition(spStart); int skipLines = 0; - if (vs.annotationVisible) { + if (vs.annotationVisible != AnnotationVisible::Hidden) { const Sci::Line lineDoc = pdoc->SciLineFromPosition(spStart.Position()); const Point ptStartLine = LocationFromPosition(pdoc->LineStart(lineDoc)); const int subLine = static_cast(pt.y - ptStartLine.y) / vs.lineHeight; @@ -3168,19 +3172,19 @@ SelectionPosition Editor::PositionUpOrDown(SelectionPosition spStart, int direct return posNew; } -void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { - if ((selt == Selection::noSel) && sel.MoveExtends()) { - selt = !sel.IsRectangular() ? Selection::selStream : Selection::selRectangle; +void Editor::CursorUpOrDown(int direction, Selection::SelTypes selt) { + if ((selt == Selection::SelTypes::none) && sel.MoveExtends()) { + selt = !sel.IsRectangular() ? Selection::SelTypes::stream : Selection::SelTypes::rectangle; } SelectionPosition caretToUse = sel.Range(sel.Main()).caret; if (sel.IsRectangular()) { - if (selt == Selection::noSel) { + if (selt == Selection::SelTypes::none) { caretToUse = (direction > 0) ? sel.Limits().end : sel.Limits().start; } else { caretToUse = sel.Rectangular().caret; } } - if (selt == Selection::selRectangle) { + if (selt == Selection::SelTypes::rectangle) { const SelectionRange rangeBase = sel.IsRectangular() ? sel.Rectangular() : sel.RangeMain(); if (!sel.IsRectangular()) { InvalidateWholeSelection(); @@ -3188,11 +3192,11 @@ void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { } const SelectionPosition posNew = MovePositionSoVisible( PositionUpOrDown(caretToUse, direction, lastXChosen), direction); - sel.selType = Selection::selRectangle; + sel.selType = Selection::SelTypes::rectangle; sel.Rectangular() = SelectionRange(posNew, rangeBase.anchor); SetRectangularRange(); MovedCaret(posNew, caretToUse, true, caretPolicies); - } else if (sel.selType == Selection::selLines && sel.MoveExtends()) { + } else if (sel.selType == Selection::SelTypes::lines && sel.MoveExtends()) { // Calculate new caret position and call SetSelection(), which will ensure whole lines are selected. const SelectionPosition posNew = MovePositionSoVisible( PositionUpOrDown(caretToUse, direction, -1), direction); @@ -3202,13 +3206,13 @@ void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { if (!additionalSelectionTyping || (sel.IsRectangular())) { sel.DropAdditionalRanges(); } - sel.selType = Selection::selStream; + sel.selType = Selection::SelTypes::stream; for (size_t r = 0; r < sel.Count(); r++) { const int lastX = (r == sel.Main()) ? lastXChosen : -1; const SelectionPosition spCaretNow = sel.Range(r).caret; const SelectionPosition posNew = MovePositionSoVisible( PositionUpOrDown(spCaretNow, direction, lastX), direction); - sel.Range(r) = selt == Selection::selStream ? + sel.Range(r) = selt == Selection::SelTypes::stream ? SelectionRange(posNew, sel.Range(r).anchor) : SelectionRange(posNew); } sel.RemoveDuplicates(); @@ -3216,7 +3220,7 @@ void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { } } -void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) { +void Editor::ParaUpOrDown(int direction, Selection::SelTypes selt) { Sci::Line lineDoc; const Sci::Position savedPos = sel.MainCaret(); do { @@ -3224,7 +3228,7 @@ void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) { lineDoc = pdoc->SciLineFromPosition(sel.MainCaret()); if (direction > 0) { if (sel.MainCaret() >= pdoc->Length() && !pcs->GetVisible(lineDoc)) { - if (selt == Selection::noSel) { + if (selt == Selection::SelTypes::none) { MovePositionTo(SelectionPosition(pdoc->LineEndPosition(savedPos))); } break; @@ -3243,7 +3247,7 @@ Sci::Position Editor::StartEndDisplayLine(Sci::Position pos, bool start) { RefreshStyleData(); AutoSurface surface(this); const Sci::Position posRet = view.StartEndDisplayLine(surface, *this, pos, start, vs); - if (posRet == INVALID_POSITION) { + if (posRet == Sci::invalidPosition) { return pos; } else { return posRet; @@ -3260,57 +3264,57 @@ constexpr short LowShortFromWParam(uptr_t x) { return static_cast(x & 0xffff); } -unsigned int WithExtends(unsigned int iMessage) noexcept { +constexpr Message WithExtends(Message iMessage) noexcept { switch (iMessage) { - case SCI_CHARLEFT: return SCI_CHARLEFTEXTEND; - case SCI_CHARRIGHT: return SCI_CHARRIGHTEXTEND; - - case SCI_WORDLEFT: return SCI_WORDLEFTEXTEND; - case SCI_WORDRIGHT: return SCI_WORDRIGHTEXTEND; - case SCI_WORDLEFTEND: return SCI_WORDLEFTENDEXTEND; - case SCI_WORDRIGHTEND: return SCI_WORDRIGHTENDEXTEND; - case SCI_WORDPARTLEFT: return SCI_WORDPARTLEFTEXTEND; - case SCI_WORDPARTRIGHT: return SCI_WORDPARTRIGHTEXTEND; - - case SCI_HOME: return SCI_HOMEEXTEND; - case SCI_HOMEDISPLAY: return SCI_HOMEDISPLAYEXTEND; - case SCI_HOMEWRAP: return SCI_HOMEWRAPEXTEND; - case SCI_VCHOME: return SCI_VCHOMEEXTEND; - case SCI_VCHOMEDISPLAY: return SCI_VCHOMEDISPLAYEXTEND; - case SCI_VCHOMEWRAP: return SCI_VCHOMEWRAPEXTEND; - - case SCI_LINEEND: return SCI_LINEENDEXTEND; - case SCI_LINEENDDISPLAY: return SCI_LINEENDDISPLAYEXTEND; - case SCI_LINEENDWRAP: return SCI_LINEENDWRAPEXTEND; + case Message::CharLeft: return Message::CharLeftExtend; + case Message::CharRight: return Message::CharRightExtend; + + case Message::WordLeft: return Message::WordLeftExtend; + case Message::WordRight: return Message::WordRightExtend; + case Message::WordLeftEnd: return Message::WordLeftEndExtend; + case Message::WordRightEnd: return Message::WordRightEndExtend; + case Message::WordPartLeft: return Message::WordPartLeftExtend; + case Message::WordPartRight: return Message::WordPartRightExtend; + + case Message::Home: return Message::HomeExtend; + case Message::HomeDisplay: return Message::HomeDisplayExtend; + case Message::HomeWrap: return Message::HomeWrapExtend; + case Message::VCHome: return Message::VCHomeExtend; + case Message::VCHomeDisplay: return Message::VCHomeDisplayExtend; + case Message::VCHomeWrap: return Message::VCHomeWrapExtend; + + case Message::LineEnd: return Message::LineEndExtend; + case Message::LineEndDisplay: return Message::LineEndDisplayExtend; + case Message::LineEndWrap: return Message::LineEndWrapExtend; default: return iMessage; } } -int NaturalDirection(unsigned int iMessage) noexcept { +constexpr int NaturalDirection(Message iMessage) noexcept { switch (iMessage) { - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: - case SCI_CHARLEFTRECTEXTEND: - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: - case SCI_HOME: - case SCI_HOMEEXTEND: - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: + case Message::CharLeft: + case Message::CharLeftExtend: + case Message::CharLeftRectExtend: + case Message::WordLeft: + case Message::WordLeftExtend: + case Message::WordLeftEnd: + case Message::WordLeftEndExtend: + case Message::WordPartLeft: + case Message::WordPartLeftExtend: + case Message::Home: + case Message::HomeExtend: + case Message::HomeDisplay: + case Message::HomeDisplayExtend: + case Message::HomeWrap: + case Message::HomeWrapExtend: // VC_HOME* mostly goes back - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: + case Message::VCHome: + case Message::VCHomeExtend: + case Message::VCHomeDisplay: + case Message::VCHomeDisplayExtend: + case Message::VCHomeWrap: + case Message::VCHomeWrapExtend: return -1; default: @@ -3318,23 +3322,23 @@ int NaturalDirection(unsigned int iMessage) noexcept { } } -bool IsRectExtend(unsigned int iMessage, bool isRectMoveExtends) noexcept { +constexpr bool IsRectExtend(Message iMessage, bool isRectMoveExtends) noexcept { switch (iMessage) { - case SCI_CHARLEFTRECTEXTEND: - case SCI_CHARRIGHTRECTEXTEND: - case SCI_HOMERECTEXTEND: - case SCI_VCHOMERECTEXTEND: - case SCI_LINEENDRECTEXTEND: + case Message::CharLeftRectExtend: + case Message::CharRightRectExtend: + case Message::HomeRectExtend: + case Message::VCHomeRectExtend: + case Message::LineEndRectExtend: return true; default: if (isRectMoveExtends) { - // Handle SCI_SETSELECTIONMODE(SC_SEL_RECTANGLE) and subsequent movements. + // Handle Message::SetSelectionMode(SelectionMode::Rectangle) and subsequent movements. switch (iMessage) { - case SCI_CHARLEFTEXTEND: - case SCI_CHARRIGHTEXTEND: - case SCI_HOMEEXTEND: - case SCI_VCHOMEEXTEND: - case SCI_LINEENDEXTEND: + case Message::CharLeftExtend: + case Message::CharRightExtend: + case Message::HomeExtend: + case Message::VCHomeExtend: + case Message::LineEndExtend: return true; default: return false; @@ -3374,8 +3378,8 @@ Sci::Position Editor::LineEndWrapPosition(Sci::Position position) { return endPos; } -int Editor::HorizontalMove(unsigned int iMessage) { - if (sel.selType == Selection::selLines) { +int Editor::HorizontalMove(Message iMessage) { + if (sel.selType == Selection::SelTypes::lines) { return 0; // horizontal moves with line selection have no effect } if (sel.MoveExtends()) { @@ -3398,57 +3402,61 @@ int Editor::HorizontalMove(unsigned int iMessage) { // Will change to rectangular if not currently rectangular SelectionPosition spCaret = rangeBase.caret; switch (iMessage) { - case SCI_CHARLEFTRECTEXTEND: - case SCI_CHARLEFTEXTEND: // only when sel.IsRectangular() && sel.MoveExtends() + case Message::CharLeftRectExtend: + case Message::CharLeftExtend: // only when sel.IsRectangular() && sel.MoveExtends() if (pdoc->IsLineEndPosition(spCaret.Position()) && spCaret.VirtualSpace()) { spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1); - } else if ((virtualSpaceOptions & SCVS_NOWRAPLINESTART) == 0 || pdoc->GetColumn(spCaret.Position()) > 0) { + } else if (!FlagSet(virtualSpaceOptions, VirtualSpace::NoWrapLineStart) || pdoc->GetColumn(spCaret.Position()) > 0) { spCaret = SelectionPosition(spCaret.Position() - 1); } break; - case SCI_CHARRIGHTRECTEXTEND: - case SCI_CHARRIGHTEXTEND: // only when sel.IsRectangular() && sel.MoveExtends() - if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) && pdoc->IsLineEndPosition(sel.MainCaret())) { + case Message::CharRightRectExtend: + case Message::CharRightExtend: // only when sel.IsRectangular() && sel.MoveExtends() + if (FlagSet(virtualSpaceOptions, VirtualSpace::RectangularSelection) && pdoc->IsLineEndPosition(sel.MainCaret())) { spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1); } else { spCaret = SelectionPosition(spCaret.Position() + 1); } break; - case SCI_HOMERECTEXTEND: - case SCI_HOMEEXTEND: // only when sel.IsRectangular() && sel.MoveExtends() + case Message::HomeRectExtend: + case Message::HomeExtend: // only when sel.IsRectangular() && sel.MoveExtends() spCaret = SelectionPosition( pdoc->LineStart(pdoc->LineFromPosition(spCaret.Position()))); break; - case SCI_VCHOMERECTEXTEND: - case SCI_VCHOMEEXTEND: // only when sel.IsRectangular() && sel.MoveExtends() + case Message::VCHomeRectExtend: + case Message::VCHomeExtend: // only when sel.IsRectangular() && sel.MoveExtends() spCaret = SelectionPosition(pdoc->VCHomePosition(spCaret.Position())); break; - case SCI_LINEENDRECTEXTEND: - case SCI_LINEENDEXTEND: // only when sel.IsRectangular() && sel.MoveExtends() + case Message::LineEndRectExtend: + case Message::LineEndExtend: // only when sel.IsRectangular() && sel.MoveExtends() spCaret = SelectionPosition(pdoc->LineEndPosition(spCaret.Position())); break; + default: + break; } const int directionMove = (spCaret < rangeBase.caret) ? -1 : 1; spCaret = MovePositionSoVisible(spCaret, directionMove); - sel.selType = Selection::selRectangle; + sel.selType = Selection::SelTypes::rectangle; sel.Rectangular() = SelectionRange(spCaret, rangeBase.anchor); SetRectangularRange(); } else if (sel.IsRectangular()) { // Not a rectangular extension so switch to stream. SelectionPosition selAtLimit = (NaturalDirection(iMessage) > 0) ? sel.Limits().end : sel.Limits().start; switch (iMessage) { - case SCI_HOME: + case Message::Home: selAtLimit = SelectionPosition( pdoc->LineStart(pdoc->LineFromPosition(selAtLimit.Position()))); break; - case SCI_VCHOME: + case Message::VCHome: selAtLimit = SelectionPosition(pdoc->VCHomePosition(selAtLimit.Position())); break; - case SCI_LINEEND: + case Message::LineEnd: selAtLimit = SelectionPosition(pdoc->LineEndPosition(selAtLimit.Position())); break; + default: + break; } - sel.selType = Selection::selStream; + sel.selType = Selection::SelTypes::stream; sel.SetSelection(SelectionRange(selAtLimit)); } else { if (!additionalSelectionTyping) { @@ -3459,85 +3467,85 @@ int Editor::HorizontalMove(unsigned int iMessage) { const SelectionPosition spCaretNow = sel.Range(r).caret; SelectionPosition spCaret = spCaretNow; switch (iMessage) { - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: + case Message::CharLeft: + case Message::CharLeftExtend: if (spCaret.VirtualSpace()) { spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1); - } else if ((virtualSpaceOptions & SCVS_NOWRAPLINESTART) == 0 || pdoc->GetColumn(spCaret.Position()) > 0) { + } else if (!FlagSet(virtualSpaceOptions, VirtualSpace::NoWrapLineStart) || pdoc->GetColumn(spCaret.Position()) > 0) { spCaret = SelectionPosition(spCaret.Position() - 1); } break; - case SCI_CHARRIGHT: - case SCI_CHARRIGHTEXTEND: - if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(spCaret.Position())) { + case Message::CharRight: + case Message::CharRightExtend: + if (FlagSet(virtualSpaceOptions, VirtualSpace::UserAccessible) && pdoc->IsLineEndPosition(spCaret.Position())) { spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1); } else { spCaret = SelectionPosition(spCaret.Position() + 1); } break; - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: + case Message::WordLeft: + case Message::WordLeftExtend: spCaret = SelectionPosition(pdoc->NextWordStart(spCaret.Position(), -1)); break; - case SCI_WORDRIGHT: - case SCI_WORDRIGHTEXTEND: + case Message::WordRight: + case Message::WordRightExtend: spCaret = SelectionPosition(pdoc->NextWordStart(spCaret.Position(), 1)); break; - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: + case Message::WordLeftEnd: + case Message::WordLeftEndExtend: spCaret = SelectionPosition(pdoc->NextWordEnd(spCaret.Position(), -1)); break; - case SCI_WORDRIGHTEND: - case SCI_WORDRIGHTENDEXTEND: + case Message::WordRightEnd: + case Message::WordRightEndExtend: spCaret = SelectionPosition(pdoc->NextWordEnd(spCaret.Position(), 1)); break; - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: + case Message::WordPartLeft: + case Message::WordPartLeftExtend: spCaret = SelectionPosition(pdoc->WordPartLeft(spCaret.Position())); break; - case SCI_WORDPARTRIGHT: - case SCI_WORDPARTRIGHTEXTEND: + case Message::WordPartRight: + case Message::WordPartRightExtend: spCaret = SelectionPosition(pdoc->WordPartRight(spCaret.Position())); break; - case SCI_HOME: - case SCI_HOMEEXTEND: + case Message::Home: + case Message::HomeExtend: spCaret = SelectionPosition( pdoc->LineStart(pdoc->LineFromPosition(spCaret.Position()))); break; - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: + case Message::HomeDisplay: + case Message::HomeDisplayExtend: spCaret = SelectionPosition(StartEndDisplayLine(spCaret.Position(), true)); break; - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: + case Message::HomeWrap: + case Message::HomeWrapExtend: spCaret = MovePositionSoVisible(StartEndDisplayLine(spCaret.Position(), true), -1); if (spCaretNow <= spCaret) spCaret = SelectionPosition( pdoc->LineStart(pdoc->LineFromPosition(spCaret.Position()))); break; - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: + case Message::VCHome: + case Message::VCHomeExtend: // VCHome alternates between beginning of line and beginning of text so may move back or forwards spCaret = SelectionPosition(pdoc->VCHomePosition(spCaret.Position())); break; - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: + case Message::VCHomeDisplay: + case Message::VCHomeDisplayExtend: spCaret = SelectionPosition(VCHomeDisplayPosition(spCaret.Position())); break; - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: + case Message::VCHomeWrap: + case Message::VCHomeWrapExtend: spCaret = SelectionPosition(VCHomeWrapPosition(spCaret.Position())); break; - case SCI_LINEEND: - case SCI_LINEENDEXTEND: + case Message::LineEnd: + case Message::LineEndExtend: spCaret = SelectionPosition(pdoc->LineEndPosition(spCaret.Position())); break; - case SCI_LINEENDDISPLAY: - case SCI_LINEENDDISPLAYEXTEND: + case Message::LineEndDisplay: + case Message::LineEndDisplayExtend: spCaret = SelectionPosition(StartEndDisplayLine(spCaret.Position(), false)); break; - case SCI_LINEENDWRAP: - case SCI_LINEENDWRAPEXTEND: + case Message::LineEndWrap: + case Message::LineEndWrapExtend: spCaret = SelectionPosition(LineEndWrapPosition(spCaret.Position())); break; @@ -3550,51 +3558,51 @@ int Editor::HorizontalMove(unsigned int iMessage) { // Handle move versus extend, and special behaviour for non-empty left/right switch (iMessage) { - case SCI_CHARLEFT: - case SCI_CHARRIGHT: + case Message::CharLeft: + case Message::CharRight: if (sel.Range(r).Empty()) { sel.Range(r) = SelectionRange(spCaret); } else { sel.Range(r) = SelectionRange( - (iMessage == SCI_CHARLEFT) ? sel.Range(r).Start() : sel.Range(r).End()); + (iMessage == Message::CharLeft) ? sel.Range(r).Start() : sel.Range(r).End()); } break; - case SCI_WORDLEFT: - case SCI_WORDRIGHT: - case SCI_WORDLEFTEND: - case SCI_WORDRIGHTEND: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTRIGHT: - case SCI_HOME: - case SCI_HOMEDISPLAY: - case SCI_HOMEWRAP: - case SCI_VCHOME: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEWRAP: - case SCI_LINEEND: - case SCI_LINEENDDISPLAY: - case SCI_LINEENDWRAP: + case Message::WordLeft: + case Message::WordRight: + case Message::WordLeftEnd: + case Message::WordRightEnd: + case Message::WordPartLeft: + case Message::WordPartRight: + case Message::Home: + case Message::HomeDisplay: + case Message::HomeWrap: + case Message::VCHome: + case Message::VCHomeDisplay: + case Message::VCHomeWrap: + case Message::LineEnd: + case Message::LineEndDisplay: + case Message::LineEndWrap: sel.Range(r) = SelectionRange(spCaret); break; - case SCI_CHARLEFTEXTEND: - case SCI_CHARRIGHTEXTEND: - case SCI_WORDLEFTEXTEND: - case SCI_WORDRIGHTEXTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDRIGHTENDEXTEND: - case SCI_WORDPARTLEFTEXTEND: - case SCI_WORDPARTRIGHTEXTEND: - case SCI_HOMEEXTEND: - case SCI_HOMEDISPLAYEXTEND: - case SCI_HOMEWRAPEXTEND: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_VCHOMEWRAPEXTEND: - case SCI_LINEENDEXTEND: - case SCI_LINEENDDISPLAYEXTEND: - case SCI_LINEENDWRAPEXTEND: { + case Message::CharLeftExtend: + case Message::CharRightExtend: + case Message::WordLeftExtend: + case Message::WordRightExtend: + case Message::WordLeftEndExtend: + case Message::WordRightEndExtend: + case Message::WordPartLeftExtend: + case Message::WordPartRightExtend: + case Message::HomeExtend: + case Message::HomeDisplayExtend: + case Message::HomeWrapExtend: + case Message::VCHomeExtend: + case Message::VCHomeDisplayExtend: + case Message::VCHomeWrapExtend: + case Message::LineEndExtend: + case Message::LineEndDisplayExtend: + case Message::LineEndWrapExtend: { SelectionRange rangeNew = SelectionRange(spCaret, sel.Range(r).anchor); sel.TrimOtherSelections(r, SelectionRange(rangeNew)); sel.Range(r) = rangeNew; @@ -3609,7 +3617,7 @@ int Editor::HorizontalMove(unsigned int iMessage) { sel.RemoveDuplicates(); - MovedCaret(sel.RangeMain().caret, SelectionPosition(INVALID_POSITION), true, caretPolicies); + MovedCaret(sel.RangeMain().caret, SelectionPosition(Sci::invalidPosition), true, caretPolicies); // Invalidate the new state of the selection InvalidateWholeSelection(); @@ -3619,13 +3627,13 @@ int Editor::HorizontalMove(unsigned int iMessage) { return 0; } -int Editor::DelWordOrLine(unsigned int iMessage) { - // Virtual space may be realised for SCI_DELWORDRIGHT or SCI_DELWORDRIGHTEND +int Editor::DelWordOrLine(Message iMessage) { + // Virtual space may be realised for Message::DelWordRight or Message::DelWordRightEnd // which means 2 actions so wrap in an undo group. // Rightwards and leftwards deletions differ in treatment of virtual space. // Clear virtual space for leftwards, realise for rightwards. - const bool leftwards = (iMessage == SCI_DELWORDLEFT) || (iMessage == SCI_DELLINELEFT); + const bool leftwards = (iMessage == Message::DelWordLeft) || (iMessage == Message::DelLineLeft); if (!additionalSelectionTyping) { InvalidateWholeSelection(); @@ -3646,31 +3654,33 @@ int Editor::DelWordOrLine(unsigned int iMessage) { Range rangeDelete; switch (iMessage) { - case SCI_DELWORDLEFT: + case Message::DelWordLeft: rangeDelete = Range( pdoc->NextWordStart(sel.Range(r).caret.Position(), -1), sel.Range(r).caret.Position()); break; - case SCI_DELWORDRIGHT: + case Message::DelWordRight: rangeDelete = Range( sel.Range(r).caret.Position(), pdoc->NextWordStart(sel.Range(r).caret.Position(), 1)); break; - case SCI_DELWORDRIGHTEND: + case Message::DelWordRightEnd: rangeDelete = Range( sel.Range(r).caret.Position(), pdoc->NextWordEnd(sel.Range(r).caret.Position(), 1)); break; - case SCI_DELLINELEFT: + case Message::DelLineLeft: rangeDelete = Range( pdoc->LineStart(pdoc->LineFromPosition(sel.Range(r).caret.Position())), sel.Range(r).caret.Position()); break; - case SCI_DELLINERIGHT: + case Message::DelLineRight: rangeDelete = Range( sel.Range(r).caret.Position(), pdoc->LineEnd(pdoc->LineFromPosition(sel.Range(r).caret.Position()))); break; + default: + break; } if (!RangeContainsProtected(rangeDelete.start, rangeDelete.end)) { pdoc->DeleteChars(rangeDelete.start, rangeDelete.end - rangeDelete.start); @@ -3680,7 +3690,7 @@ int Editor::DelWordOrLine(unsigned int iMessage) { // May need something stronger here: can selections overlap at this point? sel.RemoveDuplicates(); - MovedCaret(sel.RangeMain().caret, SelectionPosition(INVALID_POSITION), true, caretPolicies); + MovedCaret(sel.RangeMain().caret, SelectionPosition(Sci::invalidPosition), true, caretPolicies); // Invalidate the new state of the selection InvalidateWholeSelection(); @@ -3689,141 +3699,141 @@ int Editor::DelWordOrLine(unsigned int iMessage) { return 0; } -int Editor::KeyCommand(unsigned int iMessage) { +int Editor::KeyCommand(Message iMessage) { switch (iMessage) { - case SCI_LINEDOWN: - CursorUpOrDown(1, Selection::noSel); + case Message::LineDown: + CursorUpOrDown(1, Selection::SelTypes::none); break; - case SCI_LINEDOWNEXTEND: - CursorUpOrDown(1, Selection::selStream); + case Message::LineDownExtend: + CursorUpOrDown(1, Selection::SelTypes::stream); break; - case SCI_LINEDOWNRECTEXTEND: - CursorUpOrDown(1, Selection::selRectangle); + case Message::LineDownRectExtend: + CursorUpOrDown(1, Selection::SelTypes::rectangle); break; - case SCI_PARADOWN: - ParaUpOrDown(1, Selection::noSel); + case Message::ParaDown: + ParaUpOrDown(1, Selection::SelTypes::none); break; - case SCI_PARADOWNEXTEND: - ParaUpOrDown(1, Selection::selStream); + case Message::ParaDownExtend: + ParaUpOrDown(1, Selection::SelTypes::stream); break; - case SCI_LINESCROLLDOWN: + case Message::LineScrollDown: ScrollTo(topLine + 1); MoveCaretInsideView(false); break; - case SCI_LINEUP: - CursorUpOrDown(-1, Selection::noSel); + case Message::LineUp: + CursorUpOrDown(-1, Selection::SelTypes::none); break; - case SCI_LINEUPEXTEND: - CursorUpOrDown(-1, Selection::selStream); + case Message::LineUpExtend: + CursorUpOrDown(-1, Selection::SelTypes::stream); break; - case SCI_LINEUPRECTEXTEND: - CursorUpOrDown(-1, Selection::selRectangle); + case Message::LineUpRectExtend: + CursorUpOrDown(-1, Selection::SelTypes::rectangle); break; - case SCI_PARAUP: - ParaUpOrDown(-1, Selection::noSel); + case Message::ParaUp: + ParaUpOrDown(-1, Selection::SelTypes::none); break; - case SCI_PARAUPEXTEND: - ParaUpOrDown(-1, Selection::selStream); + case Message::ParaUpExtend: + ParaUpOrDown(-1, Selection::SelTypes::stream); break; - case SCI_LINESCROLLUP: + case Message::LineScrollUp: ScrollTo(topLine - 1); MoveCaretInsideView(false); break; - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: - case SCI_CHARLEFTRECTEXTEND: - case SCI_CHARRIGHT: - case SCI_CHARRIGHTEXTEND: - case SCI_CHARRIGHTRECTEXTEND: - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: - case SCI_WORDRIGHT: - case SCI_WORDRIGHTEXTEND: - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDRIGHTEND: - case SCI_WORDRIGHTENDEXTEND: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: - case SCI_WORDPARTRIGHT: - case SCI_WORDPARTRIGHTEXTEND: - case SCI_HOME: - case SCI_HOMEEXTEND: - case SCI_HOMERECTEXTEND: - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMERECTEXTEND: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: - case SCI_LINEEND: - case SCI_LINEENDEXTEND: - case SCI_LINEENDRECTEXTEND: - case SCI_LINEENDDISPLAY: - case SCI_LINEENDDISPLAYEXTEND: - case SCI_LINEENDWRAP: - case SCI_LINEENDWRAPEXTEND: + case Message::CharLeft: + case Message::CharLeftExtend: + case Message::CharLeftRectExtend: + case Message::CharRight: + case Message::CharRightExtend: + case Message::CharRightRectExtend: + case Message::WordLeft: + case Message::WordLeftExtend: + case Message::WordRight: + case Message::WordRightExtend: + case Message::WordLeftEnd: + case Message::WordLeftEndExtend: + case Message::WordRightEnd: + case Message::WordRightEndExtend: + case Message::WordPartLeft: + case Message::WordPartLeftExtend: + case Message::WordPartRight: + case Message::WordPartRightExtend: + case Message::Home: + case Message::HomeExtend: + case Message::HomeRectExtend: + case Message::HomeDisplay: + case Message::HomeDisplayExtend: + case Message::HomeWrap: + case Message::HomeWrapExtend: + case Message::VCHome: + case Message::VCHomeExtend: + case Message::VCHomeRectExtend: + case Message::VCHomeDisplay: + case Message::VCHomeDisplayExtend: + case Message::VCHomeWrap: + case Message::VCHomeWrapExtend: + case Message::LineEnd: + case Message::LineEndExtend: + case Message::LineEndRectExtend: + case Message::LineEndDisplay: + case Message::LineEndDisplayExtend: + case Message::LineEndWrap: + case Message::LineEndWrapExtend: return HorizontalMove(iMessage); - case SCI_DOCUMENTSTART: + case Message::DocumentStart: MovePositionTo(0); SetLastXChosen(); break; - case SCI_DOCUMENTSTARTEXTEND: - MovePositionTo(0, Selection::selStream); + case Message::DocumentStartExtend: + MovePositionTo(0, Selection::SelTypes::stream); SetLastXChosen(); break; - case SCI_DOCUMENTEND: + case Message::DocumentEnd: MovePositionTo(pdoc->Length()); SetLastXChosen(); break; - case SCI_DOCUMENTENDEXTEND: - MovePositionTo(pdoc->Length(), Selection::selStream); + case Message::DocumentEndExtend: + MovePositionTo(pdoc->Length(), Selection::SelTypes::stream); SetLastXChosen(); break; - case SCI_STUTTEREDPAGEUP: - PageMove(-1, Selection::noSel, true); + case Message::StutteredPageUp: + PageMove(-1, Selection::SelTypes::none, true); break; - case SCI_STUTTEREDPAGEUPEXTEND: - PageMove(-1, Selection::selStream, true); + case Message::StutteredPageUpExtend: + PageMove(-1, Selection::SelTypes::stream, true); break; - case SCI_STUTTEREDPAGEDOWN: - PageMove(1, Selection::noSel, true); + case Message::StutteredPageDown: + PageMove(1, Selection::SelTypes::none, true); break; - case SCI_STUTTEREDPAGEDOWNEXTEND: - PageMove(1, Selection::selStream, true); + case Message::StutteredPageDownExtend: + PageMove(1, Selection::SelTypes::stream, true); break; - case SCI_PAGEUP: + case Message::PageUp: PageMove(-1); break; - case SCI_PAGEUPEXTEND: - PageMove(-1, Selection::selStream); + case Message::PageUpExtend: + PageMove(-1, Selection::SelTypes::stream); break; - case SCI_PAGEUPRECTEXTEND: - PageMove(-1, Selection::selRectangle); + case Message::PageUpRectExtend: + PageMove(-1, Selection::SelTypes::rectangle); break; - case SCI_PAGEDOWN: + case Message::PageDown: PageMove(1); break; - case SCI_PAGEDOWNEXTEND: - PageMove(1, Selection::selStream); + case Message::PageDownExtend: + PageMove(1, Selection::SelTypes::stream); break; - case SCI_PAGEDOWNRECTEXTEND: - PageMove(1, Selection::selRectangle); + case Message::PageDownRectExtend: + PageMove(1, Selection::SelTypes::rectangle); break; - case SCI_EDITTOGGLEOVERTYPE: + case Message::EditToggleOvertype: inOverstrike = !inOverstrike; - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + ContainerNeedsUpdate(Update::Selection); ShowCaretAtCurrentPosition(); SetIdle(true); break; - case SCI_CANCEL: // Cancel any modes - handled in subclass + case Message::Cancel: // Cancel any modes - handled in subclass // Also unselect text CancelModes(); if ((sel.Count() > 1) && !sel.IsRectangular()) { @@ -3832,50 +3842,50 @@ int Editor::KeyCommand(unsigned int iMessage) { sel.DropAdditionalRanges(); } break; - case SCI_DELETEBACK: + case Message::DeleteBack: DelCharBack(true); - if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { + if ((caretSticky == CaretSticky::Off) || (caretSticky == CaretSticky::WhiteSpace)) { SetLastXChosen(); } EnsureCaretVisible(); break; - case SCI_DELETEBACKNOTLINE: + case Message::DeleteBackNotLine: DelCharBack(false); - if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { + if ((caretSticky == CaretSticky::Off) || (caretSticky == CaretSticky::WhiteSpace)) { SetLastXChosen(); } EnsureCaretVisible(); break; - case SCI_TAB: + case Message::Tab: Indent(true); - if (caretSticky == SC_CARETSTICKY_OFF) { + if (caretSticky == CaretSticky::Off) { SetLastXChosen(); } EnsureCaretVisible(); ShowCaretAtCurrentPosition(); // Avoid blinking break; - case SCI_BACKTAB: + case Message::BackTab: Indent(false); - if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { + if ((caretSticky == CaretSticky::Off) || (caretSticky == CaretSticky::WhiteSpace)) { SetLastXChosen(); } EnsureCaretVisible(); ShowCaretAtCurrentPosition(); // Avoid blinking break; - case SCI_NEWLINE: + case Message::NewLine: NewLine(); break; - case SCI_FORMFEED: + case Message::FormFeed: AddChar('\f'); break; - case SCI_ZOOMIN: + case Message::ZoomIn: if (vs.zoomLevel < 20) { vs.zoomLevel++; InvalidateStyleRedraw(); NotifyZoom(); } break; - case SCI_ZOOMOUT: + case Message::ZoomOut: if (vs.zoomLevel > -10) { vs.zoomLevel--; InvalidateStyleRedraw(); @@ -3883,21 +3893,21 @@ int Editor::KeyCommand(unsigned int iMessage) { } break; - case SCI_DELWORDLEFT: - case SCI_DELWORDRIGHT: - case SCI_DELWORDRIGHTEND: - case SCI_DELLINELEFT: - case SCI_DELLINERIGHT: + case Message::DelWordLeft: + case Message::DelWordRight: + case Message::DelWordRightEnd: + case Message::DelLineLeft: + case Message::DelLineRight: return DelWordOrLine(iMessage); - case SCI_LINECOPY: { + case Message::LineCopy: { const Sci::Line lineStart = pdoc->SciLineFromPosition(SelectionStart().Position()); const Sci::Line lineEnd = pdoc->SciLineFromPosition(SelectionEnd().Position()); CopyRangeToClipboard(pdoc->LineStart(lineStart), pdoc->LineStart(lineEnd + 1)); } break; - case SCI_LINECUT: { + case Message::LineCut: { const Sci::Line lineStart = pdoc->SciLineFromPosition(SelectionStart().Position()); const Sci::Line lineEnd = pdoc->SciLineFromPosition(SelectionEnd().Position()); const Sci::Position start = pdoc->LineStart(lineStart); @@ -3907,49 +3917,51 @@ int Editor::KeyCommand(unsigned int iMessage) { SetLastXChosen(); } break; - case SCI_LINEDELETE: { + case Message::LineDelete: { const Sci::Line line = pdoc->SciLineFromPosition(sel.MainCaret()); const Sci::Position start = pdoc->LineStart(line); const Sci::Position end = pdoc->LineStart(line + 1); pdoc->DeleteChars(start, end - start); } break; - case SCI_LINETRANSPOSE: + case Message::LineTranspose: LineTranspose(); break; - case SCI_LINEREVERSE: + case Message::LineReverse: LineReverse(); break; - case SCI_LINEDUPLICATE: + case Message::LineDuplicate: Duplicate(true); break; - case SCI_SELECTIONDUPLICATE: + case Message::SelectionDuplicate: Duplicate(false); break; - case SCI_LOWERCASE: - ChangeCaseOfSelection(cmLower); + case Message::LowerCase: + ChangeCaseOfSelection(CaseMapping::lower); break; - case SCI_UPPERCASE: - ChangeCaseOfSelection(cmUpper); + case Message::UpperCase: + ChangeCaseOfSelection(CaseMapping::upper); break; - case SCI_SCROLLTOSTART: + case Message::ScrollToStart: ScrollTo(0); break; - case SCI_SCROLLTOEND: + case Message::ScrollToEnd: ScrollTo(MaxScrollPos()); break; + default: + break; } return 0; } -int Editor::KeyDefault(int, int) { +int Editor::KeyDefault(Keys, KeyMod) { return 0; } -int Editor::KeyDownWithModifiers(int key, int modifiers, bool *consumed) { +int Editor::KeyDownWithModifiers(Keys key, KeyMod modifiers, bool *consumed) { DwellEnd(false); - const int msg = kmap.Find(key, modifiers); - if (msg) { + const Message msg = kmap.Find(key, modifiers); + if (msg != static_cast(0)) { if (consumed) *consumed = true; return static_cast(WndProc(msg, 0, 0)); @@ -4039,7 +4051,7 @@ void Editor::Indent(bool forwards) { } } } - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + ContainerNeedsUpdate(Update::Selection); } class CaseFolderASCII : public CaseFolderTable { @@ -4050,9 +4062,9 @@ class CaseFolderASCII : public CaseFolderTable { }; -CaseFolder *Editor::CaseFolderForEncoding() { +std::unique_ptr Editor::CaseFolderForEncoding() { // Simple default that only maps ASCII upper case to lower case. - return new CaseFolderASCII(); + return std::make_unique(); } /** @@ -4060,11 +4072,11 @@ CaseFolder *Editor::CaseFolderForEncoding() { * @return The position of the found text, -1 if not found. */ Sci::Position Editor::FindText( - uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, - ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX. + uptr_t wParam, ///< Search modes : @c FindOption::MatchCase, @c FindOption::WholeWord, + ///< @c FindOption::WordStart, @c FindOption::RegExp or @c FindOption::Posix. sptr_t lParam) { ///< @c Sci_TextToFind structure: The text to search for in the given range. - Sci_TextToFind *ft = static_cast(PtrFromSPtr(lParam)); + TextToFind *ft = static_cast(PtrFromSPtr(lParam)); Sci::Position lengthFound = strlen(ft->lpstrText); if (!pdoc->HasCaseFolder()) pdoc->SetCaseFolder(CaseFolderForEncoding()); @@ -4073,7 +4085,7 @@ Sci::Position Editor::FindText( static_cast(ft->chrg.cpMin), static_cast(ft->chrg.cpMax), ft->lpstrText, - static_cast(wParam), + static_cast(wParam), &lengthFound); if (pos != -1) { ft->chrgText.cpMin = static_cast(pos); @@ -4081,7 +4093,7 @@ Sci::Position Editor::FindText( } return pos; } catch (RegexError &) { - errorStatus = SC_STATUS_WARN_REGEX; + errorStatus = Status::RegEx; return -1; } } @@ -4107,47 +4119,49 @@ void Editor::SearchAnchor() { * @return The position of the found text, -1 if not found. */ Sci::Position Editor::SearchText( - unsigned int iMessage, ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV. - uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, - ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX. + Message iMessage, ///< Accepts both @c Message::SearchNext and @c Message::SearchPrev. + uptr_t wParam, ///< Search modes : @c FindOption::MatchCase, @c FindOption::WholeWord, + ///< @c FindOption::WordStart, @c FindOption::RegExp or @c FindOption::Posix. sptr_t lParam) { ///< The text to search for. const char *txt = CharPtrFromSPtr(lParam); - Sci::Position pos = INVALID_POSITION; + Sci::Position pos = Sci::invalidPosition; Sci::Position lengthFound = strlen(txt); if (!pdoc->HasCaseFolder()) pdoc->SetCaseFolder(CaseFolderForEncoding()); try { - if (iMessage == SCI_SEARCHNEXT) { + if (iMessage == Message::SearchNext) { pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt, - static_cast(wParam), + static_cast(wParam), &lengthFound); } else { pos = pdoc->FindText(searchAnchor, 0, txt, - static_cast(wParam), + static_cast(wParam), &lengthFound); } } catch (RegexError &) { - errorStatus = SC_STATUS_WARN_REGEX; - return INVALID_POSITION; + errorStatus = Status::RegEx; + return Sci::invalidPosition; } - if (pos != INVALID_POSITION) { + if (pos != Sci::invalidPosition) { SetSelection(pos, pos + lengthFound); } return pos; } -std::string Editor::CaseMapString(const std::string &s, int caseMapping) { +std::string Editor::CaseMapString(const std::string &s, CaseMapping caseMapping) { std::string ret(s); for (char &ch : ret) { switch (caseMapping) { - case cmUpper: + case CaseMapping::upper: ch = MakeUpperCase(ch); break; - case cmLower: + case CaseMapping::lower: ch = MakeLowerCase(ch); break; + default: // no action + break; } } return ret; @@ -4172,7 +4186,7 @@ Sci::Position Editor::SearchInTarget(const char *text, Sci::Position length) { } return pos; } catch (RegexError &) { - errorStatus = SC_STATUS_WARN_REGEX; + errorStatus = Status::RegEx; return -1; } } @@ -4200,7 +4214,7 @@ std::string Editor::RangeText(Sci::Position start, Sci::Position end) const { if (start < end) { const Sci::Position len = end - start; std::string ret(len, '\0'); - pdoc->GetCharRange(const_cast(ret.data()), start, len); + pdoc->GetCharRange(ret.data(), start, len); return ret; } return std::string(); @@ -4214,29 +4228,29 @@ void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) { const Sci::Position end = pdoc->LineEnd(currentLine); std::string text = RangeText(start, end); - if (pdoc->eolMode != SC_EOL_LF) + if (pdoc->eolMode != EndOfLine::Lf) text.push_back('\r'); - if (pdoc->eolMode != SC_EOL_CR) + if (pdoc->eolMode != EndOfLine::Cr) text.push_back('\n'); ss->Copy(text, pdoc->dbcsCodePage, - vs.styles[STYLE_DEFAULT].characterSet, false, true); + vs.styles[StyleDefault].characterSet, false, true); } } else { std::string text; std::vector rangesInOrder = sel.RangesCopy(); - if (sel.selType == Selection::selRectangle) + if (sel.selType == Selection::SelTypes::rectangle) std::sort(rangesInOrder.begin(), rangesInOrder.end()); for (const SelectionRange ¤t : rangesInOrder) { text.append(RangeText(current.Start().Position(), current.End().Position())); - if (sel.selType == Selection::selRectangle) { - if (pdoc->eolMode != SC_EOL_LF) + if (sel.selType == Selection::SelTypes::rectangle) { + if (pdoc->eolMode != EndOfLine::Lf) text.push_back('\r'); - if (pdoc->eolMode != SC_EOL_CR) + if (pdoc->eolMode != EndOfLine::Cr) text.push_back('\n'); } } ss->Copy(text, pdoc->dbcsCodePage, - vs.styles[STYLE_DEFAULT].characterSet, sel.IsRectangular(), sel.selType == Selection::selLines); + vs.styles[StyleDefault].characterSet, sel.IsRectangular(), sel.selType == Selection::SelTypes::lines); } } @@ -4246,14 +4260,14 @@ void Editor::CopyRangeToClipboard(Sci::Position start, Sci::Position end) { SelectionText selectedText; std::string text = RangeText(start, end); selectedText.Copy(text, - pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, false); + pdoc->dbcsCodePage, vs.styles[StyleDefault].characterSet, false, false); CopyToClipboard(selectedText); } void Editor::CopyText(size_t length, const char *text) { SelectionText selectedText; selectedText.Copy(std::string(text, length), - pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, false); + pdoc->dbcsCodePage, vs.styles[StyleDefault].characterSet, false, false); CopyToClipboard(selectedText); } @@ -4264,15 +4278,15 @@ void Editor::SetDragPosition(SelectionPosition newPos) { } if (!(posDrag == newPos)) { const CaretPolicies dragCaretPolicies = { - CaretPolicy(CARET_SLOP | CARET_STRICT | CARET_EVEN, 50), - CaretPolicy(CARET_SLOP | CARET_STRICT | CARET_EVEN, 2) + CaretPolicySlop(CaretPolicy::Slop | CaretPolicy::Strict | CaretPolicy::Even, 50), + CaretPolicySlop(CaretPolicy::Slop | CaretPolicy::Strict | CaretPolicy::Even, 2) }; MovedCaret(newPos, posDrag, true, dragCaretPolicies); caret.on = true; - FineTickerCancel(tickCaret); + FineTickerCancel(TickReason::caret); if ((caret.active) && (caret.period > 0) && (newPos.Position() < 0)) - FineTickerStart(tickCaret, caret.period, caret.period/10); + FineTickerStart(TickReason::caret, caret.period, caret.period/10); InvalidateCaret(); posDrag = newPos; InvalidateCaret(); @@ -4280,7 +4294,7 @@ void Editor::SetDragPosition(SelectionPosition newPos) { } void Editor::DisplayCursor(Window::Cursor c) { - if (cursorMode == SC_CURSORNORMAL) + if (cursorMode == CursorShape::Normal) wMain.SetCursor(c); else wMain.SetCursor(static_cast(cursorMode)); @@ -4295,12 +4309,12 @@ bool Editor::DragThreshold(Point ptStart, Point ptNow) { void Editor::StartDrag() { // Always handled by subclasses //SetMouseCapture(true); - //DisplayCursor(Window::cursorArrow); + //DisplayCursor(Windows::Cursor::Arrow); } void Editor::DropAt(SelectionPosition position, const char *value, size_t lengthValue, bool moving, bool rectangular) { //Platform::DebugPrintf("DropAt %d %d\n", inDragDrop, position); - if (inDragDrop == ddDragging) + if (inDragDrop == DragDrop::dragging) dropWentOutside = false; const bool positionWasInSelection = PositionInSelection(position.Position()); @@ -4308,7 +4322,7 @@ void Editor::DropAt(SelectionPosition position, const char *value, size_t length const bool positionOnEdgeOfSelection = (position == SelectionStart()) || (position == SelectionEnd()); - if ((inDragDrop != ddDragging) || !(positionWasInSelection) || + if ((inDragDrop != DragDrop::dragging) || !(positionWasInSelection) || (positionOnEdgeOfSelection && !moving)) { const SelectionPosition selStart = SelectionStart(); @@ -4317,9 +4331,9 @@ void Editor::DropAt(SelectionPosition position, const char *value, size_t length UndoGroup ug(pdoc); SelectionPosition positionAfterDeletion = position; - if ((inDragDrop == ddDragging) && moving) { + if ((inDragDrop == DragDrop::dragging) && moving) { // Remove dragged out text - if (rectangular || sel.selType == Selection::selLines) { + if (rectangular || sel.selType == Selection::SelTypes::lines) { for (size_t r=0; r= sel.Range(r).Start()) { if (position > sel.Range(r).End()) { @@ -4355,7 +4369,7 @@ void Editor::DropAt(SelectionPosition position, const char *value, size_t length SetSelection(posAfterInsertion, position); } } - } else if (inDragDrop == ddDragging) { + } else if (inDragDrop == DragDrop::dragging) { SetEmptySelection(position); } } @@ -4423,7 +4437,7 @@ Window::Cursor Editor::GetMarginCursor(Point pt) const noexcept { return static_cast(m.cursor); x += m.width; } - return Window::cursorReverseArrow; + return Window::Cursor::reverseArrow; } void Editor::TrimAndSetSelection(Sci::Position currentPos_, Sci::Position anchor_) { @@ -4493,12 +4507,12 @@ void Editor::DwellEnd(bool mouseMoved) { if (mouseMoved) ticksToDwell = dwellDelay; else - ticksToDwell = SC_TIME_FOREVER; - if (dwelling && (dwellDelay < SC_TIME_FOREVER)) { + ticksToDwell = TimeForever; + if (dwelling && (dwellDelay < TimeForever)) { dwelling = false; NotifyDwelling(ptMouseLast, dwelling); } - FineTickerCancel(tickDwell); + FineTickerCancel(TickReason::dwell); } void Editor::MouseLeave() { @@ -4510,23 +4524,23 @@ void Editor::MouseLeave() { } } -static constexpr bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) noexcept { - return (!rectangular && ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0)) - || (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0)); +static constexpr bool AllowVirtualSpace(VirtualSpace virtualSpaceOptions, bool rectangular) noexcept { + return (!rectangular && (FlagSet(virtualSpaceOptions, VirtualSpace::UserAccessible))) + || (rectangular && (FlagSet(virtualSpaceOptions, VirtualSpace::RectangularSelection))); } -void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) { +void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, KeyMod modifiers) { SetHoverIndicatorPoint(pt); //Platform::DebugPrintf("ButtonDown %d %d = %d alt=%d %d\n", curTime, lastClickTime, curTime - lastClickTime, alt, inDragDrop); ptMouseLast = pt; - const bool ctrl = (modifiers & SCI_CTRL) != 0; - const bool shift = (modifiers & SCI_SHIFT) != 0; - const bool alt = (modifiers & SCI_ALT) != 0; + const bool ctrl = FlagSet(modifiers, KeyMod::Ctrl); + const bool shift = FlagSet(modifiers, KeyMod::Shift); + const bool alt = FlagSet(modifiers, KeyMod::Alt); SelectionPosition newPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, alt)); newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position()); SelectionPosition newCharPos = SPositionFromLocation(pt, false, true, false); newCharPos = MovePositionOutsideChar(newCharPos, -1); - inDragDrop = ddNone; + inDragDrop = DragDrop::none; sel.SetMoveExtends(false); if (NotifyMarginClick(pt, modifiers)) @@ -4548,7 +4562,7 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie if ((curTime < (lastClickTime+Platform::DoubleClickTime())) && Close(pt, lastClick, doubleClickCloseThreshold)) { //Platform::DebugPrintf("Double click %d %d = %d\n", curTime, lastClickTime, curTime - lastClickTime); SetMouseCapture(true); - FineTickerStart(tickScroll, 100, 10); + FineTickerStart(TickReason::scroll, 100, 10); if (!ctrl || !multipleSelection || (selectionUnit != TextUnit::character && selectionUnit != TextUnit::word)) SetEmptySelection(newPos.Position()); bool doubleClick = false; @@ -4560,7 +4574,7 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie selectionUnit = TextUnit::wholeLine; } else if (selectionUnit != TextUnit::subLine && selectionUnit != TextUnit::wholeLine) { // If it is neither, reset selection type to line selection. - selectionUnit = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? TextUnit::subLine : TextUnit::wholeLine; + selectionUnit = (Wrapping() && (FlagSet(marginOptions, MarginOption::SubLineSelect))) ? TextUnit::subLine : TextUnit::wholeLine; } } else { if (selectionUnit == TextUnit::character) { @@ -4624,11 +4638,11 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie InvalidateWholeSelection(); sel.Clear(); } - sel.selType = Selection::selStream; + sel.selType = Selection::SelTypes::stream; if (!shift) { // Single click in margin: select wholeLine or only subLine if word wrap is enabled lineAnchorPos = newPos.Position(); - selectionUnit = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? TextUnit::subLine : TextUnit::wholeLine; + selectionUnit = (Wrapping() && (FlagSet(marginOptions, MarginOption::SubLineSelect))) ? TextUnit::subLine : TextUnit::wholeLine; LineSelection(lineAnchorPos, lineAnchorPos, selectionUnit == TextUnit::wholeLine); } else { // Single shift+click in margin: select from line anchor to clicked line @@ -4638,16 +4652,16 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie lineAnchorPos = sel.MainAnchor(); // Reset selection type if there is an empty selection. // This ensures that we don't end up stuck in previous selection mode, which is no longer valid. - // Otherwise, if there's a non empty selection, reset selection type only if it differs from subLine and wholeLine. + // Otherwise, if there's a non empty selection, reset selection type only if it differs from selSubLine and selWholeLine. // This ensures that we continue selecting in the same selection mode. if (sel.Empty() || (selectionUnit != TextUnit::subLine && selectionUnit != TextUnit::wholeLine)) - selectionUnit = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? TextUnit::subLine : TextUnit::wholeLine; + selectionUnit = (Wrapping() && (FlagSet(marginOptions, MarginOption::SubLineSelect))) ? TextUnit::subLine : TextUnit::wholeLine; LineSelection(newPos.Position(), lineAnchorPos, selectionUnit == TextUnit::wholeLine); } SetDragPosition(SelectionPosition(Sci::invalidPosition)); SetMouseCapture(true); - FineTickerStart(tickScroll, 100, 10); + FineTickerStart(TickReason::scroll, 100, 10); } else { if (PointIsHotspot(pt)) { NotifyHotSpotClicked(newCharPos.Position(), modifiers); @@ -4655,13 +4669,13 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie } if (!shift) { if (PointInSelection(pt) && !SelectionEmpty()) - inDragDrop = ddInitial; + inDragDrop = DragDrop::initial; else - inDragDrop = ddNone; + inDragDrop = DragDrop::none; } SetMouseCapture(true); - FineTickerStart(tickScroll, 100, 10); - if (inDragDrop != ddInitial) { + FineTickerStart(TickReason::scroll, 100, 10); + if (inDragDrop != DragDrop::initial) { SetDragPosition(SelectionPosition(Sci::invalidPosition)); if (!shift) { if (ctrl && multipleSelection) { @@ -4672,9 +4686,9 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie InvalidateSelection(SelectionRange(newPos), true); if (sel.Count() > 1) Redraw(); - if ((sel.Count() > 1) || (sel.selType != Selection::selStream)) + if ((sel.Count() > 1) || (sel.selType != Selection::SelTypes::stream)) sel.Clear(); - sel.selType = alt ? Selection::selRectangle : Selection::selStream; + sel.selType = alt ? Selection::SelTypes::rectangle : Selection::SelTypes::stream; SetSelection(newPos, newPos); } } @@ -4682,7 +4696,7 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie if (shift) anchorCurrent = sel.IsRectangular() ? sel.Rectangular().anchor : sel.RangeMain().anchor; - sel.selType = alt ? Selection::selRectangle : Selection::selStream; + sel.selType = alt ? Selection::SelTypes::rectangle : Selection::SelTypes::stream; selectionUnit = TextUnit::character; originalAnchorPos = sel.MainCaret(); sel.Rectangular() = SelectionRange(newPos, anchorCurrent); @@ -4696,7 +4710,7 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie ShowCaretAtCurrentPosition(); } -void Editor::RightButtonDownWithModifiers(Point pt, unsigned int, int modifiers) { +void Editor::RightButtonDownWithModifiers(Point pt, unsigned int, KeyMod modifiers) { if (NotifyMarginRightClick(pt, modifiers)) return; } @@ -4707,17 +4721,17 @@ bool Editor::PositionIsHotspot(Sci::Position position) const { bool Editor::PointIsHotspot(Point pt) { const Sci::Position pos = PositionFromLocation(pt, true, true); - if (pos == INVALID_POSITION) + if (pos == Sci::invalidPosition) return false; return PositionIsHotspot(pos); } void Editor::SetHoverIndicatorPosition(Sci::Position position) { const Sci::Position hoverIndicatorPosPrev = hoverIndicatorPos; - hoverIndicatorPos = INVALID_POSITION; + hoverIndicatorPos = Sci::invalidPosition; if (!vs.indicatorsDynamic) return; - if (position != INVALID_POSITION) { + if (position != Sci::invalidPosition) { for (const IDecoration *deco : pdoc->decorations->View()) { if (vs.indicators[deco->Indicator()].IsDynamic()) { if (pdoc->decorations->ValueAt(deco->Indicator(), position)) { @@ -4733,7 +4747,7 @@ void Editor::SetHoverIndicatorPosition(Sci::Position position) { void Editor::SetHoverIndicatorPoint(Point pt) { if (!vs.indicatorsDynamic) { - SetHoverIndicatorPosition(INVALID_POSITION); + SetHoverIndicatorPosition(Sci::invalidPosition); } else { SetHoverIndicatorPosition(PositionFromLocation(pt, true, true)); } @@ -4747,8 +4761,8 @@ void Editor::SetHotSpotRange(const Point *pt) { // range can encompass more than the run range and then // the underline will not be drawn properly. Range hsNew; - hsNew.start = pdoc->ExtendStyleRange(pos, -1, vs.hotspotSingleLine); - hsNew.end = pdoc->ExtendStyleRange(pos, 1, vs.hotspotSingleLine); + hsNew.start = pdoc->ExtendStyleRange(pos, -1, hotspotSingleLine); + hsNew.end = pdoc->ExtendStyleRange(pos, 1, hotspotSingleLine); // Only invalidate the range if the hotspot range has changed... if (!(hsNew == hotspot)) { @@ -4770,7 +4784,7 @@ Range Editor::GetHotSpotRange() const noexcept { return hotspot; } -void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { +void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, KeyMod modifiers) { if (ptMouseLast != pt) { DwellEnd(true); } @@ -4779,10 +4793,10 @@ void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular())); movePos = MovePositionOutsideChar(movePos, sel.MainCaret() - movePos.Position()); - if (inDragDrop == ddInitial) { + if (inDragDrop == DragDrop::initial) { if (DragThreshold(ptMouseLast, pt)) { SetMouseCapture(false); - FineTickerCancel(tickScroll); + FineTickerCancel(TickReason::scroll); SetDragPosition(movePos); CopySelectionRange(&drag); StartDrag(); @@ -4794,8 +4808,8 @@ void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { PRectangle rcClient = GetClientRectangle(); const Point ptOrigin = GetVisibleOriginInMain(); rcClient.Move(0, -ptOrigin.y); - if ((dwellDelay < SC_TIME_FOREVER) && rcClient.Contains(pt)) { - FineTickerStart(tickDwell, dwellDelay, dwellDelay/10); + if ((dwellDelay < TimeForever) && rcClient.Contains(pt)) { + FineTickerStart(TickReason::dwell, dwellDelay, dwellDelay/10); } //Platform::DebugPrintf("Move %d %d\n", pt.x, pt.y); if (HaveMouseCapture()) { @@ -4811,8 +4825,8 @@ void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { SetDragPosition(movePos); } else { if (selectionUnit == TextUnit::character) { - if (sel.selType == Selection::selStream && (modifiers & SCI_ALT) && mouseSelectionRectangularSwitch) { - sel.selType = Selection::selRectangle; + if (sel.selType == Selection::SelTypes::stream && FlagSet(modifiers, KeyMod::Alt) && mouseSelectionRectangularSwitch) { + sel.selType = Selection::SelTypes::rectangle; } if (sel.IsRectangular()) { sel.Rectangular() = SelectionRange(movePos, sel.Rectangular().anchor); @@ -4861,11 +4875,11 @@ void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { if (hotspot.Valid() && !PointIsHotspot(pt)) SetHotSpotRange(nullptr); - if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt, true, true) != hotSpotClickPos) { - if (inDragDrop == ddNone) { - DisplayCursor(Window::cursorText); + if (hotSpotClickPos != Sci::invalidPosition && PositionFromLocation(pt, true, true) != hotSpotClickPos) { + if (inDragDrop == DragDrop::none) { + DisplayCursor(Window::Cursor::text); } - hotSpotClickPos = INVALID_POSITION; + hotSpotClickPos = Sci::invalidPosition; } } else { @@ -4879,61 +4893,61 @@ void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { } // Display regular (drag) cursor over selection if (PointInSelection(pt) && !SelectionEmpty()) { - DisplayCursor(Window::cursorArrow); + DisplayCursor(Window::Cursor::arrow); SetHoverIndicatorPosition(Sci::invalidPosition); } else { SetHoverIndicatorPoint(pt); if (PointIsHotspot(pt)) { - DisplayCursor(Window::cursorHand); + DisplayCursor(Window::Cursor::hand); SetHotSpotRange(&pt); } else { if (hoverIndicatorPos != Sci::invalidPosition) - DisplayCursor(Window::cursorHand); + DisplayCursor(Window::Cursor::hand); else - DisplayCursor(Window::cursorText); + DisplayCursor(Window::Cursor::text); SetHotSpotRange(nullptr); } } } } -void Editor::ButtonUpWithModifiers(Point pt, unsigned int curTime, int modifiers) { +void Editor::ButtonUpWithModifiers(Point pt, unsigned int curTime, KeyMod modifiers) { //Platform::DebugPrintf("ButtonUp %d %d\n", HaveMouseCapture(), inDragDrop); SelectionPosition newPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular())); - if (hoverIndicatorPos != INVALID_POSITION) + if (hoverIndicatorPos != Sci::invalidPosition) InvalidateRange(newPos.Position(), newPos.Position() + 1); newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position()); - if (inDragDrop == ddInitial) { - inDragDrop = ddNone; + if (inDragDrop == DragDrop::initial) { + inDragDrop = DragDrop::none; SetEmptySelection(newPos); selectionUnit = TextUnit::character; originalAnchorPos = sel.MainCaret(); } - if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) { - hotSpotClickPos = INVALID_POSITION; + if (hotSpotClickPos != Sci::invalidPosition && PointIsHotspot(pt)) { + hotSpotClickPos = Sci::invalidPosition; SelectionPosition newCharPos = SPositionFromLocation(pt, false, true, false); newCharPos = MovePositionOutsideChar(newCharPos, -1); - NotifyHotSpotReleaseClick(newCharPos.Position(), modifiers & SCI_CTRL); + NotifyHotSpotReleaseClick(newCharPos.Position(), modifiers & KeyMod::Ctrl); } if (HaveMouseCapture()) { if (PointInSelMargin(pt)) { DisplayCursor(GetMarginCursor(pt)); } else { - DisplayCursor(Window::cursorText); + DisplayCursor(Window::Cursor::text); SetHotSpotRange(nullptr); } ptMouseLast = pt; SetMouseCapture(false); - FineTickerCancel(tickScroll); - NotifyIndicatorClick(false, newPos.Position(), 0); - if (inDragDrop == ddDragging) { + FineTickerCancel(TickReason::scroll); + NotifyIndicatorClick(false, newPos.Position(), modifiers); + if (inDragDrop == DragDrop::dragging) { const SelectionPosition selStart = SelectionStart(); const SelectionPosition selEnd = SelectionEnd(); if (selStart < selEnd) { if (drag.Length()) { const Sci::Position length = drag.Length(); - if (modifiers & SCI_CTRL) { + if (FlagSet(modifiers, KeyMod::Ctrl)) { const Sci::Position lengthInserted = pdoc->InsertString( newPos.Position(), drag.Data(), length); if (lengthInserted > 0) { @@ -4977,10 +4991,10 @@ void Editor::ButtonUpWithModifiers(Point pt, unsigned int curTime, int modifiers lastClickTime = curTime; lastClick = pt; lastXChosen = static_cast(pt.x) + xOffset; - if (sel.selType == Selection::selStream) { + if (sel.selType == Selection::SelTypes::stream) { SetLastXChosen(); } - inDragDrop = ddNone; + inDragDrop = DragDrop::none; EnsureCaretVisible(false); } } @@ -4996,7 +5010,7 @@ bool Editor::Idle() { // No more wrapping needWrap = wrapPending.NeedsWrap(); } else if (needIdleStyling) { - IdleStyling(); + IdleStyle(); } // Add more idle things to do here, but make sure idleDone is @@ -5011,27 +5025,27 @@ bool Editor::Idle() { void Editor::TickFor(TickReason reason) { switch (reason) { - case tickCaret: + case TickReason::caret: caret.on = !caret.on; if (caret.active) { InvalidateCaret(); } break; - case tickScroll: + case TickReason::scroll: // Auto scroll - ButtonMoveWithModifiers(ptMouseLast, 0, 0); + ButtonMoveWithModifiers(ptMouseLast, 0, KeyMod::Norm); break; - case tickWiden: + case TickReason::widen: SetScrollBars(); - FineTickerCancel(tickWiden); + FineTickerCancel(TickReason::widen); break; - case tickDwell: + case TickReason::dwell: if ((!HaveMouseCapture()) && (ptMouseLast.y >= 0)) { dwelling = true; NotifyDwelling(ptMouseLast, dwelling); } - FineTickerCancel(tickDwell); + FineTickerCancel(TickReason::dwell); break; default: // tickPlatform handled by subclass @@ -5059,7 +5073,11 @@ void Editor::FineTickerCancel(TickReason) { } void Editor::SetFocusState(bool focusState) { + const bool changing = hasFocus != focusState; hasFocus = focusState; + if (changing) { + Redraw(); + } NotifyFocus(hasFocus); if (!hasFocus) { CancelModes(); @@ -5067,6 +5085,10 @@ void Editor::SetFocusState(bool focusState) { ShowCaretAtCurrentPosition(); } +void Editor::UpdateBaseElements() { + // Overridden by subclasses +} + Sci::Position Editor::PositionAfterArea(PRectangle rcArea) const { // The start of the document line after the display line after the area // This often means that the line after a modification is restyled which helps @@ -5106,16 +5128,17 @@ Sci::Position Editor::PositionAfterMaxStyling(Sci::Position posMax, bool scrolli // When scrolling, allow less time to ensure responsive const double secondsAllowed = scrolling ? 0.005 : 0.02; - const Sci::Line linesToStyle = Sci::clamp(static_cast(secondsAllowed / pdoc->durationStyleOneLine.Duration()), - 10, 0x10000); - const Sci::Line stylingMaxLine = std::min( - pdoc->SciLineFromPosition(pdoc->GetEndStyled()) + linesToStyle, - pdoc->LinesTotal()); + const size_t actionsInAllowedTime = std::clamp( + pdoc->durationStyleOneByte.ActionsInAllowedTime(secondsAllowed), + 0x200, 0x20000); + const Sci::Line lineLast = pdoc->LineFromPositionAfter(pdoc->SciLineFromPosition(pdoc->GetEndStyled()), actionsInAllowedTime); + const Sci::Line stylingMaxLine = std::min(lineLast, pdoc->LinesTotal()); + return std::min(pdoc->LineStart(stylingMaxLine), posMax); } void Editor::StartIdleStyling(bool truncatedLastStyling) { - if ((idleStyling == SC_IDLESTYLING_ALL) || (idleStyling == SC_IDLESTYLING_AFTERVISIBLE)) { + if ((idleStyling == IdleStyling::All) || (idleStyling == IdleStyling::AfterVisible)) { if (pdoc->GetEndStyled() < pdoc->Length()) { // Style remainder of document in idle time needIdleStyling = true; @@ -5144,9 +5167,9 @@ void Editor::StyleAreaBounded(PRectangle rcArea, bool scrolling) { StartIdleStyling(posAfterMax < posAfterArea); } -void Editor::IdleStyling() { +void Editor::IdleStyle() { const Sci::Position posAfterArea = PositionAfterArea(GetClientRectangle()); - const Sci::Position endGoal = (idleStyling >= SC_IDLESTYLING_AFTERVISIBLE) ? + const Sci::Position endGoal = (idleStyling >= IdleStyling::AfterVisible) ? pdoc->Length() : posAfterArea; const Sci::Position posAfterMax = PositionAfterMaxStyling(endGoal, false); pdoc->StyleToAdjustingLineDuration(posAfterMax); @@ -5158,17 +5181,22 @@ void Editor::IdleStyling() { void Editor::IdleWork() { // Style the line after the modification as this allows modifications that change just the // line of the modification to heal instead of propagating to the rest of the window. - if (workNeeded.items & WorkNeeded::workStyle) { + if (FlagSet(workNeeded.items, WorkItems::style)) { StyleToPositionInView(pdoc->LineStart(pdoc->LineFromPosition(workNeeded.upTo) + 2)); } NotifyUpdateUI(); workNeeded.Reset(); } -void Editor::QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo) { +void Editor::QueueIdleWork(WorkItems items, Sci::Position upTo) { workNeeded.Need(items, upTo); } +int Editor::SupportsFeature(Supports feature) { + AutoSurface surface(this); + return surface->SupportsFeature(feature); +} + bool Editor::PaintContains(PRectangle rc) { if (rc.Empty()) { return true; @@ -5189,7 +5217,7 @@ bool Editor::PaintContainsMargin() { } void Editor::CheckForChangeOutsidePaint(Range r) { - if (paintState == painting && !paintingAllText) { + if (paintState == PaintState::painting && !paintingAllText) { //Platform::DebugPrintf("Checking range in paint %d-%d\n", r.start, r.end); if (!r.Valid()) return; @@ -5223,23 +5251,23 @@ void Editor::SetBraceHighlight(Sci::Position pos0, Sci::Position pos1, int match braces[1] = pos1; } bracesMatchStyle = matchStyle; - if (paintState == notPainting) { + if (paintState == PaintState::notPainting) { Redraw(); } } } void Editor::SetAnnotationHeights(Sci::Line start, Sci::Line end) { - if (vs.annotationVisible) { + if (vs.annotationVisible != AnnotationVisible::Hidden) { RefreshStyleData(); bool changedHeight = false; for (Sci::Line line=start; lineLinesTotal(); line++) { int linesWrapped = 1; if (Wrapping()) { AutoSurface surface(this); - AutoLineLayout ll(view.llc, view.RetrieveLineLayout(line, *this)); + std::shared_ptr ll = view.RetrieveLineLayout(line, *this); if (surface && ll) { - view.LayoutLine(*this, line, surface, vs, ll, wrapWidth); + view.LayoutLine(*this, surface, vs, ll.get(), wrapWidth); linesWrapped = ll->lines; } } @@ -5254,10 +5282,10 @@ void Editor::SetAnnotationHeights(Sci::Line start, Sci::Line end) { void Editor::SetDocPointer(Document *document) { //Platform::DebugPrintf("** %x setdoc to %x\n", pdoc, document); - pdoc->RemoveWatcher(this, 0); + pdoc->RemoveWatcher(this, nullptr); pdoc->Release(); if (!document) { - pdoc = new Document(SC_DOCUMENTOPTION_DEFAULT); + pdoc = new Document(DocumentOption::Default); } else { pdoc = document; } @@ -5287,17 +5315,17 @@ void Editor::SetDocPointer(Document *document) { view.ClearAllTabstops(); - pdoc->AddWatcher(this, 0); + pdoc->AddWatcher(this, nullptr); SetScrollBars(); Redraw(); } -void Editor::SetAnnotationVisible(int visible) { +void Editor::SetAnnotationVisible(AnnotationVisible visible) { if (vs.annotationVisible != visible) { - const bool changedFromOrToHidden = ((vs.annotationVisible != 0) != (visible != 0)); + const bool changedFromOrToHidden = ((vs.annotationVisible != AnnotationVisible::Hidden) != (visible != AnnotationVisible::Hidden)); vs.annotationVisible = visible; if (changedFromOrToHidden) { - const int dir = vs.annotationVisible ? 1 : -1; + const int dir = (vs.annotationVisible!= AnnotationVisible::Hidden) ? 1 : -1; for (Sci::Line line=0; lineLinesTotal(); line++) { const int annotationLines = pdoc->AnnotationLines(line); if (annotationLines > 0) { @@ -5310,7 +5338,7 @@ void Editor::SetAnnotationVisible(int visible) { } } -void Editor::SetEOLAnnotationVisible(int visible) { +void Editor::SetEOLAnnotationVisible(EOLAnnotationVisible visible) { if (vs.eolAnnotationVisible != visible) { vs.eolAnnotationVisible = visible; Redraw(); @@ -5325,8 +5353,8 @@ Sci::Line Editor::ExpandLine(Sci::Line line) { line++; while (line <= lineMaxSubord) { pcs->SetVisible(line, line, true); - const int level = pdoc->GetLevel(line); - if (level & SC_FOLDLEVELHEADERFLAG) { + const FoldLevel level = pdoc->GetFoldLevel(line); + if (LevelIsHeader(level)) { if (pcs->GetExpanded(line)) { line = ExpandLine(line); } else { @@ -5344,18 +5372,18 @@ void Editor::SetFoldExpanded(Sci::Line lineDoc, bool expanded) { } } -void Editor::FoldLine(Sci::Line line, int action) { +void Editor::FoldLine(Sci::Line line, FoldAction action) { if (line >= 0) { - if (action == SC_FOLDACTION_TOGGLE) { - if ((pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) == 0) { + if (action == FoldAction::Toggle) { + if (!LevelIsHeader(pdoc->GetFoldLevel(line))) { line = pdoc->GetFoldParent(line); if (line < 0) return; } - action = (pcs->GetExpanded(line)) ? SC_FOLDACTION_CONTRACT : SC_FOLDACTION_EXPAND; + action = (pcs->GetExpanded(line)) ? FoldAction::Contract : FoldAction::Expand; } - if (action == SC_FOLDACTION_CONTRACT) { + if (action == FoldAction::Contract) { const Sci::Line lineMaxSubord = pdoc->GetLastChild(line); if (lineMaxSubord > line) { pcs->SetExpanded(line, false); @@ -5383,24 +5411,24 @@ void Editor::FoldLine(Sci::Line line, int action) { } } -void Editor::FoldExpand(Sci::Line line, int action, int level) { - bool expanding = action == SC_FOLDACTION_EXPAND; - if (action == SC_FOLDACTION_TOGGLE) { +void Editor::FoldExpand(Sci::Line line, FoldAction action, FoldLevel level) { + bool expanding = action == FoldAction::Expand; + if (action == FoldAction::Toggle) { expanding = !pcs->GetExpanded(line); } // Ensure child lines lexed and fold information extracted before // flipping the state. - pdoc->GetLastChild(line, LevelNumber(level)); + pdoc->GetLastChild(line, LevelNumberPart(level)); SetFoldExpanded(line, expanding); if (expanding && (pcs->HiddenLines() == 0)) // Nothing to do return; - const Sci::Line lineMaxSubord = pdoc->GetLastChild(line, LevelNumber(level)); + const Sci::Line lineMaxSubord = pdoc->GetLastChild(line, LevelNumberPart(level)); line++; pcs->SetVisible(line, lineMaxSubord, expanding); while (line <= lineMaxSubord) { - const int levelLine = pdoc->GetLevel(line); - if (levelLine & SC_FOLDLEVELHEADERFLAG) { + const FoldLevel levelLine = pdoc->GetFoldLevel(line); + if (LevelIsHeader(levelLine)) { SetFoldExpanded(line, expanding); } line++; @@ -5411,7 +5439,7 @@ void Editor::FoldExpand(Sci::Line line, int action, int level) { Sci::Line Editor::ContractedFoldNext(Sci::Line lineStart) const { for (Sci::Line line = lineStart; lineLinesTotal();) { - if (!pcs->GetExpanded(line) && (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG)) + if (!pcs->GetExpanded(line) && LevelIsHeader(pdoc->GetFoldLevel(line))) return line; line = pcs->ContractedNext(line+1); if (line < 0) @@ -5437,9 +5465,9 @@ void Editor::EnsureLineVisible(Sci::Line lineDoc, bool enforcePolicy) { if (!pcs->GetVisible(lineDoc)) { // Back up to find a non-blank line Sci::Line lookLine = lineDoc; - int lookLineLevel = pdoc->GetLevel(lookLine); - while ((lookLine > 0) && (lookLineLevel & SC_FOLDLEVELWHITEFLAG)) { - lookLineLevel = pdoc->GetLevel(--lookLine); + FoldLevel lookLineLevel = pdoc->GetFoldLevel(lookLine); + while ((lookLine > 0) && LevelIsWhitespace(lookLineLevel)) { + lookLineLevel = pdoc->GetFoldLevel(--lookLine); } Sci::Line lineParent = pdoc->GetFoldParent(lookLine); if (lineParent < 0) { @@ -5459,20 +5487,20 @@ void Editor::EnsureLineVisible(Sci::Line lineDoc, bool enforcePolicy) { } if (enforcePolicy) { const Sci::Line lineDisplay = pcs->DisplayFromDoc(lineDoc); - if (visiblePolicy.policy & VISIBLE_SLOP) { - if ((topLine > lineDisplay) || ((visiblePolicy.policy & VISIBLE_STRICT) && (topLine + visiblePolicy.slop > lineDisplay))) { - SetTopLine(Sci::clamp(lineDisplay - visiblePolicy.slop, static_cast(0), MaxScrollPos())); + if (FlagSet(visiblePolicy.policy, VisiblePolicy::Slop)) { + if ((topLine > lineDisplay) || ((FlagSet(visiblePolicy.policy, VisiblePolicy::Strict)) && (topLine + visiblePolicy.slop > lineDisplay))) { + SetTopLine(std::clamp(lineDisplay - visiblePolicy.slop, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } else if ((lineDisplay > topLine + LinesOnScreen() - 1) || - ((visiblePolicy.policy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visiblePolicy.slop))) { - SetTopLine(Sci::clamp(lineDisplay - LinesOnScreen() + 1 + visiblePolicy.slop, static_cast(0), MaxScrollPos())); + ((FlagSet(visiblePolicy.policy, VisiblePolicy::Strict)) && (lineDisplay > topLine + LinesOnScreen() - 1 - visiblePolicy.slop))) { + SetTopLine(std::clamp(lineDisplay - LinesOnScreen() + 1 + visiblePolicy.slop, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } } else { - if ((topLine > lineDisplay) || (lineDisplay > topLine + LinesOnScreen() - 1) || (visiblePolicy.policy & VISIBLE_STRICT)) { - SetTopLine(Sci::clamp(lineDisplay - LinesOnScreen() / 2 + 1, static_cast(0), MaxScrollPos())); + if ((topLine > lineDisplay) || (lineDisplay > topLine + LinesOnScreen() - 1) || (FlagSet(visiblePolicy.policy, VisiblePolicy::Strict))) { + SetTopLine(std::clamp(lineDisplay - LinesOnScreen() / 2 + 1, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } @@ -5480,14 +5508,14 @@ void Editor::EnsureLineVisible(Sci::Line lineDoc, bool enforcePolicy) { } } -void Editor::FoldAll(int action) { +void Editor::FoldAll(FoldAction action) { pdoc->EnsureStyledTo(pdoc->Length()); const Sci::Line maxLine = pdoc->LinesTotal(); - bool expanding = action == SC_FOLDACTION_EXPAND; - if (action == SC_FOLDACTION_TOGGLE) { + bool expanding = action == FoldAction::Expand; + if (action == FoldAction::Toggle) { // Discover current state for (int lineSeek = 0; lineSeek < maxLine; lineSeek++) { - if (pdoc->GetLevel(lineSeek) & SC_FOLDLEVELHEADERFLAG) { + if (LevelIsHeader(pdoc->GetFoldLevel(lineSeek))) { expanding = !pcs->GetExpanded(lineSeek); break; } @@ -5496,18 +5524,18 @@ void Editor::FoldAll(int action) { if (expanding) { pcs->SetVisible(0, maxLine-1, true); for (int line = 0; line < maxLine; line++) { - const int levelLine = pdoc->GetLevel(line); - if (levelLine & SC_FOLDLEVELHEADERFLAG) { + const FoldLevel levelLine = pdoc->GetFoldLevel(line); + if (LevelIsHeader(levelLine)) { SetFoldExpanded(line, true); } } } else { for (Sci::Line line = 0; line < maxLine; line++) { - const int level = pdoc->GetLevel(line); - if ((level & SC_FOLDLEVELHEADERFLAG) && - (SC_FOLDLEVELBASE == LevelNumber(level))) { + const FoldLevel level = pdoc->GetFoldLevel(line); + if (LevelIsHeader(level) && + (FoldLevel::Base == LevelNumberPart(level))) { SetFoldExpanded(line, false); - const Sci::Line lineMaxSubord = pdoc->GetLastChild(line, -1); + const Sci::Line lineMaxSubord = pdoc->GetLastChild(line); if (lineMaxSubord > line) { pcs->SetVisible(line + 1, lineMaxSubord, false); } @@ -5518,22 +5546,22 @@ void Editor::FoldAll(int action) { Redraw(); } -void Editor::FoldChanged(Sci::Line line, int levelNow, int levelPrev) { - if (levelNow & SC_FOLDLEVELHEADERFLAG) { - if (!(levelPrev & SC_FOLDLEVELHEADERFLAG)) { +void Editor::FoldChanged(Sci::Line line, FoldLevel levelNow, FoldLevel levelPrev) { + if (LevelIsHeader(levelNow)) { + if (!LevelIsHeader(levelPrev)) { // Adding a fold point. if (pcs->SetExpanded(line, true)) { RedrawSelMargin(); } - FoldExpand(line, SC_FOLDACTION_EXPAND, levelPrev); + FoldExpand(line, FoldAction::Expand, levelPrev); } - } else if (levelPrev & SC_FOLDLEVELHEADERFLAG) { + } else if (LevelIsHeader(levelPrev)) { const Sci::Line prevLine = line - 1; - const int prevLineLevel = pdoc->GetLevel(prevLine); + const FoldLevel prevLineLevel = pdoc->GetFoldLevel(prevLine); // Combining two blocks where the first block is collapsed (e.g. by deleting the line(s) which separate(s) the two blocks) if ((LevelNumber(prevLineLevel) == LevelNumber(levelNow)) && !pcs->GetVisible(prevLine)) - FoldLine(pdoc->GetFoldParent(prevLine), SC_FOLDACTION_EXPAND); + FoldLine(pdoc->GetFoldParent(prevLine), FoldAction::Expand); if (!pcs->GetExpanded(line)) { // Removing the fold from one that has been contracted so should expand @@ -5542,10 +5570,10 @@ void Editor::FoldChanged(Sci::Line line, int levelNow, int levelPrev) { RedrawSelMargin(); } // Combining two blocks where the second one is collapsed (e.g. by adding characters in the line which separates the two blocks) - FoldExpand(line, SC_FOLDACTION_EXPAND, levelPrev); + FoldExpand(line, FoldAction::Expand, levelPrev); } } - if (!(levelNow & SC_FOLDLEVELWHITEFLAG) && + if (!LevelIsWhitespace(levelNow) && (LevelNumber(levelPrev) > LevelNumber(levelNow))) { if (pcs->HiddenLines()) { // See if should still be hidden @@ -5559,17 +5587,17 @@ void Editor::FoldChanged(Sci::Line line, int levelNow, int levelPrev) { } // Combining two blocks where the first one is collapsed (e.g. by adding characters in the line which separates the two blocks) - if (!(levelNow & SC_FOLDLEVELWHITEFLAG) && (LevelNumber(levelPrev) < LevelNumber(levelNow))) { + if (!LevelIsWhitespace(levelNow) && (LevelNumber(levelPrev) < LevelNumber(levelNow))) { if (pcs->HiddenLines()) { const Sci::Line parentLine = pdoc->GetFoldParent(line); if (!pcs->GetExpanded(parentLine) && pcs->GetVisible(line)) - FoldLine(parentLine, SC_FOLDACTION_EXPAND); + FoldLine(parentLine, FoldAction::Expand); } } } void Editor::NeedShown(Sci::Position pos, Sci::Position len) { - if (foldAutomatic & SC_AUTOMATICFOLD_SHOW) { + if (FlagSet(foldAutomatic, AutomaticFold::Show)) { const Sci::Line lineStart = pdoc->SciLineFromPosition(pos); const Sci::Line lineEnd = pdoc->SciLineFromPosition(pos+len); for (Sci::Line line = lineStart; line <= lineEnd; line++) { @@ -5626,7 +5654,7 @@ Sci::Position Editor::ReplaceTarget(bool replacePatterns, const char *text, Sci: } bool Editor::IsUnicodeMode() const noexcept { - return pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage); + return pdoc && (CpUtf8 == pdoc->dbcsCodePage); } int Editor::CodePage() const noexcept { @@ -5638,10 +5666,10 @@ int Editor::CodePage() const noexcept { Sci::Line Editor::WrapCount(Sci::Line line) { AutoSurface surface(this); - AutoLineLayout ll(view.llc, view.RetrieveLineLayout(line, *this)); + std::shared_ptr ll = view.RetrieveLineLayout(line, *this); if (surface && ll) { - view.LayoutLine(*this, line, surface, vs, ll, wrapWidth); + view.LayoutLine(*this, surface, vs, ll.get(), wrapWidth); return ll->lines; } else { return 1; @@ -5660,7 +5688,7 @@ void Editor::AddStyledText(const char *buffer, Sci::Position appendLength) { for (i = 0; i < textLength; i++) { text[i] = buffer[i*2+1]; } - pdoc->StartStyling(CurrentPosition(), static_cast(0xff)); + pdoc->StartStyling(CurrentPosition()); pdoc->SetStyles(textLength, text.c_str()); SetEmptySelection(sel.MainCaret() + lengthInserted); } @@ -5669,132 +5697,140 @@ bool Editor::ValidMargin(uptr_t wParam) const noexcept { return wParam < vs.ms.size(); } -void Editor::StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { +void Editor::StyleSetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) { vs.EnsureStyle(wParam); switch (iMessage) { - case SCI_STYLESETFORE: - vs.styles[wParam].fore = ColourDesired(static_cast(lParam)); + case Message::StyleSetFore: + vs.styles[wParam].fore = ColourRGBA::FromIpRGB(lParam); break; - case SCI_STYLESETBACK: - vs.styles[wParam].back = ColourDesired(static_cast(lParam)); + case Message::StyleSetBack: + vs.styles[wParam].back = ColourRGBA::FromIpRGB(lParam); break; - case SCI_STYLESETBOLD: - vs.styles[wParam].weight = lParam != 0 ? SC_WEIGHT_BOLD : SC_WEIGHT_NORMAL; + case Message::StyleSetBold: + vs.styles[wParam].weight = lParam != 0 ? FontWeight::Bold : FontWeight::Normal; break; - case SCI_STYLESETWEIGHT: - vs.styles[wParam].weight = static_cast(lParam); + case Message::StyleSetWeight: + vs.styles[wParam].weight = static_cast(lParam); break; - case SCI_STYLESETITALIC: + case Message::StyleSetItalic: vs.styles[wParam].italic = lParam != 0; break; - case SCI_STYLESETEOLFILLED: + case Message::StyleSetEOLFilled: vs.styles[wParam].eolFilled = lParam != 0; break; - case SCI_STYLESETSIZE: - vs.styles[wParam].size = static_cast(lParam * SC_FONT_SIZE_MULTIPLIER); + case Message::StyleSetSize: + vs.styles[wParam].size = static_cast(lParam * FontSizeMultiplier); break; - case SCI_STYLESETSIZEFRACTIONAL: + case Message::StyleSetSizeFractional: vs.styles[wParam].size = static_cast(lParam); break; - case SCI_STYLESETFONT: + case Message::StyleSetFont: if (lParam != 0) { vs.SetStyleFontName(static_cast(wParam), CharPtrFromSPtr(lParam)); } break; - case SCI_STYLESETUNDERLINE: + case Message::StyleSetUnderline: vs.styles[wParam].underline = lParam != 0; break; - case SCI_STYLESETCASE: - vs.styles[wParam].caseForce = static_cast(lParam); + case Message::StyleSetCase: + vs.styles[wParam].caseForce = static_cast(lParam); break; - case SCI_STYLESETCHARACTERSET: - vs.styles[wParam].characterSet = static_cast(lParam); + case Message::StyleSetCharacterSet: + vs.styles[wParam].characterSet = static_cast(lParam); pdoc->SetCaseFolder(nullptr); break; - case SCI_STYLESETVISIBLE: + case Message::StyleSetVisible: vs.styles[wParam].visible = lParam != 0; break; - case SCI_STYLESETCHANGEABLE: + case Message::StyleSetChangeable: vs.styles[wParam].changeable = lParam != 0; break; - case SCI_STYLESETHOTSPOT: + case Message::StyleSetHotSpot: vs.styles[wParam].hotspot = lParam != 0; break; + default: + break; } InvalidateStyleRedraw(); } -sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { +sptr_t Editor::StyleGetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) { vs.EnsureStyle(wParam); switch (iMessage) { - case SCI_STYLEGETFORE: - return vs.styles[wParam].fore.AsInteger(); - case SCI_STYLEGETBACK: - return vs.styles[wParam].back.AsInteger(); - case SCI_STYLEGETBOLD: - return vs.styles[wParam].weight > SC_WEIGHT_NORMAL; - case SCI_STYLEGETWEIGHT: - return vs.styles[wParam].weight; - case SCI_STYLEGETITALIC: + case Message::StyleGetFore: + return vs.styles[wParam].fore.OpaqueRGB(); + case Message::StyleGetBack: + return vs.styles[wParam].back.OpaqueRGB(); + case Message::StyleGetBold: + return vs.styles[wParam].weight > FontWeight::Normal; + case Message::StyleGetWeight: + return static_cast(vs.styles[wParam].weight); + case Message::StyleGetItalic: return vs.styles[wParam].italic ? 1 : 0; - case SCI_STYLEGETEOLFILLED: + case Message::StyleGetEOLFilled: return vs.styles[wParam].eolFilled ? 1 : 0; - case SCI_STYLEGETSIZE: - return vs.styles[wParam].size / SC_FONT_SIZE_MULTIPLIER; - case SCI_STYLEGETSIZEFRACTIONAL: + case Message::StyleGetSize: + return vs.styles[wParam].size / FontSizeMultiplier; + case Message::StyleGetSizeFractional: return vs.styles[wParam].size; - case SCI_STYLEGETFONT: + case Message::StyleGetFont: return StringResult(lParam, vs.styles[wParam].fontName); - case SCI_STYLEGETUNDERLINE: + case Message::StyleGetUnderline: return vs.styles[wParam].underline ? 1 : 0; - case SCI_STYLEGETCASE: + case Message::StyleGetCase: return static_cast(vs.styles[wParam].caseForce); - case SCI_STYLEGETCHARACTERSET: - return vs.styles[wParam].characterSet; - case SCI_STYLEGETVISIBLE: + case Message::StyleGetCharacterSet: + return static_cast(vs.styles[wParam].characterSet); + case Message::StyleGetVisible: return vs.styles[wParam].visible ? 1 : 0; - case SCI_STYLEGETCHANGEABLE: + case Message::StyleGetChangeable: return vs.styles[wParam].changeable ? 1 : 0; - case SCI_STYLEGETHOTSPOT: + case Message::StyleGetHotSpot: return vs.styles[wParam].hotspot ? 1 : 0; + default: + break; } return 0; } -void Editor::SetSelectionNMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { +void Editor::SetSelectionNMessage(Message iMessage, uptr_t wParam, sptr_t lParam) { if (wParam >= sel.Count()) { return; } InvalidateRange(sel.Range(wParam).Start().Position(), sel.Range(wParam).End().Position()); switch (iMessage) { - case SCI_SETSELECTIONNCARET: + case Message::SetSelectionNCaret: sel.Range(wParam).caret.SetPosition(lParam); break; - case SCI_SETSELECTIONNANCHOR: + case Message::SetSelectionNAnchor: sel.Range(wParam).anchor.SetPosition(lParam); break; - case SCI_SETSELECTIONNCARETVIRTUALSPACE: + case Message::SetSelectionNCaretVirtualSpace: sel.Range(wParam).caret.SetVirtualSpace(lParam); break; - case SCI_SETSELECTIONNANCHORVIRTUALSPACE: + case Message::SetSelectionNAnchorVirtualSpace: sel.Range(wParam).anchor.SetVirtualSpace(lParam); break; - case SCI_SETSELECTIONNSTART: + case Message::SetSelectionNStart: sel.Range(wParam).anchor.SetPosition(lParam); break; - case SCI_SETSELECTIONNEND: + case Message::SetSelectionNEnd: sel.Range(wParam).caret.SetPosition(lParam); break; + + default: + break; + } InvalidateRange(sel.Range(wParam).Start().Position(), sel.Range(wParam).End().Position()); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + ContainerNeedsUpdate(Update::Selection); } sptr_t Editor::StringResult(sptr_t lParam, const char *val) noexcept { @@ -5821,7 +5857,7 @@ sptr_t Editor::BytesResult(sptr_t lParam, const unsigned char *val, size_t len) return val ? len : 0; } -sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { +sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { //Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam); // Optional macro recording hook @@ -5830,7 +5866,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { switch (iMessage) { - case SCI_GETTEXT: { + case Message::GetText: { if (lParam == 0) return pdoc->Length() + 1; if (wParam == 0) @@ -5842,7 +5878,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return len; } - case SCI_SETTEXT: { + case Message::SetText: { if (lParam == 0) return 0; UndoGroup ug(pdoc); @@ -5853,80 +5889,89 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return 1; } - case SCI_GETTEXTLENGTH: + case Message::GetTextLength: return pdoc->Length(); - case SCI_CUT: + case Message::Cut: Cut(); SetLastXChosen(); break; - case SCI_COPY: + case Message::Copy: Copy(); break; - case SCI_COPYALLOWLINE: + case Message::CopyAllowLine: CopyAllowLine(); break; - case SCI_VERTICALCENTRECARET: + case Message::VerticalCentreCaret: VerticalCentreCaret(); break; - case SCI_MOVESELECTEDLINESUP: + case Message::MoveSelectedLinesUp: MoveSelectedLinesUp(); break; - case SCI_MOVESELECTEDLINESDOWN: + case Message::MoveSelectedLinesDown: MoveSelectedLinesDown(); break; - case SCI_COPYRANGE: - CopyRangeToClipboard(static_cast(wParam), lParam); + case Message::CopyRange: + CopyRangeToClipboard(PositionFromUPtr(wParam), lParam); break; - case SCI_COPYTEXT: + case Message::CopyText: CopyText(wParam, CharPtrFromSPtr(lParam)); break; - case SCI_PASTE: + case Message::Paste: Paste(); - if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { + if ((caretSticky == CaretSticky::Off) || (caretSticky == CaretSticky::WhiteSpace)) { SetLastXChosen(); } EnsureCaretVisible(); break; - case SCI_CLEAR: + case Message::ReplaceRectangular: { + UndoGroup ug(pdoc); + if (!sel.Empty()) { + ClearSelection(); // want to replace rectangular selection contents + } + InsertPasteShape(CharPtrFromSPtr(lParam), PositionFromUPtr(wParam), PasteShape::rectangular); + break; + } + + case Message::Clear: Clear(); SetLastXChosen(); EnsureCaretVisible(); break; - case SCI_UNDO: + case Message::Undo: Undo(); SetLastXChosen(); break; - case SCI_CANUNDO: + case Message::CanUndo: return (pdoc->CanUndo() && !pdoc->IsReadOnly()) ? 1 : 0; - case SCI_EMPTYUNDOBUFFER: + case Message::EmptyUndoBuffer: pdoc->DeleteUndoHistory(); return 0; - case SCI_GETFIRSTVISIBLELINE: + case Message::GetFirstVisibleLine: return topLine; - case SCI_SETFIRSTVISIBLELINE: - ScrollTo(static_cast(wParam)); + case Message::SetFirstVisibleLine: + ScrollTo(LineFromUPtr(wParam)); break; - case SCI_GETLINE: { // Risk of overwriting the end of the buffer + case Message::GetLine: { // Risk of overwriting the end of the buffer const Sci::Position lineStart = - pdoc->LineStart(static_cast(wParam)); + pdoc->LineStart(LineFromUPtr(wParam)); const Sci::Position lineEnd = - pdoc->LineStart(static_cast(wParam + 1)); + pdoc->LineStart(LineFromUPtr(wParam + 1)); // not NUL terminated const Sci::Position len = lineEnd - lineStart; if (lParam == 0) { @@ -5937,17 +5982,21 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return len; } - case SCI_GETLINECOUNT: + case Message::GetLineCount: if (pdoc->LinesTotal() == 0) return 1; else return pdoc->LinesTotal(); - case SCI_GETMODIFY: + case Message::AllocateLines: + pdoc->AllocateLines(wParam); + break; + + case Message::GetModify: return !pdoc->IsSavePoint(); - case SCI_SETSEL: { - Sci::Position nStart = static_cast(wParam); + case Message::SetSel: { + Sci::Position nStart = PositionFromUPtr(wParam); Sci::Position nEnd = lParam; if (nEnd < 0) nEnd = pdoc->Length(); @@ -5955,13 +6004,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { nStart = nEnd; // Remove selection InvalidateSelection(SelectionRange(nStart, nEnd)); sel.Clear(); - sel.selType = Selection::selStream; + sel.selType = Selection::SelTypes::stream; SetSelection(nEnd, nStart); EnsureCaretVisible(); } break; - case SCI_GETSELTEXT: { + case Message::GetSelText: { SelectionText selectedText; CopySelectionRange(&selectedText); if (lParam == 0) { @@ -5979,30 +6028,30 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } } - case SCI_LINEFROMPOSITION: - if (static_cast(wParam) < 0) + case Message::LineFromPosition: + if (PositionFromUPtr(wParam) < 0) return 0; - return pdoc->LineFromPosition(static_cast(wParam)); + return pdoc->LineFromPosition(PositionFromUPtr(wParam)); - case SCI_POSITIONFROMLINE: - if (static_cast(wParam) < 0) + case Message::PositionFromLine: + if (LineFromUPtr(wParam) < 0) wParam = pdoc->LineFromPosition(SelectionStart().Position()); if (wParam == 0) return 0; // Even if there is no text, there is a first line that starts at 0 - if (static_cast(wParam) > pdoc->LinesTotal()) + if (LineFromUPtr(wParam) > pdoc->LinesTotal()) return -1; //if (wParam > pdoc->LineFromPosition(pdoc->Length())) // Useful test, anyway... // return -1; - return pdoc->LineStart(static_cast(wParam)); + return pdoc->LineStart(LineFromUPtr(wParam)); // Replacement of the old Scintilla interpretation of EM_LINELENGTH - case SCI_LINELENGTH: - if ((static_cast(wParam) < 0) || - (static_cast(wParam) > pdoc->LineFromPosition(pdoc->Length()))) + case Message::LineLength: + if ((LineFromUPtr(wParam) < 0) || + (LineFromUPtr(wParam) > pdoc->LineFromPosition(pdoc->Length()))) return 0; - return pdoc->LineStart(static_cast(wParam) + 1) - pdoc->LineStart(static_cast(wParam)); + return pdoc->LineStart(LineFromUPtr(wParam) + 1) - pdoc->LineStart(LineFromUPtr(wParam)); - case SCI_REPLACESEL: { + case Message::ReplaceSel: { if (lParam == 0) return 0; UndoGroup ug(pdoc); @@ -6016,126 +6065,126 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } break; - case SCI_SETTARGETSTART: - targetRange.start.SetPosition(static_cast(wParam)); + case Message::SetTargetStart: + targetRange.start.SetPosition(PositionFromUPtr(wParam)); break; - case SCI_GETTARGETSTART: + case Message::GetTargetStart: return targetRange.start.Position(); - case SCI_SETTARGETSTARTVIRTUALSPACE: - targetRange.start.SetVirtualSpace(static_cast(wParam)); + case Message::SetTargetStartVirtualSpace: + targetRange.start.SetVirtualSpace(PositionFromUPtr(wParam)); break; - case SCI_GETTARGETSTARTVIRTUALSPACE: + case Message::GetTargetStartVirtualSpace: return targetRange.start.VirtualSpace(); - case SCI_SETTARGETEND: - targetRange.end.SetPosition(static_cast(wParam)); + case Message::SetTargetEnd: + targetRange.end.SetPosition(PositionFromUPtr(wParam)); break; - case SCI_GETTARGETEND: + case Message::GetTargetEnd: return targetRange.end.Position(); - case SCI_SETTARGETENDVIRTUALSPACE: - targetRange.end.SetVirtualSpace(static_cast(wParam)); + case Message::SetTargetEndVirtualSpace: + targetRange.end.SetVirtualSpace(PositionFromUPtr(wParam)); break; - case SCI_GETTARGETENDVIRTUALSPACE: + case Message::GetTargetEndVirtualSpace: return targetRange.end.VirtualSpace(); - case SCI_SETTARGETRANGE: - targetRange.start.SetPosition(static_cast(wParam)); + case Message::SetTargetRange: + targetRange.start.SetPosition(PositionFromUPtr(wParam)); targetRange.end.SetPosition(lParam); break; - case SCI_TARGETWHOLEDOCUMENT: + case Message::TargetWholeDocument: targetRange.start.SetPosition(0); targetRange.end.SetPosition(pdoc->Length()); break; - case SCI_TARGETFROMSELECTION: + case Message::TargetFromSelection: targetRange.start = sel.RangeMain().Start(); targetRange.end = sel.RangeMain().End(); break; - case SCI_GETTARGETTEXT: { + case Message::GetTargetText: { std::string text = RangeText(targetRange.start.Position(), targetRange.end.Position()); return BytesResult(lParam, reinterpret_cast(text.c_str()), text.length()); } - case SCI_REPLACETARGET: + case Message::ReplaceTarget: PLATFORM_ASSERT(lParam); - return ReplaceTarget(false, CharPtrFromSPtr(lParam), static_cast(wParam)); + return ReplaceTarget(false, CharPtrFromSPtr(lParam), PositionFromUPtr(wParam)); - case SCI_REPLACETARGETRE: + case Message::ReplaceTargetRE: PLATFORM_ASSERT(lParam); - return ReplaceTarget(true, CharPtrFromSPtr(lParam), static_cast(wParam)); + return ReplaceTarget(true, CharPtrFromSPtr(lParam), PositionFromUPtr(wParam)); - case SCI_SEARCHINTARGET: + case Message::SearchInTarget: PLATFORM_ASSERT(lParam); - return SearchInTarget(CharPtrFromSPtr(lParam), static_cast(wParam)); + return SearchInTarget(CharPtrFromSPtr(lParam), PositionFromUPtr(wParam)); - case SCI_SETSEARCHFLAGS: - searchFlags = static_cast(wParam); + case Message::SetSearchFlags: + searchFlags = static_cast(wParam); break; - case SCI_GETSEARCHFLAGS: - return searchFlags; + case Message::GetSearchFlags: + return static_cast(searchFlags); - case SCI_GETTAG: + case Message::GetTag: return GetTag(CharPtrFromSPtr(lParam), static_cast(wParam)); - case SCI_POSITIONBEFORE: - return pdoc->MovePositionOutsideChar(static_cast(wParam) - 1, -1, true); + case Message::PositionBefore: + return pdoc->MovePositionOutsideChar(PositionFromUPtr(wParam) - 1, -1, true); - case SCI_POSITIONAFTER: - return pdoc->MovePositionOutsideChar(static_cast(wParam) + 1, 1, true); + case Message::PositionAfter: + return pdoc->MovePositionOutsideChar(PositionFromUPtr(wParam) + 1, 1, true); - case SCI_POSITIONRELATIVE: - return Sci::clamp(pdoc->GetRelativePosition( - static_cast(wParam), lParam), - static_cast(0), pdoc->Length()); + case Message::PositionRelative: + return std::clamp(pdoc->GetRelativePosition( + PositionFromUPtr(wParam), lParam), + 0, pdoc->Length()); - case SCI_POSITIONRELATIVECODEUNITS: - return Sci::clamp(pdoc->GetRelativePositionUTF16( - static_cast(wParam), lParam), - static_cast(0), pdoc->Length()); + case Message::PositionRelativeCodeUnits: + return std::clamp(pdoc->GetRelativePositionUTF16( + PositionFromUPtr(wParam), lParam), + 0, pdoc->Length()); - case SCI_LINESCROLL: - ScrollTo(topLine + static_cast(lParam)); + case Message::LineScroll: + ScrollTo(topLine + lParam); HorizontalScrollTo(xOffset + static_cast(wParam) * static_cast(vs.spaceWidth)); return 1; - case SCI_SETXOFFSET: + case Message::SetXOffset: xOffset = static_cast(wParam); - ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); + ContainerNeedsUpdate(Update::HScroll); SetHorizontalScrollPos(); Redraw(); break; - case SCI_GETXOFFSET: + case Message::GetXOffset: return xOffset; - case SCI_CHOOSECARETX: + case Message::ChooseCaretX: SetLastXChosen(); break; - case SCI_SCROLLCARET: + case Message::ScrollCaret: EnsureCaretVisible(); break; - case SCI_SETREADONLY: + case Message::SetReadOnly: pdoc->SetReadOnly(wParam != 0); return 1; - case SCI_GETREADONLY: + case Message::GetReadOnly: return pdoc->IsReadOnly(); - case SCI_CANPASTE: + case Message::CanPaste: return CanPaste(); - case SCI_POINTXFROMPOSITION: + case Message::PointXFromPosition: if (lParam < 0) { return 0; } else { @@ -6144,7 +6193,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return static_cast(pt.x) - vs.textStart + vs.fixedColumnWidth; } - case SCI_POINTYFROMPOSITION: + case Message::PointYFromPosition: if (lParam < 0) { return 0; } else { @@ -6152,13 +6201,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return static_cast(pt.y); } - case SCI_FINDTEXT: + case Message::FindText: return FindText(wParam, lParam); - case SCI_GETTEXTRANGE: { + case Message::GetTextRange: { if (lParam == 0) return 0; - Sci_TextRange *tr = static_cast(PtrFromSPtr(lParam)); + TextRange *tr = static_cast(PtrFromSPtr(lParam)); Sci::Position cpMax = static_cast(tr->chrg.cpMax); if (cpMax == -1) cpMax = pdoc->Length(); @@ -6170,51 +6219,51 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return len; // Not including NUL } - case SCI_HIDESELECTION: + case Message::HideSelection: view.hideSelection = wParam != 0; Redraw(); break; - case SCI_FORMATRANGE: - return FormatRange(wParam != 0, static_cast(PtrFromSPtr(lParam))); + case Message::FormatRange: + return FormatRange(wParam != 0, static_cast(PtrFromSPtr(lParam))); - case SCI_GETMARGINLEFT: + case Message::GetMarginLeft: return vs.leftMarginWidth; - case SCI_GETMARGINRIGHT: + case Message::GetMarginRight: return vs.rightMarginWidth; - case SCI_SETMARGINLEFT: + case Message::SetMarginLeft: lastXChosen += static_cast(lParam) - vs.leftMarginWidth; vs.leftMarginWidth = static_cast(lParam); InvalidateStyleRedraw(); break; - case SCI_SETMARGINRIGHT: + case Message::SetMarginRight: vs.rightMarginWidth = static_cast(lParam); InvalidateStyleRedraw(); break; // Control specific messages - case SCI_ADDTEXT: { + case Message::AddText: { if (lParam == 0) return 0; const Sci::Position lengthInserted = pdoc->InsertString( - CurrentPosition(), CharPtrFromSPtr(lParam), static_cast(wParam)); + CurrentPosition(), CharPtrFromSPtr(lParam), PositionFromUPtr(wParam)); SetEmptySelection(sel.MainCaret() + lengthInserted); return 0; } - case SCI_ADDSTYLEDTEXT: + case Message::AddStyledText: if (lParam) - AddStyledText(CharPtrFromSPtr(lParam), static_cast(wParam)); + AddStyledText(CharPtrFromSPtr(lParam), PositionFromUPtr(wParam)); return 0; - case SCI_INSERTTEXT: { + case Message::InsertText: { if (lParam == 0) return 0; - Sci::Position insertPos = static_cast(wParam); + Sci::Position insertPos = PositionFromUPtr(wParam); if (insertPos == -1) insertPos = CurrentPosition(); Sci::Position newCurrent = CurrentPosition(); @@ -6226,189 +6275,189 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return 0; } - case SCI_CHANGEINSERTION: + case Message::ChangeInsertion: PLATFORM_ASSERT(lParam); - pdoc->ChangeInsertion(CharPtrFromSPtr(lParam), static_cast(wParam)); + pdoc->ChangeInsertion(CharPtrFromSPtr(lParam), PositionFromUPtr(wParam)); return 0; - case SCI_APPENDTEXT: + case Message::AppendText: pdoc->InsertString(pdoc->Length(), - CharPtrFromSPtr(lParam), static_cast(wParam)); + CharPtrFromSPtr(lParam), PositionFromUPtr(wParam)); return 0; - case SCI_CLEARALL: + case Message::ClearAll: ClearAll(); return 0; - case SCI_DELETERANGE: - pdoc->DeleteChars(static_cast(wParam), lParam); + case Message::DeleteRange: + pdoc->DeleteChars(PositionFromUPtr(wParam), lParam); return 0; - case SCI_CLEARDOCUMENTSTYLE: + case Message::ClearDocumentStyle: ClearDocumentStyle(); return 0; - case SCI_SETUNDOCOLLECTION: + case Message::SetUndoCollection: pdoc->SetUndoCollection(wParam != 0); return 0; - case SCI_GETUNDOCOLLECTION: + case Message::GetUndoCollection: return pdoc->IsCollectingUndo(); - case SCI_BEGINUNDOACTION: + case Message::BeginUndoAction: pdoc->BeginUndoAction(); return 0; - case SCI_ENDUNDOACTION: + case Message::EndUndoAction: pdoc->EndUndoAction(); return 0; - case SCI_GETCARETPERIOD: + case Message::GetCaretPeriod: return caret.period; - case SCI_SETCARETPERIOD: + case Message::SetCaretPeriod: CaretSetPeriod(static_cast(wParam)); break; - case SCI_GETWORDCHARS: - return pdoc->GetCharsOfClass(CharClassify::ccWord, UCharPtrFromSPtr(lParam)); + case Message::GetWordChars: + return pdoc->GetCharsOfClass(CharacterClass::word, UCharPtrFromSPtr(lParam)); - case SCI_SETWORDCHARS: { + case Message::SetWordChars: { pdoc->SetDefaultCharClasses(false); if (lParam == 0) return 0; - pdoc->SetCharClasses(ConstUCharPtrFromSPtr(lParam), CharClassify::ccWord); + pdoc->SetCharClasses(ConstUCharPtrFromSPtr(lParam), CharacterClass::word); } break; - case SCI_GETWHITESPACECHARS: - return pdoc->GetCharsOfClass(CharClassify::ccSpace, UCharPtrFromSPtr(lParam)); + case Message::GetWhitespaceChars: + return pdoc->GetCharsOfClass(CharacterClass::space, UCharPtrFromSPtr(lParam)); - case SCI_SETWHITESPACECHARS: { + case Message::SetWhitespaceChars: { if (lParam == 0) return 0; - pdoc->SetCharClasses(ConstUCharPtrFromSPtr(lParam), CharClassify::ccSpace); + pdoc->SetCharClasses(ConstUCharPtrFromSPtr(lParam), CharacterClass::space); } break; - case SCI_GETPUNCTUATIONCHARS: - return pdoc->GetCharsOfClass(CharClassify::ccPunctuation, UCharPtrFromSPtr(lParam)); + case Message::GetPunctuationChars: + return pdoc->GetCharsOfClass(CharacterClass::punctuation, UCharPtrFromSPtr(lParam)); - case SCI_SETPUNCTUATIONCHARS: { + case Message::SetPunctuationChars: { if (lParam == 0) return 0; - pdoc->SetCharClasses(ConstUCharPtrFromSPtr(lParam), CharClassify::ccPunctuation); + pdoc->SetCharClasses(ConstUCharPtrFromSPtr(lParam), CharacterClass::punctuation); } break; - case SCI_SETCHARSDEFAULT: + case Message::SetCharsDefault: pdoc->SetDefaultCharClasses(true); break; - case SCI_SETCHARACTERCATEGORYOPTIMIZATION: + case Message::SetCharacterCategoryOptimization: pdoc->SetCharacterCategoryOptimization(static_cast(wParam)); break; - case SCI_GETCHARACTERCATEGORYOPTIMIZATION: + case Message::GetCharacterCategoryOptimization: return pdoc->CharacterCategoryOptimization(); - case SCI_GETLENGTH: + case Message::GetLength: return pdoc->Length(); - case SCI_ALLOCATE: - pdoc->Allocate(static_cast(wParam)); + case Message::Allocate: + pdoc->Allocate(PositionFromUPtr(wParam)); break; - case SCI_GETCHARAT: - return pdoc->CharAt(static_cast(wParam)); + case Message::GetCharAt: + return pdoc->CharAt(PositionFromUPtr(wParam)); - case SCI_SETCURRENTPOS: + case Message::SetCurrentPos: if (sel.IsRectangular()) { - sel.Rectangular().caret.SetPosition(static_cast(wParam)); + sel.Rectangular().caret.SetPosition(PositionFromUPtr(wParam)); SetRectangularRange(); Redraw(); } else { - SetSelection(static_cast(wParam), sel.MainAnchor()); + SetSelection(PositionFromUPtr(wParam), sel.MainAnchor()); } break; - case SCI_GETCURRENTPOS: + case Message::GetCurrentPos: return sel.IsRectangular() ? sel.Rectangular().caret.Position() : sel.MainCaret(); - case SCI_SETANCHOR: + case Message::SetAnchor: if (sel.IsRectangular()) { - sel.Rectangular().anchor.SetPosition(static_cast(wParam)); + sel.Rectangular().anchor.SetPosition(PositionFromUPtr(wParam)); SetRectangularRange(); Redraw(); } else { - SetSelection(sel.MainCaret(), static_cast(wParam)); + SetSelection(sel.MainCaret(), PositionFromUPtr(wParam)); } break; - case SCI_GETANCHOR: + case Message::GetAnchor: return sel.IsRectangular() ? sel.Rectangular().anchor.Position() : sel.MainAnchor(); - case SCI_SETSELECTIONSTART: - SetSelection(std::max(sel.MainCaret(), static_cast(wParam)), static_cast(wParam)); + case Message::SetSelectionStart: + SetSelection(std::max(sel.MainCaret(), PositionFromUPtr(wParam)), PositionFromUPtr(wParam)); break; - case SCI_GETSELECTIONSTART: + case Message::GetSelectionStart: return sel.LimitsForRectangularElseMain().start.Position(); - case SCI_SETSELECTIONEND: - SetSelection(static_cast(wParam), std::min(sel.MainAnchor(), static_cast(wParam))); + case Message::SetSelectionEnd: + SetSelection(PositionFromUPtr(wParam), std::min(sel.MainAnchor(), PositionFromUPtr(wParam))); break; - case SCI_GETSELECTIONEND: + case Message::GetSelectionEnd: return sel.LimitsForRectangularElseMain().end.Position(); - case SCI_SETEMPTYSELECTION: - SetEmptySelection(static_cast(wParam)); + case Message::SetEmptySelection: + SetEmptySelection(PositionFromUPtr(wParam)); break; - case SCI_SETPRINTMAGNIFICATION: + case Message::SetPrintMagnification: view.printParameters.magnification = static_cast(wParam); break; - case SCI_GETPRINTMAGNIFICATION: + case Message::GetPrintMagnification: return view.printParameters.magnification; - case SCI_SETPRINTCOLOURMODE: - view.printParameters.colourMode = static_cast(wParam); + case Message::SetPrintColourMode: + view.printParameters.colourMode = static_cast(wParam); break; - case SCI_GETPRINTCOLOURMODE: - return view.printParameters.colourMode; + case Message::GetPrintColourMode: + return static_cast(view.printParameters.colourMode); - case SCI_SETPRINTWRAPMODE: - view.printParameters.wrapState = (wParam == SC_WRAP_WORD) ? WrapMode::word : WrapMode::none; + case Message::SetPrintWrapMode: + view.printParameters.wrapState = (static_cast(wParam) == Wrap::Word) ? Wrap::Word : Wrap::None; break; - case SCI_GETPRINTWRAPMODE: + case Message::GetPrintWrapMode: return static_cast(view.printParameters.wrapState); - case SCI_GETSTYLEAT: - if (static_cast(wParam) >= pdoc->Length()) + case Message::GetStyleAt: + if (PositionFromUPtr(wParam) >= pdoc->Length()) return 0; else - return pdoc->StyleAt(static_cast(wParam)); + return pdoc->StyleAt(PositionFromUPtr(wParam)); - case SCI_REDO: + case Message::Redo: Redo(); break; - case SCI_SELECTALL: + case Message::SelectAll: SelectAll(); break; - case SCI_SETSAVEPOINT: + case Message::SetSavePoint: pdoc->SetSavePoint(); break; - case SCI_GETSTYLEDTEXT: { + case Message::GetStyledText: { if (lParam == 0) return 0; - Sci_TextRange *tr = static_cast(PtrFromSPtr(lParam)); + TextRange *tr = static_cast(PtrFromSPtr(lParam)); Sci::Position iPlace = 0; for (Sci::Position iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) { tr->lpstrText[iPlace++] = pdoc->CharAt(iChar); @@ -6419,72 +6468,68 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return iPlace; } - case SCI_CANREDO: + case Message::CanRedo: return (pdoc->CanRedo() && !pdoc->IsReadOnly()) ? 1 : 0; - case SCI_MARKERLINEFROMHANDLE: + case Message::MarkerLineFromHandle: return pdoc->LineFromHandle(static_cast(wParam)); - case SCI_MARKERDELETEHANDLE: + case Message::MarkerDeleteHandle: pdoc->DeleteMarkFromHandle(static_cast(wParam)); break; - case SCI_MARKERHANDLEFROMLINE: - return pdoc->MarkerHandleFromLine(static_cast(wParam), static_cast(lParam)); + case Message::MarkerHandleFromLine: + return pdoc->MarkerHandleFromLine(LineFromUPtr(wParam), static_cast(lParam)); - case SCI_MARKERNUMBERFROMLINE: - return pdoc->MarkerNumberFromLine(static_cast(wParam), static_cast(lParam)); + case Message::MarkerNumberFromLine: + return pdoc->MarkerNumberFromLine(LineFromUPtr(wParam), static_cast(lParam)); - case SCI_GETVIEWWS: - return vs.viewWhitespace; + case Message::GetViewWS: + return static_cast(vs.viewWhitespace); - case SCI_SETVIEWWS: - vs.viewWhitespace = static_cast(wParam); + case Message::SetViewWS: + vs.viewWhitespace = static_cast(wParam); Redraw(); break; - case SCI_GETTABDRAWMODE: - return vs.tabDrawMode; + case Message::GetTabDrawMode: + return static_cast(vs.tabDrawMode); - case SCI_SETTABDRAWMODE: + case Message::SetTabDrawMode: vs.tabDrawMode = static_cast(wParam); Redraw(); break; - case SCI_GETWHITESPACESIZE: + case Message::GetWhitespaceSize: return vs.whitespaceSize; - case SCI_SETWHITESPACESIZE: + case Message::SetWhitespaceSize: vs.whitespaceSize = static_cast(wParam); Redraw(); break; - case SCI_POSITIONFROMPOINT: - return PositionFromLocation(Point::FromInts(static_cast(wParam) - vs.ExternalMarginWidth(), static_cast(lParam)), - false, false); + case Message::PositionFromPoint: + return PositionFromLocation(PointFromParameters(wParam, lParam), false, false); - case SCI_POSITIONFROMPOINTCLOSE: - return PositionFromLocation(Point::FromInts(static_cast(wParam) - vs.ExternalMarginWidth(), static_cast(lParam)), - true, false); + case Message::PositionFromPointClose: + return PositionFromLocation(PointFromParameters(wParam, lParam), true, false); - case SCI_CHARPOSITIONFROMPOINT: - return PositionFromLocation(Point::FromInts(static_cast(wParam) - vs.ExternalMarginWidth(), static_cast(lParam)), - false, true); + case Message::CharPositionFromPoint: + return PositionFromLocation(PointFromParameters(wParam, lParam), false, true); - case SCI_CHARPOSITIONFROMPOINTCLOSE: - return PositionFromLocation(Point::FromInts(static_cast(wParam) - vs.ExternalMarginWidth(), static_cast(lParam)), - true, true); + case Message::CharPositionFromPointClose: + return PositionFromLocation(PointFromParameters(wParam, lParam), true, true); - case SCI_GOTOLINE: - GoToLine(static_cast(wParam)); + case Message::GotoLine: + GoToLine(LineFromUPtr(wParam)); break; - case SCI_GOTOPOS: - SetEmptySelection(static_cast(wParam)); + case Message::GotoPos: + SetEmptySelection(PositionFromUPtr(wParam)); EnsureCaretVisible(); break; - case SCI_GETCURLINE: { + case Message::GetCurLine: { const Sci::Line lineCurrentPos = pdoc->SciLineFromPosition(sel.MainCaret()); const Sci::Position lineStart = pdoc->LineStart(lineCurrentPos); const Sci::Position lineEnd = pdoc->LineStart(lineCurrentPos + 1); @@ -6499,18 +6544,18 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return sel.MainCaret() - lineStart; } - case SCI_GETENDSTYLED: + case Message::GetEndStyled: return pdoc->GetEndStyled(); - case SCI_GETEOLMODE: - return pdoc->eolMode; + case Message::GetEOLMode: + return static_cast(pdoc->eolMode); - case SCI_SETEOLMODE: - pdoc->eolMode = static_cast(wParam); + case Message::SetEOLMode: + pdoc->eolMode = static_cast(wParam); break; - case SCI_SETLINEENDTYPESALLOWED: - if (pdoc->SetLineEndTypesAllowed(static_cast(wParam))) { + case Message::SetLineEndTypesAllowed: + if (pdoc->SetLineEndTypesAllowed(static_cast(wParam))) { pcs->Clear(); pcs->InsertLines(0, pdoc->LinesTotal() - 1); SetAnnotationHeights(0, pdoc->LinesTotal()); @@ -6518,36 +6563,37 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } break; - case SCI_GETLINEENDTYPESALLOWED: - return pdoc->GetLineEndTypesAllowed(); + case Message::GetLineEndTypesAllowed: + return static_cast(pdoc->GetLineEndTypesAllowed()); - case SCI_GETLINEENDTYPESACTIVE: - return pdoc->GetLineEndTypesActive(); + case Message::GetLineEndTypesActive: + return static_cast(pdoc->GetLineEndTypesActive()); - case SCI_STARTSTYLING: - pdoc->StartStyling(static_cast(wParam), static_cast(lParam)); + case Message::StartStyling: + pdoc->StartStyling(PositionFromUPtr(wParam)); break; - case SCI_SETSTYLING: - if (static_cast(wParam) < 0) - errorStatus = SC_STATUS_FAILURE; + case Message::SetStyling: + if (PositionFromUPtr(wParam) < 0) + errorStatus = Status::Failure; else - pdoc->SetStyleFor(static_cast(wParam), static_cast(lParam)); + pdoc->SetStyleFor(PositionFromUPtr(wParam), static_cast(lParam)); break; - case SCI_SETSTYLINGEX: // Specify a complete styling buffer + case Message::SetStylingEx: // Specify a complete styling buffer if (lParam == 0) return 0; - pdoc->SetStyles(static_cast(wParam), CharPtrFromSPtr(lParam)); + pdoc->SetStyles(PositionFromUPtr(wParam), CharPtrFromSPtr(lParam)); break; - case SCI_SETBUFFEREDDRAW: + case Message::SetBufferedDraw: view.bufferedDraw = wParam != 0; break; - case SCI_GETBUFFEREDDRAW: + case Message::GetBufferedDraw: return view.bufferedDraw; +#ifdef INCLUDE_DEPRECATED_FEATURES case SCI_GETTWOPHASEDRAW: return view.phasesDraw == EditView::phasesTwo; @@ -6555,25 +6601,27 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { if (view.SetTwoPhaseDraw(wParam != 0)) InvalidateStyleRedraw(); break; +#endif - case SCI_GETPHASESDRAW: - return view.phasesDraw; + case Message::GetPhasesDraw: + return static_cast(view.phasesDraw); - case SCI_SETPHASESDRAW: + case Message::SetPhasesDraw: if (view.SetPhasesDraw(static_cast(wParam))) InvalidateStyleRedraw(); break; - case SCI_SETFONTQUALITY: - vs.extraFontFlag &= ~SC_EFF_QUALITY_MASK; - vs.extraFontFlag |= (wParam & SC_EFF_QUALITY_MASK); + case Message::SetFontQuality: + vs.extraFontFlag = static_cast( + (static_cast(vs.extraFontFlag) & ~static_cast(FontQuality::QualityMask)) | + (wParam & static_cast(FontQuality::QualityMask))); InvalidateStyleRedraw(); break; - case SCI_GETFONTQUALITY: - return (vs.extraFontFlag & SC_EFF_QUALITY_MASK); + case Message::GetFontQuality: + return static_cast(vs.extraFontFlag) & static_cast(FontQuality::QualityMask); - case SCI_SETTABWIDTH: + case Message::SetTabWidth: if (wParam > 0) { pdoc->tabInChars = static_cast(wParam); if (pdoc->indentInChars == 0) @@ -6582,34 +6630,34 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { InvalidateStyleRedraw(); break; - case SCI_GETTABWIDTH: + case Message::GetTabWidth: return pdoc->tabInChars; - case SCI_SETTABMINIMUMWIDTH: + case Message::SetTabMinimumWidth: SetAppearance(view.tabWidthMinimumPixels, static_cast(wParam)); break; - case SCI_GETTABMINIMUMWIDTH: + case Message::GetTabMinimumWidth: return view.tabWidthMinimumPixels; - case SCI_CLEARTABSTOPS: - if (view.ClearTabstops(static_cast(wParam))) { - const DocModification mh(SC_MOD_CHANGETABSTOPS, 0, 0, 0, nullptr, static_cast(wParam)); + case Message::ClearTabStops: + if (view.ClearTabstops(LineFromUPtr(wParam))) { + const DocModification mh(ModificationFlags::ChangeTabStops, 0, 0, 0, nullptr, LineFromUPtr(wParam)); NotifyModified(pdoc, mh, nullptr); } break; - case SCI_ADDTABSTOP: - if (view.AddTabstop(static_cast(wParam), static_cast(lParam))) { - const DocModification mh(SC_MOD_CHANGETABSTOPS, 0, 0, 0, nullptr, static_cast(wParam)); + case Message::AddTabStop: + if (view.AddTabstop(LineFromUPtr(wParam), static_cast(lParam))) { + const DocModification mh(ModificationFlags::ChangeTabStops, 0, 0, 0, nullptr, LineFromUPtr(wParam)); NotifyModified(pdoc, mh, nullptr); } break; - case SCI_GETNEXTTABSTOP: - return view.GetNextTabstop(static_cast(wParam), static_cast(lParam)); + case Message::GetNextTabStop: + return view.GetNextTabstop(LineFromUPtr(wParam), static_cast(lParam)); - case SCI_SETINDENT: + case Message::SetIndent: pdoc->indentInChars = static_cast(wParam); if (pdoc->indentInChars != 0) pdoc->actualIndentInChars = pdoc->indentInChars; @@ -6618,131 +6666,133 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { InvalidateStyleRedraw(); break; - case SCI_GETINDENT: + case Message::GetIndent: return pdoc->indentInChars; - case SCI_SETUSETABS: + case Message::SetUseTabs: pdoc->useTabs = wParam != 0; InvalidateStyleRedraw(); break; - case SCI_GETUSETABS: + case Message::GetUseTabs: return pdoc->useTabs; - case SCI_SETLINEINDENTATION: - pdoc->SetLineIndentation(static_cast(wParam), lParam); + case Message::SetLineIndentation: + pdoc->SetLineIndentation(LineFromUPtr(wParam), lParam); break; - case SCI_GETLINEINDENTATION: - return pdoc->GetLineIndentation(static_cast(wParam)); + case Message::GetLineIndentation: + return pdoc->GetLineIndentation(LineFromUPtr(wParam)); - case SCI_GETLINEINDENTPOSITION: - return pdoc->GetLineIndentPosition(static_cast(wParam)); + case Message::GetLineIndentPosition: + return pdoc->GetLineIndentPosition(LineFromUPtr(wParam)); - case SCI_SETTABINDENTS: + case Message::SetTabIndents: pdoc->tabIndents = wParam != 0; break; - case SCI_GETTABINDENTS: + case Message::GetTabIndents: return pdoc->tabIndents; - case SCI_SETBACKSPACEUNINDENTS: + case Message::SetBackSpaceUnIndents: pdoc->backspaceUnindents = wParam != 0; break; - case SCI_GETBACKSPACEUNINDENTS: + case Message::GetBackSpaceUnIndents: return pdoc->backspaceUnindents; - case SCI_SETMOUSEDWELLTIME: + case Message::SetMouseDwellTime: dwellDelay = static_cast(wParam); ticksToDwell = dwellDelay; break; - case SCI_GETMOUSEDWELLTIME: + case Message::GetMouseDwellTime: return dwellDelay; - case SCI_WORDSTARTPOSITION: - return pdoc->ExtendWordSelect(static_cast(wParam), -1, lParam != 0); + case Message::WordStartPosition: + return pdoc->ExtendWordSelect(PositionFromUPtr(wParam), -1, lParam != 0); - case SCI_WORDENDPOSITION: - return pdoc->ExtendWordSelect(static_cast(wParam), 1, lParam != 0); + case Message::WordEndPosition: + return pdoc->ExtendWordSelect(PositionFromUPtr(wParam), 1, lParam != 0); - case SCI_ISRANGEWORD: - return pdoc->IsWordAt(static_cast(wParam), lParam); + case Message::IsRangeWord: + return pdoc->IsWordAt(PositionFromUPtr(wParam), lParam); - case SCI_SETIDLESTYLING: - idleStyling = static_cast(wParam); + case Message::SetIdleStyling: + idleStyling = static_cast(wParam); break; - case SCI_GETIDLESTYLING: - return idleStyling; + case Message::GetIdleStyling: + return static_cast(idleStyling); - case SCI_SETWRAPMODE: - if (vs.SetWrapState(static_cast(wParam))) { + case Message::SetWrapMode: + if (vs.SetWrapState(static_cast(wParam))) { xOffset = 0; - ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); + ContainerNeedsUpdate(Update::HScroll); InvalidateStyleRedraw(); ReconfigureScrollBars(); } break; - case SCI_GETWRAPMODE: - return static_cast(vs.wrapState); + case Message::GetWrapMode: + return static_cast(vs.wrap.state); - case SCI_SETWRAPVISUALFLAGS: - if (vs.SetWrapVisualFlags(static_cast(wParam))) { + case Message::SetWrapVisualFlags: + if (vs.SetWrapVisualFlags(static_cast(wParam))) { InvalidateStyleRedraw(); ReconfigureScrollBars(); } break; - case SCI_GETWRAPVISUALFLAGS: - return vs.wrapVisualFlags; + case Message::GetWrapVisualFlags: + return static_cast(vs.wrap.visualFlags); - case SCI_SETWRAPVISUALFLAGSLOCATION: - if (vs.SetWrapVisualFlagsLocation(static_cast(wParam))) { + case Message::SetWrapVisualFlagsLocation: + if (vs.SetWrapVisualFlagsLocation(static_cast(wParam))) { InvalidateStyleRedraw(); } break; - case SCI_GETWRAPVISUALFLAGSLOCATION: - return vs.wrapVisualFlagsLocation; + case Message::GetWrapVisualFlagsLocation: + return static_cast(vs.wrap.visualFlagsLocation); - case SCI_SETWRAPSTARTINDENT: + case Message::SetWrapStartIndent: if (vs.SetWrapVisualStartIndent(static_cast(wParam))) { InvalidateStyleRedraw(); ReconfigureScrollBars(); } break; - case SCI_GETWRAPSTARTINDENT: - return vs.wrapVisualStartIndent; + case Message::GetWrapStartIndent: + return vs.wrap.visualStartIndent; - case SCI_SETWRAPINDENTMODE: - if (vs.SetWrapIndentMode(static_cast(wParam))) { + case Message::SetWrapIndentMode: + if (vs.SetWrapIndentMode(static_cast(wParam))) { InvalidateStyleRedraw(); ReconfigureScrollBars(); } break; - case SCI_GETWRAPINDENTMODE: - return vs.wrapIndentMode; + case Message::GetWrapIndentMode: + return static_cast(vs.wrap.indentMode); - case SCI_SETLAYOUTCACHE: - view.llc.SetLevel(static_cast(wParam)); + case Message::SetLayoutCache: + if (static_cast(wParam) <= LineCache::Document) { + view.llc.SetLevel(static_cast(wParam)); + } break; - case SCI_GETLAYOUTCACHE: - return view.llc.GetLevel(); + case Message::GetLayoutCache: + return static_cast(view.llc.GetLevel()); - case SCI_SETPOSITIONCACHE: + case Message::SetPositionCache: view.posCache.SetSize(wParam); break; - case SCI_GETPOSITIONCACHE: + case Message::GetPositionCache: return view.posCache.GetSize(); - case SCI_SETSCROLLWIDTH: + case Message::SetScrollWidth: PLATFORM_ASSERT(wParam > 0); if ((wParam > 0) && (wParam != static_cast(scrollWidth))) { view.lineWidthMaxSeen = 0; @@ -6751,34 +6801,34 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } break; - case SCI_GETSCROLLWIDTH: + case Message::GetScrollWidth: return scrollWidth; - case SCI_SETSCROLLWIDTHTRACKING: + case Message::SetScrollWidthTracking: trackLineWidth = wParam != 0; break; - case SCI_GETSCROLLWIDTHTRACKING: + case Message::GetScrollWidthTracking: return trackLineWidth; - case SCI_LINESJOIN: + case Message::LinesJoin: LinesJoin(); break; - case SCI_LINESSPLIT: + case Message::LinesSplit: LinesSplit(static_cast(wParam)); break; - case SCI_TEXTWIDTH: + case Message::TextWidth: PLATFORM_ASSERT(wParam < vs.styles.size()); PLATFORM_ASSERT(lParam); - return TextWidth(static_cast(wParam), CharPtrFromSPtr(lParam)); + return TextWidth(wParam, CharPtrFromSPtr(lParam)); - case SCI_TEXTHEIGHT: + case Message::TextHeight: RefreshStyleData(); return vs.lineHeight; - case SCI_SETENDATLASTLINE: + case Message::SetEndAtLastLine: PLATFORM_ASSERT((wParam == 0) || (wParam == 1)); if (endAtLastLine != (wParam != 0)) { endAtLastLine = wParam != 0; @@ -6786,30 +6836,30 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } break; - case SCI_GETENDATLASTLINE: + case Message::GetEndAtLastLine: return endAtLastLine; - case SCI_SETCARETSTICKY: - PLATFORM_ASSERT(wParam <= SC_CARETSTICKY_WHITESPACE); - if (wParam <= SC_CARETSTICKY_WHITESPACE) { - caretSticky = static_cast(wParam); + case Message::SetCaretSticky: + PLATFORM_ASSERT(static_cast(wParam) <= CaretSticky::WhiteSpace); + if (static_cast(wParam) <= CaretSticky::WhiteSpace) { + caretSticky = static_cast(wParam); } break; - case SCI_GETCARETSTICKY: - return caretSticky; + case Message::GetCaretSticky: + return static_cast(caretSticky); - case SCI_TOGGLECARETSTICKY: - caretSticky = !caretSticky; + case Message::ToggleCaretSticky: + caretSticky = (caretSticky == CaretSticky::Off) ? CaretSticky::On : CaretSticky::Off; break; - case SCI_GETCOLUMN: - return pdoc->GetColumn(static_cast(wParam)); + case Message::GetColumn: + return pdoc->GetColumn(PositionFromUPtr(wParam)); - case SCI_FINDCOLUMN: - return pdoc->FindColumn(static_cast(wParam), lParam); + case Message::FindColumn: + return pdoc->FindColumn(LineFromUPtr(wParam), lParam); - case SCI_SETHSCROLLBAR : + case Message::SetHScrollBar : if (horizontalScrollBarVisible != (wParam != 0)) { horizontalScrollBarVisible = wParam != 0; SetScrollBars(); @@ -6817,10 +6867,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } break; - case SCI_GETHSCROLLBAR: + case Message::GetHScrollBar: return horizontalScrollBarVisible; - case SCI_SETVSCROLLBAR: + case Message::SetVScrollBar: if (verticalScrollBarVisible != (wParam != 0)) { verticalScrollBarVisible = wParam != 0; SetScrollBars(); @@ -6830,31 +6880,31 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } break; - case SCI_GETVSCROLLBAR: + case Message::GetVScrollBar: return verticalScrollBarVisible; - case SCI_SETINDENTATIONGUIDES: + case Message::SetIndentationGuides: vs.viewIndentationGuides = static_cast(wParam); Redraw(); break; - case SCI_GETINDENTATIONGUIDES: - return vs.viewIndentationGuides; + case Message::GetIndentationGuides: + return static_cast(vs.viewIndentationGuides); - case SCI_SETHIGHLIGHTGUIDE: + case Message::SetHighlightGuide: if ((highlightGuideColumn != static_cast(wParam)) || (wParam > 0)) { highlightGuideColumn = static_cast(wParam); Redraw(); } break; - case SCI_GETHIGHLIGHTGUIDE: + case Message::GetHighlightGuide: return highlightGuideColumn; - case SCI_GETLINEENDPOSITION: - return pdoc->LineEnd(static_cast(wParam)); + case Message::GetLineEndPosition: + return pdoc->LineEnd(LineFromUPtr(wParam)); - case SCI_SETCODEPAGE: + case Message::SetCodePage: if (ValidCodePage(static_cast(wParam))) { if (pdoc->SetDBCSCodePage(static_cast(wParam))) { pcs->Clear(); @@ -6866,109 +6916,156 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } break; - case SCI_GETCODEPAGE: + case Message::GetCodePage: return pdoc->dbcsCodePage; - case SCI_SETIMEINTERACTION: - imeInteraction = static_cast(wParam); + case Message::SetIMEInteraction: + imeInteraction = static_cast(wParam); break; - case SCI_GETIMEINTERACTION: - return imeInteraction; + case Message::GetIMEInteraction: + return static_cast(imeInteraction); - case SCI_GETLINECHARACTERINDEX: - return pdoc->LineCharacterIndex(); + case Message::SetBidirectional: + // Message::SetBidirectional is implemented on platform subclasses if they support bidirectional text. + break; + + case Message::GetBidirectional: + return static_cast(bidirectional); + + case Message::GetLineCharacterIndex: + return static_cast(pdoc->LineCharacterIndex()); - case SCI_ALLOCATELINECHARACTERINDEX: - pdoc->AllocateLineCharacterIndex(static_cast(wParam)); + case Message::AllocateLineCharacterIndex: + pdoc->AllocateLineCharacterIndex(static_cast(wParam)); break; - case SCI_RELEASELINECHARACTERINDEX: - pdoc->ReleaseLineCharacterIndex(static_cast(wParam)); + case Message::ReleaseLineCharacterIndex: + pdoc->ReleaseLineCharacterIndex(static_cast(wParam)); break; - case SCI_LINEFROMINDEXPOSITION: - return pdoc->LineFromPositionIndex(static_cast(wParam), static_cast(lParam)); + case Message::LineFromIndexPosition: + return pdoc->LineFromPositionIndex(PositionFromUPtr(wParam), static_cast(lParam)); - case SCI_INDEXPOSITIONFROMLINE: - return pdoc->IndexLineStart(static_cast(wParam), static_cast(lParam)); + case Message::IndexPositionFromLine: + return pdoc->IndexLineStart(LineFromUPtr(wParam), static_cast(lParam)); // Marker definition and setting - case SCI_MARKERDEFINE: - if (wParam <= MARKER_MAX) { - vs.markers[wParam].markType = static_cast(lParam); + case Message::MarkerDefine: + if (wParam <= MarkerMax) { + vs.markers[wParam].markType = static_cast(lParam); vs.CalcLargestMarkerHeight(); } InvalidateStyleData(); RedrawSelMargin(); break; - case SCI_MARKERSYMBOLDEFINED: - if (wParam <= MARKER_MAX) - return vs.markers[wParam].markType; + case Message::MarkerSymbolDefined: + if (wParam <= MarkerMax) + return static_cast(vs.markers[wParam].markType); else return 0; - case SCI_MARKERSETFORE: - if (wParam <= MARKER_MAX) - vs.markers[wParam].fore = ColourDesired(static_cast(lParam)); + case Message::MarkerSetFore: + if (wParam <= MarkerMax) + vs.markers[wParam].fore = ColourRGBA::FromIpRGB(lParam); InvalidateStyleData(); RedrawSelMargin(); break; - case SCI_MARKERSETBACKSELECTED: - if (wParam <= MARKER_MAX) - vs.markers[wParam].backSelected = ColourDesired(static_cast(lParam)); + case Message::MarkerSetBack: + if (wParam <= MarkerMax) + vs.markers[wParam].back = ColourRGBA::FromIpRGB(lParam); InvalidateStyleData(); RedrawSelMargin(); break; - case SCI_MARKERENABLEHIGHLIGHT: - marginView.highlightDelimiter.isEnabled = wParam == 1; + case Message::MarkerSetBackSelected: + if (wParam <= MarkerMax) + vs.markers[wParam].backSelected = ColourRGBA::FromIpRGB(lParam); + InvalidateStyleData(); RedrawSelMargin(); break; - case SCI_MARKERSETBACK: - if (wParam <= MARKER_MAX) - vs.markers[wParam].back = ColourDesired(static_cast(lParam)); + case Message::MarkerSetForeTranslucent: + if (wParam <= MarkerMax) + vs.markers[wParam].fore = ColourRGBA(static_cast(lParam)); InvalidateStyleData(); RedrawSelMargin(); break; - case SCI_MARKERSETALPHA: - if (wParam <= MARKER_MAX) - vs.markers[wParam].alpha = static_cast(lParam); - InvalidateStyleRedraw(); + case Message::MarkerSetBackTranslucent: + if (wParam <= MarkerMax) + vs.markers[wParam].back = ColourRGBA(static_cast(lParam)); + InvalidateStyleData(); + RedrawSelMargin(); break; - case SCI_MARKERADD: { - const int markerID = pdoc->AddMark(static_cast(wParam), static_cast(lParam)); + case Message::MarkerSetBackSelectedTranslucent: + if (wParam <= MarkerMax) + vs.markers[wParam].backSelected = ColourRGBA(static_cast(lParam)); + InvalidateStyleData(); + RedrawSelMargin(); + break; + case Message::MarkerSetStrokeWidth: + if (wParam <= MarkerMax) + vs.markers[wParam].strokeWidth = lParam / 100.0f; + InvalidateStyleData(); + RedrawSelMargin(); + break; + case Message::MarkerEnableHighlight: + marginView.highlightDelimiter.isEnabled = wParam == 1; + RedrawSelMargin(); + break; + case Message::MarkerSetAlpha: + if (wParam <= MarkerMax) { + if (static_cast(lParam) == Alpha::NoAlpha) { + SetAppearance(vs.markers[wParam].alpha, Alpha::Opaque); + SetAppearance(vs.markers[wParam].layer, Layer::Base); + } else { + SetAppearance(vs.markers[wParam].alpha, static_cast(lParam)); + SetAppearance(vs.markers[wParam].layer, Layer::OverText); + } + } + break; + case Message::MarkerSetLayer: + if (wParam <= MarkerMax) { + SetAppearance(vs.markers[wParam].layer, static_cast(lParam)); + } + break; + case Message::MarkerGetLayer: + if (wParam <= MarkerMax) { + return static_cast(vs.markers[wParam].layer); + } + return 0; + case Message::MarkerAdd: { + const int markerID = pdoc->AddMark(LineFromUPtr(wParam), static_cast(lParam)); return markerID; } - case SCI_MARKERADDSET: + case Message::MarkerAddSet: if (lParam != 0) - pdoc->AddMarkSet(static_cast(wParam), static_cast(lParam)); + pdoc->AddMarkSet(LineFromUPtr(wParam), static_cast(lParam)); break; - case SCI_MARKERDELETE: - pdoc->DeleteMark(static_cast(wParam), static_cast(lParam)); + case Message::MarkerDelete: + pdoc->DeleteMark(LineFromUPtr(wParam), static_cast(lParam)); break; - case SCI_MARKERDELETEALL: + case Message::MarkerDeleteAll: pdoc->DeleteAllMarks(static_cast(wParam)); break; - case SCI_MARKERGET: - return pdoc->GetMark(static_cast(wParam)); + case Message::MarkerGet: + return pdoc->GetMark(LineFromUPtr(wParam)); - case SCI_MARKERNEXT: - return pdoc->MarkerNext(static_cast(wParam), static_cast(lParam)); + case Message::MarkerNext: + return pdoc->MarkerNext(LineFromUPtr(wParam), static_cast(lParam)); - case SCI_MARKERPREVIOUS: { - for (Sci::Line iLine = static_cast(wParam); iLine >= 0; iLine--) { + case Message::MarkerPrevious: { + for (Sci::Line iLine = LineFromUPtr(wParam); iLine >= 0; iLine--) { if ((pdoc->GetMark(iLine) & lParam) != 0) return iLine; } } return -1; - case SCI_MARKERDEFINEPIXMAP: - if (wParam <= MARKER_MAX) { + case Message::MarkerDefinePixmap: + if (wParam <= MarkerMax) { vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam)); vs.CalcLargestMarkerHeight(); } @@ -6976,20 +7073,20 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { RedrawSelMargin(); break; - case SCI_RGBAIMAGESETWIDTH: + case Message::RGBAImageSetWidth: sizeRGBAImage.x = static_cast(wParam); break; - case SCI_RGBAIMAGESETHEIGHT: + case Message::RGBAImageSetHeight: sizeRGBAImage.y = static_cast(wParam); break; - case SCI_RGBAIMAGESETSCALE: + case Message::RGBAImageSetScale: scaleRGBAImage = static_cast(wParam); break; - case SCI_MARKERDEFINERGBAIMAGE: - if (wParam <= MARKER_MAX) { + case Message::MarkerDefineRGBAImage: + if (wParam <= MarkerMax) { vs.markers[wParam].SetRGBAImage(sizeRGBAImage, scaleRGBAImage / 100.0f, ConstUCharPtrFromSPtr(lParam)); vs.CalcLargestMarkerHeight(); } @@ -6997,20 +7094,20 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { RedrawSelMargin(); break; - case SCI_SETMARGINTYPEN: + case Message::SetMarginTypeN: if (ValidMargin(wParam)) { - vs.ms[wParam].style = static_cast(lParam); + vs.ms[wParam].style = static_cast(lParam); InvalidateStyleRedraw(); } break; - case SCI_GETMARGINTYPEN: + case Message::GetMarginTypeN: if (ValidMargin(wParam)) - return vs.ms[wParam].style; + return static_cast(vs.ms[wParam].style); else return 0; - case SCI_SETMARGINWIDTHN: + case Message::SetMarginWidthN: if (ValidMargin(wParam)) { // Short-circuit if the width is unchanged, to avoid unnecessary redraw. if (vs.ms[wParam].width != lParam) { @@ -7021,115 +7118,149 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { } break; - case SCI_GETMARGINWIDTHN: + case Message::GetMarginWidthN: if (ValidMargin(wParam)) return vs.ms[wParam].width; else return 0; - case SCI_SETMARGINMASKN: + case Message::SetMarginMaskN: if (ValidMargin(wParam)) { vs.ms[wParam].mask = static_cast(lParam); InvalidateStyleRedraw(); } break; - case SCI_GETMARGINMASKN: + case Message::GetMarginMaskN: if (ValidMargin(wParam)) return vs.ms[wParam].mask; else return 0; - case SCI_SETMARGINSENSITIVEN: + case Message::SetMarginSensitiveN: if (ValidMargin(wParam)) { vs.ms[wParam].sensitive = lParam != 0; InvalidateStyleRedraw(); } break; - case SCI_GETMARGINSENSITIVEN: + case Message::GetMarginSensitiveN: if (ValidMargin(wParam)) return vs.ms[wParam].sensitive ? 1 : 0; else return 0; - case SCI_SETMARGINCURSORN: + case Message::SetMarginCursorN: if (ValidMargin(wParam)) - vs.ms[wParam].cursor = static_cast(lParam); + vs.ms[wParam].cursor = static_cast(lParam); break; - case SCI_GETMARGINCURSORN: + case Message::GetMarginCursorN: if (ValidMargin(wParam)) - return vs.ms[wParam].cursor; + return static_cast(vs.ms[wParam].cursor); else return 0; - case SCI_SETMARGINBACKN: + case Message::SetMarginBackN: if (ValidMargin(wParam)) { - vs.ms[wParam].back = ColourDesired(static_cast(lParam)); + vs.ms[wParam].back = ColourRGBA::FromIpRGB(lParam); InvalidateStyleRedraw(); } break; - case SCI_GETMARGINBACKN: + case Message::GetMarginBackN: if (ValidMargin(wParam)) - return vs.ms[wParam].back.AsInteger(); + return vs.ms[wParam].back.OpaqueRGB(); else return 0; - case SCI_SETMARGINS: + case Message::SetMargins: if (wParam < 1000) vs.ms.resize(wParam); break; - case SCI_GETMARGINS: + case Message::GetMargins: return vs.ms.size(); - case SCI_STYLECLEARALL: + case Message::StyleClearAll: vs.ClearStyles(); InvalidateStyleRedraw(); break; - case SCI_STYLESETFORE: - case SCI_STYLESETBACK: - case SCI_STYLESETBOLD: - case SCI_STYLESETWEIGHT: - case SCI_STYLESETITALIC: - case SCI_STYLESETEOLFILLED: - case SCI_STYLESETSIZE: - case SCI_STYLESETSIZEFRACTIONAL: - case SCI_STYLESETFONT: - case SCI_STYLESETUNDERLINE: - case SCI_STYLESETCASE: - case SCI_STYLESETCHARACTERSET: - case SCI_STYLESETVISIBLE: - case SCI_STYLESETCHANGEABLE: - case SCI_STYLESETHOTSPOT: + case Message::StyleSetFore: + case Message::StyleSetBack: + case Message::StyleSetBold: + case Message::StyleSetWeight: + case Message::StyleSetItalic: + case Message::StyleSetEOLFilled: + case Message::StyleSetSize: + case Message::StyleSetSizeFractional: + case Message::StyleSetFont: + case Message::StyleSetUnderline: + case Message::StyleSetCase: + case Message::StyleSetCharacterSet: + case Message::StyleSetVisible: + case Message::StyleSetChangeable: + case Message::StyleSetHotSpot: StyleSetMessage(iMessage, wParam, lParam); break; - case SCI_STYLEGETFORE: - case SCI_STYLEGETBACK: - case SCI_STYLEGETBOLD: - case SCI_STYLEGETWEIGHT: - case SCI_STYLEGETITALIC: - case SCI_STYLEGETEOLFILLED: - case SCI_STYLEGETSIZE: - case SCI_STYLEGETSIZEFRACTIONAL: - case SCI_STYLEGETFONT: - case SCI_STYLEGETUNDERLINE: - case SCI_STYLEGETCASE: - case SCI_STYLEGETCHARACTERSET: - case SCI_STYLEGETVISIBLE: - case SCI_STYLEGETCHANGEABLE: - case SCI_STYLEGETHOTSPOT: + case Message::StyleGetFore: + case Message::StyleGetBack: + case Message::StyleGetBold: + case Message::StyleGetWeight: + case Message::StyleGetItalic: + case Message::StyleGetEOLFilled: + case Message::StyleGetSize: + case Message::StyleGetSizeFractional: + case Message::StyleGetFont: + case Message::StyleGetUnderline: + case Message::StyleGetCase: + case Message::StyleGetCharacterSet: + case Message::StyleGetVisible: + case Message::StyleGetChangeable: + case Message::StyleGetHotSpot: return StyleGetMessage(iMessage, wParam, lParam); - case SCI_STYLERESETDEFAULT: + case Message::StyleResetDefault: vs.ResetDefaultStyle(); InvalidateStyleRedraw(); break; + case Message::SetElementColour: + if (vs.SetElementColour(static_cast(wParam), ColourRGBA(static_cast(lParam)))) { + InvalidateStyleRedraw(); + } + break; + + case Message::GetElementColour: + return vs.ElementColour(static_cast(wParam)).value_or(ColourRGBA()).AsInteger(); + + case Message::ResetElementColour: + if (vs.ResetElement(static_cast(wParam))) { + InvalidateStyleRedraw(); + } + break; + + case Message::GetElementIsSet: + return vs.ElementColour(static_cast(wParam)).has_value(); + + case Message::GetElementAllowsTranslucent: + return vs.ElementAllowsTranslucent(static_cast(wParam)); + + case Message::GetElementBaseColour: + return vs.elementBaseColours[static_cast(wParam)].value_or(ColourRGBA()).AsInteger(); + + case Message::SetFontLocale: + if (lParam) { + vs.SetFontLocaleName(CharPtrFromSPtr(lParam)); + InvalidateStyleRedraw(); + } + break; + + case Message::GetFontLocale: + return StringResult(lParam, vs.localeName.c_str()); + #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_SETSTYLEBITS: vs.EnsureStyle(0xff); @@ -7139,521 +7270,602 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return 8; #endif - case SCI_SETLINESTATE: - return pdoc->SetLineState(static_cast(wParam), static_cast(lParam)); + case Message::SetLineState: + return pdoc->SetLineState(LineFromUPtr(wParam), static_cast(lParam)); - case SCI_GETLINESTATE: - return pdoc->GetLineState(static_cast(wParam)); + case Message::GetLineState: + return pdoc->GetLineState(LineFromUPtr(wParam)); - case SCI_GETMAXLINESTATE: + case Message::GetMaxLineState: return pdoc->GetMaxLineState(); - case SCI_GETCARETLINEVISIBLE: - return vs.showCaretLineBackground; - case SCI_SETCARETLINEVISIBLE: - vs.showCaretLineBackground = wParam != 0; - InvalidateStyleRedraw(); + case Message::GetCaretLineVisible: + return vs.ElementColour(Element::CaretLineBack) ? 1 : 0; + case Message::SetCaretLineVisible: + if (wParam) { + if (!vs.elementColours.count(Element::CaretLineBack)) { + vs.elementColours[Element::CaretLineBack] = ColourRGBA(0xFF, 0xFF, 0); + InvalidateStyleRedraw(); + } + } else { + if (vs.ResetElement(Element::CaretLineBack)) { + InvalidateStyleRedraw(); + } + } break; - case SCI_GETCARETLINEVISIBLEALWAYS: - return vs.alwaysShowCaretLineBackground; - case SCI_SETCARETLINEVISIBLEALWAYS: - vs.alwaysShowCaretLineBackground = wParam != 0; + case Message::GetCaretLineVisibleAlways: + return vs.caretLine.alwaysShow; + case Message::SetCaretLineVisibleAlways: + vs.caretLine.alwaysShow = wParam != 0; InvalidateStyleRedraw(); break; - case SCI_GETCARETLINEFRAME: - return vs.caretLineFrame; - case SCI_SETCARETLINEFRAME: - vs.caretLineFrame = static_cast(wParam); + case Message::GetCaretLineFrame: + return vs.caretLine.frame; + case Message::SetCaretLineFrame: + vs.caretLine.frame = static_cast(wParam); InvalidateStyleRedraw(); break; - case SCI_GETCARETLINEBACK: - return vs.caretLineBackground.AsInteger(); - case SCI_SETCARETLINEBACK: - vs.caretLineBackground = ColourDesired(static_cast(wParam)); + case Message::GetCaretLineBack: + if (vs.ElementColour(Element::CaretLineBack)) + return vs.ElementColour(Element::CaretLineBack)->OpaqueRGB(); + else + return 0; + + case Message::SetCaretLineBack: + vs.SetElementRGB(Element::CaretLineBack, static_cast(wParam)); InvalidateStyleRedraw(); break; - case SCI_GETCARETLINEBACKALPHA: - return vs.caretLineAlpha; - case SCI_SETCARETLINEBACKALPHA: - vs.caretLineAlpha = static_cast(wParam); - InvalidateStyleRedraw(); + + case Message::GetCaretLineLayer: + return static_cast(vs.caretLine.layer); + + case Message::SetCaretLineLayer: + if (vs.caretLine.layer != static_cast(wParam)) { + vs.caretLine.layer = static_cast(wParam); + UpdateBaseElements(); + InvalidateStyleRedraw(); + } + break; + + case Message::GetCaretLineBackAlpha: + if (vs.caretLine.layer == Layer::Base) + return static_cast(Alpha::NoAlpha); + return vs.ElementColour(Element::CaretLineBack).value_or(ColourRGBA()).GetAlpha(); + + case Message::SetCaretLineBackAlpha: { + const Layer layerNew = (static_cast(wParam) == Alpha::NoAlpha) ? Layer::Base : Layer::OverText; + vs.caretLine.layer = layerNew; + if (vs.ElementColour(Element::CaretLineBack)) { + vs.SetElementAlpha(Element::CaretLineBack, static_cast(wParam)); + } + InvalidateStyleRedraw(); + } break; // Folding messages - case SCI_VISIBLEFROMDOCLINE: - return pcs->DisplayFromDoc(static_cast(wParam)); + case Message::VisibleFromDocLine: + return pcs->DisplayFromDoc(LineFromUPtr(wParam)); - case SCI_DOCLINEFROMVISIBLE: - return pcs->DocFromDisplay(static_cast(wParam)); + case Message::DocLineFromVisible: + return pcs->DocFromDisplay(LineFromUPtr(wParam)); - case SCI_WRAPCOUNT: - return WrapCount(static_cast(wParam)); + case Message::WrapCount: + return WrapCount(LineFromUPtr(wParam)); - case SCI_SETFOLDLEVEL: { - const int prev = pdoc->SetLevel(static_cast(wParam), static_cast(lParam)); + case Message::SetFoldLevel: { + const int prev = pdoc->SetLevel(LineFromUPtr(wParam), static_cast(lParam)); if (prev != static_cast(lParam)) RedrawSelMargin(); return prev; } - case SCI_GETFOLDLEVEL: - return pdoc->GetLevel(static_cast(wParam)); + case Message::GetFoldLevel: + return pdoc->GetLevel(LineFromUPtr(wParam)); - case SCI_GETLASTCHILD: - return pdoc->GetLastChild(static_cast(wParam), static_cast(lParam)); + case Message::GetLastChild: + return pdoc->GetLastChild(LineFromUPtr(wParam), OptionalFoldLevel(lParam)); - case SCI_GETFOLDPARENT: - return pdoc->GetFoldParent(static_cast(wParam)); + case Message::GetFoldParent: + return pdoc->GetFoldParent(LineFromUPtr(wParam)); - case SCI_SHOWLINES: - pcs->SetVisible(static_cast(wParam), static_cast(lParam), true); + case Message::ShowLines: + pcs->SetVisible(LineFromUPtr(wParam), lParam, true); SetScrollBars(); Redraw(); break; - case SCI_HIDELINES: + case Message::HideLines: if (wParam > 0) - pcs->SetVisible(static_cast(wParam), static_cast(lParam), false); + pcs->SetVisible(LineFromUPtr(wParam), lParam, false); SetScrollBars(); Redraw(); break; - case SCI_GETLINEVISIBLE: - return pcs->GetVisible(static_cast(wParam)); + case Message::GetLineVisible: + return pcs->GetVisible(LineFromUPtr(wParam)); - case SCI_GETALLLINESVISIBLE: + case Message::GetAllLinesVisible: return pcs->HiddenLines() ? 0 : 1; - case SCI_SETFOLDEXPANDED: - SetFoldExpanded(static_cast(wParam), lParam != 0); + case Message::SetFoldExpanded: + SetFoldExpanded(LineFromUPtr(wParam), lParam != 0); break; - case SCI_GETFOLDEXPANDED: - return pcs->GetExpanded(static_cast(wParam)); + case Message::GetFoldExpanded: + return pcs->GetExpanded(LineFromUPtr(wParam)); - case SCI_SETAUTOMATICFOLD: - foldAutomatic = static_cast(wParam); + case Message::SetAutomaticFold: + foldAutomatic = static_cast(wParam); break; - case SCI_GETAUTOMATICFOLD: - return foldAutomatic; + case Message::GetAutomaticFold: + return static_cast(foldAutomatic); - case SCI_SETFOLDFLAGS: - foldFlags = static_cast(wParam); + case Message::SetFoldFlags: + foldFlags = static_cast(wParam); Redraw(); break; - case SCI_TOGGLEFOLDSHOWTEXT: - pcs->SetFoldDisplayText(static_cast(wParam), CharPtrFromSPtr(lParam)); - FoldLine(static_cast(wParam), SC_FOLDACTION_TOGGLE); + case Message::ToggleFoldShowText: + pcs->SetFoldDisplayText(LineFromUPtr(wParam), CharPtrFromSPtr(lParam)); + FoldLine(LineFromUPtr(wParam), FoldAction::Toggle); break; - case SCI_FOLDDISPLAYTEXTSETSTYLE: - foldDisplayTextStyle = static_cast(wParam); + case Message::FoldDisplayTextSetStyle: + foldDisplayTextStyle = static_cast(wParam); Redraw(); break; - case SCI_FOLDDISPLAYTEXTGETSTYLE: - return foldDisplayTextStyle; + case Message::FoldDisplayTextGetStyle: + return static_cast(foldDisplayTextStyle); - case SCI_SETDEFAULTFOLDDISPLAYTEXT: + case Message::SetDefaultFoldDisplayText: SetDefaultFoldDisplayText(CharPtrFromSPtr(lParam)); Redraw(); break; - case SCI_GETDEFAULTFOLDDISPLAYTEXT: + case Message::GetDefaultFoldDisplayText: return StringResult(lParam, GetDefaultFoldDisplayText()); - case SCI_TOGGLEFOLD: - FoldLine(static_cast(wParam), SC_FOLDACTION_TOGGLE); + case Message::ToggleFold: + FoldLine(LineFromUPtr(wParam), FoldAction::Toggle); break; - case SCI_FOLDLINE: - FoldLine(static_cast(wParam), static_cast(lParam)); + case Message::FoldLine: + FoldLine(LineFromUPtr(wParam), static_cast(lParam)); break; - case SCI_FOLDCHILDREN: - FoldExpand(static_cast(wParam), static_cast(lParam), pdoc->GetLevel(static_cast(wParam))); + case Message::FoldChildren: + FoldExpand(LineFromUPtr(wParam), static_cast(lParam), pdoc->GetFoldLevel(LineFromUPtr(wParam))); break; - case SCI_FOLDALL: - FoldAll(static_cast(wParam)); + case Message::FoldAll: + FoldAll(static_cast(wParam)); break; - case SCI_EXPANDCHILDREN: - FoldExpand(static_cast(wParam), SC_FOLDACTION_EXPAND, static_cast(lParam)); + case Message::ExpandChildren: + FoldExpand(LineFromUPtr(wParam), FoldAction::Expand, static_cast(lParam)); break; - case SCI_CONTRACTEDFOLDNEXT: - return ContractedFoldNext(static_cast(wParam)); + case Message::ContractedFoldNext: + return ContractedFoldNext(LineFromUPtr(wParam)); - case SCI_ENSUREVISIBLE: - EnsureLineVisible(static_cast(wParam), false); + case Message::EnsureVisible: + EnsureLineVisible(LineFromUPtr(wParam), false); break; - case SCI_ENSUREVISIBLEENFORCEPOLICY: - EnsureLineVisible(static_cast(wParam), true); + case Message::EnsureVisibleEnforcePolicy: + EnsureLineVisible(LineFromUPtr(wParam), true); break; - case SCI_SCROLLRANGE: - ScrollRange(SelectionRange(static_cast(wParam), lParam)); + case Message::ScrollRange: + ScrollRange(SelectionRange(PositionFromUPtr(wParam), lParam)); break; - case SCI_SEARCHANCHOR: + case Message::SearchAnchor: SearchAnchor(); break; - case SCI_SEARCHNEXT: - case SCI_SEARCHPREV: + case Message::SearchNext: + case Message::SearchPrev: return SearchText(iMessage, wParam, lParam); - case SCI_SETXCARETPOLICY: - caretPolicies.x = CaretPolicy(wParam, lParam); + case Message::SetXCaretPolicy: + caretPolicies.x = CaretPolicySlop(wParam, lParam); break; - case SCI_SETYCARETPOLICY: - caretPolicies.y = CaretPolicy(wParam, lParam); + case Message::SetYCaretPolicy: + caretPolicies.y = CaretPolicySlop(wParam, lParam); break; - case SCI_SETVISIBLEPOLICY: - visiblePolicy = CaretPolicy(wParam, lParam); + case Message::SetVisiblePolicy: + visiblePolicy = VisiblePolicySlop(wParam, lParam); break; - case SCI_LINESONSCREEN: + case Message::LinesOnScreen: return LinesOnScreen(); - case SCI_SETSELFORE: - vs.selColours.fore = ColourOptional(wParam, lParam); - vs.selAdditionalForeground = ColourDesired(static_cast(lParam)); + case Message::SetSelFore: + vs.elementColours[Element::SelectionText] = OptionalColour(wParam, lParam); + vs.elementColours[Element::SelectionAdditionalText] = OptionalColour(wParam, lParam); InvalidateStyleRedraw(); break; - case SCI_SETSELBACK: - vs.selColours.back = ColourOptional(wParam, lParam); - vs.selAdditionalBackground = ColourDesired(static_cast(lParam)); + case Message::SetSelBack: + if (wParam) { + vs.SetElementRGB(Element::SelectionBack, static_cast(lParam)); + vs.SetElementRGB(Element::SelectionAdditionalBack, static_cast(lParam)); + } else { + vs.ResetElement(Element::SelectionBack); + vs.ResetElement(Element::SelectionAdditionalBack); + } InvalidateStyleRedraw(); break; - case SCI_SETSELALPHA: - vs.selAlpha = static_cast(wParam); - vs.selAdditionalAlpha = static_cast(wParam); - InvalidateStyleRedraw(); + case Message::SetSelAlpha: { + const Layer layerNew = (static_cast(wParam) == Alpha::NoAlpha) ? Layer::Base : Layer::OverText; + if (vs.selection.layer != layerNew) { + vs.selection.layer = layerNew; + UpdateBaseElements(); + } + const int alpha = static_cast(wParam); + vs.SetElementAlpha(Element::SelectionBack, alpha); + vs.SetElementAlpha(Element::SelectionAdditionalBack, alpha); + vs.SetElementAlpha(Element::SelectionSecondaryBack, alpha); + vs.SetElementAlpha(Element::SelectionInactiveBack, alpha); + InvalidateStyleRedraw(); + } break; - case SCI_GETSELALPHA: - return vs.selAlpha; + case Message::GetSelAlpha: + if (vs.selection.layer == Layer::Base) + return static_cast(Alpha::NoAlpha); + return vs.ElementColour(Element::SelectionBack)->GetAlpha(); - case SCI_GETSELEOLFILLED: - return vs.selEOLFilled; + case Message::GetSelEOLFilled: + return vs.selection.eolFilled; - case SCI_SETSELEOLFILLED: - vs.selEOLFilled = wParam != 0; + case Message::SetSelEOLFilled: + vs.selection.eolFilled = wParam != 0; InvalidateStyleRedraw(); break; - case SCI_SETWHITESPACEFORE: - vs.whitespaceColours.fore = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); + case Message::SetWhitespaceFore: + if (vs.SetElementColourOptional(Element::WhiteSpace, wParam, lParam)) { + InvalidateStyleRedraw(); + } break; - case SCI_SETWHITESPACEBACK: - vs.whitespaceColours.back = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); + case Message::SetWhitespaceBack: + if (vs.SetElementColourOptional(Element::WhiteSpaceBack, wParam, lParam)) { + InvalidateStyleRedraw(); + } + break; + + case Message::SetSelectionLayer: + if (vs.selection.layer != static_cast(wParam)) { + vs.selection.layer = static_cast(wParam); + UpdateBaseElements(); + InvalidateStyleRedraw(); + } break; - case SCI_SETCARETFORE: - vs.caretcolour = ColourDesired(static_cast(wParam)); + case Message::GetSelectionLayer: + return static_cast(vs.selection.layer); + + case Message::SetCaretFore: + vs.elementColours[Element::Caret] = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam)); InvalidateStyleRedraw(); break; - case SCI_GETCARETFORE: - return vs.caretcolour.AsInteger(); + case Message::GetCaretFore: + return vs.ElementColour(Element::Caret)->OpaqueRGB(); - case SCI_SETCARETSTYLE: - if (wParam <= (CARETSTYLE_BLOCK | CARETSTYLE_OVERSTRIKE_BLOCK | CARETSTYLE_BLOCK_AFTER)) - vs.caretStyle = static_cast(wParam); + case Message::SetCaretStyle: + if (static_cast(wParam) <= (CaretStyle::Block | CaretStyle::OverstrikeBlock | CaretStyle::BlockAfter)) + vs.caret.style = static_cast(wParam); else /* Default to the line caret */ - vs.caretStyle = CARETSTYLE_LINE; + vs.caret.style = CaretStyle::Line; InvalidateStyleRedraw(); break; - case SCI_GETCARETSTYLE: - return vs.caretStyle; + case Message::GetCaretStyle: + return static_cast(vs.caret.style); - case SCI_SETCARETWIDTH: - vs.caretWidth = Sci::clamp(static_cast(wParam), 0, 20); + case Message::SetCaretWidth: + vs.caret.width = std::clamp(static_cast(wParam), 0, 20); InvalidateStyleRedraw(); break; - case SCI_GETCARETWIDTH: - return vs.caretWidth; + case Message::GetCaretWidth: + return vs.caret.width; - case SCI_ASSIGNCMDKEY: - kmap.AssignCmdKey(LowShortFromWParam(wParam), - HighShortFromWParam(wParam), static_cast(lParam)); + case Message::AssignCmdKey: + kmap.AssignCmdKey(static_cast(LowShortFromWParam(wParam)), + static_cast(HighShortFromWParam(wParam)), static_cast(lParam)); break; - case SCI_CLEARCMDKEY: - kmap.AssignCmdKey(LowShortFromWParam(wParam), - HighShortFromWParam(wParam), SCI_NULL); + case Message::ClearCmdKey: + kmap.AssignCmdKey(static_cast(LowShortFromWParam(wParam)), + static_cast(HighShortFromWParam(wParam)), Message::Null); break; - case SCI_CLEARALLCMDKEYS: + case Message::ClearAllCmdKeys: kmap.Clear(); break; - case SCI_INDICSETSTYLE: - if (wParam <= INDICATOR_MAX) { - vs.indicators[wParam].sacNormal.style = static_cast(lParam); - vs.indicators[wParam].sacHover.style = static_cast(lParam); + case Message::IndicSetStyle: + if (wParam <= IndicatorMax) { + vs.indicators[wParam].sacNormal.style = static_cast(lParam); + vs.indicators[wParam].sacHover.style = static_cast(lParam); InvalidateStyleRedraw(); } break; - case SCI_INDICGETSTYLE: - return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].sacNormal.style : 0; + case Message::IndicGetStyle: + return (wParam <= IndicatorMax) ? + static_cast(vs.indicators[wParam].sacNormal.style) : 0; - case SCI_INDICSETFORE: - if (wParam <= INDICATOR_MAX) { - vs.indicators[wParam].sacNormal.fore = ColourDesired(static_cast(lParam)); - vs.indicators[wParam].sacHover.fore = ColourDesired(static_cast(lParam)); + case Message::IndicSetFore: + if (wParam <= IndicatorMax) { + vs.indicators[wParam].sacNormal.fore = ColourRGBA::FromIpRGB(lParam); + vs.indicators[wParam].sacHover.fore = ColourRGBA::FromIpRGB(lParam); InvalidateStyleRedraw(); } break; - case SCI_INDICGETFORE: - return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].sacNormal.fore.AsInteger() : 0; + case Message::IndicGetFore: + return (wParam <= IndicatorMax) ? + vs.indicators[wParam].sacNormal.fore.OpaqueRGB() : 0; - case SCI_INDICSETHOVERSTYLE: - if (wParam <= INDICATOR_MAX) { - vs.indicators[wParam].sacHover.style = static_cast(lParam); + case Message::IndicSetHoverStyle: + if (wParam <= IndicatorMax) { + vs.indicators[wParam].sacHover.style = static_cast(lParam); InvalidateStyleRedraw(); } break; - case SCI_INDICGETHOVERSTYLE: - return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].sacHover.style : 0; + case Message::IndicGetHoverStyle: + return (wParam <= IndicatorMax) ? + static_cast(vs.indicators[wParam].sacHover.style) : 0; - case SCI_INDICSETHOVERFORE: - if (wParam <= INDICATOR_MAX) { - vs.indicators[wParam].sacHover.fore = ColourDesired(static_cast(lParam)); + case Message::IndicSetHoverFore: + if (wParam <= IndicatorMax) { + vs.indicators[wParam].sacHover.fore = ColourRGBA::FromIpRGB(lParam); InvalidateStyleRedraw(); } break; - case SCI_INDICGETHOVERFORE: - return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].sacHover.fore.AsInteger() : 0; + case Message::IndicGetHoverFore: + return (wParam <= IndicatorMax) ? + vs.indicators[wParam].sacHover.fore.OpaqueRGB() : 0; - case SCI_INDICSETFLAGS: - if (wParam <= INDICATOR_MAX) { - vs.indicators[wParam].SetFlags(static_cast(lParam)); + case Message::IndicSetFlags: + if (wParam <= IndicatorMax) { + vs.indicators[wParam].SetFlags(static_cast(lParam)); InvalidateStyleRedraw(); } break; - case SCI_INDICGETFLAGS: - return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].Flags() : 0; + case Message::IndicGetFlags: + return (wParam <= IndicatorMax) ? + static_cast(vs.indicators[wParam].Flags()) : 0; - case SCI_INDICSETUNDER: - if (wParam <= INDICATOR_MAX) { + case Message::IndicSetUnder: + if (wParam <= IndicatorMax) { vs.indicators[wParam].under = lParam != 0; InvalidateStyleRedraw(); } break; - case SCI_INDICGETUNDER: - return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].under : 0; + case Message::IndicGetUnder: + return (wParam <= IndicatorMax) ? + vs.indicators[wParam].under : 0; - case SCI_INDICSETALPHA: - if (wParam <= INDICATOR_MAX && lParam >=0 && lParam <= 255) { + case Message::IndicSetAlpha: + if (wParam <= IndicatorMax && lParam >=0 && lParam <= 255) { vs.indicators[wParam].fillAlpha = static_cast(lParam); InvalidateStyleRedraw(); } break; - case SCI_INDICGETALPHA: - return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].fillAlpha : 0; + case Message::IndicGetAlpha: + return (wParam <= IndicatorMax) + ? vs.indicators[wParam].fillAlpha : 0; - case SCI_INDICSETOUTLINEALPHA: - if (wParam <= INDICATOR_MAX && lParam >=0 && lParam <= 255) { + case Message::IndicSetOutlineAlpha: + if (wParam <= IndicatorMax && lParam >=0 && lParam <= 255) { vs.indicators[wParam].outlineAlpha = static_cast(lParam); InvalidateStyleRedraw(); } break; - case SCI_INDICGETOUTLINEALPHA: - return (wParam <= INDICATOR_MAX) ? vs.indicators[wParam].outlineAlpha : 0; + case Message::IndicGetOutlineAlpha: + return (wParam <= IndicatorMax) ? vs.indicators[wParam].outlineAlpha : 0; + + case Message::IndicSetStrokeWidth: + if (wParam <= IndicatorMax && lParam >= 0 && lParam <= 1000) { + vs.indicators[wParam].strokeWidth = lParam / 100.0f; + InvalidateStyleRedraw(); + } + break; + + case Message::IndicGetStrokeWidth: + if (wParam <= IndicatorMax) { + return std::lround(vs.indicators[wParam].strokeWidth * 100); + } + break; - case SCI_SETINDICATORCURRENT: + case Message::SetIndicatorCurrent: pdoc->DecorationSetCurrentIndicator(static_cast(wParam)); break; - case SCI_GETINDICATORCURRENT: + case Message::GetIndicatorCurrent: return pdoc->decorations->GetCurrentIndicator(); - case SCI_SETINDICATORVALUE: + case Message::SetIndicatorValue: pdoc->decorations->SetCurrentValue(static_cast(wParam)); break; - case SCI_GETINDICATORVALUE: + case Message::GetIndicatorValue: return pdoc->decorations->GetCurrentValue(); - case SCI_INDICATORFILLRANGE: - pdoc->DecorationFillRange(static_cast(wParam), + case Message::IndicatorFillRange: + pdoc->DecorationFillRange(PositionFromUPtr(wParam), pdoc->decorations->GetCurrentValue(), lParam); break; - case SCI_INDICATORCLEARRANGE: - pdoc->DecorationFillRange(static_cast(wParam), 0, + case Message::IndicatorClearRange: + pdoc->DecorationFillRange(PositionFromUPtr(wParam), 0, lParam); break; - case SCI_INDICATORALLONFOR: - return pdoc->decorations->AllOnFor(static_cast(wParam)); + case Message::IndicatorAllOnFor: + return pdoc->decorations->AllOnFor(PositionFromUPtr(wParam)); - case SCI_INDICATORVALUEAT: + case Message::IndicatorValueAt: return pdoc->decorations->ValueAt(static_cast(wParam), lParam); - case SCI_INDICATORSTART: + case Message::IndicatorStart: return pdoc->decorations->Start(static_cast(wParam), lParam); - case SCI_INDICATOREND: + case Message::IndicatorEnd: return pdoc->decorations->End(static_cast(wParam), lParam); - case SCI_LINEDOWN: - case SCI_LINEDOWNEXTEND: - case SCI_PARADOWN: - case SCI_PARADOWNEXTEND: - case SCI_LINEUP: - case SCI_LINEUPEXTEND: - case SCI_PARAUP: - case SCI_PARAUPEXTEND: - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: - case SCI_CHARRIGHT: - case SCI_CHARRIGHTEXTEND: - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: - case SCI_WORDRIGHT: - case SCI_WORDRIGHTEXTEND: - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDRIGHTEND: - case SCI_WORDRIGHTENDEXTEND: - case SCI_HOME: - case SCI_HOMEEXTEND: - case SCI_LINEEND: - case SCI_LINEENDEXTEND: - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: - case SCI_LINEENDWRAP: - case SCI_LINEENDWRAPEXTEND: - case SCI_DOCUMENTSTART: - case SCI_DOCUMENTSTARTEXTEND: - case SCI_DOCUMENTEND: - case SCI_DOCUMENTENDEXTEND: - case SCI_SCROLLTOSTART: - case SCI_SCROLLTOEND: - - case SCI_STUTTEREDPAGEUP: - case SCI_STUTTEREDPAGEUPEXTEND: - case SCI_STUTTEREDPAGEDOWN: - case SCI_STUTTEREDPAGEDOWNEXTEND: - - case SCI_PAGEUP: - case SCI_PAGEUPEXTEND: - case SCI_PAGEDOWN: - case SCI_PAGEDOWNEXTEND: - case SCI_EDITTOGGLEOVERTYPE: - case SCI_CANCEL: - case SCI_DELETEBACK: - case SCI_TAB: - case SCI_BACKTAB: - case SCI_NEWLINE: - case SCI_FORMFEED: - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_ZOOMIN: - case SCI_ZOOMOUT: - case SCI_DELWORDLEFT: - case SCI_DELWORDRIGHT: - case SCI_DELWORDRIGHTEND: - case SCI_DELLINELEFT: - case SCI_DELLINERIGHT: - case SCI_LINECOPY: - case SCI_LINECUT: - case SCI_LINEDELETE: - case SCI_LINETRANSPOSE: - case SCI_LINEREVERSE: - case SCI_LINEDUPLICATE: - case SCI_LOWERCASE: - case SCI_UPPERCASE: - case SCI_LINESCROLLDOWN: - case SCI_LINESCROLLUP: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: - case SCI_WORDPARTRIGHT: - case SCI_WORDPARTRIGHTEXTEND: - case SCI_DELETEBACKNOTLINE: - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: - case SCI_LINEENDDISPLAY: - case SCI_LINEENDDISPLAYEXTEND: - case SCI_LINEDOWNRECTEXTEND: - case SCI_LINEUPRECTEXTEND: - case SCI_CHARLEFTRECTEXTEND: - case SCI_CHARRIGHTRECTEXTEND: - case SCI_HOMERECTEXTEND: - case SCI_VCHOMERECTEXTEND: - case SCI_LINEENDRECTEXTEND: - case SCI_PAGEUPRECTEXTEND: - case SCI_PAGEDOWNRECTEXTEND: - case SCI_SELECTIONDUPLICATE: + case Message::LineDown: + case Message::LineDownExtend: + case Message::ParaDown: + case Message::ParaDownExtend: + case Message::LineUp: + case Message::LineUpExtend: + case Message::ParaUp: + case Message::ParaUpExtend: + case Message::CharLeft: + case Message::CharLeftExtend: + case Message::CharRight: + case Message::CharRightExtend: + case Message::WordLeft: + case Message::WordLeftExtend: + case Message::WordRight: + case Message::WordRightExtend: + case Message::WordLeftEnd: + case Message::WordLeftEndExtend: + case Message::WordRightEnd: + case Message::WordRightEndExtend: + case Message::Home: + case Message::HomeExtend: + case Message::LineEnd: + case Message::LineEndExtend: + case Message::HomeWrap: + case Message::HomeWrapExtend: + case Message::LineEndWrap: + case Message::LineEndWrapExtend: + case Message::DocumentStart: + case Message::DocumentStartExtend: + case Message::DocumentEnd: + case Message::DocumentEndExtend: + case Message::ScrollToStart: + case Message::ScrollToEnd: + + case Message::StutteredPageUp: + case Message::StutteredPageUpExtend: + case Message::StutteredPageDown: + case Message::StutteredPageDownExtend: + + case Message::PageUp: + case Message::PageUpExtend: + case Message::PageDown: + case Message::PageDownExtend: + case Message::EditToggleOvertype: + case Message::Cancel: + case Message::DeleteBack: + case Message::Tab: + case Message::BackTab: + case Message::NewLine: + case Message::FormFeed: + case Message::VCHome: + case Message::VCHomeExtend: + case Message::VCHomeWrap: + case Message::VCHomeWrapExtend: + case Message::VCHomeDisplay: + case Message::VCHomeDisplayExtend: + case Message::ZoomIn: + case Message::ZoomOut: + case Message::DelWordLeft: + case Message::DelWordRight: + case Message::DelWordRightEnd: + case Message::DelLineLeft: + case Message::DelLineRight: + case Message::LineCopy: + case Message::LineCut: + case Message::LineDelete: + case Message::LineTranspose: + case Message::LineReverse: + case Message::LineDuplicate: + case Message::LowerCase: + case Message::UpperCase: + case Message::LineScrollDown: + case Message::LineScrollUp: + case Message::WordPartLeft: + case Message::WordPartLeftExtend: + case Message::WordPartRight: + case Message::WordPartRightExtend: + case Message::DeleteBackNotLine: + case Message::HomeDisplay: + case Message::HomeDisplayExtend: + case Message::LineEndDisplay: + case Message::LineEndDisplayExtend: + case Message::LineDownRectExtend: + case Message::LineUpRectExtend: + case Message::CharLeftRectExtend: + case Message::CharRightRectExtend: + case Message::HomeRectExtend: + case Message::VCHomeRectExtend: + case Message::LineEndRectExtend: + case Message::PageUpRectExtend: + case Message::PageDownRectExtend: + case Message::SelectionDuplicate: return KeyCommand(iMessage); - case SCI_BRACEHIGHLIGHT: - SetBraceHighlight(static_cast(wParam), lParam, STYLE_BRACELIGHT); + case Message::BraceHighlight: + SetBraceHighlight(PositionFromUPtr(wParam), lParam, StyleBraceLight); break; - case SCI_BRACEHIGHLIGHTINDICATOR: - if (lParam >= 0 && lParam <= INDICATOR_MAX) { + case Message::BraceHighlightIndicator: + if (lParam >= 0 && static_cast(lParam) <= IndicatorMax) { vs.braceHighlightIndicatorSet = wParam != 0; vs.braceHighlightIndicator = static_cast(lParam); } break; - case SCI_BRACEBADLIGHT: - SetBraceHighlight(static_cast(wParam), -1, STYLE_BRACEBAD); + case Message::BraceBadLight: + SetBraceHighlight(PositionFromUPtr(wParam), -1, StyleBraceBad); break; - case SCI_BRACEBADLIGHTINDICATOR: - if (lParam >= 0 && lParam <= INDICATOR_MAX) { + case Message::BraceBadLightIndicator: + if (lParam >= 0 && static_cast(lParam) <= IndicatorMax) { vs.braceBadLightIndicatorSet = wParam != 0; vs.braceBadLightIndicator = static_cast(lParam); } break; - case SCI_BRACEMATCH: + case Message::BraceMatch: // wParam is position of char to find brace for, // lParam is maximum amount of text to restyle to find it - return pdoc->BraceMatch(static_cast(wParam), lParam, 0, false); + return pdoc->BraceMatch(PositionFromUPtr(wParam), lParam, 0, false); - case SCI_BRACEMATCHNEXT: - return pdoc->BraceMatch(static_cast(wParam), 0, lParam, true); + case Message::BraceMatchNext: + return pdoc->BraceMatch(PositionFromUPtr(wParam), 0, lParam, true); - case SCI_GETVIEWEOL: + case Message::GetViewEOL: return vs.viewEOL; - case SCI_SETVIEWEOL: + case Message::SetViewEOL: vs.viewEOL = wParam != 0; InvalidateStyleRedraw(); break; - case SCI_SETZOOM: { + case Message::SetZoom: { const int zoomLevel = static_cast(wParam); if (zoomLevel != vs.zoomLevel) { vs.zoomLevel = zoomLevel; @@ -7663,44 +7875,44 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; } - case SCI_GETZOOM: + case Message::GetZoom: return vs.zoomLevel; - case SCI_GETEDGECOLUMN: + case Message::GetEdgeColumn: return vs.theEdge.column; - case SCI_SETEDGECOLUMN: + case Message::SetEdgeColumn: vs.theEdge.column = static_cast(wParam); InvalidateStyleRedraw(); break; - case SCI_GETEDGEMODE: - return vs.edgeState; + case Message::GetEdgeMode: + return static_cast(vs.edgeState); - case SCI_SETEDGEMODE: - vs.edgeState = static_cast(wParam); + case Message::SetEdgeMode: + vs.edgeState = static_cast(wParam); InvalidateStyleRedraw(); break; - case SCI_GETEDGECOLOUR: - return vs.theEdge.colour.AsInteger(); + case Message::GetEdgeColour: + return vs.theEdge.colour.OpaqueRGB(); - case SCI_SETEDGECOLOUR: - vs.theEdge.colour = ColourDesired(static_cast(wParam)); + case Message::SetEdgeColour: + vs.theEdge.colour = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam)); InvalidateStyleRedraw(); break; - case SCI_MULTIEDGEADDLINE: + case Message::MultiEdgeAddLine: vs.AddMultiEdge(wParam, lParam); InvalidateStyleRedraw(); break; - case SCI_MULTIEDGECLEARALL: + case Message::MultiEdgeClearAll: std::vector().swap(vs.theMultiEdge); // Free vector and memory, C++03 compatible InvalidateStyleRedraw(); break; - case SCI_GETMULTIEDGECOLUMN: { + case Message::GetMultiEdgeColumn: { const size_t which = wParam; // size_t is unsigned so this also handles negative inputs. if (which >= vs.theMultiEdge.size()) { @@ -7709,673 +7921,710 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return vs.theMultiEdge[which].column; } - case SCI_GETACCESSIBILITY: - return SC_ACCESSIBILITY_DISABLED; + case Message::GetAccessibility: + return static_cast(Accessibility::Disabled); - case SCI_SETACCESSIBILITY: + case Message::SetAccessibility: // May be implemented by platform code. break; - case SCI_GETDOCPOINTER: + case Message::GetDocPointer: return reinterpret_cast(pdoc); - case SCI_SETDOCPOINTER: + case Message::SetDocPointer: CancelModes(); SetDocPointer(static_cast(PtrFromSPtr(lParam))); return 0; - case SCI_CREATEDOCUMENT: { - Document *doc = new Document(static_cast(lParam)); + case Message::CreateDocument: { + Document *doc = new Document(static_cast(lParam)); doc->AddRef(); - doc->Allocate(static_cast(wParam)); + doc->Allocate(PositionFromUPtr(wParam)); pcs = ContractionStateCreate(pdoc->IsLarge()); return reinterpret_cast(doc); } - case SCI_ADDREFDOCUMENT: + case Message::AddRefDocument: (static_cast(PtrFromSPtr(lParam)))->AddRef(); break; - case SCI_RELEASEDOCUMENT: + case Message::ReleaseDocument: (static_cast(PtrFromSPtr(lParam)))->Release(); break; - case SCI_GETDOCUMENTOPTIONS: - return pdoc->Options(); + case Message::GetDocumentOptions: + return static_cast(pdoc->Options()); - case SCI_CREATELOADER: { - Document *doc = new Document(static_cast(lParam)); + case Message::CreateLoader: { + Document *doc = new Document(static_cast(lParam)); doc->AddRef(); - doc->Allocate(static_cast(wParam)); + doc->Allocate(PositionFromUPtr(wParam)); doc->SetUndoCollection(false); pcs = ContractionStateCreate(pdoc->IsLarge()); return reinterpret_cast(static_cast(doc)); } - case SCI_SETMODEVENTMASK: - modEventMask = static_cast(wParam); + case Message::SetModEventMask: + modEventMask = static_cast(wParam); return 0; - case SCI_GETMODEVENTMASK: - return modEventMask; + case Message::GetModEventMask: + return static_cast(modEventMask); - case SCI_SETCOMMANDEVENTS: + case Message::SetCommandEvents: commandEvents = static_cast(wParam); return 0; - case SCI_GETCOMMANDEVENTS: + case Message::GetCommandEvents: return commandEvents; - case SCI_CONVERTEOLS: - pdoc->ConvertLineEnds(static_cast(wParam)); + case Message::ConvertEOLs: + pdoc->ConvertLineEnds(static_cast(wParam)); SetSelection(sel.MainCaret(), sel.MainAnchor()); // Ensure selection inside document return 0; - case SCI_SETLENGTHFORENCODE: - lengthForEncode = static_cast(wParam); + case Message::SetLengthForEncode: + lengthForEncode = PositionFromUPtr(wParam); return 0; - case SCI_SELECTIONISRECTANGLE: - return sel.selType == Selection::selRectangle ? 1 : 0; + case Message::SelectionIsRectangle: + return sel.selType == Selection::SelTypes::rectangle ? 1 : 0; - case SCI_SETSELECTIONMODE: { - switch (wParam) { - case SC_SEL_STREAM: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream)); - sel.selType = Selection::selStream; + case Message::SetSelectionMode: { + switch (static_cast(wParam)) { + case SelectionMode::Stream: + sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::SelTypes::stream)); + sel.selType = Selection::SelTypes::stream; break; - case SC_SEL_RECTANGLE: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selRectangle)); - sel.selType = Selection::selRectangle; + case SelectionMode::Rectangle: + sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::SelTypes::rectangle)); + sel.selType = Selection::SelTypes::rectangle; sel.Rectangular() = sel.RangeMain(); // adjust current selection break; - case SC_SEL_LINES: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selLines)); - sel.selType = Selection::selLines; + case SelectionMode::Lines: + sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::SelTypes::lines)); + sel.selType = Selection::SelTypes::lines; SetSelection(sel.RangeMain().caret, sel.RangeMain().anchor); // adjust current selection break; - case SC_SEL_THIN: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selThin)); - sel.selType = Selection::selThin; + case SelectionMode::Thin: + sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::SelTypes::thin)); + sel.selType = Selection::SelTypes::thin; break; default: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream)); - sel.selType = Selection::selStream; + sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::SelTypes::stream)); + sel.selType = Selection::SelTypes::stream; } InvalidateWholeSelection(); break; } - case SCI_GETSELECTIONMODE: + case Message::GetSelectionMode: switch (sel.selType) { - case Selection::selStream: - return SC_SEL_STREAM; - case Selection::selRectangle: - return SC_SEL_RECTANGLE; - case Selection::selLines: - return SC_SEL_LINES; - case Selection::selThin: - return SC_SEL_THIN; + case Selection::SelTypes::stream: + return static_cast(SelectionMode::Stream); + case Selection::SelTypes::rectangle: + return static_cast(SelectionMode::Rectangle); + case Selection::SelTypes::lines: + return static_cast(SelectionMode::Lines); + case Selection::SelTypes::thin: + return static_cast(SelectionMode::Thin); default: // ?! - return SC_SEL_STREAM; + return static_cast(SelectionMode::Stream); } - case SCI_GETMOVEEXTENDSSELECTION: + case Message::GetMoveExtendsSelection: return sel.MoveExtends(); - case SCI_GETLINESELSTARTPOSITION: - case SCI_GETLINESELENDPOSITION: { + case Message::GetLineSelStartPosition: + case Message::GetLineSelEndPosition: { const SelectionSegment segmentLine( - SelectionPosition(pdoc->LineStart(static_cast(wParam))), - SelectionPosition(pdoc->LineEnd(static_cast(wParam)))); + SelectionPosition(pdoc->LineStart(LineFromUPtr(wParam))), + SelectionPosition(pdoc->LineEnd(LineFromUPtr(wParam)))); for (size_t r=0; r(wParam); + case Message::SetStatus: + errorStatus = static_cast(wParam); break; - case SCI_GETSTATUS: - return errorStatus; + case Message::GetStatus: + return static_cast(errorStatus); - case SCI_SETMOUSEDOWNCAPTURES: + case Message::SetMouseDownCaptures: mouseDownCaptures = wParam != 0; break; - case SCI_GETMOUSEDOWNCAPTURES: + case Message::GetMouseDownCaptures: return mouseDownCaptures; - case SCI_SETMOUSEWHEELCAPTURES: + case Message::SetMouseWheelCaptures: mouseWheelCaptures = wParam != 0; break; - case SCI_GETMOUSEWHEELCAPTURES: + case Message::GetMouseWheelCaptures: return mouseWheelCaptures; - case SCI_SETCURSOR: - cursorMode = static_cast(wParam); - DisplayCursor(Window::cursorText); + case Message::SetCursor: + cursorMode = static_cast(wParam); + DisplayCursor(Window::Cursor::text); break; - case SCI_GETCURSOR: - return cursorMode; + case Message::GetCursor: + return static_cast(cursorMode); - case SCI_SETCONTROLCHARSYMBOL: + case Message::SetControlCharSymbol: vs.controlCharSymbol = static_cast(wParam); InvalidateStyleRedraw(); break; - case SCI_GETCONTROLCHARSYMBOL: + case Message::GetControlCharSymbol: return vs.controlCharSymbol; - case SCI_SETREPRESENTATION: + case Message::SetRepresentation: reprs.SetRepresentation(ConstCharPtrFromUPtr(wParam), ConstCharPtrFromSPtr(lParam)); break; - case SCI_GETREPRESENTATION: { + case Message::GetRepresentation: { const Representation *repr = reprs.RepresentationFromCharacter( - ConstCharPtrFromUPtr(wParam), UTF8MaxBytes); + ConstCharPtrFromUPtr(wParam)); if (repr) { return StringResult(lParam, repr->stringRep.c_str()); } return 0; } - case SCI_CLEARREPRESENTATION: + case Message::ClearRepresentation: reprs.ClearRepresentation(ConstCharPtrFromUPtr(wParam)); break; - case SCI_STARTRECORD: + case Message::ClearAllRepresentations: + SetRepresentations(); + break; + + case Message::SetRepresentationAppearance: + reprs.SetRepresentationAppearance(ConstCharPtrFromUPtr(wParam), static_cast(lParam)); + break; + + case Message::GetRepresentationAppearance: { + const Representation *repr = reprs.RepresentationFromCharacter( + ConstCharPtrFromUPtr(wParam)); + if (repr) { + return static_cast(repr->appearance); + } + return 0; + } + case Message::SetRepresentationColour: + reprs.SetRepresentationColour(ConstCharPtrFromUPtr(wParam), ColourRGBA(static_cast(lParam))); + break; + + case Message::GetRepresentationColour: { + const Representation *repr = reprs.RepresentationFromCharacter( + ConstCharPtrFromUPtr(wParam)); + if (repr) { + return repr->colour.AsInteger(); + } + return 0; + } + + case Message::StartRecord: recordingMacro = true; return 0; - case SCI_STOPRECORD: + case Message::StopRecord: recordingMacro = false; return 0; - case SCI_MOVECARETINSIDEVIEW: + case Message::MoveCaretInsideView: MoveCaretInsideView(); break; - case SCI_SETFOLDMARGINCOLOUR: - vs.foldmarginColour = ColourOptional(wParam, lParam); + case Message::SetFoldMarginColour: + vs.foldmarginColour = OptionalColour(wParam, lParam); InvalidateStyleRedraw(); break; - case SCI_SETFOLDMARGINHICOLOUR: - vs.foldmarginHighlightColour = ColourOptional(wParam, lParam); + case Message::SetFoldMarginHiColour: + vs.foldmarginHighlightColour = OptionalColour(wParam, lParam); InvalidateStyleRedraw(); break; - case SCI_SETHOTSPOTACTIVEFORE: - vs.hotspotColours.fore = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); + case Message::SetHotspotActiveFore: + if (vs.SetElementColourOptional(Element::HotSpotActive, wParam, lParam)) { + InvalidateStyleRedraw(); + } break; - case SCI_GETHOTSPOTACTIVEFORE: - return vs.hotspotColours.fore.AsInteger(); + case Message::GetHotspotActiveFore: + return vs.ElementColour(Element::HotSpotActive).value_or(ColourRGBA()).OpaqueRGB(); - case SCI_SETHOTSPOTACTIVEBACK: - vs.hotspotColours.back = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); + case Message::SetHotspotActiveBack: + if (vs.SetElementColourOptional(Element::HotSpotActiveBack, wParam, lParam)) { + InvalidateStyleRedraw(); + } break; - case SCI_GETHOTSPOTACTIVEBACK: - return vs.hotspotColours.back.AsInteger(); + case Message::GetHotspotActiveBack: + return vs.ElementColour(Element::HotSpotActiveBack).value_or(ColourRGBA()).OpaqueRGB(); - case SCI_SETHOTSPOTACTIVEUNDERLINE: + case Message::SetHotspotActiveUnderline: vs.hotspotUnderline = wParam != 0; InvalidateStyleRedraw(); break; - case SCI_GETHOTSPOTACTIVEUNDERLINE: + case Message::GetHotspotActiveUnderline: return vs.hotspotUnderline ? 1 : 0; - case SCI_SETHOTSPOTSINGLELINE: - vs.hotspotSingleLine = wParam != 0; + case Message::SetHotspotSingleLine: + hotspotSingleLine = wParam != 0; InvalidateStyleRedraw(); break; - case SCI_GETHOTSPOTSINGLELINE: - return vs.hotspotSingleLine ? 1 : 0; + case Message::GetHotspotSingleLine: + return hotspotSingleLine ? 1 : 0; - case SCI_SETPASTECONVERTENDINGS: + case Message::SetPasteConvertEndings: convertPastes = wParam != 0; break; - case SCI_GETPASTECONVERTENDINGS: + case Message::GetPasteConvertEndings: return convertPastes ? 1 : 0; - case SCI_GETCHARACTERPOINTER: + case Message::GetCharacterPointer: return reinterpret_cast(pdoc->BufferPointer()); - case SCI_GETRANGEPOINTER: + case Message::GetRangePointer: return reinterpret_cast(pdoc->RangePointer( - static_cast(wParam), lParam)); + PositionFromUPtr(wParam), lParam)); - case SCI_GETGAPPOSITION: + case Message::GetGapPosition: return pdoc->GapPosition(); - case SCI_SETEXTRAASCENT: + case Message::SetExtraAscent: vs.extraAscent = static_cast(wParam); InvalidateStyleRedraw(); break; - case SCI_GETEXTRAASCENT: + case Message::GetExtraAscent: return vs.extraAscent; - case SCI_SETEXTRADESCENT: + case Message::SetExtraDescent: vs.extraDescent = static_cast(wParam); InvalidateStyleRedraw(); break; - case SCI_GETEXTRADESCENT: + case Message::GetExtraDescent: return vs.extraDescent; - case SCI_MARGINSETSTYLEOFFSET: + case Message::MarginSetStyleOffset: vs.marginStyleOffset = static_cast(wParam); InvalidateStyleRedraw(); break; - case SCI_MARGINGETSTYLEOFFSET: + case Message::MarginGetStyleOffset: return vs.marginStyleOffset; - case SCI_SETMARGINOPTIONS: - marginOptions = static_cast(wParam); + case Message::SetMarginOptions: + marginOptions = static_cast(wParam); break; - case SCI_GETMARGINOPTIONS: - return marginOptions; + case Message::GetMarginOptions: + return static_cast(marginOptions); - case SCI_MARGINSETTEXT: - pdoc->MarginSetText(static_cast(wParam), CharPtrFromSPtr(lParam)); + case Message::MarginSetText: + pdoc->MarginSetText(LineFromUPtr(wParam), CharPtrFromSPtr(lParam)); break; - case SCI_MARGINGETTEXT: { - const StyledText st = pdoc->MarginStyledText(static_cast(wParam)); + case Message::MarginGetText: { + const StyledText st = pdoc->MarginStyledText(LineFromUPtr(wParam)); return BytesResult(lParam, reinterpret_cast(st.text), st.length); } - case SCI_MARGINSETSTYLE: - pdoc->MarginSetStyle(static_cast(wParam), static_cast(lParam)); + case Message::MarginSetStyle: + pdoc->MarginSetStyle(LineFromUPtr(wParam), static_cast(lParam)); break; - case SCI_MARGINGETSTYLE: { - const StyledText st = pdoc->MarginStyledText(static_cast(wParam)); + case Message::MarginGetStyle: { + const StyledText st = pdoc->MarginStyledText(LineFromUPtr(wParam)); return st.style; } - case SCI_MARGINSETSTYLES: - pdoc->MarginSetStyles(static_cast(wParam), ConstUCharPtrFromSPtr(lParam)); + case Message::MarginSetStyles: + pdoc->MarginSetStyles(LineFromUPtr(wParam), ConstUCharPtrFromSPtr(lParam)); break; - case SCI_MARGINGETSTYLES: { - const StyledText st = pdoc->MarginStyledText(static_cast(wParam)); + case Message::MarginGetStyles: { + const StyledText st = pdoc->MarginStyledText(LineFromUPtr(wParam)); return BytesResult(lParam, st.styles, st.length); } - case SCI_MARGINTEXTCLEARALL: + case Message::MarginTextClearAll: pdoc->MarginClearAll(); break; - case SCI_ANNOTATIONSETTEXT: - pdoc->AnnotationSetText(static_cast(wParam), CharPtrFromSPtr(lParam)); + case Message::AnnotationSetText: + pdoc->AnnotationSetText(LineFromUPtr(wParam), CharPtrFromSPtr(lParam)); break; - case SCI_ANNOTATIONGETTEXT: { - const StyledText st = pdoc->AnnotationStyledText(static_cast(wParam)); + case Message::AnnotationGetText: { + const StyledText st = pdoc->AnnotationStyledText(LineFromUPtr(wParam)); return BytesResult(lParam, reinterpret_cast(st.text), st.length); } - case SCI_ANNOTATIONGETSTYLE: { - const StyledText st = pdoc->AnnotationStyledText(static_cast(wParam)); + case Message::AnnotationGetStyle: { + const StyledText st = pdoc->AnnotationStyledText(LineFromUPtr(wParam)); return st.style; } - case SCI_ANNOTATIONSETSTYLE: - pdoc->AnnotationSetStyle(static_cast(wParam), static_cast(lParam)); + case Message::AnnotationSetStyle: + pdoc->AnnotationSetStyle(LineFromUPtr(wParam), static_cast(lParam)); break; - case SCI_ANNOTATIONSETSTYLES: - pdoc->AnnotationSetStyles(static_cast(wParam), ConstUCharPtrFromSPtr(lParam)); + case Message::AnnotationSetStyles: + pdoc->AnnotationSetStyles(LineFromUPtr(wParam), ConstUCharPtrFromSPtr(lParam)); break; - case SCI_ANNOTATIONGETSTYLES: { - const StyledText st = pdoc->AnnotationStyledText(static_cast(wParam)); + case Message::AnnotationGetStyles: { + const StyledText st = pdoc->AnnotationStyledText(LineFromUPtr(wParam)); return BytesResult(lParam, st.styles, st.length); } - case SCI_ANNOTATIONGETLINES: - return pdoc->AnnotationLines(static_cast(wParam)); + case Message::AnnotationGetLines: + return pdoc->AnnotationLines(LineFromUPtr(wParam)); - case SCI_ANNOTATIONCLEARALL: + case Message::AnnotationClearAll: pdoc->AnnotationClearAll(); break; - case SCI_ANNOTATIONSETVISIBLE: - SetAnnotationVisible(static_cast(wParam)); + case Message::AnnotationSetVisible: + SetAnnotationVisible(static_cast(wParam)); break; - case SCI_ANNOTATIONGETVISIBLE: - return vs.annotationVisible; + case Message::AnnotationGetVisible: + return static_cast(vs.annotationVisible); - case SCI_ANNOTATIONSETSTYLEOFFSET: + case Message::AnnotationSetStyleOffset: vs.annotationStyleOffset = static_cast(wParam); InvalidateStyleRedraw(); break; - case SCI_ANNOTATIONGETSTYLEOFFSET: + case Message::AnnotationGetStyleOffset: return vs.annotationStyleOffset; - case SCI_EOLANNOTATIONSETTEXT: - pdoc->EOLAnnotationSetText(static_cast(wParam), CharPtrFromSPtr(lParam)); + case Message::EOLAnnotationSetText: + pdoc->EOLAnnotationSetText(LineFromUPtr(wParam), CharPtrFromSPtr(lParam)); break; - case SCI_EOLANNOTATIONGETTEXT: { - const StyledText st = pdoc->EOLAnnotationStyledText(static_cast(wParam)); + case Message::EOLAnnotationGetText: { + const StyledText st = pdoc->EOLAnnotationStyledText(LineFromUPtr(wParam)); return BytesResult(lParam, reinterpret_cast(st.text), st.length); } - case SCI_EOLANNOTATIONGETSTYLE: { - const StyledText st = pdoc->EOLAnnotationStyledText(static_cast(wParam)); + case Message::EOLAnnotationGetStyle: { + const StyledText st = pdoc->EOLAnnotationStyledText(LineFromUPtr(wParam)); return st.style; } - case SCI_EOLANNOTATIONSETSTYLE: - pdoc->EOLAnnotationSetStyle(static_cast(wParam), static_cast(lParam)); + case Message::EOLAnnotationSetStyle: + pdoc->EOLAnnotationSetStyle(LineFromUPtr(wParam), static_cast(lParam)); break; - case SCI_EOLANNOTATIONCLEARALL: + case Message::EOLAnnotationClearAll: pdoc->EOLAnnotationClearAll(); break; - case SCI_EOLANNOTATIONSETVISIBLE: - SetEOLAnnotationVisible(static_cast(wParam)); + case Message::EOLAnnotationSetVisible: + SetEOLAnnotationVisible(static_cast(wParam)); break; - case SCI_EOLANNOTATIONGETVISIBLE: - return vs.eolAnnotationVisible; + case Message::EOLAnnotationGetVisible: + return static_cast(vs.eolAnnotationVisible); - case SCI_EOLANNOTATIONSETSTYLEOFFSET: + case Message::EOLAnnotationSetStyleOffset: vs.eolAnnotationStyleOffset = static_cast(wParam); InvalidateStyleRedraw(); break; - case SCI_EOLANNOTATIONGETSTYLEOFFSET: + case Message::EOLAnnotationGetStyleOffset: return vs.eolAnnotationStyleOffset; - case SCI_RELEASEALLEXTENDEDSTYLES: + case Message::ReleaseAllExtendedStyles: vs.ReleaseAllExtendedStyles(); break; - case SCI_ALLOCATEEXTENDEDSTYLES: + case Message::AllocateExtendedStyles: return vs.AllocateExtendedStyles(static_cast(wParam)); - case SCI_ADDUNDOACTION: - pdoc->AddUndoAction(static_cast(wParam), lParam & UNDO_MAY_COALESCE); + case Message::SupportsFeature: + return SupportsFeature(static_cast(wParam)); + + case Message::AddUndoAction: + pdoc->AddUndoAction(PositionFromUPtr(wParam), + FlagSet(static_cast(lParam), UndoFlags::MayCoalesce)); break; - case SCI_SETMOUSESELECTIONRECTANGULARSWITCH: + case Message::SetMouseSelectionRectangularSwitch: mouseSelectionRectangularSwitch = wParam != 0; break; - case SCI_GETMOUSESELECTIONRECTANGULARSWITCH: + case Message::GetMouseSelectionRectangularSwitch: return mouseSelectionRectangularSwitch; - case SCI_SETMULTIPLESELECTION: + case Message::SetMultipleSelection: multipleSelection = wParam != 0; InvalidateCaret(); break; - case SCI_GETMULTIPLESELECTION: + case Message::GetMultipleSelection: return multipleSelection; - case SCI_SETADDITIONALSELECTIONTYPING: + case Message::SetAdditionalSelectionTyping: additionalSelectionTyping = wParam != 0; InvalidateCaret(); break; - case SCI_GETADDITIONALSELECTIONTYPING: + case Message::GetAdditionalSelectionTyping: return additionalSelectionTyping; - case SCI_SETMULTIPASTE: - multiPasteMode = static_cast(wParam); + case Message::SetMultiPaste: + multiPasteMode = static_cast(wParam); break; - case SCI_GETMULTIPASTE: - return multiPasteMode; + case Message::GetMultiPaste: + return static_cast(multiPasteMode); - case SCI_SETADDITIONALCARETSBLINK: + case Message::SetAdditionalCaretsBlink: view.additionalCaretsBlink = wParam != 0; InvalidateCaret(); break; - case SCI_GETADDITIONALCARETSBLINK: + case Message::GetAdditionalCaretsBlink: return view.additionalCaretsBlink; - case SCI_SETADDITIONALCARETSVISIBLE: + case Message::SetAdditionalCaretsVisible: view.additionalCaretsVisible = wParam != 0; InvalidateCaret(); break; - case SCI_GETADDITIONALCARETSVISIBLE: + case Message::GetAdditionalCaretsVisible: return view.additionalCaretsVisible; - case SCI_GETSELECTIONS: + case Message::GetSelections: return sel.Count(); - case SCI_GETSELECTIONEMPTY: + case Message::GetSelectionEmpty: return sel.Empty(); - case SCI_CLEARSELECTIONS: + case Message::ClearSelections: sel.Clear(); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + ContainerNeedsUpdate(Update::Selection); Redraw(); break; - case SCI_SETSELECTION: - sel.SetSelection(SelectionRange(static_cast(wParam), lParam)); + case Message::SetSelection: + sel.SetSelection(SelectionRange(PositionFromUPtr(wParam), lParam)); Redraw(); break; - case SCI_ADDSELECTION: - sel.AddSelection(SelectionRange(static_cast(wParam), lParam)); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + case Message::AddSelection: + sel.AddSelection(SelectionRange(PositionFromUPtr(wParam), lParam)); + ContainerNeedsUpdate(Update::Selection); Redraw(); break; - case SCI_DROPSELECTIONN: - sel.DropSelection(static_cast(wParam)); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + case Message::DropSelectionN: + sel.DropSelection(wParam); + ContainerNeedsUpdate(Update::Selection); Redraw(); break; - case SCI_SETMAINSELECTION: - sel.SetMain(static_cast(wParam)); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); + case Message::SetMainSelection: + sel.SetMain(wParam); + ContainerNeedsUpdate(Update::Selection); Redraw(); break; - case SCI_GETMAINSELECTION: + case Message::GetMainSelection: return sel.Main(); - case SCI_SETSELECTIONNCARET: - case SCI_SETSELECTIONNANCHOR: - case SCI_SETSELECTIONNCARETVIRTUALSPACE: - case SCI_SETSELECTIONNANCHORVIRTUALSPACE: - case SCI_SETSELECTIONNSTART: - case SCI_SETSELECTIONNEND: + case Message::SetSelectionNCaret: + case Message::SetSelectionNAnchor: + case Message::SetSelectionNCaretVirtualSpace: + case Message::SetSelectionNAnchorVirtualSpace: + case Message::SetSelectionNStart: + case Message::SetSelectionNEnd: SetSelectionNMessage(iMessage, wParam, lParam); break; - case SCI_GETSELECTIONNCARET: + case Message::GetSelectionNCaret: return sel.Range(wParam).caret.Position(); - case SCI_GETSELECTIONNANCHOR: + case Message::GetSelectionNAnchor: return sel.Range(wParam).anchor.Position(); - case SCI_GETSELECTIONNCARETVIRTUALSPACE: + case Message::GetSelectionNCaretVirtualSpace: return sel.Range(wParam).caret.VirtualSpace(); - case SCI_GETSELECTIONNANCHORVIRTUALSPACE: + case Message::GetSelectionNAnchorVirtualSpace: return sel.Range(wParam).anchor.VirtualSpace(); - case SCI_GETSELECTIONNSTART: + case Message::GetSelectionNStart: return sel.Range(wParam).Start().Position(); - case SCI_GETSELECTIONNSTARTVIRTUALSPACE: + case Message::GetSelectionNStartVirtualSpace: return sel.Range(wParam).Start().VirtualSpace(); - case SCI_GETSELECTIONNEND: + case Message::GetSelectionNEnd: return sel.Range(wParam).End().Position(); - case SCI_GETSELECTIONNENDVIRTUALSPACE: + case Message::GetSelectionNEndVirtualSpace: return sel.Range(wParam).End().VirtualSpace(); - case SCI_SETRECTANGULARSELECTIONCARET: + case Message::SetRectangularSelectionCaret: if (!sel.IsRectangular()) sel.Clear(); - sel.selType = Selection::selRectangle; - sel.Rectangular().caret.SetPosition(static_cast(wParam)); + sel.selType = Selection::SelTypes::rectangle; + sel.Rectangular().caret.SetPosition(PositionFromUPtr(wParam)); SetRectangularRange(); Redraw(); break; - case SCI_GETRECTANGULARSELECTIONCARET: + case Message::GetRectangularSelectionCaret: return sel.Rectangular().caret.Position(); - case SCI_SETRECTANGULARSELECTIONANCHOR: + case Message::SetRectangularSelectionAnchor: if (!sel.IsRectangular()) sel.Clear(); - sel.selType = Selection::selRectangle; - sel.Rectangular().anchor.SetPosition(static_cast(wParam)); + sel.selType = Selection::SelTypes::rectangle; + sel.Rectangular().anchor.SetPosition(PositionFromUPtr(wParam)); SetRectangularRange(); Redraw(); break; - case SCI_GETRECTANGULARSELECTIONANCHOR: + case Message::GetRectangularSelectionAnchor: return sel.Rectangular().anchor.Position(); - case SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE: + case Message::SetRectangularSelectionCaretVirtualSpace: if (!sel.IsRectangular()) sel.Clear(); - sel.selType = Selection::selRectangle; - sel.Rectangular().caret.SetVirtualSpace(static_cast(wParam)); + sel.selType = Selection::SelTypes::rectangle; + sel.Rectangular().caret.SetVirtualSpace(PositionFromUPtr(wParam)); SetRectangularRange(); Redraw(); break; - case SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE: + case Message::GetRectangularSelectionCaretVirtualSpace: return sel.Rectangular().caret.VirtualSpace(); - case SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE: + case Message::SetRectangularSelectionAnchorVirtualSpace: if (!sel.IsRectangular()) sel.Clear(); - sel.selType = Selection::selRectangle; - sel.Rectangular().anchor.SetVirtualSpace(static_cast(wParam)); + sel.selType = Selection::SelTypes::rectangle; + sel.Rectangular().anchor.SetVirtualSpace(PositionFromUPtr(wParam)); SetRectangularRange(); Redraw(); break; - case SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE: + case Message::GetRectangularSelectionAnchorVirtualSpace: return sel.Rectangular().anchor.VirtualSpace(); - case SCI_SETVIRTUALSPACEOPTIONS: - virtualSpaceOptions = static_cast(wParam); + case Message::SetVirtualSpaceOptions: + virtualSpaceOptions = static_cast(wParam); break; - case SCI_GETVIRTUALSPACEOPTIONS: - return virtualSpaceOptions; + case Message::GetVirtualSpaceOptions: + return static_cast(virtualSpaceOptions); - case SCI_SETADDITIONALSELFORE: - vs.selAdditionalForeground = ColourDesired(static_cast(wParam)); + case Message::SetAdditionalSelFore: + vs.elementColours[Element::SelectionAdditionalText] = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam)); InvalidateStyleRedraw(); break; - case SCI_SETADDITIONALSELBACK: - vs.selAdditionalBackground = ColourDesired(static_cast(wParam)); + case Message::SetAdditionalSelBack: + vs.SetElementRGB(Element::SelectionAdditionalBack, static_cast(wParam)); InvalidateStyleRedraw(); break; - case SCI_SETADDITIONALSELALPHA: - vs.selAdditionalAlpha = static_cast(wParam); + case Message::SetAdditionalSelAlpha: + vs.SetElementAlpha(Element::SelectionAdditionalBack, static_cast(wParam)); InvalidateStyleRedraw(); break; - case SCI_GETADDITIONALSELALPHA: - return vs.selAdditionalAlpha; + case Message::GetAdditionalSelAlpha: + if (vs.selection.layer == Layer::Base) + return static_cast(Alpha::NoAlpha); + return vs.ElementColour(Element::SelectionAdditionalBack)->GetAlpha(); - case SCI_SETADDITIONALCARETFORE: - vs.additionalCaretColour = ColourDesired(static_cast(wParam)); + case Message::SetAdditionalCaretFore: + vs.elementColours[Element::CaretAdditional] = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam)); InvalidateStyleRedraw(); break; - case SCI_GETADDITIONALCARETFORE: - return vs.additionalCaretColour.AsInteger(); + case Message::GetAdditionalCaretFore: + return vs.ElementColour(Element::CaretAdditional)->OpaqueRGB(); - case SCI_ROTATESELECTION: + case Message::RotateSelection: sel.RotateMain(); InvalidateWholeSelection(); break; - case SCI_SWAPMAINANCHORCARET: + case Message::SwapMainAnchorCaret: InvalidateSelection(sel.RangeMain()); sel.RangeMain().Swap(); break; - case SCI_MULTIPLESELECTADDNEXT: + case Message::MultipleSelectAddNext: MultipleSelectAdd(AddNumber::one); break; - case SCI_MULTIPLESELECTADDEACH: + case Message::MultipleSelectAddEach: MultipleSelectAdd(AddNumber::each); break; - case SCI_CHANGELEXERSTATE: - pdoc->ChangeLexerState(static_cast(wParam), lParam); + case Message::ChangeLexerState: + pdoc->ChangeLexerState(PositionFromUPtr(wParam), lParam); break; - case SCI_SETIDENTIFIER: + case Message::SetIdentifier: SetCtrlID(static_cast(wParam)); break; - case SCI_GETIDENTIFIER: + case Message::GetIdentifier: return GetCtrlID(); - case SCI_SETTECHNOLOGY: + case Message::SetTechnology: // No action by default break; - case SCI_GETTECHNOLOGY: - return technology; + case Message::GetTechnology: + return static_cast(technology); - case SCI_COUNTCHARACTERS: - return pdoc->CountCharacters(static_cast(wParam), lParam); + case Message::CountCharacters: + return pdoc->CountCharacters(PositionFromUPtr(wParam), lParam); - case SCI_COUNTCODEUNITS: - return pdoc->CountUTF16(static_cast(wParam), lParam); + case Message::CountCodeUnits: + return pdoc->CountUTF16(PositionFromUPtr(wParam), lParam); default: return DefWndProc(iMessage, wParam, lParam); diff --git a/scintilla/src/Editor.h b/scintilla/src/Editor.h index cf77c8d789..417700ed53 100644 --- a/scintilla/src/Editor.h +++ b/scintilla/src/Editor.h @@ -8,7 +8,7 @@ #ifndef EDITOR_H #define EDITOR_H -namespace Scintilla { +namespace Scintilla::Internal { /** */ @@ -37,25 +37,27 @@ class Idler { * accumulate needed styling range and other work items in * WorkNeeded to avoid unnecessary work inside paint handler */ + +enum class WorkItems { + none = 0, + style = 1, + updateUI = 2 +}; + class WorkNeeded { public: - enum workItems { - workNone=0, - workStyle=1, - workUpdateUI=2 - }; - enum workItems items; + enum WorkItems items; Sci::Position upTo; - WorkNeeded() noexcept : items(workNone), upTo(0) {} + WorkNeeded() noexcept : items(WorkItems::none), upTo(0) {} void Reset() noexcept { - items = workNone; + items = WorkItems::none; upTo = 0; } - void Need(workItems items_, Sci::Position pos) noexcept { - if ((items_ & workStyle) && (upTo < pos)) + void Need(WorkItems items_, Sci::Position pos) noexcept { + if (Scintilla::FlagSet(items_, WorkItems::style) && (upTo < pos)) upTo = pos; - items = static_cast(items | items_); + items = static_cast(static_cast(items) | static_cast(items_)); } }; @@ -68,16 +70,16 @@ class SelectionText { bool rectangular; bool lineCopy; int codePage; - int characterSet; - SelectionText() noexcept : rectangular(false), lineCopy(false), codePage(0), characterSet(0) {} + Scintilla::CharacterSet characterSet; + SelectionText() noexcept : rectangular(false), lineCopy(false), codePage(0), characterSet(Scintilla::CharacterSet::Ansi) {} void Clear() noexcept { s.clear(); rectangular = false; lineCopy = false; codePage = 0; - characterSet = 0; + characterSet = Scintilla::CharacterSet::Ansi; } - void Copy(const std::string &s_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) { + void Copy(const std::string &s_, int codePage_, Scintilla::CharacterSet characterSet_, bool rectangular_, bool lineCopy_) { s = s_; codePage = codePage_; characterSet = characterSet_; @@ -143,18 +145,39 @@ struct WrapPending { } }; -struct CaretPolicy { - int policy; // Combination from CARET_SLOP, CARET_STRICT, CARET_JUMPS, CARET_EVEN +struct CaretPolicySlop { + Scintilla::CaretPolicy policy; // Combination from CaretPolicy::Slop, CaretPolicy::Strict, CaretPolicy::Jumps, CaretPolicy::Even int slop; // Pixels for X, lines for Y - CaretPolicy(uptr_t policy_=0, sptr_t slop_=0) noexcept : - policy(static_cast(policy_)), slop(static_cast(slop_)) {} + CaretPolicySlop(Scintilla::CaretPolicy policy_, intptr_t slop_) noexcept : + policy(policy_), slop(static_cast(slop_)) {} + CaretPolicySlop(uintptr_t policy_=0, intptr_t slop_=0) noexcept : + policy(static_cast(policy_)), slop(static_cast(slop_)) {} }; struct CaretPolicies { - CaretPolicy x; - CaretPolicy y; + CaretPolicySlop x; + CaretPolicySlop y; +}; + +struct VisiblePolicySlop { + Scintilla::VisiblePolicy policy; // Combination from VisiblePolicy::Slop, VisiblePolicy::Strict + int slop; // Pixels for X, lines for Y + VisiblePolicySlop(uintptr_t policy_ = 0, intptr_t slop_ = 0) noexcept : + policy(static_cast(policy_)), slop(static_cast(slop_)) {} }; +enum class XYScrollOptions { + none = 0x0, + useMargin = 0x1, + vertical = 0x2, + horizontal = 0x4, + all = useMargin | vertical | horizontal +}; + +constexpr XYScrollOptions operator|(XYScrollOptions a, XYScrollOptions b) noexcept { + return static_cast(static_cast(a) | static_cast(b)); +} + /** */ class Editor : public EditModel, public DocWatcher { @@ -169,16 +192,15 @@ class Editor : public EditModel, public DocWatcher { * When a style attribute is changed, this cache is flushed. */ bool stylesValid; ViewStyle vs; - int technology; + Scintilla::Technology technology; Point sizeRGBAImage; float scaleRGBAImage; MarginView marginView; EditView view; - int cursorMode; + Scintilla::CursorShape cursorMode; - bool hasFocus; bool mouseDownCaptures; bool mouseWheelCaptures; @@ -187,14 +209,14 @@ class Editor : public EditModel, public DocWatcher { int scrollWidth; bool verticalScrollBarVisible; bool endAtLastLine; - int caretSticky; - int marginOptions; + Scintilla::CaretSticky caretSticky; + Scintilla::MarginOption marginOptions; bool mouseSelectionRectangularSwitch; bool multipleSelection; bool additionalSelectionTyping; - int multiPasteMode; + Scintilla::MultiPaste multiPasteMode; - int virtualSpaceOptions; + Scintilla::VirtualSpace virtualSpaceOptions; KeyMap kmap; @@ -212,7 +234,7 @@ class Editor : public EditModel, public DocWatcher { bool dwelling; enum class TextUnit { character, word, subLine, wholeLine } selectionUnit; Point ptMouseLast; - enum { ddNone, ddInitial, ddDragging } inDragDrop; + enum class DragDrop { none, initial, dragging } inDragDrop; bool dropWentOutside; SelectionPosition posDrop; Sci::Position hotSpotClickPos; @@ -223,40 +245,40 @@ class Editor : public EditModel, public DocWatcher { Sci::Position wordSelectAnchorEndPos; Sci::Position wordSelectInitialCaretPos; SelectionSegment targetRange; - int searchFlags; + Scintilla::FindOption searchFlags; Sci::Line topLine; Sci::Position posTopLine; Sci::Position lengthForEncode; - int needUpdateUI; + Scintilla::Update needUpdateUI; - enum { notPainting, painting, paintAbandoned } paintState; + enum class PaintState { notPainting, painting, abandoned } paintState; bool paintAbandonedByStyling; PRectangle rcPaint; bool paintingAllText; bool willRedrawAll; WorkNeeded workNeeded; - int idleStyling; + Scintilla::IdleStyling idleStyling; bool needIdleStyling; - int modEventMask; + Scintilla::ModificationFlags modEventMask; bool commandEvents; SelectionText drag; CaretPolicies caretPolicies; - CaretPolicy visiblePolicy; + VisiblePolicySlop visiblePolicy; Sci::Position searchAnchor; bool recordingMacro; - int foldAutomatic; + Scintilla::AutomaticFold foldAutomatic; // Wrapping support WrapPending wrapPending; - ActionDuration durationWrapOneLine; + ActionDuration durationWrapOneByte; bool convertPastes; @@ -274,8 +296,7 @@ class Editor : public EditModel, public DocWatcher { void InvalidateStyleRedraw(); void RefreshStyleData(); void SetRepresentations(); - void DropGraphics(bool freeObjects); - void AllocateGraphics(); + void DropGraphics() noexcept; // The top left visible point in main window coordinates. Will be 0,0 except for // scroll views where it will be equivalent to the current scroll position. @@ -290,8 +311,8 @@ class Editor : public EditModel, public DocWatcher { Sci::Line LinesToScroll() const; Sci::Line MaxScrollPos() const; SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const; - Point LocationFromPosition(SelectionPosition pos, PointEnd pe=peDefault); - Point LocationFromPosition(Sci::Position pos, PointEnd pe=peDefault); + Point LocationFromPosition(SelectionPosition pos, PointEnd pe=PointEnd::start); + Point LocationFromPosition(Sci::Position pos, PointEnd pe=PointEnd::start); int XFromPosition(SelectionPosition sp); SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true); Sci::Position PositionFromLocation(Point pt, bool canReturnInvalid = false, bool charPosition = false); @@ -309,7 +330,7 @@ class Editor : public EditModel, public DocWatcher { void InvalidateRange(Sci::Position start, Sci::Position end); bool UserVirtualSpace() const noexcept { - return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0); + return (FlagSet(virtualSpaceOptions, Scintilla::VirtualSpace::UserAccessible)); } Sci::Position CurrentPosition() const; bool SelectionEmpty() const noexcept; @@ -323,7 +344,6 @@ class Editor : public EditModel, public DocWatcher { void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_); void SetSelection(Sci::Position currentPos_, Sci::Position anchor_); void SetSelection(SelectionPosition currentPos_); - void SetSelection(int currentPos_); void SetEmptySelection(SelectionPosition currentPos_); void SetEmptySelection(Sci::Position currentPos_); enum class AddNumber { one, each }; @@ -334,8 +354,8 @@ class Editor : public EditModel, public DocWatcher { SelectionPosition MovePositionOutsideChar(SelectionPosition pos, Sci::Position moveDir, bool checkLineEnd=true) const; void MovedCaret(SelectionPosition newPos, SelectionPosition previousPos, bool ensureVisible, CaretPolicies policies); - void MovePositionTo(SelectionPosition newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true); - void MovePositionTo(Sci::Position newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true); + void MovePositionTo(SelectionPosition newPos, Selection::SelTypes selt=Selection::SelTypes::none, bool ensureVisible=true); + void MovePositionTo(Sci::Position newPos, Selection::SelTypes selt=Selection::SelTypes::none, bool ensureVisible=true); SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir); SelectionPosition MovePositionSoVisible(Sci::Position pos, int moveDir); Point PointMainCaret(); @@ -359,11 +379,6 @@ class Editor : public EditModel, public DocWatcher { return (xOffset == other.xOffset) && (topLine == other.topLine); } }; - enum XYScrollOptions { - xysUseMargin=0x1, - xysVertical=0x2, - xysHorizontal=0x4, - xysDefault=xysUseMargin|xysVertical|xysHorizontal}; XYScrollPosition XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options, CaretPolicies policies); void SetXYScroll(XYScrollPosition newXY); @@ -387,8 +402,8 @@ class Editor : public EditModel, public DocWatcher { void PaintSelMargin(Surface *surfaceWindow, const PRectangle &rc); void RefreshPixMaps(Surface *surfaceWindow); void Paint(Surface *surfaceWindow, PRectangle rcArea); - Sci::Position FormatRange(bool draw, const Sci_RangeToFormat *pfr); - long TextWidth(uptr_t style, const char *text); + Sci::Position FormatRange(bool draw, const Scintilla::RangeToFormat *pfr); + long TextWidth(Scintilla::uptr_t style, const char *text); virtual void SetVerticalScrollPos() = 0; virtual void SetHorizontalScrollPos() = 0; @@ -401,10 +416,10 @@ class Editor : public EditModel, public DocWatcher { Sci::Position RealizeVirtualSpace(Sci::Position position, Sci::Position virtualSpace); SelectionPosition RealizeVirtualSpace(const SelectionPosition &position); void AddChar(char ch); - virtual void InsertCharacter(const char *s, unsigned int len, CharacterSource charSource); + virtual void InsertCharacter(std::string_view sv, Scintilla::CharacterSource charSource); void ClearBeforeTentativeStart(); void InsertPaste(const char *text, Sci::Position len); - enum PasteShape { pasteStream=0, pasteRectangular = 1, pasteLine = 2 }; + enum class PasteShape { stream=0, rectangular = 1, line = 2 }; void InsertPasteShape(const char *text, Sci::Position len, PasteShape shape); void ClearSelection(bool retainMultipleSelections = false); void ClearAll(); @@ -422,25 +437,25 @@ class Editor : public EditModel, public DocWatcher { void DelCharBack(bool allowLineStartDeletion); virtual void ClaimSelection() = 0; - static int ModifierFlags(bool shift, bool ctrl, bool alt, bool meta=false, bool super=false) noexcept; + static Scintilla::KeyMod ModifierFlags(bool shift, bool ctrl, bool alt, bool meta=false, bool super=false) noexcept; virtual void NotifyChange() = 0; virtual void NotifyFocus(bool focus); virtual void SetCtrlID(int identifier); virtual int GetCtrlID() { return ctrlID; } - virtual void NotifyParent(SCNotification scn) = 0; + virtual void NotifyParent(Scintilla::NotificationData scn) = 0; virtual void NotifyStyleToNeeded(Sci::Position endStyleNeeded); - void NotifyChar(int ch, CharacterSource charSource); + void NotifyChar(int ch, Scintilla::CharacterSource charSource); void NotifySavePoint(bool isSavePoint); void NotifyModifyAttempt(); - virtual void NotifyDoubleClick(Point pt, int modifiers); - void NotifyHotSpotClicked(Sci::Position position, int modifiers); - void NotifyHotSpotDoubleClicked(Sci::Position position, int modifiers); - void NotifyHotSpotReleaseClick(Sci::Position position, int modifiers); + virtual void NotifyDoubleClick(Point pt, Scintilla::KeyMod modifiers); + void NotifyHotSpotClicked(Sci::Position position, Scintilla::KeyMod modifiers); + void NotifyHotSpotDoubleClicked(Sci::Position position, Scintilla::KeyMod modifiers); + void NotifyHotSpotReleaseClick(Sci::Position position, Scintilla::KeyMod modifiers); bool NotifyUpdateUI(); void NotifyPainted(); - void NotifyIndicatorClick(bool click, Sci::Position position, int modifiers); - bool NotifyMarginClick(Point pt, int modifiers); - bool NotifyMarginRightClick(Point pt, int modifiers); + void NotifyIndicatorClick(bool click, Sci::Position position, Scintilla::KeyMod modifiers); + bool NotifyMarginClick(Point pt, Scintilla::KeyMod modifiers); + bool NotifyMarginRightClick(Point pt, Scintilla::KeyMod modifiers); void NotifyNeedShown(Sci::Position pos, Sci::Position len); void NotifyDwelling(Point pt, bool state); void NotifyZoom(); @@ -452,39 +467,39 @@ class Editor : public EditModel, public DocWatcher { void NotifyDeleted(Document *document, void *userData) noexcept override; void NotifyStyleNeeded(Document *doc, void *userData, Sci::Position endStyleNeeded) override; void NotifyLexerChanged(Document *doc, void *userData) override; - void NotifyErrorOccurred(Document *doc, void *userData, int status) override; - void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - - void ContainerNeedsUpdate(int flags) noexcept; - void PageMove(int direction, Selection::selTypes selt=Selection::noSel, bool stuttered = false); - enum { cmSame, cmUpper, cmLower }; - virtual std::string CaseMapString(const std::string &s, int caseMapping); - void ChangeCaseOfSelection(int caseMapping); + void NotifyErrorOccurred(Document *doc, void *userData, Scintilla::Status status) override; + void NotifyMacroRecord(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam); + + void ContainerNeedsUpdate(Scintilla::Update flags) noexcept; + void PageMove(int direction, Selection::SelTypes selt=Selection::SelTypes::none, bool stuttered = false); + enum class CaseMapping { same, upper, lower }; + virtual std::string CaseMapString(const std::string &s, CaseMapping caseMapping); + void ChangeCaseOfSelection(CaseMapping caseMapping); void LineTranspose(); void LineReverse(); void Duplicate(bool forLine); virtual void CancelModes(); void NewLine(); SelectionPosition PositionUpOrDown(SelectionPosition spStart, int direction, int lastX); - void CursorUpOrDown(int direction, Selection::selTypes selt); - void ParaUpOrDown(int direction, Selection::selTypes selt); + void CursorUpOrDown(int direction, Selection::SelTypes selt); + void ParaUpOrDown(int direction, Selection::SelTypes selt); Range RangeDisplayLine(Sci::Line lineVisible); Sci::Position StartEndDisplayLine(Sci::Position pos, bool start); Sci::Position VCHomeDisplayPosition(Sci::Position position); Sci::Position VCHomeWrapPosition(Sci::Position position); Sci::Position LineEndWrapPosition(Sci::Position position); - int HorizontalMove(unsigned int iMessage); - int DelWordOrLine(unsigned int iMessage); - virtual int KeyCommand(unsigned int iMessage); - virtual int KeyDefault(int /* key */, int /*modifiers*/); - int KeyDownWithModifiers(int key, int modifiers, bool *consumed); + int HorizontalMove(Scintilla::Message iMessage); + int DelWordOrLine(Scintilla::Message iMessage); + virtual int KeyCommand(Scintilla::Message iMessage); + virtual int KeyDefault(Scintilla::Keys /* key */, Scintilla::KeyMod /*modifiers*/); + int KeyDownWithModifiers(Scintilla::Keys key, Scintilla::KeyMod modifiers, bool *consumed); void Indent(bool forwards); - virtual CaseFolder *CaseFolderForEncoding(); - Sci::Position FindText(uptr_t wParam, sptr_t lParam); + virtual std::unique_ptr CaseFolderForEncoding(); + Sci::Position FindText(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam); void SearchAnchor(); - Sci::Position SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + Sci::Position SearchText(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam); Sci::Position SearchInTarget(const char *text, Sci::Position length); void GoToLine(Sci::Line lineNo); @@ -509,13 +524,13 @@ class Editor : public EditModel, public DocWatcher { void WordSelection(Sci::Position pos); void DwellEnd(bool mouseMoved); void MouseLeave(); - virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers); - virtual void RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers); - void ButtonMoveWithModifiers(Point pt, unsigned int curTime, int modifiers); - void ButtonUpWithModifiers(Point pt, unsigned int curTime, int modifiers); + virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers); + virtual void RightButtonDownWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers); + void ButtonMoveWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers); + void ButtonUpWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers); bool Idle(); - enum TickReason { tickCaret, tickScroll, tickWiden, tickDwell, tickPlatform }; + enum class TickReason { caret, scroll, widen, dwell, platform }; virtual void TickFor(TickReason reason); virtual bool FineTickerRunning(TickReason reason); virtual void FineTickerStart(TickReason reason, int millis, int tolerance); @@ -524,19 +539,21 @@ class Editor : public EditModel, public DocWatcher { virtual void SetMouseCapture(bool on) = 0; virtual bool HaveMouseCapture() = 0; void SetFocusState(bool focusState); + virtual void UpdateBaseElements(); Sci::Position PositionAfterArea(PRectangle rcArea) const; void StyleToPositionInView(Sci::Position pos); Sci::Position PositionAfterMaxStyling(Sci::Position posMax, bool scrolling) const; void StartIdleStyling(bool truncatedLastStyling); void StyleAreaBounded(PRectangle rcArea, bool scrolling); - bool SynchronousStylingToVisible() const noexcept { - return (idleStyling == SC_IDLESTYLING_NONE) || (idleStyling == SC_IDLESTYLING_AFTERVISIBLE); + constexpr bool SynchronousStylingToVisible() const noexcept { + return (idleStyling == Scintilla::IdleStyling::None) || (idleStyling == Scintilla::IdleStyling::AfterVisible); } - void IdleStyling(); + void IdleStyle(); virtual void IdleWork(); - virtual void QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo=0); + virtual void QueueIdleWork(WorkItems items, Sci::Position upTo=0); + virtual int SupportsFeature(Scintilla::Supports feature); virtual bool PaintContains(PRectangle rc); bool PaintContainsMargin(); void CheckForChangeOutsidePaint(Range r); @@ -545,18 +562,18 @@ class Editor : public EditModel, public DocWatcher { void SetAnnotationHeights(Sci::Line start, Sci::Line end); virtual void SetDocPointer(Document *document); - void SetAnnotationVisible(int visible); - void SetEOLAnnotationVisible(int visible); + void SetAnnotationVisible(Scintilla::AnnotationVisible visible); + void SetEOLAnnotationVisible(Scintilla::EOLAnnotationVisible visible); Sci::Line ExpandLine(Sci::Line line); void SetFoldExpanded(Sci::Line lineDoc, bool expanded); - void FoldLine(Sci::Line line, int action); - void FoldExpand(Sci::Line line, int action, int level); + void FoldLine(Sci::Line line, Scintilla::FoldAction action); + void FoldExpand(Sci::Line line, Scintilla::FoldAction action, Scintilla::FoldLevel level); Sci::Line ContractedFoldNext(Sci::Line lineStart) const; void EnsureLineVisible(Sci::Line lineDoc, bool enforcePolicy); - void FoldChanged(Sci::Line line, int levelNow, int levelPrev); + void FoldChanged(Sci::Line line, Scintilla::FoldLevel levelNow, Scintilla::FoldLevel levelPrev); void NeedShown(Sci::Position pos, Sci::Position len); - void FoldAll(int action); + void FoldAll(Scintilla::FoldAction action); Sci::Position GetTag(char *tagValue, int tagNumber); Sci::Position ReplaceTarget(bool replacePatterns, const char *text, Sci::Position length=-1); @@ -570,42 +587,65 @@ class Editor : public EditModel, public DocWatcher { int CodePage() const noexcept; virtual bool ValidCodePage(int /* codePage */) const { return true; } + virtual std::string UTF8FromEncoded(std::string_view encoded) const = 0; + virtual std::string EncodedFromUTF8(std::string_view utf8) const = 0; + Sci::Line WrapCount(Sci::Line line); void AddStyledText(const char *buffer, Sci::Position appendLength); - virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; - bool ValidMargin(uptr_t wParam) const noexcept; - void StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - sptr_t StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - void SetSelectionNMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + virtual Scintilla::sptr_t DefWndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) = 0; + bool ValidMargin(Scintilla::uptr_t wParam) const noexcept; + void StyleSetMessage(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam); + 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(int eolMode) noexcept; + static const char *StringFromEOLMode(Scintilla::EndOfLine eolMode) noexcept; // Coercion functions for transforming WndProc parameters into pointers - static void *PtrFromSPtr(sptr_t lParam) noexcept { + static void *PtrFromSPtr(Scintilla::sptr_t lParam) noexcept { return reinterpret_cast(lParam); } - static const char *ConstCharPtrFromSPtr(sptr_t lParam) noexcept { + static const char *ConstCharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept { return static_cast(PtrFromSPtr(lParam)); } - static const unsigned char *ConstUCharPtrFromSPtr(sptr_t lParam) noexcept { + static const unsigned char *ConstUCharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept { return static_cast(PtrFromSPtr(lParam)); } - static char *CharPtrFromSPtr(sptr_t lParam) noexcept { + static char *CharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept { return static_cast(PtrFromSPtr(lParam)); } - static unsigned char *UCharPtrFromSPtr(sptr_t lParam) noexcept { + static unsigned char *UCharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept { return static_cast(PtrFromSPtr(lParam)); } - static void *PtrFromUPtr(uptr_t wParam) noexcept { + static void *PtrFromUPtr(Scintilla::uptr_t wParam) noexcept { return reinterpret_cast(wParam); } - static const char *ConstCharPtrFromUPtr(uptr_t wParam) noexcept { + static const char *ConstCharPtrFromUPtr(Scintilla::uptr_t wParam) noexcept { return static_cast(PtrFromUPtr(wParam)); } - static sptr_t StringResult(sptr_t lParam, const char *val) noexcept; - static sptr_t BytesResult(sptr_t lParam, const unsigned char *val, size_t len) noexcept; + static constexpr Scintilla::sptr_t SPtrFromUPtr(Scintilla::uptr_t wParam) noexcept { + return static_cast(wParam); + } + static constexpr Sci::Position PositionFromUPtr(Scintilla::uptr_t wParam) noexcept { + return SPtrFromUPtr(wParam); + } + static constexpr Sci::Line LineFromUPtr(Scintilla::uptr_t wParam) noexcept { + return SPtrFromUPtr(wParam); + } + Point PointFromParameters(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) const noexcept { + return Point(static_cast(wParam) - vs.ExternalMarginWidth(), static_cast(lParam)); + } + + constexpr std::optional OptionalFoldLevel(Scintilla::sptr_t lParam) { + if (lParam >= 0) { + return static_cast(lParam); + } + return std::nullopt; + } + + static Scintilla::sptr_t StringResult(Scintilla::sptr_t lParam, const char *val) noexcept; + static Scintilla::sptr_t BytesResult(Scintilla::sptr_t lParam, const unsigned char *val, size_t len) noexcept; // Set a variable controlling appearance to a value and invalidates the display // if a change was made. Avoids extra text and the possibility of mistyping. @@ -626,11 +666,11 @@ class Editor : public EditModel, public DocWatcher { // Public so the COM thunks can access it. bool IsUnicodeMode() const noexcept; // Public so scintilla_send_message can use it. - virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + virtual Scintilla::sptr_t WndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam); // Public so scintilla_set_id can use it. int ctrlID; // Public so COM methods for drag and drop can set it. - int errorStatus; + Scintilla::Status errorStatus; friend class AutoSurface; }; @@ -641,20 +681,18 @@ class AutoSurface { private: std::unique_ptr surf; public: - AutoSurface(const Editor *ed, int technology = -1) { + AutoSurface(const Editor *ed) { if (ed->wMain.GetID()) { - surf.reset(Surface::Allocate(technology != -1 ? technology : ed->technology)); + surf = Surface::Allocate(ed->technology); surf->Init(ed->wMain.GetID()); - surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); - surf->SetDBCSMode(ed->CodePage()); + surf->SetMode(SurfaceMode(ed->CodePage(), ed->BidirectionalR2L())); } } - AutoSurface(SurfaceID sid, Editor *ed, int technology = -1) { + AutoSurface(SurfaceID sid, Editor *ed, std::optional technology = {}) { if (ed->wMain.GetID()) { - surf.reset(Surface::Allocate(technology != -1 ? technology : ed->technology)); + surf = Surface::Allocate(technology ? *technology : ed->technology); surf->Init(sid, ed->wMain.GetID()); - surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); - surf->SetDBCSMode(ed->CodePage()); + surf->SetMode(SurfaceMode(ed->CodePage(), ed->BidirectionalR2L())); } } // Deleted so AutoSurface objects can not be copied. diff --git a/scintilla/src/ElapsedPeriod.h b/scintilla/src/ElapsedPeriod.h index e083c0dda0..36f03e1624 100644 --- a/scintilla/src/ElapsedPeriod.h +++ b/scintilla/src/ElapsedPeriod.h @@ -8,25 +8,25 @@ #ifndef ELAPSEDPERIOD_H #define ELAPSEDPERIOD_H -namespace Scintilla { +namespace Scintilla::Internal { // Simplified access to high precision timing. class ElapsedPeriod { - std::chrono::high_resolution_clock::time_point tp; + using ElapsedClock = std::chrono::steady_clock; + ElapsedClock::time_point tp; public: /// Capture the moment - ElapsedPeriod() noexcept : tp(std::chrono::high_resolution_clock::now()) { + ElapsedPeriod() noexcept : tp(ElapsedClock::now()) { } /// Return duration as floating point seconds double Duration(bool reset=false) noexcept { - const std::chrono::high_resolution_clock::time_point tpNow = - std::chrono::high_resolution_clock::now(); - const std::chrono::duration stylingDuration = + const ElapsedClock::time_point tpNow = ElapsedClock::now(); + const std::chrono::duration duration = std::chrono::duration_cast>(tpNow - tp); if (reset) { tp = tpNow; } - return stylingDuration.count(); + return duration.count(); } }; diff --git a/scintilla/src/ExternalLexer.cxx b/scintilla/src/ExternalLexer.cxx deleted file mode 100644 index 748789ed09..0000000000 --- a/scintilla/src/ExternalLexer.cxx +++ /dev/null @@ -1,221 +0,0 @@ -// Scintilla source code edit control -/** @file ExternalLexer.cxx - ** Support external lexers in DLLs or shared libraries. - **/ -// Copyright 2001 Simon Steele , portions copyright Neil Hodgson. -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include - -#include -#include -#include -#include - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "LexerModule.h" -#include "Catalogue.h" -#include "ExternalLexer.h" - -using namespace Scintilla; - -#if PLAT_WIN -#define EXT_LEXER_DECL __stdcall -#else -#define EXT_LEXER_DECL -#endif - -namespace { - -int nextLanguage = SCLEX_AUTOMATIC + 1; - -typedef int (EXT_LEXER_DECL *GetLexerCountFn)(); -typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); -typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index); - -/// Generic function to convert from a void* to a function pointer. -/// This avoids undefined and conditionally defined behaviour. -template -T FunctionPointer(void *function) noexcept { - static_assert(sizeof(T) == sizeof(function), "size mismatch"); - T fp; - memcpy(&fp, &function, sizeof(T)); - return fp; -} - -/// Sub-class of LexerModule to use an external lexer. -class ExternalLexerModule : public LexerModule { -protected: - GetLexerFactoryFunction fneFactory; - std::string name; -public: - ExternalLexerModule(int language_, LexerFunction fnLexer_, - const char *languageName_=nullptr, LexerFunction fnFolder_=nullptr) : - LexerModule(language_, fnLexer_, nullptr, fnFolder_), - fneFactory(nullptr), name(languageName_){ - languageName = name.c_str(); - } - void SetExternal(GetLexerFactoryFunction fFactory, int index) noexcept; -}; - -/// LexerLibrary exists for every External Lexer DLL, contains ExternalLexerModules. -class LexerLibrary { - std::unique_ptr lib; - std::vector> modules; -public: - explicit LexerLibrary(const char *moduleName_); - ~LexerLibrary(); - - std::string moduleName; -}; - -/// LexerManager manages external lexers, contains LexerLibrarys. -class LexerManager { -public: - ~LexerManager(); - - static LexerManager *GetInstance(); - static void DeleteInstance() noexcept; - - void Load(const char *path); - void Clear() noexcept; - -private: - LexerManager(); - static std::unique_ptr theInstance; - std::vector> libraries; -}; - -class LMMinder { -public: - ~LMMinder(); -}; - -std::unique_ptr LexerManager::theInstance; - -//------------------------------------------ -// -// ExternalLexerModule -// -//------------------------------------------ - -void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) noexcept { - fneFactory = fFactory; - fnFactory = fFactory(index); -} - -//------------------------------------------ -// -// LexerLibrary -// -//------------------------------------------ - -LexerLibrary::LexerLibrary(const char *moduleName_) { - // Load the DLL - lib.reset(DynamicLibrary::Load(moduleName_)); - if (lib->IsValid()) { - moduleName = moduleName_; - GetLexerCountFn GetLexerCount = FunctionPointer(lib->FindFunction("GetLexerCount")); - - if (GetLexerCount) { - // Find functions in the DLL - GetLexerNameFn GetLexerName = FunctionPointer(lib->FindFunction("GetLexerName")); - GetLexerFactoryFunction fnFactory = FunctionPointer(lib->FindFunction("GetLexerFactory")); - - if (!GetLexerName || !fnFactory) { - return; - } - - const int nl = GetLexerCount(); - - for (int i = 0; i < nl; i++) { - // Assign a buffer for the lexer name. - char lexname[100] = ""; - GetLexerName(i, lexname, sizeof(lexname)); - ExternalLexerModule *lex = new ExternalLexerModule(nextLanguage, nullptr, lexname, nullptr); - nextLanguage++; - - // This is storing a second reference to lex in the Catalogue as well as in modules. - // TODO: Should use std::shared_ptr or similar to ensure allocation safety. - Catalogue::AddLexerModule(lex); - - // Remember ExternalLexerModule so we don't leak it - modules.push_back(std::unique_ptr(lex)); - - // The external lexer needs to know how to call into its DLL to - // do its lexing and folding, we tell it here. - lex->SetExternal(fnFactory, i); - } - } - } -} - -LexerLibrary::~LexerLibrary() { -} - -//------------------------------------------ -// -// LexerManager -// -//------------------------------------------ - -/// Return the single LexerManager instance... -LexerManager *LexerManager::GetInstance() { - if (!theInstance) - theInstance.reset(new LexerManager); - return theInstance.get(); -} - -/// Delete any LexerManager instance... -void LexerManager::DeleteInstance() noexcept { - theInstance.reset(); -} - -/// protected constructor - this is a singleton... -LexerManager::LexerManager() { -} - -LexerManager::~LexerManager() { - Clear(); -} - -void LexerManager::Load(const char *path) { - for (const std::unique_ptr &ll : libraries) { - if (ll->moduleName == path) - return; - } - libraries.push_back(Sci::make_unique(path)); -} - -void LexerManager::Clear() noexcept { - libraries.clear(); -} - -//------------------------------------------ -// -// LMMinder -- trigger to clean up at exit. -// -//------------------------------------------ - -LMMinder::~LMMinder() { - LexerManager::DeleteInstance(); -} - -LMMinder minder; - -} - -namespace Scintilla { - -void ExternalLexerLoad(const char *path) { - LexerManager::GetInstance()->Load(path); -} - -} diff --git a/scintilla/src/ExternalLexer.h b/scintilla/src/ExternalLexer.h deleted file mode 100644 index d0a615e31a..0000000000 --- a/scintilla/src/ExternalLexer.h +++ /dev/null @@ -1,17 +0,0 @@ -// Scintilla source code edit control -/** @file ExternalLexer.h - ** Support external lexers in DLLs or shared libraries. - **/ -// Copyright 2001 Simon Steele , portions copyright Neil Hodgson. -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef EXTERNALLEXER_H -#define EXTERNALLEXER_H - -namespace Scintilla { - -void ExternalLexerLoad(const char *path); - -} - -#endif diff --git a/scintilla/src/FontQuality.h b/scintilla/src/FontQuality.h index 85dca1e164..b587fc6d40 100644 --- a/scintilla/src/FontQuality.h +++ b/scintilla/src/FontQuality.h @@ -12,15 +12,15 @@ namespace Scintilla { // These definitions match Scintilla.h -#define SC_EFF_QUALITY_MASK 0xF -#define SC_EFF_QUALITY_DEFAULT 0 -#define SC_EFF_QUALITY_NON_ANTIALIASED 1 -#define SC_EFF_QUALITY_ANTIALIASED 2 -#define SC_EFF_QUALITY_LCD_OPTIMIZED 3 +//#define SC_EFF_QUALITY_MASK 0xF +//#define SC_EFF_QUALITY_DEFAULT 0 +//#define SC_EFF_QUALITY_NON_ANTIALIASED 1 +//#define SC_EFF_QUALITY_ANTIALIASED 2 +//#define SC_EFF_QUALITY_LCD_OPTIMIZED 3 // These definitions must match SC_TECHNOLOGY_* in Scintilla.h -#define SCWIN_TECH_GDI 0 -#define SCWIN_TECH_DIRECTWRITE 1 +//#define SCWIN_TECH_GDI 0 +//#define SCWIN_TECH_DIRECTWRITE 1 } diff --git a/scintilla/src/Geometry.cxx b/scintilla/src/Geometry.cxx new file mode 100644 index 0000000000..afdc5d1610 --- /dev/null +++ b/scintilla/src/Geometry.cxx @@ -0,0 +1,98 @@ +// Scintilla source code edit control +/** @file Geometry.cxx + ** Helper functions for geometric calculations. + **/ +// Copyright 2020 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include + +#include + +#include "Geometry.h" + +namespace Scintilla::Internal { + +PRectangle Clamp(PRectangle rc, Edge edge, XYPOSITION position) noexcept { + switch (edge) { + case Edge::left: + return PRectangle(std::clamp(position, rc.left, rc.right), rc.top, rc.right, rc.bottom); + case Edge::top: + return PRectangle(rc.left, std::clamp(position, rc.top, rc.bottom), rc.right, rc.bottom); + case Edge::right: + return PRectangle(rc.left, rc.top, std::clamp(position, rc.left, rc.right), rc.bottom); + case Edge::bottom: + default: + return PRectangle(rc.left, rc.top, rc.right, std::clamp(position, rc.top, rc.bottom)); + } +} + +PRectangle Side(PRectangle rc, Edge edge, XYPOSITION size) noexcept { + switch (edge) { + case Edge::left: + return PRectangle(rc.left, rc.top, std::min(rc.left + size, rc.right), rc.bottom); + case Edge::top: + return PRectangle(rc.left, rc.top, rc.right, std::min(rc.top + size, rc.bottom)); + case Edge::right: + return PRectangle(std::max(rc.left, rc.right - size), rc.top, rc.right, rc.bottom); + case Edge::bottom: + default: + return PRectangle(rc.left, std::max(rc.top, rc.bottom - size), rc.right, rc.bottom); + } +} + +Interval Intersection(Interval a, Interval b) noexcept { + const XYPOSITION leftMax = std::max(a.left, b.left); + const XYPOSITION rightMin = std::min(a.right, b.right); + // If the result would have a negative width. make empty instead. + const XYPOSITION rightResult = (rightMin >= leftMax) ? rightMin : leftMax; + return { leftMax, rightResult }; +} + +PRectangle Intersection(PRectangle rc, Interval horizontalBounds) noexcept { + const Interval intersection = Intersection(HorizontalBounds(rc), horizontalBounds); + return PRectangle(intersection.left, rc.top, intersection.right, rc.bottom); +} + +Interval HorizontalBounds(PRectangle rc) noexcept { + return { rc.left, rc.right }; +} + +XYPOSITION PixelAlign(XYPOSITION xy, int pixelDivisions) noexcept { + return std::round(xy * pixelDivisions) / pixelDivisions; +} + +XYPOSITION PixelAlignFloor(XYPOSITION xy, int pixelDivisions) noexcept { + return std::floor(xy * pixelDivisions) / pixelDivisions; +} + +Point PixelAlign(const Point &pt, int pixelDivisions) noexcept { + return Point( + std::round(pt.x * pixelDivisions) / pixelDivisions, + std::round(pt.y * pixelDivisions) / pixelDivisions); +} + +PRectangle PixelAlign(const PRectangle &rc, int pixelDivisions) noexcept { + // Move left and right side to nearest pixel to avoid blurry visuals. + // The top and bottom should be integers but floor them to make sure. + // `pixelDivisions` is commonly 1 except for 'retina' displays where it is 2. + // On retina displays, the positions should be moved to the nearest device + // pixel which is the nearest half logical pixel. + return PRectangle( + std::round(rc.left * pixelDivisions) / pixelDivisions, + PixelAlignFloor(rc.top, pixelDivisions), + std::round(rc.right * pixelDivisions) / pixelDivisions, + PixelAlignFloor(rc.bottom, pixelDivisions)); +} + +PRectangle PixelAlignOutside(const PRectangle &rc, int pixelDivisions) noexcept { + // Move left and right side to extremes (floor(left) ceil(right)) to avoid blurry visuals. + return PRectangle( + std::floor(rc.left * pixelDivisions) / pixelDivisions, + std::floor(rc.top * pixelDivisions) / pixelDivisions, + std::ceil(rc.right * pixelDivisions) / pixelDivisions, + std::floor(rc.bottom * pixelDivisions) / pixelDivisions); +} + +} diff --git a/scintilla/src/Geometry.h b/scintilla/src/Geometry.h new file mode 100644 index 0000000000..6456af0e82 --- /dev/null +++ b/scintilla/src/Geometry.h @@ -0,0 +1,311 @@ +// Scintilla source code edit control +/** @file Geometry.h + ** Classes and functions for geometric and colour calculations. + **/ +// Copyright 2020 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef GEOMETRY_H +#define GEOMETRY_H + +namespace Scintilla::Internal { + +typedef double XYPOSITION; +typedef double XYACCUMULATOR; + +/** + * A geometric point class. + * Point is similar to the Win32 POINT and GTK+ GdkPoint types. + */ +class Point { +public: + XYPOSITION x; + XYPOSITION y; + + constexpr explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) noexcept : x(x_), y(y_) { + } + + static constexpr Point FromInts(int x_, int y_) noexcept { + return Point(static_cast(x_), static_cast(y_)); + } + + constexpr bool operator==(Point other) const noexcept { + return (x == other.x) && (y == other.y); + } + + constexpr bool operator!=(Point other) const noexcept { + return (x != other.x) || (y != other.y); + } + + constexpr Point operator+(Point other) const noexcept { + return Point(x + other.x, y + other.y); + } + + constexpr Point operator-(Point other) const noexcept { + return Point(x - other.x, y - other.y); + } + + // Other automatically defined methods (assignment, copy constructor, destructor) are fine +}; + + +/** + * A geometric interval class. + */ +class Interval { +public: + XYPOSITION left; + XYPOSITION right; + constexpr bool operator==(const Interval &other) const noexcept { + return (left == other.left) && (right == other.right); + } + constexpr XYPOSITION Width() const noexcept { return right - left; } + constexpr bool Empty() const noexcept { + return Width() <= 0; + } + constexpr bool Intersects(Interval other) const noexcept { + return (right > other.left) && (left < other.right); + } +}; + +/** + * A geometric rectangle class. + * PRectangle is similar to Win32 RECT. + * PRectangles contain their top and left sides, but not their right and bottom sides. + */ +class PRectangle { +public: + XYPOSITION left; + XYPOSITION top; + XYPOSITION right; + XYPOSITION bottom; + + constexpr explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) noexcept : + left(left_), top(top_), right(right_), bottom(bottom_) { + } + + static constexpr PRectangle FromInts(int left_, int top_, int right_, int bottom_) noexcept { + return PRectangle(static_cast(left_), static_cast(top_), + static_cast(right_), static_cast(bottom_)); + } + + // Other automatically defined methods (assignment, copy constructor, destructor) are fine + + constexpr bool operator==(const PRectangle &rc) const noexcept { + return (rc.left == left) && (rc.right == right) && + (rc.top == top) && (rc.bottom == bottom); + } + constexpr bool Contains(Point pt) const noexcept { + return (pt.x >= left) && (pt.x <= right) && + (pt.y >= top) && (pt.y <= bottom); + } + constexpr bool ContainsWholePixel(Point pt) const noexcept { + // Does the rectangle contain all of the pixel to left/below the point + return (pt.x >= left) && ((pt.x+1) <= right) && + (pt.y >= top) && ((pt.y+1) <= bottom); + } + constexpr bool Contains(PRectangle rc) const noexcept { + return (rc.left >= left) && (rc.right <= right) && + (rc.top >= top) && (rc.bottom <= bottom); + } + constexpr bool Intersects(PRectangle other) const noexcept { + return (right > other.left) && (left < other.right) && + (bottom > other.top) && (top < other.bottom); + } + void Move(XYPOSITION xDelta, XYPOSITION yDelta) noexcept { + left += xDelta; + top += yDelta; + right += xDelta; + bottom += yDelta; + } + + constexpr PRectangle Inset(XYPOSITION delta) const noexcept { + return PRectangle(left + delta, top + delta, right - delta, bottom - delta); + } + + constexpr PRectangle Inset(Point delta) const noexcept { + return PRectangle(left + delta.x, top + delta.y, right - delta.x, bottom - delta.y); + } + + constexpr Point Centre() const noexcept { + return Point((left + right) / 2, (top + bottom) / 2); + } + + constexpr XYPOSITION Width() const noexcept { return right - left; } + constexpr XYPOSITION Height() const noexcept { return bottom - top; } + constexpr bool Empty() const noexcept { + return (Height() <= 0) || (Width() <= 0); + } +}; + +enum class Edge { left, top, bottom, right }; + +PRectangle Clamp(PRectangle rc, Edge edge, XYPOSITION position) noexcept; +PRectangle Side(PRectangle rc, Edge edge, XYPOSITION size) noexcept; + +Interval Intersection(Interval a, Interval b) noexcept; +PRectangle Intersection(PRectangle rc, Interval horizontalBounds) noexcept; +Interval HorizontalBounds(PRectangle rc) noexcept; + +XYPOSITION PixelAlign(XYPOSITION xy, int pixelDivisions) noexcept; +XYPOSITION PixelAlignFloor(XYPOSITION xy, int pixelDivisions) noexcept; + +Point PixelAlign(const Point &pt, int pixelDivisions) noexcept; + +PRectangle PixelAlign(const PRectangle &rc, int pixelDivisions) noexcept; +PRectangle PixelAlignOutside(const PRectangle &rc, int pixelDivisions) noexcept; + +/** +* Holds an RGBA colour with 8 bits for each component. +*/ +constexpr const float componentMaximum = 255.0f; +class ColourRGBA { + int co; + constexpr static unsigned int Mixed(unsigned char a, unsigned char b, double proportion) noexcept { + return static_cast(a + proportion * (b - a)); + } +public: + constexpr explicit ColourRGBA(int co_ = 0) noexcept : co(co_) { + } + + constexpr ColourRGBA(unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha=0xff) noexcept : + ColourRGBA(red | (green << 8) | (blue << 16) | (alpha << 24)) { + } + + constexpr ColourRGBA(ColourRGBA cd, unsigned int alpha) noexcept : + ColourRGBA(cd.OpaqueRGB() | (alpha << 24)) { + } + + static constexpr ColourRGBA FromRGB(int co_) noexcept { + return ColourRGBA(co_ | (0xffu << 24)); + } + + static constexpr ColourRGBA FromIpRGB(intptr_t co_) noexcept { + return ColourRGBA(static_cast(co_) | (0xffu << 24)); + } + + constexpr ColourRGBA WithoutAlpha() const noexcept { + return ColourRGBA(co & 0xffffff); + } + + constexpr ColourRGBA Opaque() const noexcept { + return ColourRGBA(co | (0xffu << 24)); + } + + constexpr int AsInteger() const noexcept { + return co; + } + + constexpr int OpaqueRGB() const noexcept { + return co & 0xffffff; + } + + // Red, green and blue values as bytes 0..255 + constexpr unsigned char GetRed() const noexcept { + return co & 0xff; + } + constexpr unsigned char GetGreen() const noexcept { + return (co >> 8) & 0xff; + } + constexpr unsigned char GetBlue() const noexcept { + return (co >> 16) & 0xff; + } + constexpr unsigned char GetAlpha() const noexcept { + return (co >> 24) & 0xff; + } + + // Red, green, blue, and alpha values as float 0..1.0 + constexpr float GetRedComponent() const noexcept { + return GetRed() / componentMaximum; + } + constexpr float GetGreenComponent() const noexcept { + return GetGreen() / componentMaximum; + } + constexpr float GetBlueComponent() const noexcept { + return GetBlue() / componentMaximum; + } + constexpr float GetAlphaComponent() const noexcept { + return GetAlpha() / componentMaximum; + } + + constexpr bool operator==(const ColourRGBA &other) const noexcept { + return co == other.co; + } + + constexpr bool IsOpaque() const noexcept { + return GetAlpha() == 0xff; + } + + constexpr ColourRGBA MixedWith(ColourRGBA other) const noexcept { + const unsigned int red = (GetRed() + other.GetRed()) / 2; + const unsigned int green = (GetGreen() + other.GetGreen()) / 2; + const unsigned int blue = (GetBlue() + other.GetBlue()) / 2; + const unsigned int alpha = (GetAlpha() + other.GetAlpha()) / 2; + return ColourRGBA(red, green, blue, alpha); + } + + constexpr ColourRGBA MixedWith(ColourRGBA other, double proportion) const noexcept { + return ColourRGBA( + Mixed(GetRed(), other.GetRed(), proportion), + Mixed(GetGreen(), other.GetGreen(), proportion), + Mixed(GetBlue(), other.GetBlue(), proportion), + Mixed(GetAlpha(), other.GetAlpha(), proportion)); + } +}; + +/** +* Holds an RGBA colour and stroke width to stroke a shape. +*/ +class Stroke { +public: + ColourRGBA colour; + XYPOSITION width; + constexpr Stroke(ColourRGBA colour_, XYPOSITION width_=1.0) noexcept : + colour(colour_), width(width_) { + } + constexpr float WidthF() const noexcept { + return static_cast(width); + } +}; + +/** +* Holds an RGBA colour to fill a shape. +*/ +class Fill { +public: + ColourRGBA colour; + constexpr Fill(ColourRGBA colour_) noexcept : + colour(colour_) { + } +}; + +/** +* Holds a pair of RGBA colours and stroke width to fill and stroke a shape. +*/ +class FillStroke { +public: + Fill fill; + Stroke stroke; + constexpr FillStroke(ColourRGBA colourFill_, ColourRGBA colourStroke_, XYPOSITION widthStroke_=1.0) noexcept : + fill(colourFill_), stroke(colourStroke_, widthStroke_) { + } + constexpr FillStroke(ColourRGBA colourBoth, XYPOSITION widthStroke_=1.0) noexcept : + fill(colourBoth), stroke(colourBoth, widthStroke_) { + } +}; + +/** +* Holds an element of a gradient with an RGBA colour and a relative position. +*/ +class ColourStop { +public: + XYPOSITION position; + ColourRGBA colour; + constexpr ColourStop(XYPOSITION position_, ColourRGBA colour_) noexcept : + position(position_), colour(colour_) { + } +}; + +} + +#endif diff --git a/scintilla/src/Indicator.cxx b/scintilla/src/Indicator.cxx index f721027725..0dd9ba7c2c 100644 --- a/scintilla/src/Indicator.cxx +++ b/scintilla/src/Indicator.cxx @@ -8,266 +8,284 @@ #include #include +#include #include #include +#include #include #include +#include "ScintillaTypes.h" + +#include "Debugging.h" +#include "Geometry.h" #include "Platform.h" -#include "Scintilla.h" -#include "IntegerRectangle.h" #include "Indicator.h" #include "XPM.h" using namespace Scintilla; - -static PRectangle PixelGridAlign(const PRectangle &rc) noexcept { - // Move left and right side to nearest pixel to avoid blurry visuals - return PRectangle(Sci::round(rc.left), std::floor(rc.top), - Sci::round(rc.right), std::floor(rc.bottom)); -} +using namespace Scintilla::Internal; void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, State state, int value) const { StyleAndColour sacDraw = sacNormal; - if (Flags() & SC_INDICFLAG_VALUEFORE) { - sacDraw.fore = ColourDesired(value & SC_INDICVALUEMASK); + if (FlagSet(Flags(), IndicFlag::ValueFore)) { + sacDraw.fore = ColourRGBA::FromRGB(value & static_cast(IndicValue::Mask)); } if (state == State::hover) { sacDraw = sacHover; } - const IntegerRectangle irc(rc); - surface->PenColour(sacDraw.fore); - const int ymid = (irc.bottom + irc.top) / 2; + + const int pixelDivisions = surface->PixelDivisions(); + + const XYPOSITION halfWidth = strokeWidth / 2.0f; + + const PRectangle rcAligned(PixelAlignOutside(rc, pixelDivisions)); + PRectangle rcFullHeightAligned = PixelAlignOutside(rcLine, pixelDivisions); + rcFullHeightAligned.left = rcAligned.left; + rcFullHeightAligned.right = rcAligned.right; + + const XYPOSITION ymid = PixelAlign(rc.Centre().y, pixelDivisions); + + // This is a reasonable clip for indicators beneath text like underlines + PRectangle rcClip = rcAligned; + rcClip.bottom = rcFullHeightAligned.bottom; switch (sacDraw.style) { - case INDIC_SQUIGGLE: { - const IntegerRectangle ircSquiggle(PixelGridAlign(rc)); - int x = ircSquiggle.left; - const int xLast = ircSquiggle.right; - int y = 0; - surface->MoveTo(x, irc.top + y); + case IndicatorStyle::Squiggle: { + surface->SetClip(rcClip); + XYPOSITION x = rcAligned.left + halfWidth; + const XYPOSITION top = rcAligned.top + halfWidth; + const XYPOSITION xLast = rcAligned.right + halfWidth; + XYPOSITION y = 0; + std::vector pts; + const XYPOSITION pitch = 1 + strokeWidth; + pts.emplace_back(x, top + y); while (x < xLast) { - if ((x + 2) > xLast) { - y = 1; - x = xLast; - } else { - x += 2; - y = 2 - y; + x += pitch; + y = pitch - y; + pts.emplace_back(x, top + y); } - surface->LineTo(x, irc.top + y); - } + surface->PolyLine(pts.data(), std::size(pts), Stroke(sacDraw.fore, strokeWidth)); + surface->PopClip(); } break; - case INDIC_SQUIGGLEPIXMAP: { - const PRectangle rcSquiggle = PixelGridAlign(rc); + case IndicatorStyle::SquigglePixmap: { + const PRectangle rcSquiggle = PixelAlign(rc, 1); const int width = std::min(4000, static_cast(rcSquiggle.Width())); RGBAImage image(width, 3, 1.0, nullptr); - enum { alphaFull = 0xff, alphaSide = 0x2f, alphaSide2=0x5f }; + constexpr unsigned int alphaFull = 0xff; + constexpr unsigned int alphaSide = 0x2f; + constexpr unsigned int alphaSide2 = 0x5f; for (int x = 0; x < width; x++) { if (x%2) { // Two halfway columns have a full pixel in middle flanked by light pixels - image.SetPixel(x, 0, sacDraw.fore, alphaSide); - image.SetPixel(x, 1, sacDraw.fore, alphaFull); - image.SetPixel(x, 2, sacDraw.fore, alphaSide); + image.SetPixel(x, 0, ColourRGBA(sacDraw.fore, alphaSide)); + image.SetPixel(x, 1, ColourRGBA(sacDraw.fore, alphaFull)); + image.SetPixel(x, 2, ColourRGBA(sacDraw.fore, alphaSide)); } else { // Extreme columns have a full pixel at bottom or top and a mid-tone pixel in centre - image.SetPixel(x, (x % 4) ? 0 : 2, sacDraw.fore, alphaFull); - image.SetPixel(x, 1, sacDraw.fore, alphaSide2); + image.SetPixel(x, (x % 4) ? 0 : 2, ColourRGBA(sacDraw.fore, alphaFull)); + image.SetPixel(x, 1, ColourRGBA(sacDraw.fore, alphaSide2)); } } surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels()); } break; - case INDIC_SQUIGGLELOW: { - surface->MoveTo(irc.left, irc.top); - int x = irc.left + 3; + case IndicatorStyle::SquiggleLow: { + std::vector pts; + const XYPOSITION top = rcAligned.top + halfWidth; int y = 0; - while (x < rc.right) { - surface->LineTo(x - 1, irc.top + y); + XYPOSITION x = std::round(rcAligned.left) + halfWidth; + pts.emplace_back(x, top + y); + const XYPOSITION pitch = 2 + strokeWidth; + x += pitch; + while (x < rcAligned.right) { + pts.emplace_back(x - 1, top + y); y = 1 - y; - surface->LineTo(x, irc.top + y); - x += 3; + pts.emplace_back(x, top + y); + x += pitch; } - surface->LineTo(irc.right, irc.top + y); // Finish the line + pts.emplace_back(rcAligned.right, top + y); + surface->PolyLine(pts.data(), std::size(pts), Stroke(sacDraw.fore, strokeWidth)); } break; - case INDIC_TT: { - surface->MoveTo(irc.left, ymid); - int x = irc.left + 5; - while (x < rc.right) { - surface->LineTo(x, ymid); - surface->MoveTo(x-3, ymid); - surface->LineTo(x-3, ymid+2); + case IndicatorStyle::TT: { + surface->SetClip(rcClip); + const XYPOSITION yLine = ymid; + XYPOSITION x = rcAligned.left + 5.0f; + const XYPOSITION pitch = 4 + strokeWidth; + while (x < rc.right + pitch) { + const PRectangle line(x-pitch, yLine, x, yLine + strokeWidth); + surface->FillRectangle(line, sacDraw.fore); + const PRectangle tail(x - 2 - strokeWidth, yLine + strokeWidth, x - 2, yLine + strokeWidth * 2); + surface->FillRectangle(tail, sacDraw.fore); x++; - surface->MoveTo(x, ymid); - x += 5; - } - surface->LineTo(irc.right, ymid); // Finish the line - if (x - 3 <= rc.right) { - surface->MoveTo(x-3, ymid); - surface->LineTo(x-3, ymid+2); + x += pitch; } + surface->PopClip(); } break; - case INDIC_DIAGONAL: { - int x = irc.left; + case IndicatorStyle::Diagonal: { + surface->SetClip(rcClip); + XYPOSITION x = rcAligned.left + halfWidth; + const XYPOSITION top = rcAligned.top + halfWidth; + const XYPOSITION pitch = 3 + strokeWidth; while (x < rc.right) { - surface->MoveTo(x, irc.top + 2); - int endX = x+3; - int endY = irc.top - 1; - if (endX > rc.right) { - endY += endX - irc.right; - endX = irc.right; - } - surface->LineTo(endX, endY); - x += 4; + const XYPOSITION endX = x+3; + const XYPOSITION endY = top - 1; + surface->LineDraw(Point(x, top + 2), Point(endX, endY), Stroke(sacDraw.fore, strokeWidth)); + x += pitch; } + surface->PopClip(); } break; - case INDIC_STRIKE: { - surface->MoveTo(irc.left, irc.top - 4); - surface->LineTo(irc.right, irc.top - 4); + case IndicatorStyle::Strike: { + const XYPOSITION yStrike = std::round(rcLine.Centre().y); + const PRectangle rcStrike( + rcAligned.left, yStrike, rcAligned.right, yStrike + strokeWidth); + surface->FillRectangle(rcStrike, sacDraw.fore); } break; - case INDIC_HIDDEN: - case INDIC_TEXTFORE: + case IndicatorStyle::Hidden: + case IndicatorStyle::TextFore: // Draw nothing break; - case INDIC_BOX: { - surface->MoveTo(irc.left, ymid + 1); - surface->LineTo(irc.right, ymid + 1); - const int lineTop = static_cast(rcLine.top) + 1; - surface->LineTo(irc.right, lineTop); - surface->LineTo(irc.left, lineTop); - surface->LineTo(irc.left, ymid + 1); + case IndicatorStyle::Box: { + PRectangle rcBox = rcFullHeightAligned; + rcBox.top = rcBox.top + 1.0f; + rcBox.bottom = ymid + 1.0f; + surface->RectangleFrame(rcBox, Stroke(ColourRGBA(sacDraw.fore, outlineAlpha), strokeWidth)); } break; - case INDIC_ROUNDBOX: - case INDIC_STRAIGHTBOX: - case INDIC_FULLBOX: { - PRectangle rcBox = rcLine; - if (sacDraw.style != INDIC_FULLBOX) - rcBox.top = rcLine.top + 1; - rcBox.left = rc.left; - rcBox.right = rc.right; - surface->AlphaRectangle(rcBox, (sacDraw.style == INDIC_ROUNDBOX) ? 1 : 0, - sacDraw.fore, fillAlpha, sacDraw.fore, outlineAlpha, 0); + case IndicatorStyle::RoundBox: + case IndicatorStyle::StraightBox: + case IndicatorStyle::FullBox: { + PRectangle rcBox = rcFullHeightAligned; + if (sacDraw.style != IndicatorStyle::FullBox) + rcBox.top = rcBox.top + 1; + surface->AlphaRectangle(rcBox, (sacDraw.style == IndicatorStyle::RoundBox) ? 1.0f : 0.0f, + FillStroke(ColourRGBA(sacDraw.fore, fillAlpha), ColourRGBA(sacDraw.fore, outlineAlpha), strokeWidth)); } break; - case INDIC_GRADIENT: - case INDIC_GRADIENTCENTRE: { - PRectangle rcBox = rc; - rcBox.top = rcLine.top + 1; - rcBox.bottom = rcLine.bottom; + case IndicatorStyle::Gradient: + case IndicatorStyle::GradientCentre: { + PRectangle rcBox = rcFullHeightAligned; + rcBox.top = rcBox.top + 1; const Surface::GradientOptions options = Surface::GradientOptions::topToBottom; - const ColourAlpha start(sacDraw.fore, fillAlpha); - const ColourAlpha end(sacDraw.fore, 0); + const ColourRGBA start(sacDraw.fore, fillAlpha); + const ColourRGBA end(sacDraw.fore, 0); std::vector stops; switch (sacDraw.style) { - case INDIC_GRADIENT: + case IndicatorStyle::Gradient: stops.push_back(ColourStop(0.0, start)); stops.push_back(ColourStop(1.0, end)); break; - case INDIC_GRADIENTCENTRE: + case IndicatorStyle::GradientCentre: stops.push_back(ColourStop(0.0, end)); stops.push_back(ColourStop(0.5, start)); stops.push_back(ColourStop(1.0, end)); break; + default: + break; } surface->GradientRectangle(rcBox, stops, options); } break; - case INDIC_DOTBOX: { - PRectangle rcBox = PixelGridAlign(rc); - rcBox.top = rcLine.top + 1; - rcBox.bottom = rcLine.bottom; - const IntegerRectangle ircBox(rcBox); + case IndicatorStyle::DotBox: { + PRectangle rcBox = rcFullHeightAligned; + rcBox.top = rcBox.top + 1; // Cap width at 4000 to avoid large allocations when mistakes made - const int width = std::min(ircBox.Width(), 4000); - RGBAImage image(width, ircBox.Height(), 1.0, nullptr); + const int width = std::min(static_cast(rcBox.Width()), 4000); + const int height = static_cast(rcBox.Height()); + RGBAImage image(width, height, 1.0, nullptr); // Draw horizontal lines top and bottom for (int x=0; xDrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels()); } break; - case INDIC_DASH: { - int x = irc.left; + case IndicatorStyle::Dash: { + XYPOSITION x = std::floor(rc.left); + const XYPOSITION widthDash = 3 + std::round(strokeWidth); while (x < rc.right) { - surface->MoveTo(x, ymid); - surface->LineTo(std::min(x + 4, irc.right), ymid); - x += 7; + const PRectangle rcDash = PRectangle(x, ymid, + x + widthDash, ymid + std::round(strokeWidth)); + surface->FillRectangle(rcDash, sacDraw.fore); + x += 3 + widthDash; } } break; - case INDIC_DOTS: { - int x = irc.left; - while (x < irc.right) { - const PRectangle rcDot = PRectangle::FromInts(x, ymid, x + 1, ymid + 1); + case IndicatorStyle::Dots: { + const XYPOSITION widthDot = std::round(strokeWidth); + XYPOSITION x = std::floor(rc.left); + while (x < rc.right) { + const PRectangle rcDot = PRectangle(x, ymid, + x + widthDot, ymid + widthDot); surface->FillRectangle(rcDot, sacDraw.fore); - x += 2; + x += widthDot * 2; } } break; - case INDIC_COMPOSITIONTHICK: { + case IndicatorStyle::CompositionThick: { const PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom); surface->FillRectangle(rcComposition, sacDraw.fore); } break; - case INDIC_COMPOSITIONTHIN: { + case IndicatorStyle::CompositionThin: { const PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom-1); surface->FillRectangle(rcComposition, sacDraw.fore); } break; - case INDIC_POINT: - case INDIC_POINTCHARACTER: + case IndicatorStyle::Point: + case IndicatorStyle::PointCharacter: if (rcCharacter.Width() >= 0.1) { const XYPOSITION pixelHeight = std::floor(rc.Height() - 1.0f); // 1 pixel onto next line if multiphase - const XYPOSITION x = (sacDraw.style == INDIC_POINT) ? (rcCharacter.left) : ((rcCharacter.right + rcCharacter.left) / 2); - const XYPOSITION ix = Sci::round(x); - const XYPOSITION iy = std::floor(rc.top + 1.0f); - Point pts[] = { + const XYPOSITION x = (sacDraw.style == IndicatorStyle::Point) ? (rcCharacter.left) : ((rcCharacter.right + rcCharacter.left) / 2); + // 0.5f is to hit midpoint of pixels: + const XYPOSITION ix = std::round(x) + 0.5f; + const XYPOSITION iy = std::floor(rc.top + 1.0f) + 0.5f; + const Point pts[] = { Point(ix - pixelHeight, iy + pixelHeight), // Left Point(ix + pixelHeight, iy + pixelHeight), // Right Point(ix, iy) // Top }; - surface->Polygon(pts, Sci::size(pts), sacDraw.fore, sacDraw.fore); + surface->Polygon(pts, std::size(pts), FillStroke(sacDraw.fore)); } break; default: - // Either INDIC_PLAIN or unknown - surface->MoveTo(irc.left, ymid); - surface->LineTo(irc.right, ymid); + // Either IndicatorStyle::Plain or unknown + surface->FillRectangle(PRectangle(rcAligned.left, ymid, + rcAligned.right, ymid + std::round(strokeWidth)), sacDraw.fore); } } -void Indicator::SetFlags(int attributes_) noexcept { +void Indicator::SetFlags(IndicFlag attributes_) noexcept { attributes = attributes_; } diff --git a/scintilla/src/Indicator.h b/scintilla/src/Indicator.h index 669d9a2d87..fc17a82c2e 100644 --- a/scintilla/src/Indicator.h +++ b/scintilla/src/Indicator.h @@ -8,14 +8,14 @@ #ifndef INDICATOR_H #define INDICATOR_H -namespace Scintilla { +namespace Scintilla::Internal { struct StyleAndColour { - int style; - ColourDesired fore; - StyleAndColour() noexcept : style(INDIC_PLAIN), fore(0, 0, 0) { + Scintilla::IndicatorStyle style; + ColourRGBA fore; + StyleAndColour() noexcept : style(Scintilla::IndicatorStyle::Plain), fore(0, 0, 0) { } - StyleAndColour(int style_, ColourDesired fore_ = ColourDesired(0, 0, 0)) noexcept : style(style_), fore(fore_) { + StyleAndColour(Scintilla::IndicatorStyle style_, ColourRGBA fore_ = ColourRGBA(0, 0, 0)) noexcept : style(style_), fore(fore_) { } bool operator==(const StyleAndColour &other) const noexcept { return (style == other.style) && (fore == other.fore); @@ -32,23 +32,24 @@ class Indicator { bool under; int fillAlpha; int outlineAlpha; - int attributes; - Indicator() noexcept : under(false), fillAlpha(30), outlineAlpha(50), attributes(0) { + Scintilla::IndicFlag attributes; + XYPOSITION strokeWidth = 1.0f; + Indicator() noexcept : under(false), fillAlpha(30), outlineAlpha(50), attributes(Scintilla::IndicFlag::None) { } - Indicator(int style_, ColourDesired fore_=ColourDesired(0,0,0), bool under_=false, int fillAlpha_=30, int outlineAlpha_=50) noexcept : - sacNormal(style_, fore_), sacHover(style_, fore_), under(under_), fillAlpha(fillAlpha_), outlineAlpha(outlineAlpha_), attributes(0) { + Indicator(Scintilla::IndicatorStyle style_, ColourRGBA fore_= ColourRGBA(0,0,0), bool under_=false, int fillAlpha_=30, int outlineAlpha_=50) noexcept : + sacNormal(style_, fore_), sacHover(style_, fore_), under(under_), fillAlpha(fillAlpha_), outlineAlpha(outlineAlpha_), attributes(Scintilla::IndicFlag::None) { } void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, State drawState, int value) const; bool IsDynamic() const noexcept { return !(sacNormal == sacHover); } bool OverridesTextFore() const noexcept { - return sacNormal.style == INDIC_TEXTFORE || sacHover.style == INDIC_TEXTFORE; + return sacNormal.style == Scintilla::IndicatorStyle::TextFore || sacHover.style == Scintilla::IndicatorStyle::TextFore; } - int Flags() const noexcept { + Scintilla::IndicFlag Flags() const noexcept { return attributes; } - void SetFlags(int attributes_) noexcept; + void SetFlags(Scintilla::IndicFlag attributes_) noexcept; }; } diff --git a/scintilla/src/IntegerRectangle.h b/scintilla/src/IntegerRectangle.h deleted file mode 100644 index 4eaf39c434..0000000000 --- a/scintilla/src/IntegerRectangle.h +++ /dev/null @@ -1,29 +0,0 @@ -// Scintilla source code edit control -/** @file IntegerRectangle.h - ** A rectangle with integer coordinates. - **/ -// Copyright 2018 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef INTEGERRECTANGLE_H -#define INTEGERRECTANGLE_H - -namespace Scintilla { - -struct IntegerRectangle { - int left; - int top; - int right; - int bottom; - - explicit IntegerRectangle(PRectangle rc) noexcept : - left(static_cast(rc.left)), top(static_cast(rc.top)), - right(static_cast(rc.right)), bottom(static_cast(rc.bottom)) { - } - int Width() const noexcept { return right - left; } - int Height() const noexcept { return bottom - top; } -}; - -} - -#endif diff --git a/scintilla/src/KeyMap.cxx b/scintilla/src/KeyMap.cxx index 8dc4feff92..ae189db55a 100644 --- a/scintilla/src/KeyMap.cxx +++ b/scintilla/src/KeyMap.cxx @@ -8,20 +8,24 @@ #include #include +#include #include #include +#include #include -#include "Platform.h" +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" -#include "Scintilla.h" +#include "Debugging.h" #include "KeyMap.h" using namespace Scintilla; +using namespace Scintilla::Internal; KeyMap::KeyMap() { - for (int i = 0; MapDefault[i].key; i++) { + for (int i = 0; static_cast(MapDefault[i].key); i++) { AssignCmdKey(MapDefault[i].key, MapDefault[i].modifiers, MapDefault[i].msg); @@ -36,16 +40,16 @@ void KeyMap::Clear() noexcept { kmap.clear(); } -void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) { +void KeyMap::AssignCmdKey(Keys key, KeyMod modifiers, Message msg) { kmap[KeyModifiers(key, modifiers)] = msg; } -unsigned int KeyMap::Find(int key, int modifiers) const { - std::map::const_iterator it = kmap.find(KeyModifiers(key, modifiers)); - return (it == kmap.end()) ? 0 : it->second; +Message KeyMap::Find(Keys key, KeyMod modifiers) const { + std::map::const_iterator it = kmap.find(KeyModifiers(key, modifiers)); + return (it == kmap.end()) ? static_cast(0) : it->second; } -const std::map &KeyMap::GetKeyMap() const noexcept { +const std::map &KeyMap::GetKeyMap() const noexcept { return kmap; } @@ -65,100 +69,108 @@ const std::map &KeyMap::GetKeyMap() const noexcept { #define SCI_SCTRL_META (SCI_CTRL | SCI_SHIFT) #endif +namespace { + +constexpr Keys Key(char ch) { + return static_cast(ch); +} + +} + const KeyToCommand KeyMap::MapDefault[] = { #if OS_X_KEYS - {SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND}, - {SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, - {SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART}, - {SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, - {SCK_LEFT, SCI_CTRL, SCI_VCHOME}, - {SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND}, - {SCK_RIGHT, SCI_CTRL, SCI_LINEEND}, - {SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND}, + {Keys::Down, SCI_CTRL, Message::DocumentEnd}, + {Keys::Down, SCI_CSHIFT, Message::DocumentEndExtend}, + {Keys::Up, SCI_CTRL, Message::DocumentStart}, + {Keys::Up, SCI_CSHIFT, Message::DocumentStartExtend}, + {Keys::Left, SCI_CTRL, Message::VCHome}, + {Keys::Left, SCI_CSHIFT, Message::VCHomeExtend}, + {Keys::Right, SCI_CTRL, Message::LineEnd}, + {Keys::Right, SCI_CSHIFT, Message::LineEndExtend}, #endif - {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, - {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, - {SCK_DOWN, SCI_CTRL_META, SCI_LINESCROLLDOWN}, - {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, - {SCK_UP, SCI_NORM, SCI_LINEUP}, - {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, - {SCK_UP, SCI_CTRL_META, SCI_LINESCROLLUP}, - {SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND}, - {'[', SCI_CTRL, SCI_PARAUP}, - {'[', SCI_CSHIFT, SCI_PARAUPEXTEND}, - {']', SCI_CTRL, SCI_PARADOWN}, - {']', SCI_CSHIFT, SCI_PARADOWNEXTEND}, - {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, - {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, - {SCK_LEFT, SCI_CTRL_META, SCI_WORDLEFT}, - {SCK_LEFT, SCI_SCTRL_META, SCI_WORDLEFTEXTEND}, - {SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND}, - {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, - {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, - {SCK_RIGHT, SCI_CTRL_META, SCI_WORDRIGHT}, - {SCK_RIGHT, SCI_SCTRL_META, SCI_WORDRIGHTEXTEND}, - {SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND}, - {'/', SCI_CTRL, SCI_WORDPARTLEFT}, - {'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND}, - {'\\', SCI_CTRL, SCI_WORDPARTRIGHT}, - {'\\', SCI_CSHIFT, SCI_WORDPARTRIGHTEXTEND}, - {SCK_HOME, SCI_NORM, SCI_VCHOME}, - {SCK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND}, - {SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART}, - {SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, - {SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY}, - {SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND}, - {SCK_END, SCI_NORM, SCI_LINEEND}, - {SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND}, - {SCK_END, SCI_CTRL, SCI_DOCUMENTEND}, - {SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, - {SCK_END, SCI_ALT, SCI_LINEENDDISPLAY}, - {SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND}, - {SCK_PRIOR, SCI_NORM, SCI_PAGEUP}, - {SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND}, - {SCK_PRIOR, SCI_ASHIFT, SCI_PAGEUPRECTEXTEND}, - {SCK_NEXT, SCI_NORM, SCI_PAGEDOWN}, - {SCK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND}, - {SCK_NEXT, SCI_ASHIFT, SCI_PAGEDOWNRECTEXTEND}, - {SCK_DELETE, SCI_NORM, SCI_CLEAR}, - {SCK_DELETE, SCI_SHIFT, SCI_CUT}, - {SCK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT}, - {SCK_DELETE, SCI_CSHIFT, SCI_DELLINERIGHT}, - {SCK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE}, - {SCK_INSERT, SCI_SHIFT, SCI_PASTE}, - {SCK_INSERT, SCI_CTRL, SCI_COPY}, - {SCK_ESCAPE, SCI_NORM, SCI_CANCEL}, - {SCK_BACK, SCI_NORM, SCI_DELETEBACK}, - {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, - {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, - {SCK_BACK, SCI_ALT, SCI_UNDO}, - {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, - {'Z', SCI_CTRL, SCI_UNDO}, + {Keys::Down, SCI_NORM, Message::LineDown}, + {Keys::Down, SCI_SHIFT, Message::LineDownExtend}, + {Keys::Down, SCI_CTRL_META, Message::LineScrollDown}, + {Keys::Down, SCI_ASHIFT, Message::LineDownRectExtend}, + {Keys::Up, SCI_NORM, Message::LineUp}, + {Keys::Up, SCI_SHIFT, Message::LineUpExtend}, + {Keys::Up, SCI_CTRL_META, Message::LineScrollUp}, + {Keys::Up, SCI_ASHIFT, Message::LineUpRectExtend}, + {Key('['), SCI_CTRL, Message::ParaUp}, + {Key('['), SCI_CSHIFT, Message::ParaUpExtend}, + {Key(']'), SCI_CTRL, Message::ParaDown}, + {Key(']'), SCI_CSHIFT, Message::ParaDownExtend}, + {Keys::Left, SCI_NORM, Message::CharLeft}, + {Keys::Left, SCI_SHIFT, Message::CharLeftExtend}, + {Keys::Left, SCI_CTRL_META, Message::WordLeft}, + {Keys::Left, SCI_SCTRL_META, Message::WordLeftExtend}, + {Keys::Left, SCI_ASHIFT, Message::CharLeftRectExtend}, + {Keys::Right, SCI_NORM, Message::CharRight}, + {Keys::Right, SCI_SHIFT, Message::CharRightExtend}, + {Keys::Right, SCI_CTRL_META, Message::WordRight}, + {Keys::Right, SCI_SCTRL_META, Message::WordRightExtend}, + {Keys::Right, SCI_ASHIFT, Message::CharRightRectExtend}, + {Key('/'), SCI_CTRL, Message::WordPartLeft}, + {Key('/'), SCI_CSHIFT, Message::WordPartLeftExtend}, + {Key('\\'), SCI_CTRL, Message::WordPartRight}, + {Key('\\'), SCI_CSHIFT, Message::WordPartRightExtend}, + {Keys::Home, SCI_NORM, Message::VCHome}, + {Keys::Home, SCI_SHIFT, Message::VCHomeExtend}, + {Keys::Home, SCI_CTRL, Message::DocumentStart}, + {Keys::Home, SCI_CSHIFT, Message::DocumentStartExtend}, + {Keys::Home, SCI_ALT, Message::HomeDisplay}, + {Keys::Home, SCI_ASHIFT, Message::VCHomeRectExtend}, + {Keys::End, SCI_NORM, Message::LineEnd}, + {Keys::End, SCI_SHIFT, Message::LineEndExtend}, + {Keys::End, SCI_CTRL, Message::DocumentEnd}, + {Keys::End, SCI_CSHIFT, Message::DocumentEndExtend}, + {Keys::End, SCI_ALT, Message::LineEndDisplay}, + {Keys::End, SCI_ASHIFT, Message::LineEndRectExtend}, + {Keys::Prior, SCI_NORM, Message::PageUp}, + {Keys::Prior, SCI_SHIFT, Message::PageUpExtend}, + {Keys::Prior, SCI_ASHIFT, Message::PageUpRectExtend}, + {Keys::Next, SCI_NORM, Message::PageDown}, + {Keys::Next, SCI_SHIFT, Message::PageDownExtend}, + {Keys::Next, SCI_ASHIFT, Message::PageDownRectExtend}, + {Keys::Delete, SCI_NORM, Message::Clear}, + {Keys::Delete, SCI_SHIFT, Message::Cut}, + {Keys::Delete, SCI_CTRL, Message::DelWordRight}, + {Keys::Delete, SCI_CSHIFT, Message::DelLineRight}, + {Keys::Insert, SCI_NORM, Message::EditToggleOvertype}, + {Keys::Insert, SCI_SHIFT, Message::Paste}, + {Keys::Insert, SCI_CTRL, Message::Copy}, + {Keys::Escape, SCI_NORM, Message::Cancel}, + {Keys::Back, SCI_NORM, Message::DeleteBack}, + {Keys::Back, SCI_SHIFT, Message::DeleteBack}, + {Keys::Back, SCI_CTRL, Message::DelWordLeft}, + {Keys::Back, SCI_ALT, Message::Undo}, + {Keys::Back, SCI_CSHIFT, Message::DelLineLeft}, + {Key('Z'), SCI_CTRL, Message::Undo}, #if OS_X_KEYS - {'Z', SCI_CSHIFT, SCI_REDO}, + {Key('Z'), SCI_CSHIFT, Message::Redo}, #else - {'Y', SCI_CTRL, SCI_REDO}, + {Key('Y'), SCI_CTRL, Message::Redo}, #endif - {'X', SCI_CTRL, SCI_CUT}, - {'C', SCI_CTRL, SCI_COPY}, - {'V', SCI_CTRL, SCI_PASTE}, - {'A', SCI_CTRL, SCI_SELECTALL}, - {SCK_TAB, SCI_NORM, SCI_TAB}, - {SCK_TAB, SCI_SHIFT, SCI_BACKTAB}, - {SCK_RETURN, SCI_NORM, SCI_NEWLINE}, - {SCK_RETURN, SCI_SHIFT, SCI_NEWLINE}, - {SCK_ADD, SCI_CTRL, SCI_ZOOMIN}, - {SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT}, - {SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM}, - {'L', SCI_CTRL, SCI_LINECUT}, - {'L', SCI_CSHIFT, SCI_LINEDELETE}, - {'T', SCI_CSHIFT, SCI_LINECOPY}, - {'T', SCI_CTRL, SCI_LINETRANSPOSE}, - {'D', SCI_CTRL, SCI_SELECTIONDUPLICATE}, - {'U', SCI_CTRL, SCI_LOWERCASE}, - {'U', SCI_CSHIFT, SCI_UPPERCASE}, - {0,0,0}, + {Key('X'), SCI_CTRL, Message::Cut}, + {Key('C'), SCI_CTRL, Message::Copy}, + {Key('V'), SCI_CTRL, Message::Paste}, + {Key('A'), SCI_CTRL, Message::SelectAll}, + {Keys::Tab, SCI_NORM, Message::Tab}, + {Keys::Tab, SCI_SHIFT, Message::BackTab}, + {Keys::Return, SCI_NORM, Message::NewLine}, + {Keys::Return, SCI_SHIFT, Message::NewLine}, + {Keys::Add, SCI_CTRL, Message::ZoomIn}, + {Keys::Subtract, SCI_CTRL, Message::ZoomOut}, + {Keys::Divide, SCI_CTRL, Message::SetZoom}, + {Key('L'), SCI_CTRL, Message::LineCut}, + {Key('L'), SCI_CSHIFT, Message::LineDelete}, + {Key('T'), SCI_CSHIFT, Message::LineCopy}, + {Key('T'), SCI_CTRL, Message::LineTranspose}, + {Key('D'), SCI_CTRL, Message::SelectionDuplicate}, + {Key('U'), SCI_CTRL, Message::LowerCase}, + {Key('U'), SCI_CSHIFT, Message::UpperCase}, + {Key(0),SCI_NORM,static_cast(0)}, }; diff --git a/scintilla/src/KeyMap.h b/scintilla/src/KeyMap.h index 245b6daaa9..6662118b20 100644 --- a/scintilla/src/KeyMap.h +++ b/scintilla/src/KeyMap.h @@ -8,24 +8,24 @@ #ifndef KEYMAP_H #define KEYMAP_H -namespace Scintilla { +namespace Scintilla::Internal { -#define SCI_NORM 0 -#define SCI_SHIFT SCMOD_SHIFT -#define SCI_CTRL SCMOD_CTRL -#define SCI_ALT SCMOD_ALT -#define SCI_META SCMOD_META -#define SCI_SUPER SCMOD_SUPER -#define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT) -#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT) +#define SCI_NORM KeyMod::Norm +#define SCI_SHIFT KeyMod::Shift +#define SCI_CTRL KeyMod::Ctrl +#define SCI_ALT KeyMod::Alt +#define SCI_META KeyMod::Meta +#define SCI_SUPER KeyMod::Super +#define SCI_CSHIFT (KeyMod::Ctrl | KeyMod::Shift) +#define SCI_ASHIFT (KeyMod::Alt | KeyMod::Shift) /** */ class KeyModifiers { public: - int key; - int modifiers; - KeyModifiers(int key_, int modifiers_) noexcept : key(key_), modifiers(modifiers_) { + Scintilla::Keys key; + Scintilla::KeyMod modifiers; + KeyModifiers(Scintilla::Keys key_, Scintilla::KeyMod modifiers_) noexcept : key(key_), modifiers(modifiers_) { } bool operator<(const KeyModifiers &other) const noexcept { if (key == other.key) @@ -39,24 +39,24 @@ class KeyModifiers { */ class KeyToCommand { public: - int key; - int modifiers; - unsigned int msg; + Scintilla::Keys key; + Scintilla::KeyMod modifiers; + Scintilla::Message msg; }; /** */ class KeyMap { - std::map kmap; + std::map kmap; static const KeyToCommand MapDefault[]; public: KeyMap(); ~KeyMap(); void Clear() noexcept; - void AssignCmdKey(int key, int modifiers, unsigned int msg); - unsigned int Find(int key, int modifiers) const; // 0 returned on failure - const std::map &GetKeyMap() const noexcept; + void AssignCmdKey(Scintilla::Keys key, Scintilla::KeyMod modifiers, Scintilla::Message msg); + Scintilla::Message Find(Scintilla::Keys key, Scintilla::KeyMod modifiers) const; // 0 returned on failure + const std::map &GetKeyMap() const noexcept; }; } diff --git a/scintilla/src/LineMarker.cxx b/scintilla/src/LineMarker.cxx index c7ab08966a..5bfb893079 100644 --- a/scintilla/src/LineMarker.cxx +++ b/scintilla/src/LineMarker.cxx @@ -9,20 +9,28 @@ #include #include +#include +#include #include #include +#include #include +#include #include -#include "Platform.h" +#include "ScintillaTypes.h" + +#include "Debugging.h" +#include "Geometry.h" -#include "Scintilla.h" +#include "Platform.h" -#include "IntegerRectangle.h" #include "XPM.h" #include "LineMarker.h" +#include "UniConversion.h" using namespace Scintilla; +using namespace Scintilla::Internal; LineMarker::LineMarker(const LineMarker &other) { // Defined to avoid pxpm and image being blindly copied, not as a complete copy constructor. @@ -30,13 +38,15 @@ LineMarker::LineMarker(const LineMarker &other) { fore = other.fore; back = other.back; backSelected = other.backSelected; + strokeWidth = other.strokeWidth; + layer = other.layer; alpha = other.alpha; if (other.pxpm) - pxpm = Sci::make_unique(*other.pxpm); + pxpm = std::make_unique(*other.pxpm); else pxpm = nullptr; if (other.image) - image = Sci::make_unique(*other.image); + image = std::make_unique(*other.image); else image = nullptr; customDraw = other.customDraw; @@ -49,13 +59,15 @@ LineMarker &LineMarker::operator=(const LineMarker &other) { fore = other.fore; back = other.back; backSelected = other.backSelected; + strokeWidth = other.strokeWidth; + layer = other.layer; alpha = other.alpha; if (other.pxpm) - pxpm = Sci::make_unique(*other.pxpm); + pxpm = std::make_unique(*other.pxpm); else pxpm = nullptr; if (other.image) - image = Sci::make_unique(*other.image); + image = std::make_unique(*other.image); else image = nullptr; customDraw = other.customDraw; @@ -63,60 +75,94 @@ LineMarker &LineMarker::operator=(const LineMarker &other) { return *this; } +ColourRGBA LineMarker::BackWithAlpha() const noexcept { + return ColourRGBA(back, static_cast(alpha)); +} + void LineMarker::SetXPM(const char *textForm) { - pxpm = Sci::make_unique(textForm); - markType = SC_MARK_PIXMAP; + pxpm = std::make_unique(textForm); + markType = MarkerSymbol::Pixmap; } void LineMarker::SetXPM(const char *const *linesForm) { - pxpm = Sci::make_unique(linesForm); - markType = SC_MARK_PIXMAP; + pxpm = std::make_unique(linesForm); + markType = MarkerSymbol::Pixmap; } void LineMarker::SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage) { - image = Sci::make_unique(static_cast(sizeRGBAImage.x), static_cast(sizeRGBAImage.y), scale, pixelsRGBAImage); - markType = SC_MARK_RGBAIMAGE; + image = std::make_unique(static_cast(sizeRGBAImage.x), static_cast(sizeRGBAImage.y), scale, pixelsRGBAImage); + markType = MarkerSymbol::RgbaImage; } -static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { - const PRectangle rc = PRectangle::FromInts( - centreX - armSize, - centreY - armSize, - centreX + armSize + 1, - centreY + armSize + 1); - surface->RectangleDraw(rc, back, fore); -} +namespace { + +enum class Expansion { Minus, Plus }; +enum class Shape { Square, Circle }; -static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { - const PRectangle rcCircle = PRectangle::FromInts( - centreX - armSize, - centreY - armSize, - centreX + armSize + 1, - centreY + armSize + 1); - surface->Ellipse(rcCircle, back, fore); +void DrawSymbol(Surface *surface, Shape shape, Expansion expansion, PRectangle rcSymbol, XYPOSITION widthStroke, + ColourRGBA colourFill, ColourRGBA colourFrame, ColourRGBA colourFrameRight, ColourRGBA colourExpansion) { + + const FillStroke fillStroke(colourFill, colourFrame, widthStroke); + const PRectangle rcSymbolLeft = Side(rcSymbol, Edge::left, (rcSymbol.Width() + widthStroke) / 2.0f); + surface->SetClip(rcSymbolLeft); + if (shape == Shape::Square) { + // Hollowed square + surface->RectangleDraw(rcSymbol, fillStroke); + } else { + surface->Ellipse(rcSymbol, fillStroke); + } + surface->PopClip(); + + const FillStroke fillStrokeRight(colourFill, colourFrameRight, widthStroke); + const PRectangle rcSymbolRight = Side(rcSymbol, Edge::right, (rcSymbol.Width() - widthStroke) / 2.0f); + surface->SetClip(rcSymbolRight); + if (shape == Shape::Square) { + surface->RectangleDraw(rcSymbol, fillStrokeRight); + } else { + surface->Ellipse(rcSymbol, fillStrokeRight); + } + surface->PopClip(); + + const PRectangle rcPlusMinus = rcSymbol.Inset(widthStroke + 1.0f); + const XYPOSITION armWidth = (rcPlusMinus.Width() - widthStroke) / 2.0f; + const XYPOSITION top = rcPlusMinus.top + armWidth; + const PRectangle rcH = PRectangle( + rcPlusMinus.left, top, + rcPlusMinus.right, top + widthStroke); + surface->FillRectangle(rcH, colourExpansion); + if (expansion == Expansion::Plus) { + const XYPOSITION left = rcPlusMinus.left + armWidth; + const PRectangle rcV = PRectangle( + left, rcPlusMinus.top, + left + widthStroke, rcPlusMinus.bottom); + surface->FillRectangle(rcV, colourExpansion); + } } -static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) { - const PRectangle rcV = PRectangle::FromInts(centreX, centreY - armSize + 2, centreX + 1, centreY + armSize - 2 + 1); - surface->FillRectangle(rcV, fore); - const PRectangle rcH = PRectangle::FromInts(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY + 1); - surface->FillRectangle(rcH, fore); +void DrawTail(Surface *surface, XYPOSITION leftLine, XYPOSITION rightTail, XYPOSITION centreY, XYPOSITION widthSymbolStroke, ColourRGBA fill) { + const XYPOSITION slopeLength = 2.0f + widthSymbolStroke; + const XYPOSITION strokeTop = centreY + slopeLength; + const XYPOSITION halfWidth = widthSymbolStroke / 2.0f; + const XYPOSITION strokeMiddle = strokeTop + halfWidth; + Point lines[] = { + // Stick + Point(rightTail, strokeMiddle), + Point(leftLine + halfWidth + slopeLength, strokeMiddle), + // Slope + Point(leftLine + widthSymbolStroke / 2.0f, centreY + halfWidth), + }; + surface->PolyLine(lines, std::size(lines), Stroke(fill, widthSymbolStroke)); } -static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) { - const PRectangle rcH = PRectangle::FromInts(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY + 1); - surface->FillRectangle(rcH, fore); } -void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, FoldPart part, int marginStyle) const { - if (customDraw) { - customDraw(surface, rcWhole, fontForCharacter, static_cast(part), marginStyle, this); - return; - } +void LineMarker::DrawFoldingMark(Surface *surface, const PRectangle &rcWhole, FoldPart part) const { + // Assume: edges of rcWhole are integers. + // Code can only really handle integer strokeWidth. - ColourDesired colourHead = back; - ColourDesired colourBody = back; - ColourDesired colourTail = back; + ColourRGBA colourHead = back; + ColourRGBA colourBody = back; + ColourRGBA colourTail = back; switch (part) { case FoldPart::head: @@ -133,15 +179,172 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac colourTail = backSelected; break; default: - // FoldPart::undefined + // LineMarker::undefined break; } - if ((markType == SC_MARK_PIXMAP) && (pxpm)) { + const int pixelDivisions = surface->PixelDivisions(); + + // Folding symbols should have equal height and width to be either a circle or square. + // So find the minimum of width and height. + const XYPOSITION minDimension = std::floor(std::min(rcWhole.Width(), rcWhole.Height() - 2)) - 1; + + // If strokeWidth would take up too much of area reduce to reasonable width. + const XYPOSITION widthStroke = PixelAlignFloor(std::min(strokeWidth, minDimension / 5.0f), pixelDivisions); + + // To centre +/-, odd strokeWidth -> odd symbol width, even -> even + const XYPOSITION widthSymbol = + ((std::lround(minDimension * pixelDivisions) % 2) == (std::lround(widthStroke * pixelDivisions) % 2)) ? + minDimension : minDimension - 1.0f / pixelDivisions; + + const Point centre = PixelAlign(rcWhole.Centre(), pixelDivisions); + + // Folder symbols and lines follow some rules to join up, fit the pixel grid, + // and avoid over-painting. + + const XYPOSITION halfSymbol = std::round(widthSymbol / 2); + const Point topLeft(centre.x - halfSymbol, centre.y - halfSymbol); + const PRectangle rcSymbol( + topLeft.x, topLeft.y, + topLeft.x + widthSymbol, topLeft.y + widthSymbol); + const XYPOSITION leftLine = rcSymbol.Centre().x - widthStroke / 2.0f; + const XYPOSITION rightLine = leftLine + widthStroke; + + // This is the vertical line through the whole area which is subdivided + // when there is a symbol on the line or the colour changes for highlighting. + const PRectangle rcVLine(leftLine, rcWhole.top, rightLine, rcWhole.bottom); + + // Portions of rcVLine above and below the symbol. + const PRectangle rcAboveSymbol = Clamp(rcVLine, Edge::bottom, rcSymbol.top); + const PRectangle rcBelowSymbol = Clamp(rcVLine, Edge::top, rcSymbol.bottom); + + // Projection to right. + const PRectangle rcStick( + rcVLine.right, centre.y + 1.0f - widthStroke, + rcWhole.right - 1, centre.y + 1.0f); + + switch (markType) { + + case MarkerSymbol::VLine: + surface->FillRectangle(rcVLine, colourBody); + break; + + case MarkerSymbol::LCorner: + surface->FillRectangle(Clamp(rcVLine, Edge::bottom, centre.y + 1.0f), colourTail); + surface->FillRectangle(rcStick, colourTail); + break; + + case MarkerSymbol::TCorner: + surface->FillRectangle(Clamp(rcVLine, Edge::bottom, centre.y + 1.0f), colourBody); + surface->FillRectangle(Clamp(rcVLine, Edge::top, centre.y + 1.0f), colourHead); + surface->FillRectangle(rcStick, colourTail); + break; + + // CORNERCURVE cases divide slightly lower than CORNER to accommodate the curve + case MarkerSymbol::LCornerCurve: + surface->FillRectangle(Clamp(rcVLine, Edge::bottom, centre.y), colourTail); + DrawTail(surface, leftLine, rcWhole.right - 1.0f, centre.y - widthStroke, + widthStroke, colourTail); + break; + + case MarkerSymbol::TCornerCurve: + surface->FillRectangle(Clamp(rcVLine, Edge::bottom, centre.y), colourBody); + surface->FillRectangle(Clamp(rcVLine, Edge::top, centre.y), colourHead); + DrawTail(surface, leftLine, rcWhole.right - 1.0f, centre.y - widthStroke, + widthStroke, colourTail); + break; + + case MarkerSymbol::BoxPlus: + DrawSymbol(surface, Shape::Square, Expansion::Plus, rcSymbol, widthStroke, + fore, colourHead, colourHead, colourTail); + break; + + case MarkerSymbol::BoxPlusConnected: { + const ColourRGBA colourBelow = (part == FoldPart::headWithTail) ? colourTail : colourBody; + surface->FillRectangle(rcBelowSymbol, colourBelow); + surface->FillRectangle(rcAboveSymbol, colourBody); + + const ColourRGBA colourRight = (part == FoldPart::body) ? colourTail : colourHead; + DrawSymbol(surface, Shape::Square, Expansion::Plus, rcSymbol, widthStroke, + fore, colourHead, colourRight, colourTail); + } + break; + + case MarkerSymbol::BoxMinus: + surface->FillRectangle(rcBelowSymbol, colourHead); + DrawSymbol(surface, Shape::Square, Expansion::Minus, rcSymbol, widthStroke, + fore, colourHead, colourHead, colourTail); + break; + + case MarkerSymbol::BoxMinusConnected: { + surface->FillRectangle(rcBelowSymbol, colourHead); + surface->FillRectangle(rcAboveSymbol, colourBody); + + const ColourRGBA colourRight = (part == FoldPart::body) ? colourTail : colourHead; + DrawSymbol(surface, Shape::Square, Expansion::Minus, rcSymbol, widthStroke, + fore, colourHead, colourRight, colourTail); + } + break; + + case MarkerSymbol::CirclePlus: + DrawSymbol(surface, Shape::Circle, Expansion::Plus, rcSymbol, widthStroke, + fore, colourHead, colourHead, colourTail); + break; + + case MarkerSymbol::CirclePlusConnected: { + const ColourRGBA colourBelow = (part == FoldPart::headWithTail) ? colourTail : colourBody; + surface->FillRectangle(rcBelowSymbol, colourBelow); + surface->FillRectangle(rcAboveSymbol, colourBody); + + const ColourRGBA colourRight = (part == FoldPart::body) ? colourTail : colourHead; + DrawSymbol(surface, Shape::Circle, Expansion::Plus, rcSymbol, widthStroke, + fore, colourHead, colourRight, colourTail); + } + break; + + case MarkerSymbol::CircleMinus: + surface->FillRectangle(rcBelowSymbol, colourHead); + DrawSymbol(surface, Shape::Circle, Expansion::Minus, rcSymbol, widthStroke, + fore, colourHead, colourHead, colourTail); + break; + + case MarkerSymbol::CircleMinusConnected: { + surface->FillRectangle(rcBelowSymbol, colourHead); + surface->FillRectangle(rcAboveSymbol, colourBody); + const ColourRGBA colourRight = (part == FoldPart::body) ? colourTail : colourHead; + DrawSymbol(surface, Shape::Circle, Expansion::Minus, rcSymbol, widthStroke, + fore, colourHead, colourRight, colourTail); + } + break; + + default: + break; + + } +} + +void LineMarker::AlignedPolygon(Surface *surface, const Point *pts, size_t npts) const { + const XYPOSITION move = strokeWidth / 2.0; + std::vector points; + std::transform(pts, pts + npts, std::back_inserter(points), [=](Point pt)->Point { + return Point(pt.x + move, pt.y + move); + }); + surface->Polygon(points.data(), std::size(points), FillStroke(back, fore, strokeWidth)); +} + +void LineMarker::Draw(Surface *surface, const PRectangle &rcWhole, const Font *fontForCharacter, FoldPart part, MarginType marginStyle) const { + // This is to satisfy the changed API - eventually the stroke width will be exposed to clients + + if (customDraw) { + customDraw(surface, rcWhole, fontForCharacter, static_cast(part), marginStyle, this); + return; + } + + if ((markType == MarkerSymbol::Pixmap) && (pxpm)) { pxpm->Draw(surface, rcWhole); return; } - if ((markType == SC_MARK_RGBAIMAGE) && (image)) { + if ((markType == MarkerSymbol::RgbaImage) && (image)) { // Make rectangle just large enough to fit image centred on centre of rcWhole PRectangle rcImage; rcImage.top = ((rcWhole.top + rcWhole.bottom) - image->GetScaledHeight()) / 2; @@ -152,280 +355,114 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac return; } - const IntegerRectangle ircWhole(rcWhole); + if ((markType >= MarkerSymbol::VLine) && markType <= (MarkerSymbol::CircleMinusConnected)) { + DrawFoldingMark(surface, rcWhole, part); + return; + } + // Restrict most shapes a bit const PRectangle rc(rcWhole.left, rcWhole.top + 1, rcWhole.right, rcWhole.bottom - 1); // Ensure does not go beyond edge - const int minDim = std::min(ircWhole.Width(), ircWhole.Height() - 2) - 1; - int centreX = (ircWhole.right + ircWhole.left) / 2; - const int centreY = (ircWhole.bottom + ircWhole.top) / 2; - const int dimOn2 = minDim / 2; - const int dimOn4 = minDim / 4; - const int blobSize = dimOn2 - 1; - const int armSize = dimOn2 - 2; - if (marginStyle == SC_MARGIN_NUMBER || marginStyle == SC_MARGIN_TEXT || marginStyle == SC_MARGIN_RTEXT) { + const XYPOSITION minDim = std::min(rcWhole.Width(), rcWhole.Height() - 2) - 1; + + const Point centre = rcWhole.Centre(); + XYPOSITION centreX = std::floor(centre.x); + const XYPOSITION centreY = std::floor(centre.y); + const XYPOSITION dimOn2 = std::floor(minDim / 2); + const XYPOSITION dimOn4 = std::floor(minDim / 4); + const XYPOSITION armSize = dimOn2 - 2; + if (marginStyle == MarginType::Number || marginStyle == MarginType::Text || marginStyle == MarginType::RText) { // On textual margins move marker to the left to try to avoid overlapping the text - centreX = ircWhole.left + dimOn2 + 1; + centreX = rcWhole.left + dimOn2 + 1; } switch (markType) { - case SC_MARK_ROUNDRECT: { + case MarkerSymbol::RoundRect: { PRectangle rcRounded = rc; rcRounded.left = rc.left + 1; rcRounded.right = rc.right - 1; - surface->RoundedRectangle(rcRounded, fore, back); + surface->RoundedRectangle(rcRounded, FillStroke(back, fore, strokeWidth)); } break; - case SC_MARK_CIRCLE: { - const PRectangle rcCircle = PRectangle::FromInts( + case MarkerSymbol::Circle: { + const PRectangle rcCircle = PRectangle( centreX - dimOn2, centreY - dimOn2, centreX + dimOn2, centreY + dimOn2); - surface->Ellipse(rcCircle, fore, back); + surface->Ellipse(rcCircle, FillStroke(back, fore, strokeWidth)); } break; - case SC_MARK_ARROW: { + case MarkerSymbol::Arrow: { Point pts[] = { - Point::FromInts(centreX - dimOn4, centreY - dimOn2), - Point::FromInts(centreX - dimOn4, centreY + dimOn2), - Point::FromInts(centreX + dimOn2 - dimOn4, centreY), + Point(centreX - dimOn4, centreY - dimOn2), + Point(centreX - dimOn4, centreY + dimOn2), + Point(centreX + dimOn2 - dimOn4, centreY), }; - surface->Polygon(pts, Sci::size(pts), fore, back); + AlignedPolygon(surface, pts, std::size(pts)); } break; - case SC_MARK_ARROWDOWN: { + case MarkerSymbol::ArrowDown: { Point pts[] = { - Point::FromInts(centreX - dimOn2, centreY - dimOn4), - Point::FromInts(centreX + dimOn2, centreY - dimOn4), - Point::FromInts(centreX, centreY + dimOn2 - dimOn4), + Point(centreX - dimOn2, centreY - dimOn4), + Point(centreX + dimOn2, centreY - dimOn4), + Point(centreX, centreY + dimOn2 - dimOn4), }; - surface->Polygon(pts, Sci::size(pts), fore, back); + AlignedPolygon(surface, pts, std::size(pts)); } break; - case SC_MARK_PLUS: { + case MarkerSymbol::Plus: { Point pts[] = { - Point::FromInts(centreX - armSize, centreY - 1), - Point::FromInts(centreX - 1, centreY - 1), - Point::FromInts(centreX - 1, centreY - armSize), - Point::FromInts(centreX + 1, centreY - armSize), - Point::FromInts(centreX + 1, centreY - 1), - Point::FromInts(centreX + armSize, centreY - 1), - Point::FromInts(centreX + armSize, centreY + 1), - Point::FromInts(centreX + 1, centreY + 1), - Point::FromInts(centreX + 1, centreY + armSize), - Point::FromInts(centreX - 1, centreY + armSize), - Point::FromInts(centreX - 1, centreY + 1), - Point::FromInts(centreX - armSize, centreY + 1), + Point(centreX - armSize, centreY - 1), + Point(centreX - 1, centreY - 1), + Point(centreX - 1, centreY - armSize), + Point(centreX + 1, centreY - armSize), + Point(centreX + 1, centreY - 1), + Point(centreX + armSize, centreY - 1), + Point(centreX + armSize, centreY + 1), + Point(centreX + 1, centreY + 1), + Point(centreX + 1, centreY + armSize), + Point(centreX - 1, centreY + armSize), + Point(centreX - 1, centreY + 1), + Point(centreX - armSize, centreY + 1), }; - surface->Polygon(pts, Sci::size(pts), fore, back); + AlignedPolygon(surface, pts, std::size(pts)); } break; - case SC_MARK_MINUS: { + case MarkerSymbol::Minus: { Point pts[] = { - Point::FromInts(centreX - armSize, centreY - 1), - Point::FromInts(centreX + armSize, centreY - 1), - Point::FromInts(centreX + armSize, centreY + 1), - Point::FromInts(centreX - armSize, centreY + 1), + Point(centreX - armSize, centreY - 1), + Point(centreX + armSize, centreY - 1), + Point(centreX + armSize, centreY + 1), + Point(centreX - armSize, centreY + 1), }; - surface->Polygon(pts, Sci::size(pts), fore, back); + AlignedPolygon(surface, pts, std::size(pts)); } break; - case SC_MARK_SMALLRECT: { + case MarkerSymbol::SmallRect: { PRectangle rcSmall; rcSmall.left = rc.left + 1; rcSmall.top = rc.top + 2; rcSmall.right = rc.right - 1; rcSmall.bottom = rc.bottom - 2; - surface->RectangleDraw(rcSmall, fore, back); + surface->RectangleDraw(rcSmall, FillStroke(back, fore, strokeWidth)); } break; - case SC_MARK_EMPTY: - case SC_MARK_BACKGROUND: - case SC_MARK_UNDERLINE: - case SC_MARK_AVAILABLE: + case MarkerSymbol::Empty: + case MarkerSymbol::Background: + case MarkerSymbol::Underline: + case MarkerSymbol::Available: // An invisible marker so don't draw anything break; - case SC_MARK_VLINE: { - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, ircWhole.bottom); - } - break; - - case SC_MARK_LCORNER: { - surface->PenColour(colourTail); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY); - surface->LineTo(ircWhole.right - 1, centreY); - } - break; - - case SC_MARK_TCORNER: { - surface->PenColour(colourTail); - surface->MoveTo(centreX, centreY); - surface->LineTo(ircWhole.right - 1, centreY); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY + 1); - - surface->PenColour(colourHead); - surface->LineTo(centreX, ircWhole.bottom); - } - break; - - case SC_MARK_LCORNERCURVE: { - surface->PenColour(colourTail); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - 3); - surface->LineTo(centreX + 3, centreY); - surface->LineTo(ircWhole.right - 1, centreY); - } - break; - - case SC_MARK_TCORNERCURVE: { - surface->PenColour(colourTail); - surface->MoveTo(centreX, centreY - 3); - surface->LineTo(centreX + 3, centreY); - surface->LineTo(ircWhole.right - 1, centreY); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - 2); - - surface->PenColour(colourHead); - surface->LineTo(centreX, ircWhole.bottom); - } - break; - - case SC_MARK_BOXPLUS: { - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - } - break; - - case SC_MARK_BOXPLUSCONNECTED: { - if (part == FoldPart::headWithTail) - surface->PenColour(colourTail); - else - surface->PenColour(colourBody); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - blobSize); - - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - - if (part == FoldPart::body) { - surface->PenColour(colourTail); - surface->MoveTo(centreX + 1, centreY + blobSize); - surface->LineTo(centreX + blobSize + 1, centreY + blobSize); - - surface->MoveTo(centreX + blobSize, centreY + blobSize); - surface->LineTo(centreX + blobSize, centreY - blobSize); - - surface->MoveTo(centreX + 1, centreY - blobSize); - surface->LineTo(centreX + blobSize + 1, centreY - blobSize); - } - } - break; - - case SC_MARK_BOXMINUS: { - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); - } - break; - - case SC_MARK_BOXMINUSCONNECTED: { - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - blobSize); - - if (part == FoldPart::body) { - surface->PenColour(colourTail); - surface->MoveTo(centreX + 1, centreY + blobSize); - surface->LineTo(centreX + blobSize + 1, centreY + blobSize); - - surface->MoveTo(centreX + blobSize, centreY + blobSize); - surface->LineTo(centreX + blobSize, centreY - blobSize); - - surface->MoveTo(centreX + 1, centreY - blobSize); - surface->LineTo(centreX + blobSize + 1, centreY - blobSize); - } - } - break; - - case SC_MARK_CIRCLEPLUS: { - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - } - break; - - case SC_MARK_CIRCLEPLUSCONNECTED: { - if (part == FoldPart::headWithTail) - surface->PenColour(colourTail); - else - surface->PenColour(colourBody); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - blobSize); - - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - } - break; - - case SC_MARK_CIRCLEMINUS: { - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); - - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - } - break; - - case SC_MARK_CIRCLEMINUSCONNECTED: { - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, ircWhole.bottom); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, ircWhole.top); - surface->LineTo(centreX, centreY - blobSize); - - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - } - break; - - case SC_MARK_DOTDOTDOT: { + case MarkerSymbol::DotDotDot: { XYPOSITION right = static_cast(centreX - 6); for (int b = 0; b < 3; b++) { const PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom - 2); @@ -435,84 +472,87 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac } break; - case SC_MARK_ARROWS: { - surface->PenColour(fore); - int right = centreX - 2; - const int armLength = dimOn2 - 1; + case MarkerSymbol::Arrows: { + XYPOSITION right = centreX - 4.0f + strokeWidth / 2.0f; + const XYPOSITION midY = centreY + strokeWidth / 2.0f; + const XYPOSITION armLength = std::round(dimOn2 - strokeWidth); for (int b = 0; b < 3; b++) { - surface->MoveTo(right, centreY); - surface->LineTo(right - armLength, centreY - armLength); - surface->MoveTo(right, centreY); - surface->LineTo(right - armLength, centreY + armLength); - right += 4; + const Point pts[] = { + Point(right - armLength, midY - armLength), + Point(right, midY), + Point(right - armLength, midY + armLength) + }; + surface->PolyLine(pts, std::size(pts), Stroke(fore, strokeWidth)); + right += strokeWidth + 3.0f; } } break; - case SC_MARK_SHORTARROW: { + case MarkerSymbol::ShortArrow: { Point pts[] = { - Point::FromInts(centreX, centreY + dimOn2), - Point::FromInts(centreX + dimOn2, centreY), - Point::FromInts(centreX, centreY - dimOn2), - Point::FromInts(centreX, centreY - dimOn4), - Point::FromInts(centreX - dimOn4, centreY - dimOn4), - Point::FromInts(centreX - dimOn4, centreY + dimOn4), - Point::FromInts(centreX, centreY + dimOn4), - Point::FromInts(centreX, centreY + dimOn2), + Point(centreX, centreY + dimOn2), + Point(centreX + dimOn2, centreY), + Point(centreX, centreY - dimOn2), + Point(centreX, centreY - dimOn4), + Point(centreX - dimOn4, centreY - dimOn4), + Point(centreX - dimOn4, centreY + dimOn4), + Point(centreX, centreY + dimOn4), + Point(centreX, centreY + dimOn2), }; - surface->Polygon(pts, Sci::size(pts), fore, back); + AlignedPolygon(surface, pts, std::size(pts)); } break; - case SC_MARK_FULLRECT: + case MarkerSymbol::FullRect: surface->FillRectangle(rcWhole, back); break; - case SC_MARK_LEFTRECT: { + case MarkerSymbol::LeftRect: { PRectangle rcLeft = rcWhole; rcLeft.right = rcLeft.left + 4; surface->FillRectangle(rcLeft, back); } break; - case SC_MARK_BOOKMARK: { - const int halfHeight = minDim / 3; + case MarkerSymbol::Bookmark: { + const XYPOSITION halfHeight = std::floor(minDim / 3); Point pts[] = { - Point::FromInts(ircWhole.left, centreY - halfHeight), - Point::FromInts(ircWhole.right - 3, centreY - halfHeight), - Point::FromInts(ircWhole.right - 3 - halfHeight, centreY), - Point::FromInts(ircWhole.right - 3, centreY + halfHeight), - Point::FromInts(ircWhole.left, centreY + halfHeight), + Point(rcWhole.left, centreY - halfHeight), + Point(rcWhole.right - strokeWidth - 2, centreY - halfHeight), + Point(rcWhole.right - strokeWidth - 2 - halfHeight, centreY), + Point(rcWhole.right - strokeWidth - 2, centreY + halfHeight), + Point(rcWhole.left, centreY + halfHeight), }; - surface->Polygon(pts, Sci::size(pts), fore, back); + AlignedPolygon(surface, pts, std::size(pts)); } break; - case SC_MARK_VERTICALBOOKMARK: { - const int halfWidth = minDim / 3; + case MarkerSymbol::VerticalBookmark: { + const XYPOSITION halfWidth = std::floor(minDim / 3); Point pts[] = { - Point::FromInts(centreX - halfWidth, centreY - dimOn2), - Point::FromInts(centreX + halfWidth, centreY - dimOn2), - Point::FromInts(centreX + halfWidth, centreY + dimOn2), - Point::FromInts(centreX, centreY + dimOn2 - halfWidth), - Point::FromInts(centreX - halfWidth, centreY + dimOn2), + Point(centreX - halfWidth, centreY - dimOn2), + Point(centreX + halfWidth, centreY - dimOn2), + Point(centreX + halfWidth, centreY + dimOn2), + Point(centreX, centreY + dimOn2 - halfWidth), + Point(centreX - halfWidth, centreY + dimOn2), }; - surface->Polygon(pts, Sci::size(pts), fore, back); + AlignedPolygon(surface, pts, std::size(pts)); } break; default: - if (markType >= SC_MARK_CHARACTER) { - char character[1]; - character[0] = static_cast(markType - SC_MARK_CHARACTER); - const XYPOSITION width = surface->WidthText(fontForCharacter, character, 1); + if (markType >= MarkerSymbol::Character) { + char character[UTF8MaxBytes + 1] {}; + const int uch = static_cast(markType) - static_cast(MarkerSymbol::Character); + UTF8FromUTF32Character(uch, character); + const XYPOSITION width = surface->WidthTextUTF8(fontForCharacter, character); PRectangle rcText = rc; rcText.left += (rc.Width() - width) / 2; - rcText.right = rc.left + width; - surface->DrawTextClipped(rcText, fontForCharacter, rcText.bottom - 2, - character, 1, fore, back); + rcText.right = rcText.left + width; + surface->DrawTextNoClipUTF8(rcText, fontForCharacter, rcText.bottom - 2, + character, fore, back); } else { - // treat as SC_MARK_FULLRECT + // treat as MarkerSymbol::FullRect surface->FillRectangle(rcWhole, back); } break; diff --git a/scintilla/src/LineMarker.h b/scintilla/src/LineMarker.h index 00fe0b7e0c..0a60da962b 100644 --- a/scintilla/src/LineMarker.h +++ b/scintilla/src/LineMarker.h @@ -8,12 +8,12 @@ #ifndef LINEMARKER_H #define LINEMARKER_H -namespace Scintilla { +namespace Scintilla::Internal { class XPM; class RGBAImage; -typedef void (*DrawLineMarkerFn)(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, int tFold, int marginStyle, const void *lineMarker); +typedef void (*DrawLineMarkerFn)(Surface *surface, const PRectangle &rcWhole, const Font *fontForCharacter, int tFold, Scintilla::MarginType marginStyle, const void *lineMarker); /** */ @@ -21,11 +21,13 @@ class LineMarker { public: enum class FoldPart { undefined, head, body, tail, headWithTail }; - int markType = SC_MARK_CIRCLE; - ColourDesired fore = ColourDesired(0, 0, 0); - ColourDesired back = ColourDesired(0xff, 0xff, 0xff); - ColourDesired backSelected = ColourDesired(0xff, 0x00, 0x00); - int alpha = SC_ALPHA_NOALPHA; + Scintilla::MarkerSymbol markType = Scintilla::MarkerSymbol::Circle; + ColourRGBA fore = ColourRGBA(0, 0, 0); + ColourRGBA back = ColourRGBA(0xff, 0xff, 0xff); + ColourRGBA backSelected = ColourRGBA(0xff, 0x00, 0x00); + Scintilla::Layer layer = Scintilla::Layer::Base; + Scintilla::Alpha alpha = Scintilla::Alpha::NoAlpha; + XYPOSITION strokeWidth = 1.0f; std::unique_ptr pxpm; std::unique_ptr image; /** Some platforms, notably PLAT_CURSES, do not support Scintilla's native @@ -34,17 +36,21 @@ class LineMarker { * platforms must implement as empty. */ DrawLineMarkerFn customDraw = nullptr; - LineMarker() = default; + LineMarker() noexcept = default; LineMarker(const LineMarker &other); LineMarker(LineMarker &&) noexcept = default; LineMarker &operator=(const LineMarker& other); LineMarker &operator=(LineMarker&&) noexcept = default; virtual ~LineMarker() = default; + ColourRGBA BackWithAlpha() const noexcept; + void SetXPM(const char *textForm); void SetXPM(const char *const *linesForm); void SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage); - void Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, FoldPart part, int marginStyle) const; + void AlignedPolygon(Surface *surface, const Point *pts, size_t npts) const; + void Draw(Surface *surface, const PRectangle &rcWhole, const Font *fontForCharacter, FoldPart part, Scintilla::MarginType marginStyle) const; + void DrawFoldingMark(Surface *surface, const PRectangle &rcWhole, FoldPart part) const; }; } diff --git a/scintilla/src/MarginView.cxx b/scintilla/src/MarginView.cxx index a742bdc4bc..50e3822d3d 100644 --- a/scintilla/src/MarginView.cxx +++ b/scintilla/src/MarginView.cxx @@ -14,20 +14,26 @@ #include #include +#include #include #include +#include +#include #include #include -#include "Platform.h" - +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" +#include "ScintillaStructures.h" #include "ILoader.h" #include "ILexer.h" -#include "Scintilla.h" -#include "CharacterCategory.h" +#include "Debugging.h" +#include "Geometry.h" +#include "Platform.h" + +#include "CharacterCategoryMap.h" #include "Position.h" -#include "IntegerRectangle.h" #include "UniqueString.h" #include "SplitVector.h" #include "Partitioning.h" @@ -52,52 +58,57 @@ using namespace Scintilla; -namespace Scintilla { +namespace Scintilla::Internal { void DrawWrapMarker(Surface *surface, PRectangle rcPlace, - bool isEndMarker, ColourDesired wrapColour) { - surface->PenColour(wrapColour); + bool isEndMarker, ColourRGBA wrapColour) { - const IntegerRectangle ircPlace(rcPlace); + const XYPOSITION extraFinalPixel = surface->SupportsFeature(Supports::LineDrawsFinal) ? 0.0f : 1.0f; - enum { xa = 1 }; // gap before start - const int w = ircPlace.Width() - xa - 1; + const PRectangle rcAligned = PixelAlignOutside(rcPlace, surface->PixelDivisions()); - const bool xStraight = isEndMarker; // x-mirrored symbol for start marker + const XYPOSITION widthStroke = std::floor(rcAligned.Width() / 6); - const int x0 = xStraight ? ircPlace.left : ircPlace.right - 1; - const int y0 = ircPlace.top; + constexpr XYPOSITION xa = 1; // gap before start + const XYPOSITION w = rcAligned.Width() - xa - widthStroke; - const int dy = ircPlace.Height() / 5; - const int y = ircPlace.Height() / 2 + dy; + // isEndMarker -> x-mirrored symbol for start marker + + const XYPOSITION x0 = isEndMarker ? rcAligned.left : rcAligned.right - widthStroke; + const XYPOSITION y0 = rcAligned.top; + + const XYPOSITION dy = std::floor(rcAligned.Height() / 5); + const XYPOSITION y = std::floor(rcAligned.Height() / 2) + dy; struct Relative { - Surface *surface; - int xBase; + XYPOSITION xBase; int xDir; - int yBase; + XYPOSITION yBase; int yDir; - void MoveTo(int xRelative, int yRelative) { - surface->MoveTo(xBase + xDir * xRelative, yBase + yDir * yRelative); - } - void LineTo(int xRelative, int yRelative) { - surface->LineTo(xBase + xDir * xRelative, yBase + yDir * yRelative); + XYPOSITION halfWidth; + Point At(XYPOSITION xRelative, XYPOSITION yRelative) noexcept { + return Point(xBase + xDir * xRelative + halfWidth, yBase + yDir * yRelative + halfWidth); } }; - Relative rel = { surface, x0, xStraight ? 1 : -1, y0, 1 }; + + Relative rel = { x0, isEndMarker ? 1 : -1, y0, 1, widthStroke / 2.0f }; // arrow head - rel.MoveTo(xa, y); - rel.LineTo(xa + 2 * w / 3, y - dy); - rel.MoveTo(xa, y); - rel.LineTo(xa + 2 * w / 3, y + dy); + const Point head[] = { + rel.At(xa + dy, y - dy), + rel.At(xa, y), + rel.At(xa + dy + extraFinalPixel, y + dy + extraFinalPixel) + }; + surface->PolyLine(head, std::size(head), Stroke(wrapColour, widthStroke)); // arrow body - rel.MoveTo(xa, y); - rel.LineTo(xa + w, y); - rel.LineTo(xa + w, y - 2 * dy); - rel.LineTo(xa - 1, // on windows lineto is exclusive endpoint, perhaps GTK not... - y - 2 * dy); + const Point body[] = { + rel.At(xa, y), + rel.At(xa + w, y), + rel.At(xa + w, y - 2 * dy), + rel.At(xa, y - 2 * dy), + }; + surface->PolyLine(body, std::size(body), Stroke(wrapColour, widthStroke)); } MarginView::MarginView() noexcept { @@ -105,35 +116,17 @@ MarginView::MarginView() noexcept { customDrawWrapMarker = nullptr; } -void MarginView::DropGraphics(bool freeObjects) { - if (freeObjects) { - pixmapSelMargin.reset(); - pixmapSelPattern.reset(); - pixmapSelPatternOffset1.reset(); - } else { - if (pixmapSelMargin) - pixmapSelMargin->Release(); - if (pixmapSelPattern) - pixmapSelPattern->Release(); - if (pixmapSelPatternOffset1) - pixmapSelPatternOffset1->Release(); - } -} - -void MarginView::AllocateGraphics(const ViewStyle &vsDraw) { - if (!pixmapSelMargin) - pixmapSelMargin.reset(Surface::Allocate(vsDraw.technology)); - if (!pixmapSelPattern) - pixmapSelPattern.reset(Surface::Allocate(vsDraw.technology)); - if (!pixmapSelPatternOffset1) - pixmapSelPatternOffset1.reset(Surface::Allocate(vsDraw.technology)); +void MarginView::DropGraphics() noexcept { + pixmapSelMargin.reset(); + pixmapSelPattern.reset(); + pixmapSelPatternOffset1.reset(); } -void MarginView::RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw) { - if (!pixmapSelPattern->Initialised()) { - const int patternSize = 8; - pixmapSelPattern->InitPixMap(patternSize, patternSize, surfaceWindow, wid); - pixmapSelPatternOffset1->InitPixMap(patternSize, patternSize, surfaceWindow, wid); +void MarginView::RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw) { + if (!pixmapSelPattern) { + constexpr int patternSize = 8; + pixmapSelPattern = surfaceWindow->AllocatePixMap(patternSize, patternSize); + pixmapSelPatternOffset1 = surfaceWindow->AllocatePixMap(patternSize, patternSize); // This complex procedure is to reproduce the checkerboard dithered pattern used by windows // for scroll bars and Visual Studio for its selection margin. The colour of this pattern is half // way between the chrome colour and the chrome highlight colour making a nice transition @@ -141,22 +134,22 @@ void MarginView::RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const View const PRectangle rcPattern = PRectangle::FromInts(0, 0, patternSize, patternSize); // Initialize default colours based on the chrome colour scheme. Typically the highlight is white. - ColourDesired colourFMFill = vsDraw.selbar; - ColourDesired colourFMStripes = vsDraw.selbarlight; + ColourRGBA colourFMFill = vsDraw.selbar; + ColourRGBA colourFMStripes = vsDraw.selbarlight; - if (!(vsDraw.selbarlight == ColourDesired(0xff, 0xff, 0xff))) { + if (!(vsDraw.selbarlight == ColourRGBA(0xff, 0xff, 0xff))) { // User has chosen an unusual chrome colour scheme so just use the highlight edge colour. // (Typically, the highlight colour is white.) colourFMFill = vsDraw.selbarlight; } - if (vsDraw.foldmarginColour.isSet) { + if (vsDraw.foldmarginColour) { // override default fold margin colour - colourFMFill = vsDraw.foldmarginColour; + colourFMFill = *vsDraw.foldmarginColour; } - if (vsDraw.foldmarginHighlightColour.isSet) { + if (vsDraw.foldmarginHighlightColour) { // override default fold margin highlight colour - colourFMStripes = vsDraw.foldmarginHighlightColour; + colourFMStripes = *vsDraw.foldmarginHighlightColour; } pixmapSelPattern->FillRectangle(rcPattern, colourFMFill); @@ -168,11 +161,13 @@ void MarginView::RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const View pixmapSelPatternOffset1->FillRectangle(rcPixel, colourFMFill); } } + pixmapSelPattern->FlushDrawing(); + pixmapSelPatternOffset1->FlushDrawing(); } } -static int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault, const ViewStyle &vs) noexcept { - if (vs.markers[markerCheck].markType == SC_MARK_EMPTY) +static MarkerOutline SubstituteMarkerIfEmpty(MarkerOutline markerCheck, MarkerOutline markerDefault, const ViewStyle &vs) noexcept { + if (vs.markers[static_cast(markerCheck)].markType == MarkerSymbol::Empty) return markerDefault; return markerCheck; } @@ -186,15 +181,15 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, rcSelMargin.bottom = rc.bottom; const Point ptOrigin = model.GetVisibleOriginInMain(); - FontAlias fontLineNumber = vs.styles[STYLE_LINENUMBER].font; + const Font *fontLineNumber = vs.styles[StyleLineNumber].font.get(); for (size_t margin = 0; margin < vs.ms.size(); margin++) { if (vs.ms[margin].width > 0) { rcSelMargin.left = rcSelMargin.right; rcSelMargin.right = rcSelMargin.left + vs.ms[margin].width; - if (vs.ms[margin].style != SC_MARGIN_NUMBER) { - if (vs.ms[margin].mask & SC_MASK_FOLDERS) { + if (vs.ms[margin].style != MarginType::Number) { + if (vs.ms[margin].ShowsFolding()) { // Required because of special way brush is created for selection margin // Ensure patterns line up when scrolling with separate margin view // by choosing correctly aligned variant. @@ -202,44 +197,44 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, surface->FillRectangle(rcSelMargin, invertPhase ? *pixmapSelPattern : *pixmapSelPatternOffset1); } else { - ColourDesired colour; + ColourRGBA colour; switch (vs.ms[margin].style) { - case SC_MARGIN_BACK: - colour = vs.styles[STYLE_DEFAULT].back; + case MarginType::Back: + colour = vs.styles[StyleDefault].back; break; - case SC_MARGIN_FORE: - colour = vs.styles[STYLE_DEFAULT].fore; + case MarginType::Fore: + colour = vs.styles[StyleDefault].fore; break; - case SC_MARGIN_COLOUR: + case MarginType::Colour: colour = vs.ms[margin].back; break; default: - colour = vs.styles[STYLE_LINENUMBER].back; + colour = vs.styles[StyleLineNumber].back; break; } surface->FillRectangle(rcSelMargin, colour); } } else { - surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back); + surface->FillRectangle(rcSelMargin, vs.styles[StyleLineNumber].back); } - const int lineStartPaint = static_cast(rcMargin.top + ptOrigin.y) / vs.lineHeight; + const Sci::Line lineStartPaint = static_cast(rcMargin.top + ptOrigin.y) / vs.lineHeight; Sci::Line visibleLine = model.TopLineOfMain() + lineStartPaint; Sci::Position yposScreen = lineStartPaint * vs.lineHeight - static_cast(ptOrigin.y); // Work out whether the top line is whitespace located after a // lessening of fold level which implies a 'fold tail' but which should not // be displayed until the last of a sequence of whitespace. bool needWhiteClosure = false; - if (vs.ms[margin].mask & SC_MASK_FOLDERS) { - const int level = model.pdoc->GetLevel(model.pcs->DocFromDisplay(visibleLine)); - if (level & SC_FOLDLEVELWHITEFLAG) { + if (vs.ms[margin].ShowsFolding()) { + const FoldLevel level = model.pdoc->GetFoldLevel(model.pcs->DocFromDisplay(visibleLine)); + if (LevelIsWhitespace(level)) { Sci::Line lineBack = model.pcs->DocFromDisplay(visibleLine); - int levelPrev = level; - while ((lineBack > 0) && (levelPrev & SC_FOLDLEVELWHITEFLAG)) { + FoldLevel levelPrev = level; + while ((lineBack > 0) && LevelIsWhitespace(levelPrev)) { lineBack--; - levelPrev = model.pdoc->GetLevel(lineBack); + levelPrev = model.pdoc->GetFoldLevel(lineBack); } - if (!(levelPrev & SC_FOLDLEVELHEADERFLAG)) { + if (!LevelIsHeader(levelPrev)) { if (LevelNumber(level) < LevelNumber(levelPrev)) needWhiteClosure = true; } @@ -252,10 +247,10 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, } // Old code does not know about new markers needed to distinguish all cases - const int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID, - SC_MARKNUM_FOLDEROPEN, vs); - const int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND, - SC_MARKNUM_FOLDER, vs); + const MarkerOutline folderOpenMid = SubstituteMarkerIfEmpty(MarkerOutline::FolderOpenMid, + MarkerOutline::FolderOpen, vs); + const MarkerOutline folderEnd = SubstituteMarkerIfEmpty(MarkerOutline::FolderEnd, + MarkerOutline::Folder, vs); while ((visibleLine < model.pcs->LinesDisplayed()) && yposScreen < rc.bottom) { @@ -273,117 +268,117 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, bool headWithTail = false; - if (vs.ms[margin].mask & SC_MASK_FOLDERS) { + if (vs.ms[margin].ShowsFolding()) { // Decide which fold indicator should be displayed - const int level = model.pdoc->GetLevel(lineDoc); - const int levelNext = model.pdoc->GetLevel(lineDoc + 1); - const int levelNum = LevelNumber(level); - const int levelNextNum = LevelNumber(levelNext); - if (level & SC_FOLDLEVELHEADERFLAG) { + const FoldLevel level = model.pdoc->GetFoldLevel(lineDoc); + const FoldLevel levelNext = model.pdoc->GetFoldLevel(lineDoc + 1); + const FoldLevel levelNum = LevelNumberPart(level); + const FoldLevel levelNextNum = LevelNumberPart(levelNext); + if (LevelIsHeader(level)) { if (firstSubLine) { if (levelNum < levelNextNum) { if (model.pcs->GetExpanded(lineDoc)) { - if (levelNum == SC_FOLDLEVELBASE) - marks |= 1 << SC_MARKNUM_FOLDEROPEN; + if (levelNum == FoldLevel::Base) + marks |= 1 << MarkerOutline::FolderOpen; else marks |= 1 << folderOpenMid; } else { - if (levelNum == SC_FOLDLEVELBASE) - marks |= 1 << SC_MARKNUM_FOLDER; + if (levelNum == FoldLevel::Base) + marks |= 1 << MarkerOutline::Folder; else marks |= 1 << folderEnd; } - } else if (levelNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; + } else if (levelNum > FoldLevel::Base) { + marks |= 1 << MarkerOutline::FolderSub; } } else { if (levelNum < levelNextNum) { if (model.pcs->GetExpanded(lineDoc)) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } else if (levelNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; + marks |= 1 << MarkerOutline::FolderSub; + } else if (levelNum > FoldLevel::Base) { + marks |= 1 << MarkerOutline::FolderSub; } - } else if (levelNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; + } else if (levelNum > FoldLevel::Base) { + marks |= 1 << MarkerOutline::FolderSub; } } needWhiteClosure = false; const Sci::Line firstFollowupLine = model.pcs->DocFromDisplay(model.pcs->DisplayFromDoc(lineDoc + 1)); - const int firstFollowupLineLevel = model.pdoc->GetLevel(firstFollowupLine); - const int secondFollowupLineLevelNum = LevelNumber(model.pdoc->GetLevel(firstFollowupLine + 1)); + const FoldLevel firstFollowupLineLevel = model.pdoc->GetFoldLevel(firstFollowupLine); + const FoldLevel secondFollowupLineLevelNum = LevelNumberPart(model.pdoc->GetFoldLevel(firstFollowupLine + 1)); if (!model.pcs->GetExpanded(lineDoc)) { - if ((firstFollowupLineLevel & SC_FOLDLEVELWHITEFLAG) && + if (LevelIsWhitespace(firstFollowupLineLevel) && (levelNum > secondFollowupLineLevelNum)) needWhiteClosure = true; if (highlightDelimiter.IsFoldBlockHighlighted(firstFollowupLine)) headWithTail = true; } - } else if (level & SC_FOLDLEVELWHITEFLAG) { + } else if (LevelIsWhitespace(level)) { if (needWhiteClosure) { - if (levelNext & SC_FOLDLEVELWHITEFLAG) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } else if (levelNextNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; + if (LevelIsWhitespace(levelNext)) { + marks |= 1 << MarkerOutline::FolderSub; + } else if (levelNextNum > FoldLevel::Base) { + marks |= 1 << MarkerOutline::FolderMidTail; needWhiteClosure = false; } else { - marks |= 1 << SC_MARKNUM_FOLDERTAIL; + marks |= 1 << MarkerOutline::FolderTail; needWhiteClosure = false; } - } else if (levelNum > SC_FOLDLEVELBASE) { + } else if (levelNum > FoldLevel::Base) { if (levelNextNum < levelNum) { - if (levelNextNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; + if (levelNextNum > FoldLevel::Base) { + marks |= 1 << MarkerOutline::FolderMidTail; } else { - marks |= 1 << SC_MARKNUM_FOLDERTAIL; + marks |= 1 << MarkerOutline::FolderTail; } } else { - marks |= 1 << SC_MARKNUM_FOLDERSUB; + marks |= 1 << MarkerOutline::FolderSub; } } - } else if (levelNum > SC_FOLDLEVELBASE) { + } else if (levelNum > FoldLevel::Base) { if (levelNextNum < levelNum) { needWhiteClosure = false; - if (levelNext & SC_FOLDLEVELWHITEFLAG) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; + if (LevelIsWhitespace(levelNext)) { + marks |= 1 << MarkerOutline::FolderSub; needWhiteClosure = true; } else if (lastSubLine) { - if (levelNextNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; + if (levelNextNum > FoldLevel::Base) { + marks |= 1 << MarkerOutline::FolderMidTail; } else { - marks |= 1 << SC_MARKNUM_FOLDERTAIL; + marks |= 1 << MarkerOutline::FolderTail; } } else { - marks |= 1 << SC_MARKNUM_FOLDERSUB; + marks |= 1 << MarkerOutline::FolderSub; } } else { - marks |= 1 << SC_MARKNUM_FOLDERSUB; + marks |= 1 << MarkerOutline::FolderSub; } } } marks &= vs.ms[margin].mask; - PRectangle rcMarker( + const PRectangle rcMarker( rcSelMargin.left, static_cast(yposScreen), rcSelMargin.right, static_cast(yposScreen + vs.lineHeight)); - if (vs.ms[margin].style == SC_MARGIN_NUMBER) { + if (vs.ms[margin].style == MarginType::Number) { if (firstSubLine) { std::string sNumber; if (lineDoc >= 0) { sNumber = std::to_string(lineDoc + 1); } - if (model.foldFlags & (SC_FOLDFLAG_LEVELNUMBERS | SC_FOLDFLAG_LINESTATE)) { + if (FlagSet(model.foldFlags, (FoldFlag::LevelNumbers | FoldFlag::LineState))) { char number[100] = ""; - if (model.foldFlags & SC_FOLDFLAG_LEVELNUMBERS) { - const int lev = model.pdoc->GetLevel(lineDoc); + if (FlagSet(model.foldFlags, FoldFlag::LevelNumbers)) { + const FoldLevel lev = model.pdoc->GetFoldLevel(lineDoc); sprintf(number, "%c%c %03X %03X", - (lev & SC_FOLDLEVELHEADERFLAG) ? 'H' : '_', - (lev & SC_FOLDLEVELWHITEFLAG) ? 'W' : '_', + LevelIsHeader(lev) ? 'H' : '_', + LevelIsWhitespace(lev) ? 'W' : '_', LevelNumber(lev), - lev >> 16 + static_cast(lev) >> 16 ); } else { const int state = model.pdoc->GetLineState(lineDoc); @@ -393,34 +388,34 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, } PRectangle rcNumber = rcMarker; // Right justify - const XYPOSITION width = surface->WidthText(fontLineNumber, sNumber.c_str(), static_cast(sNumber.length())); + const XYPOSITION width = surface->WidthText(fontLineNumber, sNumber); const XYPOSITION xpos = rcNumber.right - width - vs.marginNumberPadding; rcNumber.left = xpos; - DrawTextNoClipPhase(surface, rcNumber, vs.styles[STYLE_LINENUMBER], - rcNumber.top + vs.maxAscent, sNumber.c_str(), static_cast(sNumber.length()), drawAll); - } else if (vs.wrapVisualFlags & SC_WRAPVISUALFLAG_MARGIN) { + DrawTextNoClipPhase(surface, rcNumber, vs.styles[StyleLineNumber], + rcNumber.top + vs.maxAscent, sNumber, DrawPhase::all); + } else if (FlagSet(vs.wrap.visualFlags, WrapVisualFlag::Margin)) { PRectangle rcWrapMarker = rcMarker; rcWrapMarker.right -= wrapMarkerPaddingRight; - rcWrapMarker.left = rcWrapMarker.right - vs.styles[STYLE_LINENUMBER].aveCharWidth; + rcWrapMarker.left = rcWrapMarker.right - vs.styles[StyleLineNumber].aveCharWidth; if (!customDrawWrapMarker) { - DrawWrapMarker(surface, rcWrapMarker, false, vs.styles[STYLE_LINENUMBER].fore); + DrawWrapMarker(surface, rcWrapMarker, false, vs.styles[StyleLineNumber].fore); } else { - customDrawWrapMarker(surface, rcWrapMarker, false, vs.styles[STYLE_LINENUMBER].fore); + customDrawWrapMarker(surface, rcWrapMarker, false, vs.styles[StyleLineNumber].fore); } } - } else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) { + } else if (vs.ms[margin].style == MarginType::Text || vs.ms[margin].style == MarginType::RText) { const StyledText stMargin = model.pdoc->MarginStyledText(lineDoc); if (stMargin.text && ValidStyledText(vs, vs.marginStyleOffset, stMargin)) { if (firstSubLine) { surface->FillRectangle(rcMarker, vs.styles[stMargin.StyleAt(0) + vs.marginStyleOffset].back); PRectangle rcText = rcMarker; - if (vs.ms[margin].style == SC_MARGIN_RTEXT) { + if (vs.ms[margin].style == MarginType::RText) { const int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin); rcText.left = rcText.right - width - 3; } DrawStyledText(surface, vs, vs.marginStyleOffset, rcText, - stMargin, 0, stMargin.length, drawAll); + stMargin, 0, stMargin.length, DrawPhase::all); } else { // if we're displaying annotation lines, colour the margin to match the associated document line const int annotationLines = model.pdoc->AnnotationLines(lineDoc); @@ -435,7 +430,7 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, for (int markBit = 0; (markBit < 32) && marks; markBit++) { if (marks & 1) { LineMarker::FoldPart part = LineMarker::FoldPart::undefined; - if ((vs.ms[margin].mask & SC_MASK_FOLDERS) && highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) { + if (vs.ms[margin].ShowsFolding() && highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) { if (highlightDelimiter.IsBodyOfFoldBlock(lineDoc)) { part = LineMarker::FoldPart::body; } else if (highlightDelimiter.IsHeadOfFoldBlock(lineDoc)) { @@ -466,7 +461,7 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, PRectangle rcBlankMargin = rcMargin; rcBlankMargin.left = rcSelMargin.right; - surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back); + surface->FillRectangle(rcBlankMargin, vs.styles[StyleDefault].back); } } diff --git a/scintilla/src/MarginView.h b/scintilla/src/MarginView.h index 4468afa1be..f73a188586 100644 --- a/scintilla/src/MarginView.h +++ b/scintilla/src/MarginView.h @@ -8,11 +8,11 @@ #ifndef MARGINVIEW_H #define MARGINVIEW_H -namespace Scintilla { +namespace Scintilla::Internal { -void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour); +void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourRGBA wrapColour); -typedef void (*DrawWrapMarkerFn)(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour); +typedef void (*DrawWrapMarkerFn)(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourRGBA wrapColour); /** * MarginView draws the margins. @@ -34,9 +34,8 @@ class MarginView { MarginView() noexcept; - void DropGraphics(bool freeObjects); - void AllocateGraphics(const ViewStyle &vsDraw); - void RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw); + void DropGraphics() noexcept; + void RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw); void PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, PRectangle rcMargin, const EditModel &model, const ViewStyle &vs); }; diff --git a/scintilla/src/Partitioning.h b/scintilla/src/Partitioning.h index 171a694d97..efa6bf95ef 100644 --- a/scintilla/src/Partitioning.h +++ b/scintilla/src/Partitioning.h @@ -8,9 +8,7 @@ #ifndef PARTITIONING_H #define PARTITIONING_H -#include "Compat.h" - -namespace Scintilla { +namespace Scintilla::Internal { /// A split vector of integers with a method for adding a value to all elements /// in a range. @@ -87,7 +85,7 @@ class Partitioning { } void Allocate(ptrdiff_t growSize) { - body = Sci::make_unique>(growSize); + body = std::make_unique>(growSize); stepPartition = 0; stepLength = 0; body->Insert(0, 0); // This value stays 0 for ever @@ -112,6 +110,11 @@ class Partitioning { return static_cast(body->Length())-1; } + void ReAllocate(ptrdiff_t newSize) { + // + 1 accounts for initial element that is always 0. + body->ReAllocate(newSize + 1); + } + T Length() const noexcept { return PositionFromPartition(Partitions()); } diff --git a/scintilla/src/PerLine.cxx b/scintilla/src/PerLine.cxx index 3c8272372f..068d5d0a5f 100644 --- a/scintilla/src/PerLine.cxx +++ b/scintilla/src/PerLine.cxx @@ -10,21 +10,26 @@ #include #include +#include #include #include +#include #include #include +#include "ScintillaTypes.h" + +#include "Debugging.h" +#include "Geometry.h" #include "Platform.h" -#include "Scintilla.h" #include "Position.h" #include "SplitVector.h" #include "Partitioning.h" #include "CellBuffer.h" #include "PerLine.h" -using namespace Scintilla; +using namespace Scintilla::Internal; MarkerHandleSet::MarkerHandleSet() { } @@ -145,7 +150,7 @@ int LineMarkers::NumberFromLine(Sci::Line line, int which) const noexcept { void LineMarkers::MergeMarkers(Sci::Line line) { if (markers[line + 1]) { if (!markers[line]) - markers[line] = Sci::make_unique(); + markers[line] = std::make_unique(); markers[line]->CombineWith(markers[line + 1].get()); markers[line + 1].reset(); } @@ -181,7 +186,7 @@ int LineMarkers::AddMark(Sci::Line line, int markerNum, Sci::Line lines) { } if (!markers[line]) { // Need new structure to hold marker handle - markers[line] = Sci::make_unique(); + markers[line] = std::make_unique(); } markers[line]->InsertHandle(handleCurrent, markerNum); @@ -223,14 +228,14 @@ void LineLevels::Init() { void LineLevels::InsertLine(Sci::Line line) { if (levels.Length()) { - const int level = (line < levels.Length()) ? levels[line] : SC_FOLDLEVELBASE; + const int level = (line < levels.Length()) ? levels[line] : static_cast(Scintilla::FoldLevel::Base); levels.Insert(line, level); } } void LineLevels::InsertLines(Sci::Line line, Sci::Line lines) { if (levels.Length()) { - const int level = (line < levels.Length()) ? levels[line] : SC_FOLDLEVELBASE; + const int level = (line < levels.Length()) ? levels[line] : static_cast(Scintilla::FoldLevel::Base); levels.InsertValue(line, lines, level); } } @@ -239,17 +244,17 @@ void LineLevels::RemoveLine(Sci::Line line) { if (levels.Length()) { // Move up following lines but merge header flag from this line // to line before to avoid a temporary disappearance causing expansion. - int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG; + int firstHeader = levels[line] & static_cast(Scintilla::FoldLevel::HeaderFlag); levels.Delete(line); if (line == levels.Length()-1) // Last line loses the header flag - levels[line-1] &= ~SC_FOLDLEVELHEADERFLAG; + levels[line-1] &= ~static_cast(Scintilla::FoldLevel::HeaderFlag); else if (line > 0) levels[line-1] |= firstHeader; } } void LineLevels::ExpandLevels(Sci::Line sizeNew) { - levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE); + levels.InsertValue(levels.Length(), sizeNew - levels.Length(), static_cast(Scintilla::FoldLevel::Base)); } void LineLevels::ClearLevels() { @@ -274,7 +279,7 @@ int LineLevels::GetLevel(Sci::Line line) const noexcept { if (levels.Length() && (line >= 0) && (line < levels.Length())) { return levels[line]; } else { - return SC_FOLDLEVELBASE; + return static_cast(Scintilla::FoldLevel::Base); } } @@ -338,21 +343,13 @@ namespace { constexpr int IndividualStyles = 0x100; -size_t NumberLines(const char *text) noexcept { - int lines = 1; - if (text) { - while (*text) { - if (*text == '\n') - lines++; - text++; - } - } - return lines; +size_t NumberLines(std::string_view sv) { + return std::count(sv.begin(), sv.end(), '\n') + 1; } std::unique_ptrAllocateAnnotation(size_t length, int style) { const size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0); - return Sci::make_unique(len); + return std::make_unique(len); } } @@ -522,7 +519,7 @@ bool LineTabstops::ClearTabstops(Sci::Line line) noexcept { bool LineTabstops::AddTabstop(Sci::Line line, int x) { tabstops.EnsureLength(line + 1); if (!tabstops[line]) { - tabstops[line] = Sci::make_unique(); + tabstops[line] = std::make_unique(); } TabstopList *tl = tabstops[line].get(); diff --git a/scintilla/src/PerLine.h b/scintilla/src/PerLine.h index b43b0a18be..8f88183f1b 100644 --- a/scintilla/src/PerLine.h +++ b/scintilla/src/PerLine.h @@ -8,7 +8,7 @@ #ifndef PERLINE_H #define PERLINE_H -namespace Scintilla { +namespace Scintilla::Internal { /** * This holds the marker identifier and the marker type to display. diff --git a/scintilla/src/Platform.h b/scintilla/src/Platform.h new file mode 100644 index 0000000000..ce04d9b220 --- /dev/null +++ b/scintilla/src/Platform.h @@ -0,0 +1,379 @@ +// Scintilla source code edit control +/** @file Platform.h + ** Interface to platform facilities. Also includes some basic utilities. + ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows. + **/ +// Copyright 1998-2009 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef PLATFORM_H +#define PLATFORM_H + +// PLAT_GTK = GTK+ on Linux or Win32 +// PLAT_GTK_WIN32 is defined additionally when running PLAT_GTK under Win32 +// PLAT_WIN = Win32 API on Win32 OS +// PLAT_WX is wxWindows on any supported platform +// PLAT_TK = Tcl/TK on Linux or Win32 + +#define PLAT_GTK 0 +#define PLAT_GTK_WIN32 0 +#define PLAT_GTK_MACOSX 0 +#define PLAT_MACOSX 0 +#define PLAT_WIN 0 +#define PLAT_WX 0 +#define PLAT_QT 0 +#define PLAT_QT_QML 0 +#define PLAT_FOX 0 +#define PLAT_CURSES 0 +#define PLAT_TK 0 +#define PLAT_HAIKU 0 + +#if defined(FOX) +#undef PLAT_FOX +#define PLAT_FOX 1 + +#elif defined(__WX__) +#undef PLAT_WX +#define PLAT_WX 1 + +#elif defined(CURSES) +#undef PLAT_CURSES +#define PLAT_CURSES 1 + +#elif defined(__HAIKU__) +#undef PLAT_HAIKU +#define PLAT_HAIKU 1 + +#elif defined(SCINTILLA_QT) +#undef PLAT_QT +#define PLAT_QT 1 + +#elif defined(SCINTILLA_QT_QML) +#undef PLAT_QT_QML +#define PLAT_QT_QML 1 + +#elif defined(TK) +#undef PLAT_TK +#define PLAT_TK 1 + +#elif defined(GTK) +#undef PLAT_GTK +#define PLAT_GTK 1 + +#if defined(__WIN32__) || defined(_MSC_VER) +#undef PLAT_GTK_WIN32 +#define PLAT_GTK_WIN32 1 +#endif + +#if defined(__APPLE__) +#undef PLAT_GTK_MACOSX +#define PLAT_GTK_MACOSX 1 +#endif + +#elif defined(__APPLE__) + +#undef PLAT_MACOSX +#define PLAT_MACOSX 1 + +#else +#undef PLAT_WIN +#define PLAT_WIN 1 + +#endif + +namespace Scintilla::Internal { + +// Underlying the implementation of the platform classes are platform specific types. +// Sometimes these need to be passed around by client code so they are defined here + +typedef void *SurfaceID; +typedef void *WindowID; +typedef void *MenuID; +typedef void *TickerID; +typedef void *Function; +typedef void *IdlerID; + +/** + * Font management. + */ + +constexpr const char *localeNameDefault = "en-us"; + +struct FontParameters { + const char *faceName; + XYPOSITION size; + Scintilla::FontWeight weight; + bool italic; + Scintilla::FontQuality extraFontFlag; + Scintilla::Technology technology; + Scintilla::CharacterSet characterSet; + const char *localeName; + + constexpr FontParameters( + const char *faceName_, + XYPOSITION size_=10, + Scintilla::FontWeight weight_= Scintilla::FontWeight::Normal, + bool italic_=false, + Scintilla::FontQuality extraFontFlag_= Scintilla::FontQuality::QualityDefault, + Scintilla::Technology technology_= Scintilla::Technology::Default, + Scintilla::CharacterSet characterSet_= Scintilla::CharacterSet::Ansi, + const char *localeName_=localeNameDefault) noexcept : + + faceName(faceName_), + size(size_), + weight(weight_), + italic(italic_), + extraFontFlag(extraFontFlag_), + technology(technology_), + characterSet(characterSet_), + localeName(localeName_) + { + } + +}; + +class Font { +public: + Font() noexcept = default; + // Deleted so Font objects can not be copied + Font(const Font &) = delete; + Font(Font &&) = delete; + Font &operator=(const Font &) = delete; + Font &operator=(Font &&) = delete; + virtual ~Font() noexcept = default; + + static std::shared_ptr Allocate(const FontParameters &fp); +}; + +class IScreenLine { +public: + virtual std::string_view Text() const = 0; + virtual size_t Length() const = 0; + virtual size_t RepresentationCount() const = 0; + virtual XYPOSITION Width() const = 0; + virtual XYPOSITION Height() const = 0; + virtual XYPOSITION TabWidth() const = 0; + virtual XYPOSITION TabWidthMinimumPixels() const = 0; + virtual const Font *FontOfPosition(size_t position) const = 0; + virtual XYPOSITION RepresentationWidth(size_t position) const = 0; + virtual XYPOSITION TabPositionAfter(XYPOSITION xPosition) const = 0; +}; + +class IScreenLineLayout { +public: + virtual ~IScreenLineLayout() noexcept = default; + virtual size_t PositionFromX(XYPOSITION xDistance, bool charPosition) = 0; + virtual XYPOSITION XFromPosition(size_t caretPosition) = 0; + virtual std::vector FindRangeIntervals(size_t start, size_t end) = 0; +}; + +/** + * Parameters for surfaces. + */ +struct SurfaceMode { + int codePage = 0; + bool bidiR2L = false; + SurfaceMode() = default; + explicit SurfaceMode(int codePage_, bool bidiR2L_) noexcept : codePage(codePage_), bidiR2L(bidiR2L_) { + } +}; + +/** + * A surface abstracts a place to draw. + */ +class Surface { +public: + Surface() noexcept = default; + Surface(const Surface &) = delete; + Surface(Surface &&) = delete; + Surface &operator=(const Surface &) = delete; + Surface &operator=(Surface &&) = delete; + virtual ~Surface() noexcept = default; + static std::unique_ptr Allocate(Scintilla::Technology technology); + + virtual void Init(WindowID wid)=0; + virtual void Init(SurfaceID sid, WindowID wid)=0; + virtual std::unique_ptr AllocatePixMap(int width, int height)=0; + + virtual void SetMode(SurfaceMode mode)=0; + + enum class Ends { + semiCircles = 0x0, + leftFlat = 0x1, + leftAngle = 0x2, + rightFlat = 0x10, + rightAngle = 0x20, + }; + + virtual void Release() noexcept=0; + virtual int SupportsFeature(Scintilla::Supports feature) noexcept=0; + virtual bool Initialised()=0; + virtual int LogPixelsY()=0; + virtual int PixelDivisions()=0; + virtual int DeviceHeightFont(int points)=0; + virtual void LineDraw(Point start, Point end, Stroke stroke)=0; + virtual void PolyLine(const Point *pts, size_t npts, Stroke stroke)=0; + virtual void Polygon(const Point *pts, size_t npts, FillStroke fillStroke)=0; + virtual void RectangleDraw(PRectangle rc, FillStroke fillStroke)=0; + virtual void RectangleFrame(PRectangle rc, Stroke stroke)=0; + virtual void FillRectangle(PRectangle rc, Fill fill)=0; + virtual void FillRectangleAligned(PRectangle rc, Fill fill)=0; + virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; + virtual void RoundedRectangle(PRectangle rc, FillStroke fillStroke)=0; + virtual void AlphaRectangle(PRectangle rc, XYPOSITION cornerSize, FillStroke fillStroke)=0; + enum class GradientOptions { leftToRight, topToBottom }; + virtual void GradientRectangle(PRectangle rc, const std::vector &stops, GradientOptions options)=0; + virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0; + virtual void Ellipse(PRectangle rc, FillStroke fillStroke)=0; + virtual void Stadium(PRectangle rc, FillStroke fillStroke, Ends ends)=0; + virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; + + virtual std::unique_ptr Layout(const IScreenLine *screenLine) = 0; + + virtual void DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) = 0; + virtual void DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) = 0; + virtual void DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore) = 0; + virtual void MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) = 0; + virtual XYPOSITION WidthText(const Font *font_, std::string_view text) = 0; + + virtual void DrawTextNoClipUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) = 0; + virtual void DrawTextClippedUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) = 0; + virtual void DrawTextTransparentUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore) = 0; + virtual void MeasureWidthsUTF8(const Font *font_, std::string_view text, XYPOSITION *positions) = 0; + virtual XYPOSITION WidthTextUTF8(const Font *font_, std::string_view text) = 0; + + virtual XYPOSITION Ascent(const Font *font_)=0; + virtual XYPOSITION Descent(const Font *font_)=0; + virtual XYPOSITION InternalLeading(const Font *font_)=0; + virtual XYPOSITION Height(const Font *font_)=0; + virtual XYPOSITION AverageCharWidth(const Font *font_)=0; + + virtual void SetClip(PRectangle rc)=0; + virtual void PopClip()=0; + virtual void FlushCachedState()=0; + virtual void FlushDrawing()=0; +}; + +/** + * Class to hide the details of window manipulation. + * Does not own the window which will normally have a longer life than this object. + */ +class Window { +protected: + WindowID wid; +public: + Window() noexcept : wid(nullptr), cursorLast(Cursor::invalid) { + } + Window(const Window &source) = delete; + Window(Window &&) = delete; + Window &operator=(WindowID wid_) noexcept { + wid = wid_; + cursorLast = Cursor::invalid; + return *this; + } + Window &operator=(const Window &) = delete; + Window &operator=(Window &&) = delete; + virtual ~Window() noexcept; + WindowID GetID() const noexcept { return wid; } + bool Created() const noexcept { return wid != nullptr; } + void Destroy() noexcept; + PRectangle GetPosition() const; + void SetPosition(PRectangle rc); + void SetPositionRelative(PRectangle rc, const Window *relativeTo); + PRectangle GetClientPosition() const; + void Show(bool show=true); + void InvalidateAll(); + void InvalidateRectangle(PRectangle rc); + enum class Cursor { invalid, text, arrow, up, wait, horizontal, vertical, reverseArrow, hand }; + void SetCursor(Cursor curs); + PRectangle GetMonitorRect(Point pt); +private: + Cursor cursorLast; +}; + +/** + * Listbox management. + */ + +// ScintillaBase implements IListBoxDelegate to receive ListBoxEvents from a ListBox + +struct ListBoxEvent { + enum class EventType { selectionChange, doubleClick } event; + ListBoxEvent(EventType event_) noexcept : event(event_) { + } +}; + +class IListBoxDelegate { +public: + virtual void ListNotify(ListBoxEvent *plbe)=0; +}; + +struct ListOptions { + std::optional fore; + std::optional back; + std::optional foreSelected; + std::optional backSelected; + AutoCompleteOption options=AutoCompleteOption::Normal; +}; + +class ListBox : public Window { +public: + ListBox() noexcept; + virtual ~ListBox() noexcept override; + static std::unique_ptr Allocate(); + + virtual void SetFont(const Font *font)=0; + virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, Scintilla::Technology technology_)=0; + virtual void SetAverageCharWidth(int width)=0; + virtual void SetVisibleRows(int rows)=0; + virtual int GetVisibleRows() const=0; + virtual PRectangle GetDesiredRect()=0; + virtual int CaretFromEdge()=0; + virtual void Clear() noexcept=0; + virtual void Append(char *s, int type = -1)=0; + virtual int Length()=0; + virtual void Select(int n)=0; + virtual int GetSelection()=0; + virtual int Find(const char *prefix)=0; + virtual std::string GetValue(int n)=0; + virtual void RegisterImage(int type, const char *xpm_data)=0; + virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0; + virtual void ClearRegisteredImages()=0; + virtual void SetDelegate(IListBoxDelegate *lbDelegate)=0; + virtual void SetList(const char* list, char separator, char typesep)=0; + virtual void SetOptions(ListOptions options_)=0; +}; + +/** + * Menu management. + */ +class Menu { + MenuID mid; +public: + Menu() noexcept; + MenuID GetID() const noexcept { return mid; } + void CreatePopUp(); + void Destroy() noexcept; + void Show(Point pt, const Window &w); +}; + +/** + * Platform namespace used to retrieve system wide parameters such as double click speed + * and chrome colour. + */ +namespace Platform { + +ColourRGBA Chrome(); +ColourRGBA ChromeHighlight(); +const char *DefaultFont(); +int DefaultFontSize(); +unsigned int DoubleClickTime(); +constexpr long LongFromTwoShorts(short a,short b) noexcept { + return (a) | ((b) << 16); +} + +} + +} + +#endif diff --git a/scintilla/src/Position.h b/scintilla/src/Position.h index e0bbcb53f7..b455124d27 100644 --- a/scintilla/src/Position.h +++ b/scintilla/src/Position.h @@ -19,7 +19,7 @@ namespace Sci { typedef ptrdiff_t Position; typedef ptrdiff_t Line; -const Position invalidPosition = -1; +inline constexpr Position invalidPosition = -1; } diff --git a/scintilla/src/PositionCache.cxx b/scintilla/src/PositionCache.cxx index bb581d84a0..285bf28168 100644 --- a/scintilla/src/PositionCache.cxx +++ b/scintilla/src/PositionCache.cxx @@ -12,19 +12,25 @@ #include #include +#include #include #include +#include +#include #include #include #include -#include "Platform.h" - +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" #include "ILoader.h" #include "ILexer.h" -#include "Scintilla.h" -#include "CharacterCategory.h" +#include "Debugging.h" +#include "Geometry.h" +#include "Platform.h" + +#include "CharacterCategoryMap.h" #include "Position.h" #include "UniqueString.h" #include "SplitVector.h" @@ -46,11 +52,16 @@ #include "PositionCache.h" using namespace Scintilla; +using namespace Scintilla::Internal; -LineLayout::LineLayout(int maxLineLength_) : +void BidiData::Resize(size_t maxLineLength_) { + stylesFonts.resize(maxLineLength_ + 1); + widthReprs.resize(maxLineLength_ + 1); +} + +LineLayout::LineLayout(Sci::Line lineNumber_, int maxLineLength_) : lenLineStarts(0), - lineNumber(-1), - inCache(false), + lineNumber(lineNumber_), maxLineLength(-1), numCharsInLine(0), numCharsBeforeEOL(0), @@ -74,20 +85,32 @@ LineLayout::~LineLayout() { void LineLayout::Resize(int maxLineLength_) { if (maxLineLength_ > maxLineLength) { Free(); - chars = Sci::make_unique(maxLineLength_ + 1); - styles = Sci::make_unique(maxLineLength_ + 1); + chars = std::make_unique(maxLineLength_ + 1); + styles = std::make_unique(maxLineLength_ + 1); // Extra position allocated as sometimes the Windows // GetTextExtentExPoint API writes an extra element. - positions = Sci::make_unique(maxLineLength_ + 1 + 1); + positions = std::make_unique(maxLineLength_ + 1 + 1); + if (bidiData) { + bidiData->Resize(maxLineLength_); + } + maxLineLength = maxLineLength_; } } +void LineLayout::EnsureBidiData() { + if (!bidiData) { + bidiData = std::make_unique(); + bidiData->Resize(maxLineLength); + } +} + void LineLayout::Free() noexcept { chars.reset(); styles.reset(); positions.reset(); lineStarts.reset(); + bidiData.reset(); } void LineLayout::Invalidate(ValidLevel validity_) noexcept { @@ -95,6 +118,14 @@ void LineLayout::Invalidate(ValidLevel validity_) noexcept { validity = validity_; } +Sci::Line LineLayout::LineNumber() const noexcept { + return lineNumber; +} + +bool LineLayout::CanHold(Sci::Line lineDoc, int lineLength_) const noexcept { + return (lineNumber == lineDoc) && (lineLength_ <= maxLineLength); +} + int LineLayout::LineStart(int line) const noexcept { if (line <= 0) { return 0; @@ -105,6 +136,16 @@ int LineLayout::LineStart(int line) const noexcept { } } +int LineLayout::LineLength(int line) const noexcept { + if (!lineStarts) { + return numCharsInLine; + } if (line >= lines - 1) { + return numCharsInLine - lineStarts[line]; + } else { + return lineStarts[line + 1] - lineStarts[line]; + } +} + int LineLayout::LineLastVisible(int line, Scope scope) const noexcept { if (line < 0) { return 0; @@ -124,15 +165,31 @@ bool LineLayout::InLine(int offset, int line) const noexcept { ((offset == numCharsInLine) && (line == (lines-1))); } +int LineLayout::SubLineFromPosition(int posInLine, PointEnd pe) const noexcept { + if (!lineStarts || (posInLine > maxLineLength)) { + return lines - 1; + } + + for (int line = 0; line < lines; line++) { + if (FlagSet(pe, PointEnd::subLineEnd)) { + // Return subline not start of next + if (lineStarts[line + 1] <= posInLine + 1) + return line; + } else { + if (lineStarts[line + 1] <= posInLine) + return line; + } + } + + return lines - 1; +} + void LineLayout::SetLineStart(int line, int start) { if ((line >= lenLineStarts) && (line != 0)) { const int newMaxLines = line + 20; - std::unique_ptr newLineStarts = Sci::make_unique(newMaxLines); - for (int i = 0; i < newMaxLines; i++) { - if (i < lenLineStarts) - newLineStarts[i] = lineStarts[i]; - else - newLineStarts[i] = 0; + std::unique_ptr newLineStarts = std::make_unique(newMaxLines); + if (lenLineStarts) { + std::copy(lineStarts.get(), lineStarts.get() + lenLineStarts, newLineStarts.get()); } lineStarts = std::move(newLineStarts); lenLineStarts = newMaxLines; @@ -226,9 +283,9 @@ Point LineLayout::PointFromPosition(int posInLine, int lineHeight, PointEnd pe) pt.x = positions[posInLine] - positions[rangeSubLine.start]; if (rangeSubLine.start != 0) // Wrapped lines may be indented pt.x += wrapIndent; - if (pe & peSubLineEnd) // Return end of first subline not start of next + if (FlagSet(pe, PointEnd::subLineEnd)) // Return end of first subline not start of next break; - } else if ((pe & peLineEnd) && (subLine == (lines-1))) { + } else if (FlagSet(pe, PointEnd::lineEnd) && (subLine == (lines-1))) { pt.x = positions[numCharsInLine] - positions[rangeSubLine.start]; if (rangeSubLine.start != 0) // Wrapped lines may be indented pt.x += wrapIndent; @@ -244,54 +301,159 @@ int LineLayout::EndLineStyle() const noexcept { return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0]; } +ScreenLine::ScreenLine( + const LineLayout *ll_, + int subLine, + const ViewStyle &vs, + XYPOSITION width_, + int tabWidthMinimumPixels_) : + ll(ll_), + start(ll->LineStart(subLine)), + len(ll->LineLength(subLine)), + width(width_), + height(static_cast(vs.lineHeight)), + ctrlCharPadding(vs.ctrlCharPadding), + tabWidth(vs.tabWidth), + tabWidthMinimumPixels(tabWidthMinimumPixels_) { +} + +ScreenLine::~ScreenLine() { +} + +std::string_view ScreenLine::Text() const { + return std::string_view(&ll->chars[start], len); +} + +size_t ScreenLine::Length() const { + return len; +} + +size_t ScreenLine::RepresentationCount() const { + return std::count_if(&ll->bidiData->widthReprs[start], + &ll->bidiData->widthReprs[start + len], + [](XYPOSITION w) noexcept { return w > 0.0f; }); +} + +XYPOSITION ScreenLine::Width() const { + return width; +} + +XYPOSITION ScreenLine::Height() const { + return height; +} + +XYPOSITION ScreenLine::TabWidth() const { + return tabWidth; +} + +XYPOSITION ScreenLine::TabWidthMinimumPixels() const { + return static_cast(tabWidthMinimumPixels); +} + +const Font *ScreenLine::FontOfPosition(size_t position) const { + return ll->bidiData->stylesFonts[start + position].get(); +} + +XYPOSITION ScreenLine::RepresentationWidth(size_t position) const { + return ll->bidiData->widthReprs[start + position]; +} + +XYPOSITION ScreenLine::TabPositionAfter(XYPOSITION xPosition) const { + return (std::floor((xPosition + TabWidthMinimumPixels()) / TabWidth()) + 1) * TabWidth(); +} + LineLayoutCache::LineLayoutCache() : - level(0), - allInvalidated(false), styleClock(-1), useCount(0) { - Allocate(0); + level(LineCache::None), + allInvalidated(false), styleClock(-1) { } -LineLayoutCache::~LineLayoutCache() { - Deallocate(); +LineLayoutCache::~LineLayoutCache() = default; + +namespace { + +constexpr size_t AlignUp(size_t value, size_t alignment) noexcept { + return ((value - 1) / alignment + 1) * alignment; } -void LineLayoutCache::Allocate(size_t length_) { - PLATFORM_ASSERT(cache.empty()); - allInvalidated = false; - cache.resize(length_); +constexpr size_t alignmentLLC = 20; + +} + + +size_t LineLayoutCache::EntryForLine(Sci::Line line) const noexcept { + switch (level) { + case LineCache::None: + return 0; + case LineCache::Caret: + return 0; + case LineCache::Page: + return 1 + (line % (cache.size() - 1)); + case LineCache::Document: + return line; + } + return 0; } void LineLayoutCache::AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesInDoc) { - PLATFORM_ASSERT(useCount == 0); size_t lengthForLevel = 0; - if (level == llcCaret) { + if (level == LineCache::Caret) { lengthForLevel = 1; - } else if (level == llcPage) { - lengthForLevel = linesOnScreen + 1; - } else if (level == llcDocument) { - lengthForLevel = linesInDoc; - } - if (lengthForLevel > cache.size()) { - Deallocate(); - Allocate(lengthForLevel); - } else { - if (lengthForLevel < cache.size()) { - for (size_t i = lengthForLevel; i < cache.size(); i++) { - cache[i].reset(); + } else if (level == LineCache::Page) { + lengthForLevel = AlignUp(linesOnScreen + 1, alignmentLLC); + } else if (level == LineCache::Document) { + lengthForLevel = AlignUp(linesInDoc, alignmentLLC); + } + + if (lengthForLevel != cache.size()) { + allInvalidated = false; + cache.resize(lengthForLevel); + // Cache::none -> no entries + // Cache::caret -> 1 entry can take any line + // Cache::document -> entry per line so each line in correct entry after resize + if (level == LineCache::Page) { + // Cache::page -> locates lines in particular entries which may be incorrect after + // a resize so move them to correct entries. + for (size_t i = 1; i < cache.size();) { + size_t increment = 1; + if (cache[i]) { + const size_t posForLine = EntryForLine(cache[i]->LineNumber()); + if (posForLine != i) { + if (cache[posForLine]) { + if (EntryForLine(cache[posForLine]->LineNumber()) == posForLine) { + // [posForLine] already holds line that is in correct place + cache[i].reset(); // This line has nowhere to go so reset it. + } else { + std::swap(cache[i], cache[posForLine]); + increment = 0; + // Don't increment as newly swapped in value may have to move + } + } else { + cache[posForLine] = std::move(cache[i]); + } + } + } + i += increment; } + +#ifdef CHECK_LLC + for (size_t i = 1; i < cache.size(); i++) { + if (cache[i]) { + PLATFORM_ASSERT(EntryForLine(cache[i]->LineNumber()) == i); + } + } +#endif } - cache.resize(lengthForLevel); } PLATFORM_ASSERT(cache.size() == lengthForLevel); } void LineLayoutCache::Deallocate() noexcept { - PLATFORM_ASSERT(useCount == 0); cache.clear(); } void LineLayoutCache::Invalidate(LineLayout::ValidLevel validity_) noexcept { if (!cache.empty() && !allInvalidated) { - for (const std::unique_ptr &ll : cache) { + for (const std::shared_ptr &ll : cache) { if (ll) { ll->Invalidate(validity_); } @@ -302,15 +464,15 @@ void LineLayoutCache::Invalidate(LineLayout::ValidLevel validity_) noexcept { } } -void LineLayoutCache::SetLevel(int level_) noexcept { - allInvalidated = false; - if ((level_ != -1) && (level != level_)) { +void LineLayoutCache::SetLevel(LineCache level_) noexcept { + if (level != level_) { level = level_; - Deallocate(); + allInvalidated = false; + cache.clear(); } } -LineLayout *LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_, +std::shared_ptr LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_, Sci::Line linesOnScreen, Sci::Line linesInDoc) { AllocateForLevel(linesOnScreen, linesInDoc); if (styleClock != styleClock_) { @@ -318,62 +480,64 @@ LineLayout *LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, styleClock = styleClock_; } allInvalidated = false; - Sci::Position pos = -1; - LineLayout *ret = nullptr; - if (level == llcCaret) { - pos = 0; - } else if (level == llcPage) { - if (lineNumber == lineCaret) { - pos = 0; - } else if (cache.size() > 1) { - pos = 1 + (lineNumber % (cache.size() - 1)); - } - } else if (level == llcDocument) { - pos = lineNumber; - } - if (pos >= 0) { - PLATFORM_ASSERT(useCount == 0); - if (!cache.empty() && (pos < static_cast(cache.size()))) { - if (cache[pos]) { - if ((cache[pos]->lineNumber != lineNumber) || - (cache[pos]->maxLineLength < maxChars)) { - cache[pos].reset(); + 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))) { + 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); + if (posForLine == posNewForEntry0) { + std::swap(cache[0], cache[posNewForEntry0]); + } else { + cache[posNewForEntry0] = std::move(cache[0]); + } } + if (cache[posForLine] && (cache[posForLine]->lineNumber == lineNumber)) { + // Caret line is currently somewhere else so move it to [0]. + cache[0] = std::move(cache[posForLine]); + } + } else { + pos = posForLine; } - if (!cache[pos]) { - cache[pos] = Sci::make_unique(maxChars); - } - cache[pos]->lineNumber = lineNumber; - cache[pos]->inCache = true; - ret = cache[pos].get(); - useCount++; } + } else if (level == LineCache::Document) { + pos = lineNumber; } - if (!ret) { - ret = new LineLayout(maxChars); - ret->lineNumber = lineNumber; - } - - return ret; -} - -void LineLayoutCache::Dispose(LineLayout *ll) noexcept { - allInvalidated = false; - if (ll) { - if (!ll->inCache) { - delete ll; - } else { - useCount--; + if (pos < cache.size()) { + if (cache[pos] && !cache[pos]->CanHold(lineNumber, maxChars)) { + cache[pos].reset(); } + if (!cache[pos]) { + cache[pos] = std::make_shared(lineNumber, maxChars); + } +#ifdef CHECK_LLC + // Expensive check that there is only one entry for any line number + std::vector linesInCache(linesInDoc); + for (const auto &entry : cache) { + if (entry) { + PLATFORM_ASSERT(!linesInCache[entry->LineNumber()]); + linesInCache[entry->LineNumber()] = true; + } + } +#endif + return cache[pos]; } + + // Only reach here for level == Cache::none + return std::make_shared(lineNumber, maxChars); } // Simply pack the (maximum 4) character bytes into an int -static unsigned int KeyFromString(const char *charBytes, size_t len) noexcept { - PLATFORM_ASSERT(len <= 4); +static unsigned int KeyFromString(std::string_view charBytes) noexcept { + PLATFORM_ASSERT(charBytes.length() <= 4); unsigned int k=0; - for (size_t i=0; isecond.appearance = appearance; } - mapReprs[key] = Representation(value); } -void SpecialRepresentations::ClearRepresentation(const char *charBytes) { - MapRepresentation::iterator it = mapReprs.find(KeyFromString(charBytes, UTF8MaxBytes)); - if (it != mapReprs.end()) { - mapReprs.erase(it); - const unsigned char ucStart = charBytes[0]; - startByteHasReprs[ucStart]--; +void SpecialRepresentations::SetRepresentationColour(std::string_view charBytes, ColourRGBA colour) { + if (charBytes.length() <= 4) { + const unsigned int key = KeyFromString(charBytes); + MapRepresentation::iterator it = mapReprs.find(key); + if (it == mapReprs.end()) { + // Not present so fail + return; + } + it->second.appearance = it->second.appearance | RepresentationAppearance::Colour; + it->second.colour = colour; } } -const Representation *SpecialRepresentations::RepresentationFromCharacter(const char *charBytes, size_t len) const { - PLATFORM_ASSERT(len <= 4); - const unsigned char ucStart = charBytes[0]; - if (!startByteHasReprs[ucStart]) - return nullptr; - MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes, len)); - if (it != mapReprs.end()) { - return &(it->second); +void SpecialRepresentations::ClearRepresentation(std::string_view charBytes) { + if (charBytes.length() <= 4) { + MapRepresentation::iterator it = mapReprs.find(KeyFromString(charBytes)); + if (it != mapReprs.end()) { + mapReprs.erase(it); + const unsigned char ucStart = charBytes.empty() ? 0 : charBytes[0]; + startByteHasReprs[ucStart]--; + } + } +} + +const Representation *SpecialRepresentations::RepresentationFromCharacter(std::string_view charBytes) const { + if (charBytes.length() <= 4) { + const unsigned char ucStart = charBytes.empty() ? 0 : charBytes[0]; + if (!startByteHasReprs[ucStart]) + return nullptr; + MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes)); + if (it != mapReprs.end()) { + return &(it->second); + } } return nullptr; } -bool SpecialRepresentations::Contains(const char *charBytes, size_t len) const { - PLATFORM_ASSERT(len <= 4); - const unsigned char ucStart = charBytes[0]; +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; - MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes, len)); + MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes)); return it != mapReprs.end(); } void SpecialRepresentations::Clear() { mapReprs.clear(); - const short none = 0; + constexpr short none = 0; std::fill(startByteHasReprs, std::end(startByteHasReprs), none); } @@ -446,7 +635,7 @@ void BreakFinder::Insert(Sci::Position val) { } BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, Sci::Position posLineStart_, - int xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw) : + XYPOSITION xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw) : ll(ll_), lineRange(lineRange_), posLineStart(posLineStart_), @@ -461,7 +650,7 @@ BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lin // Search for first visible break // First find the first visible character if (xStart > 0.0f) - nextBreak = ll->FindBefore(static_cast(xStart), lineRange); + nextBreak = ll->FindBefore(xStart, lineRange); // Now back to a style break while ((nextBreak > lineRange.start) && (ll->styles[nextBreak] == ll->styles[nextBreak - 1])) { nextBreak--; @@ -510,8 +699,11 @@ TextSegment BreakFinder::Next() { static_cast(lineRange.end - nextBreak)); else if (encodingFamily == EncodingFamily::dbcs) charWidth = pdoc->DBCSDrawBytes( - &ll->chars[nextBreak], static_cast(lineRange.end - nextBreak)); - const Representation *repr = preprs->RepresentationFromCharacter(&ll->chars[nextBreak], charWidth); + std::string_view(&ll->chars[nextBreak], lineRange.end - nextBreak)); + // Special case \r\n line ends if there is a representation + if (preprs->Contains("\r\n") && ll->chars[nextBreak] == '\r' && ll->chars[nextBreak + 1] == '\n') + charWidth = 2; + const Representation *repr = preprs->RepresentationFromCharacter(std::string_view(&ll->chars[nextBreak], charWidth)); if (((nextBreak > 0) && (ll->styles[nextBreak] != ll->styles[nextBreak - 1])) || repr || (nextBreak == saeNext)) { @@ -562,31 +754,31 @@ bool BreakFinder::More() const noexcept { } PositionCacheEntry::PositionCacheEntry() noexcept : - styleNumber(0), len(0), clock(0), positions(nullptr) { + styleNumber(0), len(0), clock(0) { } // Copy constructor not currently used, but needed for being element in std::vector. PositionCacheEntry::PositionCacheEntry(const PositionCacheEntry &other) : - styleNumber(other.styleNumber), len(other.styleNumber), clock(other.styleNumber), positions(nullptr) { + styleNumber(other.styleNumber), len(other.len), clock(other.clock) { if (other.positions) { const size_t lenData = len + (len / sizeof(XYPOSITION)) + 1; - positions = Sci::make_unique(lenData); + positions = std::make_unique(lenData); memcpy(positions.get(), other.positions.get(), lenData * sizeof(XYPOSITION)); } } -void PositionCacheEntry::Set(unsigned int styleNumber_, const char *s_, - unsigned int len_, const XYPOSITION *positions_, unsigned int clock_) { +void PositionCacheEntry::Set(unsigned int styleNumber_, std::string_view sv, + const XYPOSITION *positions_, unsigned int clock_) { Clear(); styleNumber = styleNumber_; - len = len_; + len = static_cast(sv.length()); clock = clock_; - if (s_ && positions_) { - positions = Sci::make_unique(len + (len / sizeof(XYPOSITION)) + 1); + if (sv.data() && positions_) { + positions = std::make_unique(len + (len / sizeof(XYPOSITION)) + 1); for (unsigned int i=0; i{}(sv); + const size_t h2 = std::hash{}(styleNumber_); + return h1 ^ (h2 << 1); } bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) const noexcept { @@ -643,10 +827,6 @@ PositionCache::PositionCache() { allClear = true; } -PositionCache::~PositionCache() { - Clear(); -} - void PositionCache::Clear() noexcept { if (!allClear) { for (PositionCacheEntry &pce : pces) { @@ -662,23 +842,26 @@ void PositionCache::SetSize(size_t size_) { pces.resize(size_); } -void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber, - const char *s, unsigned int len, XYPOSITION *positions, const Document *pdoc) { +size_t PositionCache::GetSize() const noexcept { + return pces.size(); +} +void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber, + std::string_view sv, XYPOSITION *positions) { allClear = false; size_t probe = pces.size(); // Out of bounds - if ((!pces.empty()) && (len < 30)) { + if ((!pces.empty()) && (sv.length() < 30)) { // Only store short strings in the cache so it doesn't churn with // long comments with only a single comment. // Two way associative: try two probe positions. - const unsigned int hashValue = PositionCacheEntry::Hash(styleNumber, s, len); + const size_t hashValue = PositionCacheEntry::Hash(styleNumber, sv); probe = hashValue % pces.size(); - if (pces[probe].Retrieve(styleNumber, s, len, positions)) { + if (pces[probe].Retrieve(styleNumber, sv, positions)) { return; } - const unsigned int probe2 = (hashValue * 37) % pces.size(); - if (pces[probe2].Retrieve(styleNumber, s, len, positions)) { + const size_t probe2 = (hashValue * 37) % pces.size(); + if (pces[probe2].Retrieve(styleNumber, sv, positions)) { return; } // Not found. Choose the oldest of the two slots to replace @@ -686,23 +869,8 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns probe = probe2; } } - FontAlias fontStyle = vstyle.styles[styleNumber].font; - if (len > BreakFinder::lengthStartSubdivision) { - // Break up into segments - unsigned int startSegment = 0; - XYPOSITION xStartSegment = 0; - while (startSegment < len) { - const unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision); - surface->MeasureWidths(fontStyle, s + startSegment, lenSegment, positions + startSegment); - for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) { - positions[startSegment + inSeg] += xStartSegment; - } - xStartSegment = positions[startSegment + lenSegment - 1]; - startSegment += lenSegment; - } - } else { - surface->MeasureWidths(fontStyle, s, len, positions); - } + const Font *fontStyle = vstyle.styles[styleNumber].font.get(); + surface->MeasureWidths(fontStyle, sv, positions); if (probe < pces.size()) { // Store into cache clock++; @@ -714,6 +882,6 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns } clock = 2; } - pces[probe].Set(styleNumber, s, len, positions, clock); + pces[probe].Set(styleNumber, sv, positions, clock); } } diff --git a/scintilla/src/PositionCache.h b/scintilla/src/PositionCache.h index 9647255d6f..b628b04215 100644 --- a/scintilla/src/PositionCache.h +++ b/scintilla/src/PositionCache.h @@ -8,7 +8,7 @@ #ifndef POSITIONCACHE_H #define POSITIONCACHE_H -namespace Scintilla { +namespace Scintilla::Internal { inline constexpr bool IsEOLChar(int ch) noexcept { return (ch == '\r') || (ch == '\n'); @@ -38,10 +38,18 @@ class PointDocument { // There are two points for some positions and this enumeration // can choose between the end of the first line or subline // and the start of the next line or subline. -enum PointEnd { - peDefault = 0x0, - peLineEnd = 0x1, - peSubLineEnd = 0x2 +enum class PointEnd { + start = 0x0, + lineEnd = 0x1, + subLineEnd = 0x2, + endEither = lineEnd | subLineEnd, +}; + +class BidiData { +public: + std::vector> stylesFonts; + std::vector widthReprs; + void Resize(size_t maxLineLength_); }; /** @@ -53,7 +61,6 @@ class LineLayout { int lenLineStarts; /// Drawing is only performed for @a maxLineLength characters on each line. Sci::Line lineNumber; - bool inCache; public: enum { wrapWidthInfinite = 0x7ffffff }; @@ -70,6 +77,8 @@ class LineLayout { std::unique_ptr positions; char bracePreviousStyles[2]; + std::unique_ptr bidiData; + // Hotspot support Range hotspot; @@ -78,7 +87,7 @@ class LineLayout { int lines; XYPOSITION wrapIndent; // In pixels - explicit LineLayout(int maxLineLength_); + LineLayout(Sci::Line lineNumber_, int maxLineLength_); // Deleted so LineLayout objects can not be copied. LineLayout(const LineLayout &) = delete; LineLayout(LineLayout &&) = delete; @@ -86,14 +95,18 @@ class LineLayout { void operator=(LineLayout &&) = delete; virtual ~LineLayout(); void Resize(int maxLineLength_); + void EnsureBidiData(); void Free() noexcept; void Invalidate(ValidLevel validity_) noexcept; + Sci::Line LineNumber() const noexcept; + bool CanHold(Sci::Line lineDoc, int lineLength_) const noexcept; int LineStart(int line) const noexcept; int LineLength(int line) const noexcept; enum class Scope { visibleOnly, includeEnd }; int LineLastVisible(int line, Scope scope) const noexcept; Range SubLineRange(int subLine, Scope scope) const noexcept; bool InLine(int offset, int line) const noexcept; + int SubLineFromPosition(int posInLine, PointEnd pe) const noexcept; void SetLineStart(int line, int start); void SetBracesHighlight(Range rangeLine, const Sci::Position braces[], char bracesMatchStyle, int xHighlight, bool ignoreStyle); @@ -104,15 +117,46 @@ class LineLayout { int EndLineStyle() const noexcept; }; +struct ScreenLine : public IScreenLine { + const LineLayout *ll; + size_t start; + size_t len; + XYPOSITION width; + XYPOSITION height; + int ctrlCharPadding; + XYPOSITION tabWidth; + int tabWidthMinimumPixels; + + ScreenLine(const LineLayout *ll_, int subLine, const ViewStyle &vs, XYPOSITION width_, int tabWidthMinimumPixels_); + // Deleted so ScreenLine objects can not be copied. + ScreenLine(const ScreenLine &) = delete; + ScreenLine(ScreenLine &&) = delete; + void operator=(const ScreenLine &) = delete; + void operator=(ScreenLine &&) = delete; + virtual ~ScreenLine(); + + std::string_view Text() const override; + size_t Length() const override; + size_t RepresentationCount() const override; + XYPOSITION Width() const override; + XYPOSITION Height() const override; + XYPOSITION TabWidth() const override; + XYPOSITION TabWidthMinimumPixels() const override; + const Font *FontOfPosition(size_t position) const override; + XYPOSITION RepresentationWidth(size_t position) const override; + XYPOSITION TabPositionAfter(XYPOSITION xPosition) const override; +}; + /** */ class LineLayoutCache { - int level; - std::vector>cache; +public: +private: + Scintilla::LineCache level; + std::vector>cache; bool allInvalidated; int styleClock; - int useCount; - void Allocate(size_t length_); + size_t EntryForLine(Sci::Line line) const noexcept; void AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesInDoc); public: LineLayoutCache(); @@ -123,18 +167,11 @@ class LineLayoutCache { void operator=(LineLayoutCache &&) = delete; virtual ~LineLayoutCache(); void Deallocate() noexcept; - enum { - llcNone=SC_CACHE_NONE, - llcCaret=SC_CACHE_CARET, - llcPage=SC_CACHE_PAGE, - llcDocument=SC_CACHE_DOCUMENT - }; void Invalidate(LineLayout::ValidLevel validity_) noexcept; - void SetLevel(int level_) noexcept; - int GetLevel() const noexcept { return level; } - LineLayout *Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_, + void SetLevel(Scintilla::LineCache level_) noexcept; + Scintilla::LineCache GetLevel() const noexcept { return level; } + std::shared_ptr Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_, Sci::Line linesOnScreen, Sci::Line linesInDoc); - void Dispose(LineLayout *ll) noexcept; }; class PositionCacheEntry { @@ -146,23 +183,27 @@ class PositionCacheEntry { PositionCacheEntry() noexcept; // Copy constructor not currently used, but needed for being element in std::vector. PositionCacheEntry(const PositionCacheEntry &); - // PositionCacheEntry objects should not be moved but MSVC 2015 requires this. - PositionCacheEntry(PositionCacheEntry &&) = default; + PositionCacheEntry(PositionCacheEntry &&) noexcept = default; + // Deleted so PositionCacheEntry objects can not be assigned. void operator=(const PositionCacheEntry &) = delete; void operator=(PositionCacheEntry &&) = delete; ~PositionCacheEntry(); - void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, const XYPOSITION *positions_, unsigned int clock_); + void Set(unsigned int styleNumber_, std::string_view sv, const XYPOSITION *positions_, unsigned int clock_); void Clear() noexcept; - bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const noexcept; - static unsigned int Hash(unsigned int styleNumber_, const char *s, unsigned int len_) 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 NewerThan(const PositionCacheEntry &other) const noexcept; void ResetClock() noexcept; }; class Representation { public: + static constexpr size_t maxLength = 200; std::string stringRep; - explicit Representation(const char *value="") : stringRep(value) { + RepresentationAppearance appearance; + ColourRGBA colour; + explicit Representation(std::string_view value="", RepresentationAppearance appearance_= RepresentationAppearance::Blob) : + stringRep(value), appearance(appearance_) { } }; @@ -170,13 +211,14 @@ typedef std::map MapRepresentation; class SpecialRepresentations { MapRepresentation mapReprs; - short startByteHasReprs[0x100]; + short startByteHasReprs[0x100] {}; public: - SpecialRepresentations(); - void SetRepresentation(const char *charBytes, const char *value); - void ClearRepresentation(const char *charBytes); - const Representation *RepresentationFromCharacter(const char *charBytes, size_t len) const; - bool Contains(const char *charBytes, size_t len) const; + void SetRepresentation(std::string_view charBytes, std::string_view value); + void SetRepresentationAppearance(std::string_view charBytes, RepresentationAppearance appearance); + void SetRepresentationColour(std::string_view charBytes, ColourRGBA colour); + void ClearRepresentation(std::string_view charBytes); + const Representation *RepresentationFromCharacter(std::string_view charBytes) const; + bool Contains(std::string_view charBytes) const; void Clear(); }; @@ -213,7 +255,7 @@ class BreakFinder { // Try to make each subdivided run lengthEachSubdivision or shorter. enum { lengthEachSubdivision = 100 }; BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, Sci::Position posLineStart_, - int xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw); + XYPOSITION xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw); // Deleted so BreakFinder objects can not be copied. BreakFinder(const BreakFinder &) = delete; BreakFinder(BreakFinder &&) = delete; @@ -230,17 +272,11 @@ class PositionCache { bool allClear; public: PositionCache(); - // Deleted so PositionCache objects can not be copied. - PositionCache(const PositionCache &) = delete; - PositionCache(PositionCache &&) = delete; - void operator=(const PositionCache &) = delete; - void operator=(PositionCache &&) = delete; - ~PositionCache(); void Clear() noexcept; void SetSize(size_t size_); - size_t GetSize() const noexcept { return pces.size(); } + size_t GetSize() const noexcept; void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber, - const char *s, unsigned int len, XYPOSITION *positions, const Document *pdoc); + std::string_view sv, XYPOSITION *positions); }; } diff --git a/scintilla/src/RESearch.cxx b/scintilla/src/RESearch.cxx index a682016bc8..6d30e4c6bf 100644 --- a/scintilla/src/RESearch.cxx +++ b/scintilla/src/RESearch.cxx @@ -212,7 +212,7 @@ #include "CharClassify.h" #include "RESearch.h" -using namespace Scintilla; +using namespace Scintilla::Internal; #define OKP 1 #define NOP 0 @@ -237,11 +237,8 @@ using namespace Scintilla; * The following defines are not meant to be changeable. * They are for readability only. */ -#define BLKIND 0370 #define BITIND 07 -static const char bitarr[] = { 1, 2, 4, 8, 16, 32, 64, '\200' }; - #define badpat(x) (*nfa = END, x) /* @@ -287,7 +284,7 @@ void RESearch::GrabMatches(const CharacterIndexer &ci) { } void RESearch::ChSet(unsigned char c) noexcept { - bittab[((c) & BLKIND) >> 3] |= bitarr[(c) & BITIND]; + bittab[c >> 3] |= 1 << (c & BITIND); } void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) noexcept { @@ -301,7 +298,9 @@ void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) noexcept { } } -static unsigned char escapeValue(unsigned char ch) noexcept { +namespace { + +constexpr unsigned char escapeValue(unsigned char ch) noexcept { switch (ch) { case 'a': return '\a'; case 'b': return '\b'; @@ -314,7 +313,7 @@ static unsigned char escapeValue(unsigned char ch) noexcept { return 0; } -static int GetHexaChar(unsigned char hd1, unsigned char hd2) noexcept { +constexpr int GetHexaChar(unsigned char hd1, unsigned char hd2) noexcept { int hexValue = 0; if (hd1 >= '0' && hd1 <= '9') { hexValue += 16 * (hd1 - '0'); @@ -337,6 +336,12 @@ static int GetHexaChar(unsigned char hd1, unsigned char hd2) noexcept { return hexValue; } +constexpr int isinset(const char *ap, unsigned char c) noexcept { + return ap[c >> 3] & (1 << (c & BITIND)); +} + +} + /** * Called when the parser finds a backslash not followed * by a valid expression (like \( in non-Posix mode). @@ -780,7 +785,7 @@ int RESearch::Execute(const CharacterIndexer &ci, Sci::Position lp, Sci::Positio lp++; if (lp >= endp) /* if EOS, fail, else fall through. */ return 0; - // Falls through. + [[fallthrough]]; default: /* regular matching all the way. */ while (lp < endp) { ep = PMatch(ci, lp, endp, ap); @@ -829,11 +834,7 @@ int RESearch::Execute(const CharacterIndexer &ci, Sci::Position lp, Sci::Positio * by tagged expressions (n = 1 to 9). */ -extern void re_fail(char *,char); - -static inline int isinset(const char *ap, unsigned char c) noexcept { - return ap[(c & BLKIND) >> 3] & bitarr[c & BITIND]; -} +//extern void re_fail(char *,char); /* * skip values for CLO XXX to skip past the closure diff --git a/scintilla/src/RESearch.h b/scintilla/src/RESearch.h index 49bfc05414..4f0598826e 100644 --- a/scintilla/src/RESearch.h +++ b/scintilla/src/RESearch.h @@ -9,7 +9,7 @@ #ifndef RESEARCH_H #define RESEARCH_H -namespace Scintilla { +namespace Scintilla::Internal { class CharacterIndexer { public: diff --git a/scintilla/src/RunStyles.cxx b/scintilla/src/RunStyles.cxx index da000e69df..e9d3f6e4ec 100644 --- a/scintilla/src/RunStyles.cxx +++ b/scintilla/src/RunStyles.cxx @@ -13,19 +13,20 @@ #include #include +#include #include +#include #include #include -#include "Platform.h" +#include "Debugging.h" -#include "Scintilla.h" #include "Position.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" -using namespace Scintilla; +using namespace Scintilla::Internal; // Find the first run at a position template @@ -78,8 +79,8 @@ void RunStyles::RemoveRunIfSameAsPrevious(DISTANCE run) { template RunStyles::RunStyles() { - starts = Sci::make_unique>(8); - styles = Sci::make_unique>(); + starts = std::make_unique>(8); + styles = std::make_unique>(); styles->InsertValue(0, 2, 0); } @@ -215,8 +216,8 @@ void RunStyles::InsertSpace(DISTANCE position, DISTANCE insertL template void RunStyles::DeleteAll() { - starts = Sci::make_unique>(8); - styles = Sci::make_unique>(); + starts = std::make_unique>(8); + styles = std::make_unique>(); styles->InsertValue(0, 2, 0); } @@ -306,9 +307,9 @@ void RunStyles::Check() const { } } -template class Scintilla::RunStyles; -template class Scintilla::RunStyles; +template class Scintilla::Internal::RunStyles; +template class Scintilla::Internal::RunStyles; #if (PTRDIFF_MAX != INT_MAX) || PLAT_HAIKU -template class Scintilla::RunStyles; -template class Scintilla::RunStyles; +template class Scintilla::Internal::RunStyles; +template class Scintilla::Internal::RunStyles; #endif diff --git a/scintilla/src/RunStyles.h b/scintilla/src/RunStyles.h index 97673d04ba..328fa1d4db 100644 --- a/scintilla/src/RunStyles.h +++ b/scintilla/src/RunStyles.h @@ -10,7 +10,7 @@ #ifndef RUNSTYLES_H #define RUNSTYLES_H -namespace Scintilla { +namespace Scintilla::Internal { // Return for RunStyles::FillRange reports if anything was changed and the // range that was changed. This may be trimmed from the requested range diff --git a/scintilla/src/SVector.h b/scintilla/src/SVector.h deleted file mode 100644 index 6803c20513..0000000000 --- a/scintilla/src/SVector.h +++ /dev/null @@ -1,123 +0,0 @@ -// Scintilla source code edit control -/** @file SVector.h - ** A simple expandable vector. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef SVECTOR_H -#define SVECTOR_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/** - * A simple expandable integer vector. - * Storage not allocated for elements until an element is used. - * This makes it very lightweight unless used so is a good match for optional features. - */ -class SVector { - enum { allocSize = 4000 }; - - int *v; ///< The vector - unsigned int size; ///< Number of elements allocated - unsigned int len; ///< Number of elements used in vector - - /** Internally allocate more elements than the user wants - * to avoid thrashing the memory allocator. */ - void SizeTo(int newSize) { - if (newSize < allocSize) - newSize += allocSize; - else - newSize = (newSize * 3) / 2; - int *newv = new int[newSize]; - size = newSize; - unsigned int i=0; - for (; i 0) { - SizeTo(other.Length()); - for (int i=0; i 0) { - SizeTo(other.Length()); - for (int i=0; i= len) { - if (i >= size) { - SizeTo(i); - } - len = i+1; - } - return v[i]; - } - /// Reset vector. - void Free() { - delete []v; - v = 0; - size = 0; - len = 0; - } - /** @brief Grow vector size. - * Doesn't allow a vector to be shrunk. */ - void SetLength(unsigned int newLength) { - if (newLength > len) { - if (newLength >= size) { - SizeTo(newLength); - } - } - len = newLength; - } - /// Get the current length (number of used elements) of the vector. - int Length() const { - return len; - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/scintilla/src/ScintillaBase.cxx b/scintilla/src/ScintillaBase.cxx index 082cb82d51..238299734f 100644 --- a/scintilla/src/ScintillaBase.cxx +++ b/scintilla/src/ScintillaBase.cxx @@ -12,28 +12,25 @@ #include #include +#include #include #include +#include +#include #include #include -#include "Platform.h" - +#include "ScintillaTypes.h" +#include "ScintillaMessages.h" +#include "ScintillaStructures.h" #include "ILoader.h" #include "ILexer.h" -#include "Scintilla.h" - -#ifdef SCI_LEXER -#include "SciLexer.h" -#endif -#include "PropSetSimple.h" -#include "CharacterCategory.h" +#include "Debugging.h" +#include "Geometry.h" +#include "Platform.h" -#ifdef SCI_LEXER -#include "LexerModule.h" -#include "Catalogue.h" -#endif +#include "CharacterCategoryMap.h" #include "Position.h" #include "UniqueString.h" @@ -61,20 +58,14 @@ #include "AutoComplete.h" #include "ScintillaBase.h" -#ifdef SCI_LEXER -#include "ExternalLexer.h" -#endif - using namespace Scintilla; +using namespace Scintilla::Internal; ScintillaBase::ScintillaBase() { - displayPopupMenu = SC_POPUP_ALL; + displayPopupMenu = PopUp::All; listType = 0; maxListWidth = 0; - multiAutoCMode = SC_MULTIAUTOC_ONCE; -#ifdef SCI_LEXER - Scintilla_LinkLexers(); -#endif + multiAutoCMode = MultiAutoComplete::Once; } ScintillaBase::~ScintillaBase() { @@ -85,21 +76,17 @@ void ScintillaBase::Finalise() { popup.Destroy(); } -void ScintillaBase::AddCharUTF(const char *s, unsigned int len, bool /*treatAsDBCS*/) { - InsertCharacter(s, len, CharacterSource::directInput); -} - -void ScintillaBase::InsertCharacter(const char *s, unsigned int len, CharacterSource charSource) { - const bool isFillUp = ac.Active() && ac.IsFillUpChar(s[0]); +void ScintillaBase::InsertCharacter(std::string_view sv, CharacterSource charSource) { + const bool isFillUp = ac.Active() && ac.IsFillUpChar(sv[0]); if (!isFillUp) { - Editor::InsertCharacter(s, len, charSource); + Editor::InsertCharacter(sv, charSource); } if (ac.Active()) { - AutoCompleteCharacterAdded(s[0]); + AutoCompleteCharacterAdded(sv[0]); // For fill ups add the character after the autocompletion has // triggered so containers see the key so can display a calltip. if (isFillUp) { - Editor::InsertCharacter(s, len, charSource); + Editor::InsertCharacter(sv, charSource); } } } @@ -117,73 +104,73 @@ void ScintillaBase::Command(int cmdId) { break; case idcmdUndo: - WndProc(SCI_UNDO, 0, 0); + WndProc(Message::Undo, 0, 0); break; case idcmdRedo: - WndProc(SCI_REDO, 0, 0); + WndProc(Message::Redo, 0, 0); break; case idcmdCut: - WndProc(SCI_CUT, 0, 0); + WndProc(Message::Cut, 0, 0); break; case idcmdCopy: - WndProc(SCI_COPY, 0, 0); + WndProc(Message::Copy, 0, 0); break; case idcmdPaste: - WndProc(SCI_PASTE, 0, 0); + WndProc(Message::Paste, 0, 0); break; case idcmdDelete: - WndProc(SCI_CLEAR, 0, 0); + WndProc(Message::Clear, 0, 0); break; case idcmdSelectAll: - WndProc(SCI_SELECTALL, 0, 0); + WndProc(Message::SelectAll, 0, 0); break; } } -int ScintillaBase::KeyCommand(unsigned int iMessage) { +int ScintillaBase::KeyCommand(Message iMessage) { // Most key commands cancel autocompletion mode if (ac.Active()) { switch (iMessage) { // Except for these - case SCI_LINEDOWN: + case Message::LineDown: AutoCompleteMove(1); return 0; - case SCI_LINEUP: + case Message::LineUp: AutoCompleteMove(-1); return 0; - case SCI_PAGEDOWN: + case Message::PageDown: AutoCompleteMove(ac.lb->GetVisibleRows()); return 0; - case SCI_PAGEUP: + case Message::PageUp: AutoCompleteMove(-ac.lb->GetVisibleRows()); return 0; - case SCI_VCHOME: + case Message::VCHome: AutoCompleteMove(-5000); return 0; - case SCI_LINEEND: + case Message::LineEnd: AutoCompleteMove(5000); return 0; - case SCI_DELETEBACK: + case Message::DeleteBack: DelCharBack(true); AutoCompleteCharacterDeleted(); EnsureCaretVisible(); return 0; - case SCI_DELETEBACKNOTLINE: + case Message::DeleteBackNotLine: DelCharBack(false); AutoCompleteCharacterDeleted(); EnsureCaretVisible(); return 0; - case SCI_TAB: - AutoCompleteCompleted(0, SC_AC_TAB); + case Message::Tab: + AutoCompleteCompleted(0, CompletionMethods::Tab); return 0; - case SCI_NEWLINE: - AutoCompleteCompleted(0, SC_AC_NEWLINE); + case Message::NewLine: + AutoCompleteCompleted(0, CompletionMethods::Newline); return 0; default: @@ -193,17 +180,17 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) { if (ct.inCallTipMode) { if ( - (iMessage != SCI_CHARLEFT) && - (iMessage != SCI_CHARLEFTEXTEND) && - (iMessage != SCI_CHARRIGHT) && - (iMessage != SCI_CHARRIGHTEXTEND) && - (iMessage != SCI_EDITTOGGLEOVERTYPE) && - (iMessage != SCI_DELETEBACK) && - (iMessage != SCI_DELETEBACKNOTLINE) + (iMessage != Message::CharLeft) && + (iMessage != Message::CharLeftExtend) && + (iMessage != Message::CharRight) && + (iMessage != Message::CharRightExtend) && + (iMessage != Message::EditToggleOvertype) && + (iMessage != Message::DeleteBack) && + (iMessage != Message::DeleteBackNotLine) ) { ct.CallTipCancel(); } - if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) { + if ((iMessage == Message::DeleteBack) || (iMessage == Message::DeleteBackNotLine)) { if (sel.MainCaret() <= ct.posStartCallTip) { ct.CallTipCancel(); } @@ -218,19 +205,19 @@ void ScintillaBase::ListNotify(ListBoxEvent *plbe) { AutoCompleteSelection(); break; case ListBoxEvent::EventType::doubleClick: - AutoCompleteCompleted(0, SC_AC_DOUBLECLICK); + AutoCompleteCompleted(0, CompletionMethods::DoubleClick); break; } } void ScintillaBase::AutoCompleteInsert(Sci::Position startPos, Sci::Position removeLen, const char *text, Sci::Position textLen) { UndoGroup ug(pdoc); - if (multiAutoCMode == SC_MULTIAUTOC_ONCE) { + if (multiAutoCMode == MultiAutoComplete::Once) { pdoc->DeleteChars(startPos, removeLen); const Sci::Position lengthInserted = pdoc->InsertString(startPos, text, textLen); SetEmptySelection(startPos + lengthInserted); } else { - // SC_MULTIAUTOC_EACH + // MultiAutoComplete::Each for (size_t r=0; r(std::min(static_cast(rcac.top) + heightLB, static_cast(rcPopupBounds.bottom))); ac.lb->SetPositionRelative(rcac, &wMain); - ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font); - const unsigned int aveCharWidth = static_cast(vs.styles[STYLE_DEFAULT].aveCharWidth); + ac.lb->SetFont(vs.styles[StyleDefault].font.get()); + const int aveCharWidth = static_cast(vs.styles[StyleDefault].aveCharWidth); ac.lb->SetAverageCharWidth(aveCharWidth); ac.lb->SetDelegate(this); @@ -316,7 +312,7 @@ void ScintillaBase::AutoCompleteStart(Sci::Position lenEntered, const char *list const int heightAlloced = static_cast(rcList.bottom - rcList.top); widthLB = std::max(widthLB, static_cast(rcList.right - rcList.left)); if (maxListWidth != 0) - widthLB = std::min(widthLB, static_cast(aveCharWidth)*maxListWidth); + widthLB = std::min(widthLB, aveCharWidth*maxListWidth); // Make an allowance for large strings in list rcList.left = pt.x - ac.lb->CaretFromEdge(); rcList.right = rcList.left + widthLB; @@ -336,8 +332,8 @@ void ScintillaBase::AutoCompleteStart(Sci::Position lenEntered, const char *list void ScintillaBase::AutoCompleteCancel() { if (ac.Active()) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_AUTOCCANCELLED; + NotificationData scn = {}; + scn.nmhdr.code = Notification::AutoCCancelled; scn.wParam = 0; scn.listType = 0; NotifyParent(scn); @@ -361,9 +357,9 @@ void ScintillaBase::AutoCompleteSelection() { selected = ac.GetValue(item); } - SCNotification scn = {}; - scn.nmhdr.code = SCN_AUTOCSELECTIONCHANGE; - scn.message = 0; + NotificationData scn = {}; + scn.nmhdr.code = Notification::AutoCSelectionChange; + scn.message = static_cast(0); scn.wParam = listType; scn.listType = listType; const Sci::Position firstPos = ac.posStart - ac.startLen; @@ -375,7 +371,7 @@ void ScintillaBase::AutoCompleteSelection() { void ScintillaBase::AutoCompleteCharacterAdded(char ch) { if (ac.IsFillUpChar(ch)) { - AutoCompleteCompleted(ch, SC_AC_FILLUP); + AutoCompleteCompleted(ch, CompletionMethods::FillUp); } else if (ac.IsStopChar(ch)) { AutoCompleteCancel(); } else { @@ -391,14 +387,14 @@ void ScintillaBase::AutoCompleteCharacterDeleted() { } else { AutoCompleteMoveToCurrentWord(); } - SCNotification scn = {}; - scn.nmhdr.code = SCN_AUTOCCHARDELETED; + NotificationData scn = {}; + scn.nmhdr.code = Notification::AutoCCharDeleted; scn.wParam = 0; scn.listType = 0; NotifyParent(scn); } -void ScintillaBase::AutoCompleteCompleted(char ch, unsigned int completionMethod) { +void ScintillaBase::AutoCompleteCompleted(char ch, CompletionMethods completionMethod) { const int item = ac.GetSelection(); if (item == -1) { AutoCompleteCancel(); @@ -408,9 +404,9 @@ void ScintillaBase::AutoCompleteCompleted(char ch, unsigned int completionMethod ac.Show(false); - SCNotification scn = {}; - scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION; - scn.message = 0; + NotificationData scn = {}; + scn.nmhdr.code = listType > 0 ? Notification::UserListSelection : Notification::AutoCSelection; + scn.message = static_cast(0); scn.ch = ch; scn.listCompletionMethod = completionMethod; scn.wParam = listType; @@ -436,7 +432,7 @@ void ScintillaBase::AutoCompleteCompleted(char ch, unsigned int completionMethod AutoCompleteInsert(firstPos, endPos - firstPos, selected.c_str(), selected.length()); SetLastXChosen(); - scn.nmhdr.code = SCN_AUTOCCOMPLETED; + scn.nmhdr.code = Notification::AutoCCompleted; NotifyParent(scn); } @@ -464,12 +460,12 @@ int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) const { void ScintillaBase::CallTipShow(Point pt, const char *defn) { ac.Cancel(); - // If container knows about STYLE_CALLTIP then use it in place of the - // STYLE_DEFAULT for the face name, size and character set. Also use it + // If container knows about StyleCallTip then use it in place of the + // StyleDefault for the face name, size and character set. Also use it // for the foreground and background colour. - const int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT; + const int ctStyle = ct.UseStyleCallTip() ? StyleCallTip : StyleDefault; if (ct.UseStyleCallTip()) { - ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back); + ct.SetForeBack(vs.styles[StyleCallTip].fore, vs.styles[StyleCallTip].back); } if (wMargin.Created()) { pt = pt + GetVisibleOriginInMain(); @@ -482,6 +478,7 @@ void ScintillaBase::CallTipShow(Point pt, const char *defn) { CodePage(), vs.styles[ctStyle].characterSet, vs.technology, + vs.localeName.c_str(), wMain); // If the call-tip window would be out of the client // space @@ -504,27 +501,27 @@ void ScintillaBase::CallTipShow(Point pt, const char *defn) { } void ScintillaBase::CallTipClick() { - SCNotification scn = {}; - scn.nmhdr.code = SCN_CALLTIPCLICK; + NotificationData scn = {}; + scn.nmhdr.code = Notification::CallTipClick; scn.position = ct.clickPlace; NotifyParent(scn); } bool ScintillaBase::ShouldDisplayPopup(Point ptInWindowCoordinates) const { - return (displayPopupMenu == SC_POPUP_ALL || - (displayPopupMenu == SC_POPUP_TEXT && !PointInSelMargin(ptInWindowCoordinates))); + return (displayPopupMenu == PopUp::All || + (displayPopupMenu == PopUp::Text && !PointInSelMargin(ptInWindowCoordinates))); } void ScintillaBase::ContextMenu(Point pt) { - if (displayPopupMenu) { - const bool writable = !WndProc(SCI_GETREADONLY, 0, 0); + if (displayPopupMenu != PopUp::Never) { + const bool writable = !WndProc(Message::GetReadOnly, 0, 0); popup.CreatePopUp(); AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo()); AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo()); AddToPopUp(""); AddToPopUp("Cut", idcmdCut, writable && !sel.Empty()); AddToPopUp("Copy", idcmdCopy, !sel.Empty()); - AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0)); + AddToPopUp("Paste", idcmdPaste, writable && WndProc(Message::CanPaste, 0, 0)); AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty()); AddToPopUp(""); AddToPopUp("Select All", idcmdSelectAll); @@ -538,50 +535,43 @@ void ScintillaBase::CancelModes() { Editor::CancelModes(); } -void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) { +void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, KeyMod modifiers) { CancelModes(); Editor::ButtonDownWithModifiers(pt, curTime, modifiers); } -void ScintillaBase::RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) { +void ScintillaBase::RightButtonDownWithModifiers(Point pt, unsigned int curTime, KeyMod modifiers) { CancelModes(); Editor::RightButtonDownWithModifiers(pt, curTime, modifiers); } -#ifdef SCI_LEXER - -namespace Scintilla { +namespace Scintilla::Internal { class LexState : public LexInterface { - const LexerModule *lexCurrent; - void SetLexerModule(const LexerModule *lex); - PropSetSimple props; - int interfaceVersion; public: - int lexLanguage; - - explicit LexState(Document *pdoc_); + explicit LexState(Document *pdoc_) noexcept; + void SetInstance(ILexer5 *instance_); // Deleted so LexState objects can not be copied. LexState(const LexState &) = delete; LexState(LexState &&) = delete; LexState &operator=(const LexState &) = delete; LexState &operator=(LexState &&) = delete; ~LexState() override; - void SetLexer(uptr_t wParam); - void SetLexerLanguage(const char *languageName); + const char *DescribeWordListSets(); void SetWordList(int n, const char *wl); + int GetIdentifier() const; const char *GetName() const; void *PrivateCall(int operation, void *pointer); const char *PropertyNames(); - int PropertyType(const char *name); + TypeProperty PropertyType(const char *name); const char *DescribeProperty(const char *name); 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; - int LineEndTypesSupported() override; + LineEndType LineEndTypesSupported() override; int AllocateSubStyles(int styleBase, int numberStyles); int SubStylesStart(int styleBase); int SubStylesLength(int styleBase); @@ -599,62 +589,38 @@ class LexState : public LexInterface { } -LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) { - lexCurrent = nullptr; - performingStyle = false; - interfaceVersion = lvOriginal; - lexLanguage = SCLEX_CONTAINER; +LexState::LexState(Document *pdoc_) noexcept : LexInterface(pdoc_) { } LexState::~LexState() { if (instance) { - instance->Release(); + try { + instance->Release(); + } catch (...) { + // ILexer5::Release must not throw, ignore if it does. + } instance = nullptr; } } -LexState *ScintillaBase::DocumentLexState() { - if (!pdoc->GetLexInterface()) { - pdoc->SetLexInterface(Sci::make_unique(pdoc)); - } - return dynamic_cast(pdoc->GetLexInterface()); -} - -void LexState::SetLexerModule(const LexerModule *lex) { - if (lex != lexCurrent) { - if (instance) { +void LexState::SetInstance(ILexer5 *instance_) { + if (instance) { + try { instance->Release(); - instance = nullptr; - } - interfaceVersion = lvOriginal; - lexCurrent = lex; - if (lexCurrent) { - instance = lexCurrent->Create(); - interfaceVersion = instance->Version(); + } catch (...) { + // ILexer5::Release must not throw, ignore if it does. } - pdoc->LexerChanged(); + instance = nullptr; } + instance = instance_; + pdoc->LexerChanged(); } -void LexState::SetLexer(uptr_t wParam) { - lexLanguage = static_cast(wParam); - if (lexLanguage == SCLEX_CONTAINER) { - SetLexerModule(nullptr); - } else { - const LexerModule *lex = Catalogue::Find(lexLanguage); - if (!lex) - lex = Catalogue::Find(SCLEX_NULL); - SetLexerModule(lex); +LexState *ScintillaBase::DocumentLexState() { + if (!pdoc->GetLexInterface()) { + pdoc->SetLexInterface(std::make_unique(pdoc)); } -} - -void LexState::SetLexerLanguage(const char *languageName) { - const LexerModule *lex = Catalogue::Find(languageName); - if (!lex) - lex = Catalogue::Find(SCLEX_NULL); - if (lex) - lexLanguage = lex->GetLanguage(); - SetLexerModule(lex); + return dynamic_cast(pdoc->GetLexInterface()); } const char *LexState::DescribeWordListSets() { @@ -674,20 +640,22 @@ void LexState::SetWordList(int n, const char *wl) { } } -const char *LexState::GetName() const { - if (lexCurrent) { - return lexCurrent->languageName; +int LexState::GetIdentifier() const { + if (instance) { + return instance->GetIdentifier(); } + return 0; +} + +const char *LexState::GetName() const { if (instance) { - if (instance->Version() >= lvIdentity) { - return static_cast(instance)->GetName(); - } + return instance->GetName(); } return ""; } void *LexState::PrivateCall(int operation, void *pointer) { - if (pdoc && instance) { + if (instance) { return instance->PrivateCall(operation, pointer); } else { return nullptr; @@ -702,11 +670,11 @@ const char *LexState::PropertyNames() { } } -int LexState::PropertyType(const char *name) { +TypeProperty LexState::PropertyType(const char *name) { if (instance) { - return instance->PropertyType(name); + return static_cast(instance->PropertyType(name)); } else { - return SC_TYPE_BOOLEAN; + return TypeProperty::Boolean; } } @@ -719,7 +687,6 @@ const char *LexState::DescribeProperty(const char *name) { } void LexState::PropSet(const char *key, const char *val) { - props.Set(key, val, strlen(key), strlen(val)); if (instance) { const Sci_Position firstModification = instance->PropertySet(key, val); if (firstModification >= 0) { @@ -729,123 +696,139 @@ void LexState::PropSet(const char *key, const char *val) { } const char *LexState::PropGet(const char *key) const { - return props.Get(key); + if (instance) { + return instance->PropertyGet(key); + } else { + return nullptr; + } } int LexState::PropGetInt(const char *key, int defaultValue) const { - return props.GetInt(key, defaultValue); + if (instance) { + const char *value = instance->PropertyGet(key); + if (value && *value) { + return atoi(value); + } + } + return defaultValue; } size_t LexState::PropGetExpanded(const char *key, char *result) const { - return props.GetExpanded(key, result); + if (instance) { + const char *value = instance->PropertyGet(key); + if (value) { + if (result) { + strcpy(result, value); + } + return strlen(value); + } + } + return 0; } -int LexState::LineEndTypesSupported() { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->LineEndTypesSupported(); +LineEndType LexState::LineEndTypesSupported() { + if (instance) { + return static_cast(instance->LineEndTypesSupported()); } - return 0; + return LineEndType::Default; } int LexState::AllocateSubStyles(int styleBase, int numberStyles) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->AllocateSubStyles(styleBase, numberStyles); + if (instance) { + return instance->AllocateSubStyles(styleBase, numberStyles); } return -1; } int LexState::SubStylesStart(int styleBase) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->SubStylesStart(styleBase); + if (instance) { + return instance->SubStylesStart(styleBase); } return -1; } int LexState::SubStylesLength(int styleBase) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->SubStylesLength(styleBase); + if (instance) { + return instance->SubStylesLength(styleBase); } return 0; } int LexState::StyleFromSubStyle(int subStyle) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->StyleFromSubStyle(subStyle); + if (instance) { + return instance->StyleFromSubStyle(subStyle); } return 0; } int LexState::PrimaryStyleFromStyle(int style) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->PrimaryStyleFromStyle(style); + if (instance) { + return instance->PrimaryStyleFromStyle(style); } return 0; } void LexState::FreeSubStyles() { - if (instance && (interfaceVersion >= lvSubStyles)) { - static_cast(instance)->FreeSubStyles(); + if (instance) { + instance->FreeSubStyles(); } } void LexState::SetIdentifiers(int style, const char *identifiers) { - if (instance && (interfaceVersion >= lvSubStyles)) { - static_cast(instance)->SetIdentifiers(style, identifiers); + if (instance) { + instance->SetIdentifiers(style, identifiers); pdoc->ModifiedAt(0); } } int LexState::DistanceToSecondaryStyles() { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->DistanceToSecondaryStyles(); + if (instance) { + return instance->DistanceToSecondaryStyles(); } return 0; } const char *LexState::GetSubStyleBases() { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->GetSubStyleBases(); + if (instance) { + return instance->GetSubStyleBases(); } return ""; } int LexState::NamedStyles() { - if (instance && (interfaceVersion >= lvMetaData)) { - return static_cast(instance)->NamedStyles(); + if (instance) { + return instance->NamedStyles(); } else { return -1; } } const char *LexState::NameOfStyle(int style) { - if (instance && (interfaceVersion >= lvMetaData)) { - return static_cast(instance)->NameOfStyle(style); + if (instance) { + return instance->NameOfStyle(style); } else { return nullptr; } } const char *LexState::TagsOfStyle(int style) { - if (instance && (interfaceVersion >= lvMetaData)) { - return static_cast(instance)->TagsOfStyle(style); + if (instance) { + return instance->TagsOfStyle(style); } else { return nullptr; } } const char *LexState::DescriptionOfStyle(int style) { - if (instance && (interfaceVersion >= lvMetaData)) { - return static_cast(instance)->DescriptionOfStyle(style); + if (instance) { + return instance->DescriptionOfStyle(style); } else { return nullptr; } } -#endif - void ScintillaBase::NotifyStyleToNeeded(Sci::Position endStyleNeeded) { -#ifdef SCI_LEXER - if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) { + if (!DocumentLexState()->UseContainerLexing()) { const Sci::Line lineEndStyled = pdoc->SciLineFromPosition(pdoc->GetEndStyled()); const Sci::Position endStyled = @@ -853,331 +836,324 @@ void ScintillaBase::NotifyStyleToNeeded(Sci::Position endStyleNeeded) { DocumentLexState()->Colourise(endStyled, endStyleNeeded); return; } -#endif Editor::NotifyStyleToNeeded(endStyleNeeded); } void ScintillaBase::NotifyLexerChanged(Document *, void *) { -#ifdef SCI_LEXER vs.EnsureStyle(0xff); -#endif } -sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { +sptr_t ScintillaBase::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { switch (iMessage) { - case SCI_AUTOCSHOW: + case Message::AutoCShow: listType = 0; - AutoCompleteStart(static_cast(wParam), ConstCharPtrFromSPtr(lParam)); + AutoCompleteStart(PositionFromUPtr(wParam), ConstCharPtrFromSPtr(lParam)); break; - case SCI_AUTOCCANCEL: + case Message::AutoCCancel: ac.Cancel(); break; - case SCI_AUTOCACTIVE: + case Message::AutoCActive: return ac.Active(); - case SCI_AUTOCPOSSTART: + case Message::AutoCPosStart: return ac.posStart; - case SCI_AUTOCCOMPLETE: - AutoCompleteCompleted(0, SC_AC_COMMAND); + case Message::AutoCComplete: + AutoCompleteCompleted(0, CompletionMethods::Command); break; - case SCI_AUTOCSETSEPARATOR: + case Message::AutoCSetSeparator: ac.SetSeparator(static_cast(wParam)); break; - case SCI_AUTOCGETSEPARATOR: + case Message::AutoCGetSeparator: return ac.GetSeparator(); - case SCI_AUTOCSTOPS: + case Message::AutoCStops: ac.SetStopChars(ConstCharPtrFromSPtr(lParam)); break; - case SCI_AUTOCSELECT: + case Message::AutoCSelect: ac.Select(ConstCharPtrFromSPtr(lParam)); break; - case SCI_AUTOCGETCURRENT: + case Message::AutoCGetCurrent: return AutoCompleteGetCurrent(); - case SCI_AUTOCGETCURRENTTEXT: + case Message::AutoCGetCurrentText: return AutoCompleteGetCurrentText(CharPtrFromSPtr(lParam)); - case SCI_AUTOCSETCANCELATSTART: + case Message::AutoCSetCancelAtStart: ac.cancelAtStartPos = wParam != 0; break; - case SCI_AUTOCGETCANCELATSTART: + case Message::AutoCGetCancelAtStart: return ac.cancelAtStartPos; - case SCI_AUTOCSETFILLUPS: + case Message::AutoCSetFillUps: ac.SetFillUpChars(ConstCharPtrFromSPtr(lParam)); break; - case SCI_AUTOCSETCHOOSESINGLE: + case Message::AutoCSetChooseSingle: ac.chooseSingle = wParam != 0; break; - case SCI_AUTOCGETCHOOSESINGLE: + case Message::AutoCGetChooseSingle: return ac.chooseSingle; - case SCI_AUTOCSETIGNORECASE: + case Message::AutoCSetIgnoreCase: ac.ignoreCase = wParam != 0; break; - case SCI_AUTOCGETIGNORECASE: + case Message::AutoCGetIgnoreCase: return ac.ignoreCase; - case SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR: - ac.ignoreCaseBehaviour = static_cast(wParam); + case Message::AutoCSetCaseInsensitiveBehaviour: + ac.ignoreCaseBehaviour = static_cast(wParam); break; - case SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR: - return ac.ignoreCaseBehaviour; + case Message::AutoCGetCaseInsensitiveBehaviour: + return static_cast(ac.ignoreCaseBehaviour); - case SCI_AUTOCSETMULTI: - multiAutoCMode = static_cast(wParam); + case Message::AutoCSetMulti: + multiAutoCMode = static_cast(wParam); break; - case SCI_AUTOCGETMULTI: - return multiAutoCMode; + case Message::AutoCGetMulti: + return static_cast(multiAutoCMode); - case SCI_AUTOCSETORDER: - ac.autoSort = static_cast(wParam); + case Message::AutoCSetOrder: + ac.autoSort = static_cast(wParam); break; - case SCI_AUTOCGETORDER: - return ac.autoSort; + case Message::AutoCGetOrder: + return static_cast(ac.autoSort); - case SCI_USERLISTSHOW: + case Message::UserListShow: listType = static_cast(wParam); AutoCompleteStart(0, ConstCharPtrFromSPtr(lParam)); break; - case SCI_AUTOCSETAUTOHIDE: + case Message::AutoCSetAutoHide: ac.autoHide = wParam != 0; break; - case SCI_AUTOCGETAUTOHIDE: + case Message::AutoCGetAutoHide: return ac.autoHide; - case SCI_AUTOCSETDROPRESTOFWORD: + case Message::AutoCSetOptions: + ac.options = static_cast(wParam); + break; + + case Message::AutoCGetOptions: + return static_cast(ac.options); + + case Message::AutoCSetDropRestOfWord: ac.dropRestOfWord = wParam != 0; break; - case SCI_AUTOCGETDROPRESTOFWORD: + case Message::AutoCGetDropRestOfWord: return ac.dropRestOfWord; - case SCI_AUTOCSETMAXHEIGHT: + case Message::AutoCSetMaxHeight: ac.lb->SetVisibleRows(static_cast(wParam)); break; - case SCI_AUTOCGETMAXHEIGHT: + case Message::AutoCGetMaxHeight: return ac.lb->GetVisibleRows(); - case SCI_AUTOCSETMAXWIDTH: + case Message::AutoCSetMaxWidth: maxListWidth = static_cast(wParam); break; - case SCI_AUTOCGETMAXWIDTH: + case Message::AutoCGetMaxWidth: return maxListWidth; - case SCI_REGISTERIMAGE: + case Message::RegisterImage: ac.lb->RegisterImage(static_cast(wParam), ConstCharPtrFromSPtr(lParam)); break; - case SCI_REGISTERRGBAIMAGE: + case Message::RegisterRGBAImage: ac.lb->RegisterRGBAImage(static_cast(wParam), static_cast(sizeRGBAImage.x), static_cast(sizeRGBAImage.y), ConstUCharPtrFromSPtr(lParam)); break; - case SCI_CLEARREGISTEREDIMAGES: + case Message::ClearRegisteredImages: ac.lb->ClearRegisteredImages(); break; - case SCI_AUTOCSETTYPESEPARATOR: + case Message::AutoCSetTypeSeparator: ac.SetTypesep(static_cast(wParam)); break; - case SCI_AUTOCGETTYPESEPARATOR: + case Message::AutoCGetTypeSeparator: return ac.GetTypesep(); - case SCI_CALLTIPSHOW: + case Message::CallTipShow: CallTipShow(LocationFromPosition(wParam), ConstCharPtrFromSPtr(lParam)); break; - case SCI_CALLTIPCANCEL: + case Message::CallTipCancel: ct.CallTipCancel(); break; - case SCI_CALLTIPACTIVE: + case Message::CallTipActive: return ct.inCallTipMode; - case SCI_CALLTIPPOSSTART: + case Message::CallTipPosStart: return ct.posStartCallTip; - case SCI_CALLTIPSETPOSSTART: + case Message::CallTipSetPosStart: ct.posStartCallTip = wParam; break; - case SCI_CALLTIPSETHLT: + case Message::CallTipSetHlt: ct.SetHighlight(wParam, lParam); break; - case SCI_CALLTIPSETBACK: - ct.colourBG = ColourDesired(static_cast(wParam)); - vs.styles[STYLE_CALLTIP].back = ct.colourBG; + case Message::CallTipSetBack: + ct.colourBG = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam)); + vs.styles[StyleCallTip].back = ct.colourBG; InvalidateStyleRedraw(); break; - case SCI_CALLTIPSETFORE: - ct.colourUnSel = ColourDesired(static_cast(wParam)); - vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel; + case Message::CallTipSetFore: + ct.colourUnSel = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam)); + vs.styles[StyleCallTip].fore = ct.colourUnSel; InvalidateStyleRedraw(); break; - case SCI_CALLTIPSETFOREHLT: - ct.colourSel = ColourDesired(static_cast(wParam)); + case Message::CallTipSetForeHlt: + ct.colourSel = ColourRGBA::FromIpRGB(SPtrFromUPtr(wParam)); InvalidateStyleRedraw(); break; - case SCI_CALLTIPUSESTYLE: + case Message::CallTipUseStyle: ct.SetTabSize(static_cast(wParam)); InvalidateStyleRedraw(); break; - case SCI_CALLTIPSETPOSITION: + case Message::CallTipSetPosition: ct.SetPosition(wParam != 0); InvalidateStyleRedraw(); break; - case SCI_USEPOPUP: - displayPopupMenu = static_cast(wParam); + case Message::UsePopUp: + displayPopupMenu = static_cast(wParam); break; -#ifdef SCI_LEXER - case SCI_SETLEXER: - DocumentLexState()->SetLexer(static_cast(wParam)); - break; + case Message::GetLexer: + return DocumentLexState()->GetIdentifier(); - case SCI_GETLEXER: - return DocumentLexState()->lexLanguage; + case Message::SetILexer: + DocumentLexState()->SetInstance(static_cast(PtrFromSPtr(lParam))); + return 0; - case SCI_COLOURISE: - if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) { - pdoc->ModifiedAt(static_cast(wParam)); + case Message::Colourise: + if (DocumentLexState()->UseContainerLexing()) { + pdoc->ModifiedAt(PositionFromUPtr(wParam)); NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam); } else { - DocumentLexState()->Colourise(static_cast(wParam), lParam); + DocumentLexState()->Colourise(PositionFromUPtr(wParam), lParam); } Redraw(); break; - case SCI_SETPROPERTY: + case Message::SetProperty: DocumentLexState()->PropSet(ConstCharPtrFromUPtr(wParam), ConstCharPtrFromSPtr(lParam)); break; - case SCI_GETPROPERTY: + case Message::GetProperty: return StringResult(lParam, DocumentLexState()->PropGet(ConstCharPtrFromUPtr(wParam))); - case SCI_GETPROPERTYEXPANDED: + case Message::GetPropertyExpanded: return DocumentLexState()->PropGetExpanded(ConstCharPtrFromUPtr(wParam), CharPtrFromSPtr(lParam)); - case SCI_GETPROPERTYINT: + case Message::GetPropertyInt: return DocumentLexState()->PropGetInt(ConstCharPtrFromUPtr(wParam), static_cast(lParam)); - case SCI_SETKEYWORDS: + case Message::SetKeyWords: DocumentLexState()->SetWordList(static_cast(wParam), ConstCharPtrFromSPtr(lParam)); break; - case SCI_SETLEXERLANGUAGE: - DocumentLexState()->SetLexerLanguage(ConstCharPtrFromSPtr(lParam)); - break; - - case SCI_GETLEXERLANGUAGE: + case Message::GetLexerLanguage: return StringResult(lParam, DocumentLexState()->GetName()); - case SCI_LOADLEXERLIBRARY: - ExternalLexerLoad(ConstCharPtrFromSPtr(lParam)); - break; - - case SCI_PRIVATELEXERCALL: + case Message::PrivateLexerCall: return reinterpret_cast( - DocumentLexState()->PrivateCall(static_cast(wParam), reinterpret_cast(lParam))); + DocumentLexState()->PrivateCall(static_cast(wParam), PtrFromSPtr(lParam))); #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_GETSTYLEBITSNEEDED: return 8; #endif - case SCI_PROPERTYNAMES: + case Message::PropertyNames: return StringResult(lParam, DocumentLexState()->PropertyNames()); - case SCI_PROPERTYTYPE: - return DocumentLexState()->PropertyType(ConstCharPtrFromUPtr(wParam)); + case Message::PropertyType: + return static_cast(DocumentLexState()->PropertyType(ConstCharPtrFromUPtr(wParam))); - case SCI_DESCRIBEPROPERTY: + case Message::DescribeProperty: return StringResult(lParam, DocumentLexState()->DescribeProperty(ConstCharPtrFromUPtr(wParam))); - case SCI_DESCRIBEKEYWORDSETS: + case Message::DescribeKeyWordSets: return StringResult(lParam, DocumentLexState()->DescribeWordListSets()); - case SCI_GETLINEENDTYPESSUPPORTED: - return DocumentLexState()->LineEndTypesSupported(); + case Message::GetLineEndTypesSupported: + return static_cast(DocumentLexState()->LineEndTypesSupported()); - case SCI_ALLOCATESUBSTYLES: + case Message::AllocateSubStyles: return DocumentLexState()->AllocateSubStyles(static_cast(wParam), static_cast(lParam)); - case SCI_GETSUBSTYLESSTART: + case Message::GetSubStylesStart: return DocumentLexState()->SubStylesStart(static_cast(wParam)); - case SCI_GETSUBSTYLESLENGTH: + case Message::GetSubStylesLength: return DocumentLexState()->SubStylesLength(static_cast(wParam)); - case SCI_GETSTYLEFROMSUBSTYLE: + case Message::GetStyleFromSubStyle: return DocumentLexState()->StyleFromSubStyle(static_cast(wParam)); - case SCI_GETPRIMARYSTYLEFROMSTYLE: + case Message::GetPrimaryStyleFromStyle: return DocumentLexState()->PrimaryStyleFromStyle(static_cast(wParam)); - case SCI_FREESUBSTYLES: + case Message::FreeSubStyles: DocumentLexState()->FreeSubStyles(); break; - case SCI_SETIDENTIFIERS: + case Message::SetIdentifiers: DocumentLexState()->SetIdentifiers(static_cast(wParam), ConstCharPtrFromSPtr(lParam)); break; - case SCI_DISTANCETOSECONDARYSTYLES: + case Message::DistanceToSecondaryStyles: return DocumentLexState()->DistanceToSecondaryStyles(); - case SCI_GETSUBSTYLEBASES: + case Message::GetSubStyleBases: return StringResult(lParam, DocumentLexState()->GetSubStyleBases()); - case SCI_GETNAMEDSTYLES: + case Message::GetNamedStyles: return DocumentLexState()->NamedStyles(); - case SCI_NAMEOFSTYLE: + case Message::NameOfStyle: return StringResult(lParam, DocumentLexState()-> NameOfStyle(static_cast(wParam))); - case SCI_TAGSOFSTYLE: + case Message::TagsOfStyle: return StringResult(lParam, DocumentLexState()-> TagsOfStyle(static_cast(wParam))); - case SCI_DESCRIPTIONOFSTYLE: + case Message::DescriptionOfStyle: return StringResult(lParam, DocumentLexState()-> DescriptionOfStyle(static_cast(wParam))); -#endif - default: return Editor::WndProc(iMessage, wParam, lParam); } diff --git a/scintilla/src/ScintillaBase.h b/scintilla/src/ScintillaBase.h index a558922bc5..47e24796d3 100644 --- a/scintilla/src/ScintillaBase.h +++ b/scintilla/src/ScintillaBase.h @@ -8,12 +8,9 @@ #ifndef SCINTILLABASE_H #define SCINTILLABASE_H -namespace Scintilla { +namespace Scintilla::Internal { -#ifdef SCI_LEXER class LexState; -#endif - /** */ class ScintillaBase : public Editor, IListBoxDelegate { @@ -32,24 +29,18 @@ class ScintillaBase : public Editor, IListBoxDelegate { idcmdSelectAll=16 }; - enum { maxLenInputIME = 200 }; - - int displayPopupMenu; + Scintilla::PopUp displayPopupMenu; Menu popup; - AutoComplete ac; + Scintilla::Internal::AutoComplete ac; CallTip ct; int listType; ///< 0 is an autocomplete list int maxListWidth; /// Maximum width of list, in average character widths - int multiAutoCMode; /// Mode for autocompleting when multiple selections are present + Scintilla::MultiAutoComplete multiAutoCMode; /// Mode for autocompleting when multiple selections are present -#if SCI_LEXER LexState *DocumentLexState(); - void SetLexer(uptr_t wParam); - void SetLexerLanguage(const char *languageName); void Colourise(int start, int end); -#endif ScintillaBase(); // Deleted so ScintillaBase objects can not be copied. @@ -61,13 +52,10 @@ class ScintillaBase : public Editor, IListBoxDelegate { void Initialise() override {} void Finalise() override; - // This method is deprecated, use InsertCharacter instead. The treatAsDBCS parameter is no longer used. - virtual void AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS=false); - - void InsertCharacter(const char *s, unsigned int len, CharacterSource charSource) override; + void InsertCharacter(std::string_view sv, Scintilla::CharacterSource charSource) override; void Command(int cmdId); void CancelModes() override; - int KeyCommand(unsigned int iMessage) override; + int KeyCommand(Scintilla::Message iMessage) override; void AutoCompleteInsert(Sci::Position startPos, Sci::Position removeLen, const char *text, Sci::Position textLen); void AutoCompleteStart(Sci::Position lenEntered, const char *list); @@ -77,7 +65,7 @@ class ScintillaBase : public Editor, IListBoxDelegate { int AutoCompleteGetCurrentText(char *buffer) const; void AutoCompleteCharacterAdded(char ch); void AutoCompleteCharacterDeleted(); - void AutoCompleteCompleted(char ch, unsigned int completionMethod); + void AutoCompleteCompleted(char ch, Scintilla::CompletionMethods completionMethod); void AutoCompleteMoveToCurrentWord(); void AutoCompleteSelection(); void ListNotify(ListBoxEvent *plbe) override; @@ -90,8 +78,8 @@ class ScintillaBase : public Editor, IListBoxDelegate { bool ShouldDisplayPopup(Point ptInWindowCoordinates) const; void ContextMenu(Point pt); - void ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) override; - void RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) override; + void ButtonDownWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers) override; + void RightButtonDownWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers) override; void NotifyStyleToNeeded(Sci::Position endStyleNeeded) override; void NotifyLexerChanged(Document *doc, void *userData) override; @@ -100,7 +88,7 @@ class ScintillaBase : public Editor, IListBoxDelegate { ~ScintillaBase() override; // Public so scintilla_send_message can use it - sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) override; + Scintilla::sptr_t WndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) override; }; } diff --git a/scintilla/src/Selection.cxx b/scintilla/src/Selection.cxx index 95caf74b16..9cf4e6f09d 100644 --- a/scintilla/src/Selection.cxx +++ b/scintilla/src/Selection.cxx @@ -9,18 +9,18 @@ #include #include +#include #include +#include #include #include -#include "Platform.h" - -#include "Scintilla.h" +#include "Debugging.h" #include "Position.h" #include "Selection.h" -using namespace Scintilla; +using namespace Scintilla::Internal; void SelectionPosition::MoveForInsertDelete(bool insertion, Sci::Position startChange, Sci::Position length, bool moveForEqual) noexcept { if (insertion) { @@ -190,7 +190,7 @@ void SelectionRange::MinimizeVirtualSpace() noexcept { } } -Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) { +Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(SelTypes::stream) { AddSelection(SelectionRange(SelectionPosition(0))); } @@ -198,7 +198,7 @@ Selection::~Selection() { } bool Selection::IsRectangular() const noexcept { - return (selType == selRectangle) || (selType == selThin); + return (selType == SelTypes::rectangle) || (selType == SelTypes::thin); } Sci::Position Selection::MainCaret() const noexcept { @@ -310,7 +310,7 @@ void Selection::MovePositions(bool insertion, Sci::Position startChange, Sci::Po for (SelectionRange &range : ranges) { range.MoveForInsertDelete(insertion, startChange, length); } - if (selType == selRectangle) { + if (selType == SelTypes::rectangle) { rangeRectangular.MoveForInsertDelete(insertion, startChange, length); } } @@ -390,20 +390,24 @@ void Selection::CommitTentative() noexcept { tentativeMain = false; } -int Selection::CharacterInSelection(Sci::Position posCharacter) const noexcept { +InSelection Selection::RangeType(size_t r) const noexcept { + return r == Main() ? InSelection::inMain : InSelection::inAdditional; +} + +InSelection Selection::CharacterInSelection(Sci::Position posCharacter) const noexcept { for (size_t i=0; i ranges[i].Start().Position()) && (pos <= ranges[i].End().Position())) - return i == mainRange ? 1 : 2; + return RangeType(i); } - return 0; + return InSelection::inNone; } Sci::Position Selection::VirtualSpaceFor(Sci::Position pos) const noexcept { @@ -421,7 +425,7 @@ void Selection::Clear() { ranges.clear(); ranges.emplace_back(); mainRange = ranges.size() - 1; - selType = selStream; + selType = SelTypes::stream; moveExtends = false; ranges[mainRange].Reset(); rangeRectangular.Reset(); diff --git a/scintilla/src/Selection.h b/scintilla/src/Selection.h index c5c7993cff..7912d03e52 100644 --- a/scintilla/src/Selection.h +++ b/scintilla/src/Selection.h @@ -8,13 +8,13 @@ #ifndef SELECTION_H #define SELECTION_H -namespace Scintilla { +namespace Scintilla::Internal { class SelectionPosition { Sci::Position position; Sci::Position virtualSpace; public: - explicit SelectionPosition(Sci::Position position_=INVALID_POSITION, Sci::Position virtualSpace_=0) noexcept : position(position_), virtualSpace(virtualSpace_) { + explicit SelectionPosition(Sci::Position position_= Sci::invalidPosition, Sci::Position virtualSpace_=0) noexcept : position(position_), virtualSpace(virtualSpace_) { PLATFORM_ASSERT(virtualSpace < 800000); if (virtualSpace < 0) virtualSpace = 0; @@ -133,6 +133,9 @@ struct SelectionRange { void MinimizeVirtualSpace() noexcept; }; +// Deliberately an enum rather than an enum class to allow treating as bool +enum InSelection { inNone, inMain, inAdditional }; + class Selection { std::vector ranges; std::vector rangesSaved; @@ -141,8 +144,8 @@ class Selection { bool moveExtends; bool tentativeMain; public: - enum selTypes { noSel, selStream, selRectangle, selLines, selThin }; - selTypes selType; + enum class SelTypes { none, stream, rectangle, lines, thin }; + SelTypes selType; Selection(); ~Selection(); @@ -178,8 +181,9 @@ class Selection { void DropAdditionalRanges(); void TentativeSelection(SelectionRange range); void CommitTentative() noexcept; - int CharacterInSelection(Sci::Position posCharacter) const noexcept; - int InSelectionForEOL(Sci::Position pos) const noexcept; + InSelection RangeType(size_t r) const noexcept; + InSelection CharacterInSelection(Sci::Position posCharacter) const noexcept; + InSelection InSelectionForEOL(Sci::Position pos) const noexcept; Sci::Position VirtualSpaceFor(Sci::Position pos) const noexcept; void Clear(); void RemoveDuplicates(); diff --git a/scintilla/src/SparseVector.h b/scintilla/src/SparseVector.h index e6f59e9dcc..31636165a0 100644 --- a/scintilla/src/SparseVector.h +++ b/scintilla/src/SparseVector.h @@ -8,7 +8,7 @@ #ifndef SPARSEVECTOR_H #define SPARSEVECTOR_H -namespace Scintilla { +namespace Scintilla::Internal { // SparseVector is similar to RunStyles but is more efficient for cases where values occur // for one position instead of over a range of positions. @@ -27,8 +27,8 @@ class SparseVector { } public: SparseVector() : empty() { - starts = Sci::make_unique>(8); - values = Sci::make_unique>(); + starts = std::make_unique>(8); + values = std::make_unique>(); values->InsertEmpty(0, 2); } // Deleted so SparseVector objects can not be copied. diff --git a/scintilla/src/SplitVector.h b/scintilla/src/SplitVector.h index e805c50dc5..d233a50edb 100644 --- a/scintilla/src/SplitVector.h +++ b/scintilla/src/SplitVector.h @@ -9,7 +9,7 @@ #ifndef SPLITVECTOR_H #define SPLITVECTOR_H -namespace Scintilla { +namespace Scintilla::Internal { template class SplitVector { @@ -26,27 +26,34 @@ class SplitVector { /// hence be fast. void GapTo(ptrdiff_t position) noexcept { if (position != part1Length) { - if (position < part1Length) { - // Moving the gap towards start so moving elements towards end - std::move_backward( - body.data() + position, - body.data() + part1Length, - body.data() + gapLength + part1Length); - } else { // position > part1Length - // Moving the gap towards end so moving elements towards start - std::move( - body.data() + part1Length + gapLength, - body.data() + gapLength + position, - body.data() + part1Length); + try { + if (gapLength > 0) { // If gap to move + // This can never fail but std::move and std::move_backward are not noexcept. + if (position < part1Length) { + // Moving the gap towards start so moving elements towards end + std::move_backward( + body.data() + position, + body.data() + part1Length, + body.data() + gapLength + part1Length); + } else { // position > part1Length + // Moving the gap towards end so moving elements towards start + std::move( + body.data() + part1Length + gapLength, + body.data() + gapLength + position, + body.data() + part1Length); + } + } + part1Length = position; + } catch (...) { + // Ignore any exception } - part1Length = position; } } /// Check that there is room in the buffer for an insertion, /// reallocating if more space needed. void RoomFor(ptrdiff_t insertionLength) { - if (gapLength <= insertionLength) { + if (gapLength < insertionLength) { while (growSize < static_cast(body.size() / 6)) growSize *= 2; ReAllocate(body.size() + insertionLength + growSize); @@ -280,7 +287,7 @@ class SplitVector { } /// Retrieve a range of elements into an array - void GetRange(T *buffer, ptrdiff_t position, ptrdiff_t retrieveLength) const noexcept { + void GetRange(T *buffer, ptrdiff_t position, ptrdiff_t retrieveLength) const { // Split into up to 2 ranges, before and after the split then use memcpy on each. ptrdiff_t range1Length = 0; if (position < part1Length) { @@ -323,6 +330,16 @@ class SplitVector { } } + /// Return a pointer to a single element. + /// Does not rearrange the buffer. + const T *ElementPointer(ptrdiff_t position) const noexcept { + if (position < part1Length) { + return body.data() + position; + } else { + return body.data() + position + gapLength; + } + } + /// Return the position of the gap within the buffer. ptrdiff_t GapPosition() const noexcept { return part1Length; diff --git a/scintilla/src/Style.cxx b/scintilla/src/Style.cxx index d3668be6d2..d71b62d978 100644 --- a/scintilla/src/Style.cxx +++ b/scintilla/src/Style.cxx @@ -6,35 +6,21 @@ // The License.txt file describes the conditions under which this software may be distributed. #include +#include #include +#include #include +#include "ScintillaTypes.h" + +#include "Debugging.h" +#include "Geometry.h" #include "Platform.h" -#include "Scintilla.h" #include "Style.h" using namespace Scintilla; - -FontAlias::FontAlias() noexcept { -} - -FontAlias::FontAlias(const FontAlias &other) noexcept : Font() { - SetID(other.fid); -} - -FontAlias::~FontAlias() { - SetID(FontID{}); - // ~Font will not release the actual font resource since it is now 0 -} - -void FontAlias::MakeAlias(const Font &fontOrigin) noexcept { - SetID(fontOrigin.GetID()); -} - -void FontAlias::ClearFont() noexcept { - SetID(FontID{}); -} +using namespace Scintilla::Internal; bool FontSpecification::operator==(const FontSpecification &other) const noexcept { return fontName == other.fontName && @@ -51,7 +37,7 @@ bool FontSpecification::operator<(const FontSpecification &other) const noexcept if (weight != other.weight) return weight < other.weight; if (italic != other.italic) - return italic == false; + return !italic; if (size != other.size) return size < other.size; if (characterSet != other.characterSet) @@ -75,15 +61,15 @@ void FontMeasurements::ClearMeasurements() noexcept { } Style::Style() : FontSpecification() { - Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), - Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, nullptr, SC_CHARSET_DEFAULT, - SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); + Clear(ColourRGBA(0, 0, 0), ColourRGBA(0xff, 0xff, 0xff), + Platform::DefaultFontSize() * FontSizeMultiplier, nullptr, CharacterSet::Default, + FontWeight::Normal, false, false, false, CaseForce::mixed, true, true, false); } Style::Style(const Style &source) noexcept : FontSpecification(), FontMeasurements() { - Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), - 0, nullptr, 0, - SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); + Clear(ColourRGBA(0, 0, 0), ColourRGBA(0xff, 0xff, 0xff), + 0, nullptr, CharacterSet::Ansi, + FontWeight::Normal, false, false, false, CaseForce::mixed, true, true, false); fore = source.fore; back = source.back; characterSet = source.characterSet; @@ -99,15 +85,14 @@ Style::Style(const Style &source) noexcept : FontSpecification(), FontMeasuremen hotspot = source.hotspot; } -Style::~Style() { -} +Style::~Style() = default; Style &Style::operator=(const Style &source) noexcept { if (this == &source) return * this; - Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), - 0, nullptr, SC_CHARSET_DEFAULT, - SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); + Clear(ColourRGBA(0, 0, 0), ColourRGBA(0xff, 0xff, 0xff), + 0, nullptr, CharacterSet::Default, + FontWeight::Normal, false, false, false, CaseForce::mixed, true, true, false); fore = source.fore; back = source.back; characterSet = source.characterSet; @@ -123,10 +108,10 @@ Style &Style::operator=(const Style &source) noexcept { return *this; } -void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_, - const char *fontName_, int characterSet_, - int weight_, bool italic_, bool eolFilled_, - bool underline_, ecaseForced caseForce_, +void Style::Clear(ColourRGBA fore_, ColourRGBA back_, int size_, + const char *fontName_, CharacterSet characterSet_, + FontWeight weight_, bool italic_, bool eolFilled_, + bool underline_, CaseForce caseForce_, bool visible_, bool changeable_, bool hotspot_) noexcept { fore = fore_; back = back_; @@ -141,7 +126,7 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_, visible = visible_; changeable = changeable_; hotspot = hotspot_; - font.ClearFont(); + font.reset(); FontMeasurements::ClearMeasurements(); } @@ -162,7 +147,7 @@ void Style::ClearTo(const Style &source) noexcept { source.hotspot); } -void Style::Copy(const Font &font_, const FontMeasurements &fm_) noexcept { - font.MakeAlias(font_); +void Style::Copy(std::shared_ptr font_, const FontMeasurements &fm_) noexcept { + font = std::move(font_); (FontMeasurements &)(*this) = fm_; } diff --git a/scintilla/src/Style.h b/scintilla/src/Style.h index 95ec3fa22f..8153d156e6 100644 --- a/scintilla/src/Style.h +++ b/scintilla/src/Style.h @@ -8,41 +8,27 @@ #ifndef STYLE_H #define STYLE_H -namespace Scintilla { +namespace Scintilla::Internal { struct FontSpecification { const char *fontName; - int weight; + Scintilla::FontWeight weight; bool italic; int size; - int characterSet; - int extraFontFlag; + Scintilla::CharacterSet characterSet; + Scintilla::FontQuality extraFontFlag; FontSpecification() noexcept : fontName(nullptr), - weight(SC_WEIGHT_NORMAL), + weight(Scintilla::FontWeight::Normal), italic(false), - size(10 * SC_FONT_SIZE_MULTIPLIER), - characterSet(0), - extraFontFlag(0) { + size(10 * Scintilla::FontSizeMultiplier), + characterSet(Scintilla::CharacterSet::Ansi), + extraFontFlag(Scintilla::FontQuality::QualityDefault) { } bool operator==(const FontSpecification &other) const noexcept; bool operator<(const FontSpecification &other) const noexcept; }; -// Just like Font but only has a copy of the FontID so should not delete it -class FontAlias : public Font { -public: - FontAlias() noexcept; - // FontAlias objects can not be assigned except for initialization - FontAlias(const FontAlias &) noexcept; - FontAlias(FontAlias &&) = delete; - FontAlias &operator=(const FontAlias &) = delete; - FontAlias &operator=(FontAlias &&) = delete; - ~FontAlias() override; - void MakeAlias(const Font &fontOrigin) noexcept; - void ClearFont() noexcept; -}; - struct FontMeasurements { unsigned int ascent; unsigned int descent; @@ -58,33 +44,32 @@ struct FontMeasurements { */ class Style : public FontSpecification, public FontMeasurements { public: - ColourDesired fore; - ColourDesired back; + ColourRGBA fore; + ColourRGBA back; bool eolFilled; bool underline; - enum ecaseForced {caseMixed, caseUpper, caseLower, caseCamel}; - ecaseForced caseForce; + enum class CaseForce {mixed, upper, lower, camel}; + CaseForce caseForce; bool visible; bool changeable; bool hotspot; - FontAlias font; + std::shared_ptr font; Style(); Style(const Style &source) noexcept; - // Style objects should not be moved but MSVC 2015 requires this. - Style(Style &&) = default; + Style(Style &&) noexcept = default; ~Style(); Style &operator=(const Style &source) noexcept; Style &operator=(Style &&) = delete; - void Clear(ColourDesired fore_, ColourDesired back_, + void Clear(ColourRGBA fore_, ColourRGBA back_, int size_, - const char *fontName_, int characterSet_, - int weight_, bool italic_, bool eolFilled_, - bool underline_, ecaseForced caseForce_, + const char *fontName_, Scintilla::CharacterSet characterSet_, + Scintilla::FontWeight weight_, bool italic_, bool eolFilled_, + bool underline_, CaseForce caseForce_, bool visible_, bool changeable_, bool hotspot_) noexcept; void ClearTo(const Style &source) noexcept; - void Copy(const Font &font_, const FontMeasurements &fm_) noexcept; + void Copy(std::shared_ptr font_, const FontMeasurements &fm_) noexcept; bool IsProtected() const noexcept { return !(changeable && visible);} }; diff --git a/scintilla/src/UniConversion.cxx b/scintilla/src/UniConversion.cxx index 508c33a2c1..91aea6cde5 100644 --- a/scintilla/src/UniConversion.cxx +++ b/scintilla/src/UniConversion.cxx @@ -9,17 +9,16 @@ #include #include +#include #include "UniConversion.h" -using namespace Scintilla; +namespace Scintilla::Internal { -namespace Scintilla { - -size_t UTF8Length(const wchar_t *uptr, size_t tlen) noexcept { +size_t UTF8Length(std::wstring_view wsv) noexcept { size_t len = 0; - for (size_t i = 0; i < tlen && uptr[i];) { - const unsigned int uch = uptr[i]; + for (size_t i = 0; i < wsv.length() && wsv[i];) { + const unsigned int uch = wsv[i]; if (uch < 0x80) { len++; } else if (uch < 0x800) { @@ -36,10 +35,22 @@ size_t UTF8Length(const wchar_t *uptr, size_t tlen) noexcept { return len; } -void UTF8FromUTF16(const wchar_t *uptr, size_t tlen, char *putf, size_t len) noexcept { +size_t UTF8PositionFromUTF16Position(std::string_view u8Text, size_t positionUTF16) noexcept { + size_t positionUTF8 = 0; + for (size_t lengthUTF16 = 0; (positionUTF8 < u8Text.length()) && (lengthUTF16 < positionUTF16);) { + const unsigned char uch = u8Text[positionUTF8]; + const unsigned int byteCount = UTF8BytesOfLead[uch]; + lengthUTF16 += UTF16LengthFromUTF8ByteCount(byteCount); + positionUTF8 += byteCount; + } + + return positionUTF8; +} + +void UTF8FromUTF16(std::wstring_view wsv, char *putf, size_t len) noexcept { size_t k = 0; - for (size_t i = 0; i < tlen && uptr[i];) { - const unsigned int uch = uptr[i]; + for (size_t i = 0; i < wsv.length() && wsv[i];) { + const unsigned int uch = wsv[i]; if (uch < 0x80) { putf[k++] = static_cast(uch); } else if (uch < 0x800) { @@ -49,7 +60,7 @@ void UTF8FromUTF16(const wchar_t *uptr, size_t tlen, char *putf, size_t len) noe (uch <= SURROGATE_TRAIL_LAST)) { // Half a surrogate pair i++; - const unsigned int xch = 0x10000 + ((uch & 0x3ff) << 10) + (uptr[i] & 0x3ff); + const unsigned int xch = 0x10000 + ((uch & 0x3ff) << 10) + (wsv[i] & 0x3ff); putf[k++] = static_cast(0xF0 | (xch >> 18)); putf[k++] = static_cast(0x80 | ((xch >> 12) & 0x3f)); putf[k++] = static_cast(0x80 | ((xch >> 6) & 0x3f)); @@ -85,14 +96,14 @@ void UTF8FromUTF32Character(int uch, char *putf) noexcept { putf[k] = '\0'; } -size_t UTF16Length(const char *s, size_t len) noexcept { +size_t UTF16Length(std::string_view svu8) noexcept { size_t ulen = 0; - for (size_t i = 0; i < len;) { - const unsigned char ch = s[i]; + for (size_t i = 0; i< svu8.length();) { + const unsigned char ch = svu8[i]; const unsigned int byteCount = UTF8BytesOfLead[ch]; const unsigned int utf16Len = UTF16LengthFromUTF8ByteCount(byteCount); i += byteCount; - ulen += (i > len) ? 1 : utf16Len; + ulen += (i > svu8.length()) ? 1 : utf16Len; } return ulen; } @@ -100,20 +111,20 @@ size_t UTF16Length(const char *s, size_t len) noexcept { constexpr unsigned char TrailByteValue(unsigned char c) { // The top 2 bits are 0b10 to indicate a trail byte. // The lower 6 bits contain the value. - return c & 0x3F; + return c & 0b0011'1111; } -size_t UTF16FromUTF8(const char *s, size_t len, wchar_t *tbuf, size_t tlen) { +size_t UTF16FromUTF8(std::string_view svu8, wchar_t *tbuf, size_t tlen) { size_t ui = 0; - for (size_t i = 0; i < len;) { - unsigned char ch = s[i]; + for (size_t i = 0; i < svu8.length();) { + unsigned char ch = svu8[i]; const unsigned int byteCount = UTF8BytesOfLead[ch]; unsigned int value; - if (i + byteCount > len) { + if (i + byteCount > svu8.length()) { // Trying to read past end but still have space to write if (ui < tlen) { - tbuf[ui] = ch; + tbuf[ui] = ch; ui++; } break; @@ -131,26 +142,26 @@ size_t UTF16FromUTF8(const char *s, size_t len, wchar_t *tbuf, size_t tlen) { break; case 2: value = (ch & 0x1F) << 6; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch); tbuf[ui] = static_cast(value); break; case 3: value = (ch & 0xF) << 12; - ch = s[i++]; + ch = svu8[i++]; value += (TrailByteValue(ch) << 6); - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch); tbuf[ui] = static_cast(value); break; default: // Outside the BMP so need two surrogates value = (ch & 0x7) << 18; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch) << 12; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch) << 6; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch); tbuf[ui] = static_cast(((value - 0x10000) >> 10) + SURROGATE_LEAD_FIRST); ui++; @@ -162,10 +173,10 @@ size_t UTF16FromUTF8(const char *s, size_t len, wchar_t *tbuf, size_t tlen) { return ui; } -size_t UTF32Length(const char *s, size_t len) noexcept { +size_t UTF32Length(std::string_view svu8) noexcept { size_t ulen = 0; - for (size_t i = 0; i < len;) { - const unsigned char ch = s[i]; + for (size_t i = 0; i < svu8.length();) { + const unsigned char ch = svu8[i]; const unsigned int byteCount = UTF8BytesOfLead[ch]; i += byteCount; ulen++; @@ -173,14 +184,14 @@ size_t UTF32Length(const char *s, size_t len) noexcept { return ulen; } -size_t UTF32FromUTF8(const char *s, size_t len, unsigned int *tbuf, size_t tlen) { +size_t UTF32FromUTF8(std::string_view svu8, unsigned int *tbuf, size_t tlen) { size_t ui = 0; - for (size_t i = 0; i < len;) { - unsigned char ch = s[i]; + for (size_t i = 0; i < svu8.length();) { + unsigned char ch = svu8[i]; const unsigned int byteCount = UTF8BytesOfLead[ch]; unsigned int value; - if (i + byteCount > len) { + if (i + byteCount > svu8.length()) { // Trying to read past end but still have space to write if (ui < tlen) { tbuf[ui] = ch; @@ -200,23 +211,23 @@ size_t UTF32FromUTF8(const char *s, size_t len, unsigned int *tbuf, size_t tlen) break; case 2: value = (ch & 0x1F) << 6; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch); break; case 3: value = (ch & 0xF) << 12; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch) << 6; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch); break; default: value = (ch & 0x7) << 18; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch) << 12; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch) << 6; - ch = s[i++]; + ch = svu8[i++]; value += TrailByteValue(ch); break; } @@ -226,18 +237,18 @@ size_t UTF32FromUTF8(const char *s, size_t len, unsigned int *tbuf, size_t tlen) return ui; } -std::wstring WStringFromUTF8(const char *s, size_t len) { -#ifdef _WIN32 - const size_t len16 = UTF16Length(s, len); +std::wstring WStringFromUTF8(std::string_view svu8) { + if constexpr (sizeof(wchar_t) == 2) { + const size_t len16 = UTF16Length(svu8); std::wstring ws(len16, 0); - UTF16FromUTF8(s, len, &ws[0], len16); + UTF16FromUTF8(svu8, &ws[0], len16); return ws; -#else - const size_t len32 = UTF32Length(s, len); + } else { + const size_t len32 = UTF32Length(svu8); std::wstring ws(len32, 0); - UTF32FromUTF8(s, len, reinterpret_cast(&ws[0]), len32); + UTF32FromUTF8(svu8, reinterpret_cast(&ws[0]), len32); return ws; -#endif + } } unsigned int UTF16FromUTF32Character(unsigned int val, wchar_t *tbuf) noexcept { @@ -352,9 +363,9 @@ int UTF8DrawBytes(const unsigned char *us, int len) noexcept { return (utf8StatusNext & UTF8MaskInvalid) ? 1 : (utf8StatusNext & UTF8MaskWidth); } -bool UTF8IsValid(const char *s, size_t len) noexcept { - const unsigned char *us = reinterpret_cast(s); - size_t remaining = len; +bool UTF8IsValid(std::string_view svu8) noexcept { + const unsigned char *us = reinterpret_cast(svu8.data()); + size_t remaining = svu8.length(); while (remaining > 0) { const int utf8Status = UTF8Classify(us, remaining); if (utf8Status & UTF8MaskInvalid) { diff --git a/scintilla/src/UniConversion.h b/scintilla/src/UniConversion.h index 871f2c7b08..ead7aae574 100644 --- a/scintilla/src/UniConversion.h +++ b/scintilla/src/UniConversion.h @@ -8,24 +8,25 @@ #ifndef UNICONVERSION_H #define UNICONVERSION_H -namespace Scintilla { +namespace Scintilla::Internal { constexpr int UTF8MaxBytes = 4; constexpr int unicodeReplacementChar = 0xFFFD; -size_t UTF8Length(const wchar_t *uptr, size_t tlen) noexcept; -void UTF8FromUTF16(const wchar_t *uptr, size_t tlen, char *putf, size_t len) noexcept; +size_t UTF8Length(std::wstring_view wsv) noexcept; +size_t UTF8PositionFromUTF16Position(std::string_view u8Text, size_t positionUTF16) noexcept; +void UTF8FromUTF16(std::wstring_view wsv, char *putf, size_t len) noexcept; void UTF8FromUTF32Character(int uch, char *putf) noexcept; -size_t UTF16Length(const char *s, size_t len) noexcept; -size_t UTF16FromUTF8(const char *s, size_t len, wchar_t *tbuf, size_t tlen); -size_t UTF32Length(const char *s, size_t len) noexcept; -size_t UTF32FromUTF8(const char *s, size_t len, unsigned int *tbuf, size_t tlen); +size_t UTF16Length(std::string_view svu8) noexcept; +size_t UTF16FromUTF8(std::string_view svu8, wchar_t *tbuf, size_t tlen); +size_t UTF32Length(std::string_view svu8) noexcept; +size_t UTF32FromUTF8(std::string_view svu8, unsigned int *tbuf, size_t tlen); // WStringFromUTF8 does the right thing when wchar_t is 2 or 4 bytes so // works on both Windows and Unix. -std::wstring WStringFromUTF8(const char *s, size_t len); +std::wstring WStringFromUTF8(std::string_view svu8); unsigned int UTF16FromUTF32Character(unsigned int val, wchar_t *tbuf) noexcept; -bool UTF8IsValid(const char *s, size_t len) noexcept; +bool UTF8IsValid(std::string_view svu8) noexcept; std::string FixInvalidUTF8(const std::string &text); extern const unsigned char UTF8BytesOfLead[256]; @@ -47,12 +48,20 @@ inline constexpr bool UTF8IsTrailByte(unsigned char ch) noexcept { return (ch >= 0x80) && (ch < 0xc0); } -inline constexpr bool UTF8IsAscii(int ch) noexcept { +inline constexpr bool UTF8IsAscii(unsigned char ch) noexcept { return ch < 0x80; } +inline constexpr bool UTF8IsAscii(char ch) noexcept { + const unsigned char uch = ch; + return uch < 0x80; +} + enum { UTF8MaskWidth=0x7, UTF8MaskInvalid=0x8 }; int UTF8Classify(const unsigned char *us, size_t len) noexcept; +inline int UTF8Classify(std::string_view sv) noexcept { + return UTF8Classify(reinterpret_cast(sv.data()), sv.length()); +} // Similar to UTF8Classify but returns a length of 1 for invalid bytes // instead of setting the invalid flag diff --git a/scintilla/src/UnicodeFromUTF8.h b/scintilla/src/UnicodeFromUTF8.h deleted file mode 100644 index ae66cb0a92..0000000000 --- a/scintilla/src/UnicodeFromUTF8.h +++ /dev/null @@ -1,32 +0,0 @@ -// Scintilla source code edit control -/** @file UnicodeFromUTF8.h - ** Lexer infrastructure. - **/ -// Copyright 2013 by Neil Hodgson -// This file is in the public domain. - -#ifndef UNICODEFROMUTF8_H -#define UNICODEFROMUTF8_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -inline int UnicodeFromUTF8(const unsigned char *us) { - if (us[0] < 0xC2) { - return us[0]; - } else if (us[0] < 0xE0) { - return ((us[0] & 0x1F) << 6) + (us[1] & 0x3F); - } else if (us[0] < 0xF0) { - return ((us[0] & 0xF) << 12) + ((us[1] & 0x3F) << 6) + (us[2] & 0x3F); - } else if (us[0] < 0xF5) { - return ((us[0] & 0x7) << 18) + ((us[1] & 0x3F) << 12) + ((us[2] & 0x3F) << 6) + (us[3] & 0x3F); - } - return us[0]; -} - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/scintilla/src/UniqueString.cxx b/scintilla/src/UniqueString.cxx index 8f52825d87..61c1e062c0 100644 --- a/scintilla/src/UniqueString.cxx +++ b/scintilla/src/UniqueString.cxx @@ -5,14 +5,14 @@ // Copyright 2017 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. -#include +#include #include #include #include #include "UniqueString.h" -namespace Scintilla { +namespace Scintilla::Internal { /// Equivalent to strdup but produces a std::unique_ptr allocation to go /// into collections. @@ -20,15 +20,15 @@ UniqueString UniqueStringCopy(const char *text) { if (!text) { return UniqueString(); } - const size_t len = strlen(text); - std::unique_ptr upcNew = Sci::make_unique(len + 1); - memcpy(upcNew.get(), text, len + 1); + const std::string_view sv(text); + std::unique_ptr upcNew = std::make_unique(sv.length() + 1); + sv.copy(upcNew.get(), sv.length()); return UniqueString(upcNew.release()); } // A set of strings that always returns the same pointer for each string. -UniqueStringSet::UniqueStringSet() = default; +UniqueStringSet::UniqueStringSet() noexcept = default; UniqueStringSet::~UniqueStringSet() { strings.clear(); @@ -42,8 +42,9 @@ const char *UniqueStringSet::Save(const char *text) { if (!text) return nullptr; + const std::string_view sv(text); for (const UniqueString &us : strings) { - if (strcmp(us.get(), text) == 0) { + if (sv == us.get()) { return us.get(); } } diff --git a/scintilla/src/UniqueString.h b/scintilla/src/UniqueString.h index 18f17029f2..83cb69e78a 100644 --- a/scintilla/src/UniqueString.h +++ b/scintilla/src/UniqueString.h @@ -11,9 +11,7 @@ #ifndef UNIQUESTRING_H #define UNIQUESTRING_H -#include "Compat.h" - -namespace Scintilla { +namespace Scintilla::Internal { constexpr bool IsNullOrEmpty(const char *text) noexcept { return text == nullptr || *text == '\0'; @@ -31,7 +29,7 @@ class UniqueStringSet { private: std::vector strings; public: - UniqueStringSet(); + UniqueStringSet() noexcept; // UniqueStringSet objects can not be copied. UniqueStringSet(const UniqueStringSet &) = delete; UniqueStringSet &operator=(const UniqueStringSet &) = delete; diff --git a/scintilla/src/ViewStyle.cxx b/scintilla/src/ViewStyle.cxx index da15e0d4e5..33b8614459 100644 --- a/scintilla/src/ViewStyle.cxx +++ b/scintilla/src/ViewStyle.cxx @@ -10,14 +10,21 @@ #include #include +#include +#include #include #include +#include +#include #include #include +#include "ScintillaTypes.h" + +#include "Debugging.h" +#include "Geometry.h" #include "Platform.h" -#include "Scintilla.h" #include "Position.h" #include "UniqueString.h" #include "Indicator.h" @@ -27,41 +34,45 @@ #include "ViewStyle.h" using namespace Scintilla; +using namespace Scintilla::Internal; + +MarginStyle::MarginStyle(MarginType style_, int width_, int mask_) noexcept : + style(style_), width(width_), mask(mask_), sensitive(false), cursor(CursorShape::ReverseArrow) { +} -MarginStyle::MarginStyle(int style_, int width_, int mask_) noexcept : - style(style_), width(width_), mask(mask_), sensitive(false), cursor(SC_CURSORREVERSEARROW) { +bool MarginStyle::ShowsFolding() const noexcept { + return (mask & MaskFolders) != 0; } FontRealised::FontRealised() noexcept = default; -FontRealised::~FontRealised() { - font.Release(); -} +FontRealised::~FontRealised() = default; -void FontRealised::Realise(Surface &surface, int zoomLevel, int technology, const FontSpecification &fs) { +void FontRealised::Realise(Surface &surface, int zoomLevel, Technology technology, const FontSpecification &fs, const char *localeName) { PLATFORM_ASSERT(fs.fontName); - sizeZoomed = fs.size + zoomLevel * SC_FONT_SIZE_MULTIPLIER; - if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER) // Hangs if sizeZoomed <= 1 - sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER; + sizeZoomed = fs.size + zoomLevel * FontSizeMultiplier; + if (sizeZoomed <= 2 * FontSizeMultiplier) // Hangs if sizeZoomed <= 1 + sizeZoomed = 2 * FontSizeMultiplier; const float deviceHeight = static_cast(surface.DeviceHeightFont(sizeZoomed)); - const FontParameters fp(fs.fontName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, fs.weight, fs.italic, fs.extraFontFlag, technology, fs.characterSet); - font.Create(fp); + const FontParameters fp(fs.fontName, deviceHeight / FontSizeMultiplier, fs.weight, + fs.italic, fs.extraFontFlag, technology, fs.characterSet, localeName); + font = Font::Allocate(fp); - ascent = static_cast(surface.Ascent(font)); - descent = static_cast(surface.Descent(font)); - capitalHeight = surface.Ascent(font) - surface.InternalLeading(font); - aveCharWidth = surface.AverageCharWidth(font); - spaceWidth = surface.WidthText(font, " ", 1); + ascent = static_cast(surface.Ascent(font.get())); + descent = static_cast(surface.Descent(font.get())); + capitalHeight = surface.Ascent(font.get()) - surface.InternalLeading(font.get()); + aveCharWidth = surface.AverageCharWidth(font.get()); + spaceWidth = surface.WidthText(font.get(), " "); } -ViewStyle::ViewStyle() : markers(MARKER_MAX + 1), indicators(INDICATOR_MAX + 1) { +ViewStyle::ViewStyle() : markers(MarkerMax + 1), indicators(static_cast(IndicatorNumbers::Max) + 1) { Init(); } // Copy constructor only called when printing copies the screen ViewStyle so it can be // modified for printing styles. -ViewStyle::ViewStyle(const ViewStyle &source) : markers(MARKER_MAX + 1), indicators(INDICATOR_MAX + 1) { +ViewStyle::ViewStyle(const ViewStyle &source) : markers(MarkerMax + 1), indicators(static_cast(IndicatorNumbers::Max) + 1) { Init(source.styles.size()); styles = source.styles; for (size_t sty=0; sty> &font : fonts) { - font.second->Realise(surface, zoomLevel, technology, font.first); + for (const std::pair> &font : fonts) { + font.second->Realise(surface, zoomLevel, technology, font.first, localeName.c_str()); } // Set the platform font handle and measurements for each style. for (Style &style : styles) { - FontRealised *fr = Find(style); + const FontRealised *fr = Find(style); style.Copy(fr->font, *fr); } @@ -334,16 +353,16 @@ void ViewStyle::Refresh(Surface &surface, int tabInChars) { [](const Style &style) noexcept { return style.IsProtected(); }); someStylesForceCase = std::any_of(styles.cbegin(), styles.cend(), - [](const Style &style) noexcept { return style.caseForce != Style::caseMixed; }); + [](const Style &style) noexcept { return style.caseForce != Style::CaseForce::mixed; }); - aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth; - spaceWidth = styles[STYLE_DEFAULT].spaceWidth; + aveCharWidth = styles[StyleDefault].aveCharWidth; + spaceWidth = styles[StyleDefault].spaceWidth; tabWidth = spaceWidth * tabInChars; controlCharWidth = 0.0; if (controlCharSymbol >= 32) { const char cc[2] = { static_cast(controlCharSymbol), '\0' }; - controlCharWidth = surface.WidthText(styles[STYLE_CONTROLCHAR].font, cc, 1); + controlCharWidth = surface.WidthText(styles[StyleControlChar].font.get(), cc); } CalculateMarginWidthAndMask(); @@ -359,7 +378,7 @@ int ViewStyle::AllocateExtendedStyles(int numberStyles) { nextExtendedStyle += numberStyles; EnsureStyle(nextExtendedStyle); for (int i=startRange; iGetHeight() > largestMarkerHeight) largestMarkerHeight = marker.pxpm->GetHeight(); break; - case SC_MARK_RGBAIMAGE: + case MarkerSymbol::RgbaImage: if (marker.image && marker.image->GetHeight() > largestMarkerHeight) largestMarkerHeight = marker.image->GetHeight(); break; + default: // Only images have their own natural heights + break; } } } int ViewStyle::GetFrameWidth() const noexcept { - return Sci::clamp(caretLineFrame, 1, lineHeight / 3); + return std::clamp(caretLine.frame, 1, lineHeight / 3); } -bool ViewStyle::IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const noexcept { - return caretLineFrame && (caretActive || alwaysShowCaretLineBackground) && showCaretLineBackground && - (caretLineAlpha == SC_ALPHA_NOALPHA) && lineContainsCaret; +bool ViewStyle::IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const { + return caretLine.frame && (caretActive || caretLine.alwaysShow) && + ElementColour(Element::CaretLineBack) && + (caretLine.layer == Layer::Base) && lineContainsCaret; } // See if something overrides the line background colour: Either if caret is on the line // and background colour is set for that, or if a marker is defined that forces its background // colour onto the line, or if a marker is defined but has no selection margin in which to -// display itself (as long as it's not an SC_MARK_EMPTY marker). These are checked in order +// display itself (as long as it's not an MarkerSymbol::Empty marker). These are checked in order // with the earlier taking precedence. When multiple markers cause background override, // the colour for the highest numbered one is used. -ColourOptional ViewStyle::Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const noexcept { - ColourOptional background; - if (!caretLineFrame && (caretActive || alwaysShowCaretLineBackground) && showCaretLineBackground && - (caretLineAlpha == SC_ALPHA_NOALPHA) && lineContainsCaret) { - background = ColourOptional(caretLineBackground, true); +std::optional ViewStyle::Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const { + std::optional background; + if (!caretLine.frame && (caretActive || caretLine.alwaysShow) && + (caretLine.layer == Layer::Base) && lineContainsCaret) { + background = ElementColour(Element::CaretLineBack); } - if (!background.isSet && marksOfLine) { + if (!background && marksOfLine) { int marks = marksOfLine; for (int markBit = 0; (markBit < 32) && marks; markBit++) { - if ((marks & 1) && (markers[markBit].markType == SC_MARK_BACKGROUND) && - (markers[markBit].alpha == SC_ALPHA_NOALPHA)) { - background = ColourOptional(markers[markBit].back, true); + if ((marks & 1) && (markers[markBit].markType == MarkerSymbol::Background) && + (markers[markBit].layer == Layer::Base)) { + background = markers[markBit].back; } marks >>= 1; } } - if (!background.isSet && maskInLine) { + if (!background && maskInLine) { int marksMasked = marksOfLine & maskInLine; if (marksMasked) { for (int markBit = 0; (markBit < 32) && marksMasked; markBit++) { if ((marksMasked & 1) && - (markers[markBit].alpha == SC_ALPHA_NOALPHA)) { - background = ColourOptional(markers[markBit].back, true); + (markers[markBit].layer == Layer::Base)) { + background = markers[markBit].back; } marksMasked >>= 1; } } } - return background; + if (background) { + return background->Opaque(); + } else { + return {}; + } } bool ViewStyle::SelectionBackgroundDrawn() const noexcept { - return selColours.back.isSet && - ((selAlpha == SC_ALPHA_NOALPHA) || (selAdditionalAlpha == SC_ALPHA_NOALPHA)); + return selection.layer == Layer::Base; +} + +bool ViewStyle::SelectionTextDrawn() const { + return + ElementIsSet(Element::SelectionText) || + ElementIsSet(Element::SelectionAdditionalText) || + ElementIsSet(Element::SelectionSecondaryText) || + ElementIsSet(Element::SelectionInactiveText); } -bool ViewStyle::WhitespaceBackgroundDrawn() const noexcept { - return (viewWhitespace != wsInvisible) && (whitespaceColours.back.isSet); +bool ViewStyle::WhitespaceBackgroundDrawn() const { + return (viewWhitespace != WhiteSpace::Invisible) && (ElementIsSet(Element::WhiteSpaceBack)); } bool ViewStyle::WhiteSpaceVisible(bool inIndent) const noexcept { - return (!inIndent && viewWhitespace == wsVisibleAfterIndent) || - (inIndent && viewWhitespace == wsVisibleOnlyInIndent) || - viewWhitespace == wsVisibleAlways; + return (!inIndent && viewWhitespace == WhiteSpace::VisibleAfterIndent) || + (inIndent && viewWhitespace == WhiteSpace::VisibleOnlyInIndent) || + viewWhitespace == WhiteSpace::VisibleAlways; } -ColourDesired ViewStyle::WrapColour() const noexcept { - if (whitespaceColours.fore.isSet) - return whitespaceColours.fore; - else - return styles[STYLE_DEFAULT].fore; +ColourRGBA ViewStyle::WrapColour() const { + return ElementColour(Element::WhiteSpace).value_or(styles[StyleDefault].fore); } // Insert new edge in sorted order. @@ -514,84 +548,140 @@ void ViewStyle::AddMultiEdge(uptr_t wParam, sptr_t lParam) { EdgeProperties(column, lParam)); } -bool ViewStyle::SetWrapState(int wrapState_) noexcept { - WrapMode wrapStateWanted; - switch (wrapState_) { - case SC_WRAP_WORD: - wrapStateWanted = WrapMode::word; - break; - case SC_WRAP_CHAR: - wrapStateWanted = WrapMode::character; - break; - case SC_WRAP_WHITESPACE: - wrapStateWanted = WrapMode::whitespace; - break; - default: - wrapStateWanted = WrapMode::none; - break; +std::optional ViewStyle::ElementColour(Element element) const { + ElementMap::const_iterator search = elementColours.find(element); + if (search != elementColours.end()) { + if (search->second.has_value()) { + return search->second; + } + } + ElementMap::const_iterator searchBase = elementBaseColours.find(element); + if (searchBase != elementBaseColours.end()) { + if (searchBase->second.has_value()) { + return searchBase->second; + } + } + return {}; +} + +bool ViewStyle::ElementAllowsTranslucent(Element element) const { + return elementAllowsTranslucent.count(element) > 0; +} + +bool ViewStyle::ResetElement(Element element) { + ElementMap::const_iterator search = elementColours.find(element); + const bool changed = (search != elementColours.end()) && (search->second.has_value()); + elementColours.erase(element); + return changed; +} + +bool ViewStyle::SetElementColour(Element element, ColourRGBA colour) { + ElementMap::const_iterator search = elementColours.find(element); + const bool changed = + (search == elementColours.end()) || + (search->second.has_value() && !(*search->second == colour)); + elementColours[element] = colour; + return changed; +} + +bool ViewStyle::SetElementColourOptional(Element element, uptr_t wParam, sptr_t lParam) { + if (wParam) { + return SetElementColour(element, ColourRGBA::FromIpRGB(lParam)); + } else { + return ResetElement(element); } - const bool changed = wrapState != wrapStateWanted; - wrapState = wrapStateWanted; +} + +void ViewStyle::SetElementRGB(Element element, int rgb) { + const ColourRGBA current = ElementColour(element).value_or(ColourRGBA(0, 0, 0, 0)); + elementColours[element] = ColourRGBA(ColourRGBA(rgb), current.GetAlpha()); +} + +void ViewStyle::SetElementAlpha(Element element, int alpha) { + const ColourRGBA current = ElementColour(element).value_or(ColourRGBA(0, 0, 0, 0)); + elementColours[element] = ColourRGBA(current, std::min(alpha, 0xff)); +} + +bool ViewStyle::ElementIsSet(Element element) const { + ElementMap::const_iterator search = elementColours.find(element); + if (search != elementColours.end()) { + return search->second.has_value(); + } + return false; +} + +bool ViewStyle::SetElementBase(Element element, ColourRGBA colour) { + ElementMap::const_iterator search = elementBaseColours.find(element); + const bool changed = + (search == elementBaseColours.end()) || + (search->second.has_value() && !(*search->second == colour)); + elementBaseColours[element] = colour; + return changed; +} + +bool ViewStyle::SetWrapState(Wrap wrapState_) noexcept { + const bool changed = wrap.state != wrapState_; + wrap.state = wrapState_; return changed; } -bool ViewStyle::SetWrapVisualFlags(int wrapVisualFlags_) noexcept { - const bool changed = wrapVisualFlags != wrapVisualFlags_; - wrapVisualFlags = wrapVisualFlags_; +bool ViewStyle::SetWrapVisualFlags(WrapVisualFlag wrapVisualFlags_) noexcept { + const bool changed = wrap.visualFlags != wrapVisualFlags_; + wrap.visualFlags = wrapVisualFlags_; return changed; } -bool ViewStyle::SetWrapVisualFlagsLocation(int wrapVisualFlagsLocation_) noexcept { - const bool changed = wrapVisualFlagsLocation != wrapVisualFlagsLocation_; - wrapVisualFlagsLocation = wrapVisualFlagsLocation_; +bool ViewStyle::SetWrapVisualFlagsLocation(WrapVisualLocation wrapVisualFlagsLocation_) noexcept { + const bool changed = wrap.visualFlagsLocation != wrapVisualFlagsLocation_; + wrap.visualFlagsLocation = wrapVisualFlagsLocation_; return changed; } bool ViewStyle::SetWrapVisualStartIndent(int wrapVisualStartIndent_) noexcept { - const bool changed = wrapVisualStartIndent != wrapVisualStartIndent_; - wrapVisualStartIndent = wrapVisualStartIndent_; + const bool changed = wrap.visualStartIndent != wrapVisualStartIndent_; + wrap.visualStartIndent = wrapVisualStartIndent_; return changed; } -bool ViewStyle::SetWrapIndentMode(int wrapIndentMode_) noexcept { - const bool changed = wrapIndentMode != wrapIndentMode_; - wrapIndentMode = wrapIndentMode_; +bool ViewStyle::SetWrapIndentMode(WrapIndentMode wrapIndentMode_) noexcept { + const bool changed = wrap.indentMode != wrapIndentMode_; + wrap.indentMode = wrapIndentMode_; return changed; } bool ViewStyle::IsBlockCaretStyle() const noexcept { - return ((caretStyle & CARETSTYLE_INS_MASK) == CARETSTYLE_BLOCK) || - (caretStyle & CARETSTYLE_OVERSTRIKE_BLOCK) != 0; + return ((caret.style & CaretStyle::InsMask) == CaretStyle::Block) || + FlagSet(caret.style, CaretStyle::OverstrikeBlock); } bool ViewStyle::IsCaretVisible() const noexcept { - return caretWidth > 0 && caretStyle != CARETSTYLE_INVISIBLE; + return caret.width > 0 && caret.style != CaretStyle::Invisible; } bool ViewStyle::DrawCaretInsideSelection(bool inOverstrike, bool imeCaretBlockOverride) const noexcept { - if (caretStyle & CARETSTYLE_BLOCK_AFTER) + if (FlagSet(caret.style, CaretStyle::BlockAfter)) return false; - return ((caretStyle & CARETSTYLE_INS_MASK) == CARETSTYLE_BLOCK) || - (inOverstrike && (caretStyle & CARETSTYLE_OVERSTRIKE_BLOCK) != 0) || + return ((caret.style & CaretStyle::InsMask) == CaretStyle::Block) || + (inOverstrike && FlagSet(caret.style, CaretStyle::OverstrikeBlock)) || imeCaretBlockOverride; } ViewStyle::CaretShape ViewStyle::CaretShapeForMode(bool inOverstrike) const noexcept { if (inOverstrike) { - return (caretStyle & CARETSTYLE_OVERSTRIKE_BLOCK) ? CaretShape::block : CaretShape::bar; + return (FlagSet(caret.style, CaretStyle::OverstrikeBlock)) ? CaretShape::block : CaretShape::bar; } - const int caret = caretStyle & CARETSTYLE_INS_MASK; - return (caret <= CARETSTYLE_BLOCK) ? static_cast(caret) : CaretShape::line; + const CaretStyle caretStyle = caret.style & CaretStyle::InsMask; + return (caretStyle <= CaretStyle::Block) ? static_cast(caretStyle) : CaretShape::line; } void ViewStyle::AllocStyles(size_t sizeNew) { size_t i=styles.size(); styles.resize(sizeNew); - if (styles.size() > STYLE_DEFAULT) { + if (styles.size() > StyleDefault) { for (; i(); + fonts[fs] = std::make_unique(); } } } @@ -618,10 +708,10 @@ FontRealised *ViewStyle::Find(const FontSpecification &fs) { } void ViewStyle::FindMaxAscentDescent() { - for (FontMap::const_iterator it = fonts.cbegin(); it != fonts.cend(); ++it) { - if (maxAscent < it->second->ascent) - maxAscent = it->second->ascent; - if (maxDescent < it->second->descent) - maxDescent = it->second->descent; + for (const auto &font : fonts) { + if (maxAscent < font.second->ascent) + maxAscent = font.second->ascent; + if (maxDescent < font.second->descent) + maxDescent = font.second->descent; } } diff --git a/scintilla/src/ViewStyle.h b/scintilla/src/ViewStyle.h index dc47ed380c..8b9f125bdc 100644 --- a/scintilla/src/ViewStyle.h +++ b/scintilla/src/ViewStyle.h @@ -8,19 +8,20 @@ #ifndef VIEWSTYLE_H #define VIEWSTYLE_H -namespace Scintilla { +namespace Scintilla::Internal { /** */ class MarginStyle { public: - int style; - ColourDesired back; + Scintilla::MarginType style; + ColourRGBA back; int width; int mask; bool sensitive; - int cursor; - MarginStyle(int style_= SC_MARGIN_SYMBOL, int width_=0, int mask_=0) noexcept; + Scintilla::CursorShape cursor; + MarginStyle(Scintilla::MarginType style_= Scintilla::MarginType::Symbol, int width_=0, int mask_=0) noexcept; + bool ShowsFolding() const noexcept; }; /** @@ -29,7 +30,7 @@ class MarginStyle { class FontRealised : public FontMeasurements { public: - Font font; + std::shared_ptr font; FontRealised() noexcept; // FontRealised objects can not be copied. FontRealised(const FontRealised &) = delete; @@ -37,44 +38,78 @@ class FontRealised : public FontMeasurements { FontRealised &operator=(const FontRealised &) = delete; FontRealised &operator=(FontRealised &&) = delete; virtual ~FontRealised(); - void Realise(Surface &surface, int zoomLevel, int technology, const FontSpecification &fs); + void Realise(Surface &surface, int zoomLevel, Scintilla::Technology technology, const FontSpecification &fs, const char *localeName); }; -enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth}; - -enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2, wsVisibleOnlyInIndent=3}; +typedef std::map> FontMap; -enum TabDrawMode {tdLongArrow=0, tdStrikeOut=1}; +inline std::optional OptionalColour(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) { + if (wParam) { + return ColourRGBA::FromIpRGB(lParam); + } else { + return {}; + } +} -typedef std::map> FontMap; +struct SelectionAppearance { + // Whether to draw on base layer or over text + Scintilla::Layer layer; + // Draw selection past line end characters up to right border + bool eolFilled; +}; -enum class WrapMode { none, word, character, whitespace }; +struct CaretLineAppearance { + // Whether to draw on base layer or over text + Scintilla::Layer layer; + // Also show when non-focused + bool alwaysShow; + // Non-0: draw a rectangle around line instead of filling line. Value is pixel width of frame + int frame; +}; -class ColourOptional : public ColourDesired { -public: - bool isSet; - ColourOptional(ColourDesired colour_=ColourDesired(0,0,0), bool isSet_=false) noexcept : ColourDesired(colour_), isSet(isSet_) { - } - ColourOptional(uptr_t wParam, sptr_t lParam) noexcept : ColourDesired(static_cast(lParam)), isSet(wParam != 0) { - } +struct CaretAppearance { + // Line, block, over-strike bar ... + Scintilla::CaretStyle style; + // Width in pixels + int width; }; -struct ForeBackColours { - ColourOptional fore; - ColourOptional back; +struct WrapAppearance { + // No wrapping, word, character, whitespace appearance + Scintilla::Wrap state; + // Show indication of wrap at line end, line start, or in margin + Scintilla::WrapVisualFlag visualFlags; + // Show indication near margin or near text + Scintilla::WrapVisualLocation visualFlagsLocation; + // How much indentation to show wrapping + int visualStartIndent; + // WrapIndentMode::Fixed, _SAME, _INDENT, _DEEPINDENT + Scintilla::WrapIndentMode indentMode; }; struct EdgeProperties { - int column; - ColourDesired colour; - EdgeProperties(int column_ = 0, ColourDesired colour_ = ColourDesired(0)) noexcept : + int column = 0; + ColourRGBA colour; + EdgeProperties(int column_ = 0, ColourRGBA colour_ = ColourRGBA::FromRGB(0)) noexcept : column(column_), colour(colour_) { } - EdgeProperties(uptr_t wParam, sptr_t lParam) noexcept : - column(static_cast(wParam)), colour(static_cast(lParam)) { + EdgeProperties(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) noexcept : + column(static_cast(wParam)), colour(ColourRGBA::FromIpRGB(lParam)) { } }; +// This is an old style enum so that its members can be used directly as indices without casting +enum StyleIndices { + StyleDefault = static_cast(Scintilla::StylesCommon::Default), + StyleLineNumber = static_cast(Scintilla::StylesCommon::LineNumber), + StyleBraceLight = static_cast(Scintilla::StylesCommon::BraceLight), + StyleBraceBad = static_cast(Scintilla::StylesCommon::BraceBad), + StyleControlChar = static_cast(Scintilla::StylesCommon::ControlChar), + StyleIndentGuide = static_cast(Scintilla::StylesCommon::IndentGuide), + StyleCallTip = static_cast(Scintilla::StylesCommon::CallTip), + StyleFoldDisplayText = static_cast(Scintilla::StylesCommon::FoldDisplayText), +}; + /** */ class ViewStyle { @@ -88,7 +123,7 @@ class ViewStyle { std::vector indicators; bool indicatorsDynamic; bool indicatorsSetFore; - int technology; + Scintilla::Technology technology; int lineHeight; int lineOverlap; unsigned int maxAscent; @@ -96,23 +131,16 @@ class ViewStyle { XYPOSITION aveCharWidth; XYPOSITION spaceWidth; XYPOSITION tabWidth; - ForeBackColours selColours; - ColourDesired selAdditionalForeground; - ColourDesired selAdditionalBackground; - ColourDesired selBackground2; - int selAlpha; - int selAdditionalAlpha; - bool selEOLFilled; - ForeBackColours whitespaceColours; + + SelectionAppearance selection; + int controlCharSymbol; XYPOSITION controlCharWidth; - ColourDesired selbar; - ColourDesired selbarlight; - ColourOptional foldmarginColour; - ColourOptional foldmarginHighlightColour; - ForeBackColours hotspotColours; + ColourRGBA selbar; + ColourRGBA selbarlight; + std::optional foldmarginColour; + std::optional foldmarginHighlightColour; bool hotspotUnderline; - bool hotspotSingleLine; /// 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 @@ -123,47 +151,45 @@ class ViewStyle { bool marginInside; ///< true: margin included in text view, false: separate views int textStart; ///< Starting x position of text within the view int zoomLevel; - WhiteSpaceVisibility viewWhitespace; - TabDrawMode tabDrawMode; + Scintilla::WhiteSpace viewWhitespace; + Scintilla::TabDrawMode tabDrawMode; int whitespaceSize; - IndentView viewIndentationGuides; + Scintilla::IndentView viewIndentationGuides; bool viewEOL; - ColourDesired caretcolour; - ColourDesired additionalCaretColour; - int caretLineFrame; - bool showCaretLineBackground; - bool alwaysShowCaretLineBackground; - ColourDesired caretLineBackground; - int caretLineAlpha; - int caretStyle; - int caretWidth; + + CaretAppearance caret; + + CaretLineAppearance caretLine; + bool someStylesProtected; bool someStylesForceCase; - int extraFontFlag; + Scintilla::FontQuality extraFontFlag; int extraAscent; int extraDescent; int marginStyleOffset; - int annotationVisible; + Scintilla::AnnotationVisible annotationVisible; int annotationStyleOffset; - int eolAnnotationVisible; + Scintilla::EOLAnnotationVisible eolAnnotationVisible; int eolAnnotationStyleOffset; bool braceHighlightIndicatorSet; int braceHighlightIndicator; bool braceBadLightIndicatorSet; int braceBadLightIndicator; - int edgeState; + Scintilla::EdgeVisualStyle edgeState; EdgeProperties theEdge; std::vector theMultiEdge; int marginNumberPadding; // the right-side padding of the number margin int ctrlCharPadding; // the padding around control character text blobs int lastSegItalicsOffset; // the offset so as not to clip italic characters at EOLs - // Wrapping support - WrapMode wrapState; - int wrapVisualFlags; - int wrapVisualFlagsLocation; - int wrapVisualStartIndent; - int wrapIndentMode; // SC_WRAPINDENT_FIXED, _SAME, _INDENT + using ElementMap = std::map>; + ElementMap elementColours; + ElementMap elementBaseColours; + std::set elementAllowsTranslucent; + + WrapAppearance wrap; + + std::string localeName; ViewStyle(); ViewStyle(const ViewStyle &source); @@ -181,25 +207,37 @@ class ViewStyle { void ResetDefaultStyle(); void ClearStyles(); void SetStyleFontName(int styleIndex, const char *name); + void SetFontLocaleName(const char *name); bool ProtectionActive() const noexcept; int ExternalMarginWidth() const noexcept; int MarginFromLocation(Point pt) const noexcept; bool ValidStyle(size_t styleIndex) const noexcept; void CalcLargestMarkerHeight() noexcept; int GetFrameWidth() const noexcept; - bool IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const noexcept; - ColourOptional Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const noexcept; + bool IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const; + std::optional Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const; bool SelectionBackgroundDrawn() const noexcept; - bool WhitespaceBackgroundDrawn() const noexcept; - ColourDesired WrapColour() const noexcept; + bool SelectionTextDrawn() const; + bool WhitespaceBackgroundDrawn() const; + ColourRGBA WrapColour() const; + + void AddMultiEdge(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam); - void AddMultiEdge(uptr_t wParam, sptr_t lParam); + std::optional ElementColour(Scintilla::Element element) const; + bool ElementAllowsTranslucent(Scintilla::Element element) const; + bool ResetElement(Scintilla::Element element); + bool SetElementColour(Scintilla::Element element, ColourRGBA colour); + bool SetElementColourOptional(Scintilla::Element element, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam); + void SetElementRGB(Scintilla::Element element, int rgb); + void SetElementAlpha(Scintilla::Element element, int alpha); + bool ElementIsSet(Scintilla::Element element) const; + bool SetElementBase(Scintilla::Element element, ColourRGBA colour); - bool SetWrapState(int wrapState_) noexcept; - bool SetWrapVisualFlags(int wrapVisualFlags_) noexcept; - bool SetWrapVisualFlagsLocation(int wrapVisualFlagsLocation_) noexcept; + bool SetWrapState(Scintilla::Wrap wrapState_) noexcept; + bool SetWrapVisualFlags(Scintilla::WrapVisualFlag wrapVisualFlags_) noexcept; + bool SetWrapVisualFlagsLocation(Scintilla::WrapVisualLocation wrapVisualFlagsLocation_) noexcept; bool SetWrapVisualStartIndent(int wrapVisualStartIndent_) noexcept; - bool SetWrapIndentMode(int wrapIndentMode_) noexcept; + bool SetWrapIndentMode(Scintilla::WrapIndentMode wrapIndentMode_) noexcept; bool WhiteSpaceVisible(bool inIndent) const noexcept; diff --git a/scintilla/src/XPM.cxx b/scintilla/src/XPM.cxx index 2e2fba9864..eba3fb6c2e 100644 --- a/scintilla/src/XPM.cxx +++ b/scintilla/src/XPM.cxx @@ -9,17 +9,24 @@ #include #include +#include #include #include +#include #include #include #include +#include "ScintillaTypes.h" + +#include "Debugging.h" +#include "Geometry.h" #include "Platform.h" #include "XPM.h" using namespace Scintilla; +using namespace Scintilla::Internal; namespace { @@ -56,17 +63,17 @@ unsigned int ValueOfHex(const char ch) noexcept { return 0; } -ColourDesired ColourFromHex(const char *val) noexcept { +ColourRGBA ColourFromHex(const char *val) noexcept { const unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]); const unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]); const unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]); - return ColourDesired(r, g, b); + return ColourRGBA(r, g, b); } } -ColourDesired XPM::ColourFromCode(int ch) const noexcept { +ColourRGBA XPM::ColourFromCode(int ch) const noexcept { return colourCodeTable[ch]; } @@ -112,7 +119,7 @@ void XPM::Init(const char *const *linesForm) { if (!linesForm) return; - std::fill(colourCodeTable, std::end(colourCodeTable), ColourDesired(0)); + std::fill(colourCodeTable, std::end(colourCodeTable), ColourRGBA(0, 0, 0)); const char *line0 = linesForm[0]; width = atoi(line0); line0 = NextField(line0); @@ -130,7 +137,7 @@ void XPM::Init(const char *const *linesForm) { const char *colourDef = linesForm[c+1]; const char code = colourDef[0]; colourDef += 4; - ColourDesired colour(0xff, 0xff, 0xff); + ColourRGBA colour(0, 0, 0, 0); if (*colourDef == '#') { colour = ColourFromHex(colourDef+1); } else { @@ -169,19 +176,13 @@ void XPM::Draw(Surface *surface, const PRectangle &rc) { } } -void XPM::PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const noexcept { - if (pixels.empty() || (x<0) || (x >= width) || (y<0) || (y >= height)) { - colour = ColourDesired(0); - transparent = true; - return; +ColourRGBA XPM::PixelAt(int x, int y) const noexcept { + if (pixels.empty() || (x < 0) || (x >= width) || (y < 0) || (y >= height)) { + // Out of bounds -> transparent black + return ColourRGBA(0, 0, 0, 0); } const int code = pixels[y * width + x]; - transparent = code == codeTransparent; - if (transparent) { - colour = ColourDesired(0); - } else { - colour = ColourFromCode(code); - } + return ColourFromCode(code); } std::vector XPM::LinesFormFromTextForm(const char *textForm) { @@ -235,10 +236,7 @@ RGBAImage::RGBAImage(const XPM &xpm) { pixelBytes.resize(CountBytes()); for (int y=0; y(alpha); + pixel[3] = colour.GetAlpha(); } // Transform a block of pixels from RGBA to BGRA with premultiplied alpha. @@ -293,13 +291,8 @@ void RGBAImageSet::Clear() noexcept { } /// Add an image. -void RGBAImageSet::Add(int ident, RGBAImage *image) { - ImageMap::iterator it=images.find(ident); - if (it == images.end()) { - images[ident] = std::unique_ptr(image); - } else { - it->second.reset(image); - } +void RGBAImageSet::AddImage(int ident, std::unique_ptr image) { + images[ident] = std::move(image); height = -1; width = -1; } diff --git a/scintilla/src/XPM.h b/scintilla/src/XPM.h index fb9bb4953a..4ec0205805 100644 --- a/scintilla/src/XPM.h +++ b/scintilla/src/XPM.h @@ -8,7 +8,7 @@ #ifndef XPM_H #define XPM_H -namespace Scintilla { +namespace Scintilla::Internal { /** * Hold a pixmap in XPM format. @@ -18,17 +18,17 @@ class XPM { int width=1; int nColours=1; std::vector pixels; - ColourDesired colourCodeTable[256]; + ColourRGBA colourCodeTable[256]; char codeTransparent=' '; - ColourDesired ColourFromCode(int ch) const noexcept; + ColourRGBA ColourFromCode(int ch) const noexcept; void FillRun(Surface *surface, int code, int startX, int y, int x) const; public: explicit XPM(const char *textForm); explicit XPM(const char *const *linesForm); XPM(const XPM &) = default; - XPM(XPM &&) = default; + XPM(XPM &&) noexcept = default; XPM &operator=(const XPM &) = default; - XPM &operator=(XPM &&) = default; + XPM &operator=(XPM &&) noexcept = default; ~XPM(); void Init(const char *textForm); void Init(const char *const *linesForm); @@ -36,7 +36,7 @@ class XPM { void Draw(Surface *surface, const PRectangle &rc); int GetHeight() const noexcept { return height; } int GetWidth() const noexcept { return width; } - void PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const noexcept; + ColourRGBA PixelAt(int x, int y) const noexcept; private: static std::vectorLinesFormFromTextForm(const char *textForm); }; @@ -54,9 +54,9 @@ class RGBAImage { RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_); explicit RGBAImage(const XPM &xpm); RGBAImage(const RGBAImage &) = default; - RGBAImage(RGBAImage &&) = default; + RGBAImage(RGBAImage &&) noexcept = default; RGBAImage &operator=(const RGBAImage &) = default; - RGBAImage &operator=(RGBAImage &&) = default; + RGBAImage &operator=(RGBAImage &&) noexcept = default; virtual ~RGBAImage(); int GetHeight() const noexcept { return height; } int GetWidth() const noexcept { return width; } @@ -65,7 +65,7 @@ class RGBAImage { float GetScaledWidth() const noexcept { return width / scale; } int CountBytes() const noexcept; const unsigned char *Pixels() const noexcept; - void SetPixel(int x, int y, ColourDesired colour, int alpha) noexcept; + void SetPixel(int x, int y, ColourRGBA colour) noexcept; static void BGRAFromRGBA(unsigned char *pixelsBGRA, const unsigned char *pixelsRGBA, size_t count) noexcept; }; @@ -88,7 +88,7 @@ class RGBAImageSet { /// Remove all images. void Clear() noexcept; /// Add an image. - void Add(int ident, RGBAImage *image); + void AddImage(int ident, std::unique_ptr image); /// Get image by id. RGBAImage *Get(int ident); /// Give the largest height of the set. diff --git a/scintilla/version.txt b/scintilla/version.txt index 9ceab20133..c0556fb20f 100644 --- a/scintilla/version.txt +++ b/scintilla/version.txt @@ -1 +1 @@ -3211 +511 diff --git a/scripts/update-scintilla.sh b/scripts/update-scintilla.sh index 1a9a0cbf60..2ebe6c757d 100755 --- a/scripts/update-scintilla.sh +++ b/scripts/update-scintilla.sh @@ -10,18 +10,23 @@ SCI_SRC= # parse arguments -if [ $# -eq 1 ]; then +if [ $# -eq 2 ]; then SCI_SRC="$1" + LEX_SRC="$2" else - echo "USAGE: $0 SCINTILLA_SOURCE_DIRECTORY" >&2 + echo "USAGE: $0 SCINTILLA_SOURCE_DIRECTORY LEXILLA_SOURCE_DIRECTORY" >&2 exit 1 fi # check source directory -if ! [ -f "$SCI_SRC"/version.txt ]; then +if ! [ -f "$SCI_SRC/src/ScintillaBase.cxx" ]; then echo "'$SCI_SRC' is not a valid Scintilla source directory!" >&2 exit 1 fi +if ! [ -f "$LEX_SRC/src/Lexilla.cxx" ]; then + echo "'$LEX_SRC' is not a valid Lexilla source directory!" >&2 + exit 1 +fi # check destination directory if ! [ -d .git ] || ! [ -f scintilla/version.txt ]; then echo "Please run this script from Geany's root source directory." >&2 @@ -34,32 +39,53 @@ if git status -unormal -s scintilla | grep '^??'; then exit 1 fi +copy_to() +{ + dest="$1" + shift + + if ! [ -d "$dest" ]; then + echo "$dest does not exist." >&2; + exit 1 + fi + for f in $@; do + dos2unix -k -q -n $f $dest/$(basename $f) || (echo "dos2unix $f failed" >&2 ; exit 1) + done || exit 1 +} + +# purge executbale bits +umask 111 # copy everything from scintilla but lexers -cp -v "$SCI_SRC"/src/*.cxx scintilla/src || exit 1 -cp -v "$SCI_SRC"/src/*.h scintilla/src || exit 1 -cp -v "$SCI_SRC"/include/*.h scintilla/include || exit 1 -cp -v "$SCI_SRC"/include/*.iface scintilla/include || exit 1 -cp -v "$SCI_SRC"/gtk/*.c scintilla/gtk || exit 1 -cp -v "$SCI_SRC"/gtk/*.cxx scintilla/gtk || exit 1 -cp -v "$SCI_SRC"/gtk/*.h scintilla/gtk || exit 1 -cp -v "$SCI_SRC"/gtk/*.list scintilla/gtk || exit 1 -cp -v "$SCI_SRC"/lexlib/*.cxx scintilla/lexlib || exit 1 -cp -v "$SCI_SRC"/lexlib/*.h scintilla/lexlib || exit 1 -cp -v "$SCI_SRC"/License.txt scintilla || exit 1 -cp -v "$SCI_SRC"/version.txt scintilla || exit 1 +copy_to scintilla/src "$SCI_SRC"/src/*.cxx +copy_to scintilla/src "$SCI_SRC"/src/*.h +copy_to scintilla/include "$SCI_SRC"/include/*.h +copy_to scintilla/include "$SCI_SRC"/include/*.iface +copy_to scintilla/gtk "$SCI_SRC"/gtk/*.c +copy_to scintilla/gtk "$SCI_SRC"/gtk/*.cxx +copy_to scintilla/gtk "$SCI_SRC"/gtk/*.h +copy_to scintilla/gtk "$SCI_SRC"/gtk/*.list +copy_to scintilla "$SCI_SRC"/License.txt +copy_to scintilla "$SCI_SRC"/version.txt +copy_to scintilla/lexilla/src "$LEX_SRC"/src/*.cxx +copy_to scintilla/lexilla/include "$LEX_SRC"/include/*.h +copy_to scintilla/lexilla/lexlib "$LEX_SRC"/lexlib/*.cxx +copy_to scintilla/lexilla/lexlib "$LEX_SRC"/lexlib/*.h +copy_to scintilla/lexilla/ "$LEX_SRC"/License.txt +copy_to scintilla/lexilla/ "$LEX_SRC"/version.txt # now copy the lexers we use -git ls-files scintilla/lexers/*.cxx | sed 's%^scintilla/%./%' | while read f; do - cp -v "$SCI_SRC/$f" "scintilla/$f" || exit 1 -done || exit 1 +git ls-files scintilla/lexilla/lexers/*.cxx | while read f; do + copy_to "scintilla/lexilla/lexers" "$LEX_SRC/lexers/$f" +done # apply our patch git apply -p0 scintilla/scintilla_changes.patch || { echo "scintilla_changes.patch doesn't apply, please update it and retry." - echo "Changes for the catalogue are:" - git diff -p -R --src-prefix= --dst-prefix= scintilla/src/Catalogue.cxx | cat exit 1 } +echo "Upstream lexer catalogue changes:" +git diff -p -R --src-prefix= --dst-prefix= scintilla/lexilla/src/Lexilla.cxx + # show a nice success banner echo "Scintilla update successful!" | sed 'h;s/./=/g;p;x;p;x' @@ -78,7 +104,7 @@ EOF fi # check for possible changes to styles -if ! git diff --quiet scintilla/include/SciLexer.h; then +if ! git diff --quiet scintilla/lexilla/include/SciLexer.h; then cat << EOF Check the diff of scintilla/include/SciLexer.h to see whether and which diff --git a/src/Makefile.am b/src/Makefile.am index a4c78c5db9..8acddfb800 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,6 +15,7 @@ EXTRA_DIST = \ AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/scintilla/include \ + -I$(top_srcdir)/scintilla/lexilla/include \ -I$(srcdir)/tagmanager \ -DGTK \ -DGEANY_PRIVATE \ @@ -119,6 +120,7 @@ libgeany_la_CFLAGS = $(AM_CPPFLAGS) @LIBGEANY_CFLAGS@ libgeany_la_LDFLAGS = @LIBGEANY_LDFLAGS@ libgeany_la_LIBADD = \ + $(top_builddir)/scintilla/liblexilla.la \ $(top_builddir)/scintilla/libscintilla.la \ $(builddir)/tagmanager/libtagmanager.la \ @GTK_LIBS@ \ diff --git a/src/sciwrappers.c b/src/sciwrappers.c index 804c0d91a7..b2c711e13e 100644 --- a/src/sciwrappers.c +++ b/src/sciwrappers.c @@ -35,6 +35,7 @@ #endif #include "sciwrappers.h" +#include /* ILexer5 */ #include "utils.h" @@ -674,7 +675,10 @@ void sci_set_lexer(ScintillaObject *sci, guint lexer_id) { gint old = sci_get_lexer(sci); - SSM(sci, SCI_SETLEXER, lexer_id, 0); + /* TODO, LexerNameFromID() is already deprecated */ + ILexer5 *lexer = CreateLexer(LexerNameFromID(lexer_id)); + + SSM(sci, SCI_SETILEXER, 0, (uintptr_t) lexer); if (old != (gint)lexer_id) SSM(sci, SCI_CLEARDOCUMENTSTYLE, 0, 0); @@ -1443,4 +1447,3 @@ gint sci_word_end_position(ScintillaObject *sci, gint position, gboolean onlyWor { return SSM(sci, SCI_WORDENDPOSITION, position, onlyWordCharacters); } -