diff --git a/scintilla/Makefile.am b/scintilla/Makefile.am index 970807b560..a5b7e9627e 100644 --- a/scintilla/Makefile.am +++ b/scintilla/Makefile.am @@ -148,6 +148,7 @@ src/Style.h \ src/UniConversion.cxx \ src/UniConversion.h \ src/UnicodeFromUTF8.h \ +src/UniqueString.cxx \ src/UniqueString.h \ src/ViewStyle.cxx \ src/ViewStyle.h \ diff --git a/scintilla/gtk/Converter.h b/scintilla/gtk/Converter.h index 0ef80ae23f..eb665b4b6e 100644 --- a/scintilla/gtk/Converter.h +++ b/scintilla/gtk/Converter.h @@ -15,24 +15,24 @@ const gsize sizeFailure = static_cast(-1); */ class Converter { GIConv iconvh; - void OpenHandle(const char *fullDestination, const char *charSetSource) { + void OpenHandle(const char *fullDestination, const char *charSetSource) noexcept { iconvh = g_iconv_open(fullDestination, charSetSource); } - bool Succeeded() const { + bool Succeeded() const noexcept { return iconvh != iconvhBad; } public: - Converter() { + Converter() noexcept { iconvh = iconvhBad; } Converter(const char *charSetDestination, const char *charSetSource, bool transliterations) { iconvh = iconvhBad; - Open(charSetDestination, charSetSource, transliterations); + Open(charSetDestination, charSetSource, transliterations); } ~Converter() { Close(); } - operator bool() const { + operator bool() const noexcept { return Succeeded(); } void Open(const char *charSetDestination, const char *charSetSource, bool transliterations) { @@ -50,13 +50,13 @@ class Converter { } } } - void Close() { + void Close() noexcept { if (Succeeded()) { g_iconv_close(iconvh); iconvh = iconvhBad; } } - gsize Convert(char** src, gsize *srcleft, char **dst, gsize *dstleft) const { + gsize Convert(char **src, gsize *srcleft, char **dst, gsize *dstleft) const noexcept { if (!Succeeded()) { return sizeFailure; } else { diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index 26e1b5f583..3e18423dad 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -26,56 +27,63 @@ #include "Scintilla.h" #include "ScintillaWidget.h" #include "StringCopy.h" +#include "IntegerRectangle.h" #include "XPM.h" #include "UniConversion.h" #include "Converter.h" -static const double kPi = 3.14159265358979323846; +#ifdef _MSC_VER +// Ignore unreferenced local functions in GTK+ headers +#pragma warning(disable: 4505) +#endif + +using namespace Scintilla; + +namespace { + +const double kPi = 3.14159265358979323846; // The Pango version guard for pango_units_from_double and pango_units_to_double // is more complex than simply implementing these here. -static int pangoUnitsFromDouble(double d) { +int pangoUnitsFromDouble(double d) noexcept { return static_cast(d * PANGO_SCALE + 0.5); } -static double doubleFromPangoUnits(int pu) { - return static_cast(pu) / PANGO_SCALE; +float floatFromPangoUnits(int pu) noexcept { + return static_cast(pu) / PANGO_SCALE; } -static cairo_surface_t *CreateSimilarSurface(GdkWindow *window, cairo_content_t content, int width, int height) { +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); } -static GdkWindow *WindowFromWidget(GtkWidget *w) { +GdkWindow *WindowFromWidget(GtkWidget *w) noexcept { return gtk_widget_get_window(w); } -#ifdef _MSC_VER -// Ignore unreferenced local functions in GTK+ headers -#pragma warning(disable: 4505) -#endif - -using namespace Scintilla; +GtkWidget *PWidget(WindowID wid) noexcept { + return static_cast(wid); +} -enum encodingType { singleByte, UTF8, dbcs}; +enum encodingType { singleByte, UTF8, dbcs }; // Holds a PangoFontDescription*. class FontHandle { public: PangoFontDescription *pfd; int characterSet; - FontHandle() : pfd(0), characterSet(-1) { + FontHandle() noexcept : pfd(nullptr), characterSet(-1) { } - FontHandle(PangoFontDescription *pfd_, int characterSet_) { + FontHandle(PangoFontDescription *pfd_, int characterSet_) noexcept { pfd = pfd_; characterSet = characterSet_; } ~FontHandle() { if (pfd) pango_font_description_free(pfd); - pfd = 0; + pfd = nullptr; } static FontHandle *CreateNewFont(const FontParameters &fp); }; @@ -88,24 +96,22 @@ FontHandle *FontHandle::CreateNewFont(const FontParameters &fp) { 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 new FontHandle(pfd, fp.characterSet); } - return NULL; + return nullptr; } // X has a 16 bit coordinate space, so stop drawing here to avoid wrapping -static const int maxCoordinate = 32000; +const int maxCoordinate = 32000; -static FontHandle *PFont(Font &f) { +FontHandle *PFont(const Font &f) noexcept { return static_cast(f.GetID()); } -static GtkWidget *PWidget(WindowID wid) { - return static_cast(wid); } -Font::Font() noexcept : fid(0) {} +Font::Font() noexcept : fid(nullptr) {} Font::~Font() {} @@ -117,7 +123,7 @@ void Font::Create(const FontParameters &fp) { void Font::Release() { if (fid) delete static_cast(fid); - fid = 0; + fid = nullptr; } // Required on OS X @@ -138,14 +144,14 @@ class SurfaceImpl : public Surface { int characterSet; void SetConverter(int characterSet_); public: - SurfaceImpl(); + SurfaceImpl() noexcept; ~SurfaceImpl() override; void Init(WindowID wid) override; void Init(SurfaceID sid, WindowID wid) override; void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override; - void Clear(); + void Clear() noexcept; void Release() override; bool Initialised() override; void PenColour(ColourDesired fore) override; @@ -185,7 +191,7 @@ class SurfaceImpl : public Surface { }; } -const char *CharacterSetID(int characterSet) { +const char *CharacterSetID(int characterSet) noexcept { switch (characterSet) { case SC_CHARSET_ANSI: return ""; @@ -243,33 +249,33 @@ void SurfaceImpl::SetConverter(int characterSet_) { } } -SurfaceImpl::SurfaceImpl() : et(singleByte), -context(0), -psurf(0), -x(0), y(0), inited(false), createdGC(false) -, pcontext(0), layout(0), characterSet(-1) { +SurfaceImpl::SurfaceImpl() noexcept : et(singleByte), +context(nullptr), +psurf(nullptr), +x(0), y(0), inited(false), createdGC(false), +pcontext(nullptr), layout(nullptr), characterSet(-1) { } SurfaceImpl::~SurfaceImpl() { Clear(); } -void SurfaceImpl::Clear() { +void SurfaceImpl::Clear() noexcept { et = singleByte; if (createdGC) { createdGC = false; cairo_destroy(context); } - context = 0; + context = nullptr; if (psurf) cairo_surface_destroy(psurf); - psurf = 0; + psurf = nullptr; if (layout) g_object_unref(layout); - layout = 0; + layout = nullptr; if (pcontext) g_object_unref(pcontext); - pcontext = 0; + pcontext = nullptr; conv.Close(); characterSet = -1; x = 0; @@ -306,8 +312,8 @@ void SurfaceImpl::Init(WindowID wid) { Release(); PLATFORM_ASSERT(wid); // if we are only created from a window ID, we can't perform drawing - psurf = 0; - context = 0; + psurf = nullptr; + context = nullptr; createdGC = false; pcontext = gtk_widget_create_pango_context(PWidget(wid)); PLATFORM_ASSERT(pcontext); @@ -361,7 +367,7 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID void SurfaceImpl::PenColour(ColourDesired fore) { if (context) { - ColourDesired cdFore(fore.AsInteger()); + const ColourDesired cdFore(fore.AsInteger()); cairo_set_source_rgb(context, cdFore.GetRed() / 255.0, cdFore.GetGreen() / 255.0, @@ -374,7 +380,7 @@ int SurfaceImpl::LogPixelsY() { } int SurfaceImpl::DeviceHeightFont(int points) { - int logPix = LogPixelsY(); + const int logPix = LogPixelsY(); return (points * logPix + logPix / 2) / 72; } @@ -383,7 +389,7 @@ void SurfaceImpl::MoveTo(int x_, int y_) { y = y_; } -static int Delta(int difference) { +static int Delta(int difference) noexcept { if (difference < 0) return -1; else if (difference > 0) @@ -396,21 +402,21 @@ 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) { - int xDiff = x_ - x; - int xDelta = Delta(xDiff); - int yDiff = y_ - y; - int yDelta = Delta(yDiff); + 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 - int xEnd = x_ - xDelta; - int left = std::min(x, xEnd); - int width = abs(x - xEnd) + 1; - int yEnd = y_ - yDelta; - int top = std::min(y, yEnd); - int height = abs(y - yEnd) + 1; + 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 ((abs(xDiff) == abs(yDiff))) { + } 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); @@ -453,8 +459,8 @@ void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { PenColour(back); if (context && (rc.left < maxCoordinate)) { // Protect against out of range - rc.left = lround(rc.left); - rc.right = lround(rc.right); + rc.left = std::round(rc.left); + rc.right = std::round(rc.right); cairo_rectangle(context, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); cairo_fill(context); @@ -463,17 +469,18 @@ void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { SurfaceImpl &surfi = static_cast(surfacePattern); - bool canDraw = surfi.psurf != NULL; + const bool canDraw = surfi.psurf != nullptr; if (canDraw) { PLATFORM_ASSERT(context); // Tile pattern over rectangle // Currently assumes 8x8 pattern - int widthPat = 8; - int heightPat = 8; - for (int xTile = rc.left; xTile < rc.right; xTile += widthPat) { - int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat; - for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) { - int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat; + const int widthPat = 8; + const int heightPat = 8; + const IntegerRectangle irc(rc); + for (int xTile = irc.left; xTile < irc.right; xTile += widthPat) { + const int widthx = (xTile + widthPat > irc.right) ? irc.right - xTile : widthPat; + for (int yTile = irc.top; yTile < irc.bottom; yTile += heightPat) { + const int heighty = (yTile + heightPat > irc.bottom) ? irc.bottom - yTile : heightPat; cairo_set_source_surface(context, surfi.psurf, xTile, yTile); cairo_rectangle(context, xTile, yTile, widthx, heighty); cairo_fill(context); @@ -505,8 +512,8 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesi } } -static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) { - double degrees = kPi / 180.0; +static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) noexcept { + const double degrees = kPi / 180.0; cairo_new_sub_path(context); cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees); @@ -519,7 +526,7 @@ static void PathRoundRectangle(cairo_t *context, double left, double top, double void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int /*flags*/) { if (context && rc.Width() > 0) { - ColourDesired cdFill(fill.AsInteger()); + const ColourDesired cdFill(fill.AsInteger()); cairo_set_source_rgba(context, cdFill.GetRed() / 255.0, cdFill.GetGreen() / 255.0, @@ -531,7 +538,7 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fi cairo_rectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0); cairo_fill(context); - ColourDesired cdOutline(outline.AsInteger()); + const ColourDesired cdOutline(outline.AsInteger()); cairo_set_source_rgba(context, cdOutline.GetRed() / 255.0, cdOutline.GetGreen() / 255.0, @@ -581,12 +588,12 @@ void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsi rc.bottom = rc.top + height; int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); - int ucs = stride * height; + const int ucs = stride * height; std::vector image(ucs); for (int iy=0; iy(surfaceSource); - bool canDraw = surfi.psurf != NULL; + const bool canDraw = surfi.psurf != nullptr; if (canDraw) { PLATFORM_ASSERT(context); cairo_set_source_surface(context, surfi.psurf, @@ -648,7 +655,7 @@ static std::string UTF8FromIconv(const Converter &conv, const char *s, int len) char *putf = &utfForm[0]; char *pout = putf; gsize outLeft = len*3+1; - gsize conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); + const gsize conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); if (conversions != sizeFailure) { *pout = '\0'; utfForm.resize(pout - putf); @@ -667,7 +674,7 @@ static size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t gsize inLeft = lenMB; char *pout = wcForm; gsize outLeft = 2; - gsize conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); + const gsize conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); if (conversions != sizeFailure) { return lenMB; } @@ -679,7 +686,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, con ColourDesired fore) { PenColour(fore); if (context) { - XYPOSITION xText = rc.left; + const XYPOSITION xText = rc.left; if (PFont(font_)->pfd) { std::string utfForm; if (et == UTF8) { @@ -694,7 +701,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, con } pango_layout_set_font_description(layout, PFont(font_)->pfd); pango_cairo_update_layout(context, layout); - PangoLayoutLine *pll = pango_layout_get_line_readonly(layout,0); + PangoLayoutLine *pll = pango_layout_get_line_readonly(layout, 0); cairo_move_to(context, xText, ybase); pango_cairo_show_layout_line(context, pll); } @@ -735,24 +742,24 @@ class ClusterIterator { XYPOSITION position; XYPOSITION distance; int curIndex; - ClusterIterator(PangoLayout *layout, int len) : lenPositions(len), finished(false), + ClusterIterator(PangoLayout *layout, int len) noexcept : lenPositions(len), finished(false), positionStart(0), position(0), distance(0), curIndex(0) { iter = pango_layout_get_iter(layout); - pango_layout_iter_get_cluster_extents(iter, NULL, &pos); + pango_layout_iter_get_cluster_extents(iter, nullptr, &pos); } ~ClusterIterator() { pango_layout_iter_free(iter); } - void Next() { + void Next() noexcept { positionStart = position; if (pango_layout_iter_next_cluster(iter)) { - pango_layout_iter_get_cluster_extents(iter, NULL, &pos); - position = doubleFromPangoUnits(pos.x); + pango_layout_iter_get_cluster_extents(iter, nullptr, &pos); + position = floatFromPangoUnits(pos.x); curIndex = pango_layout_iter_get_index(iter); } else { finished = true; - position = doubleFromPangoUnits(pos.x + pos.width); + position = floatFromPangoUnits(pos.x + pos.width); curIndex = lenPositions; } distance = position - positionStart; @@ -771,7 +778,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION ClusterIterator iti(layout, lenPositions); while (!iti.finished) { iti.Next(); - int places = iti.curIndex - i; + 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 @@ -798,8 +805,8 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION ClusterIterator iti(layout, strlen(utfForm.c_str())); while (!iti.finished) { iti.Next(); - int clusterEnd = iti.curIndex; - int places = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart); + 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); @@ -814,7 +821,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION PLATFORM_ASSERT(i == lenPositions); } } - if (positionsCalculated < 1 ) { + 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 || @@ -831,13 +838,13 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION ClusterIterator iti(layout, utfForm.length()); while (!iti.finished) { iti.Next(); - int clusterEnd = iti.curIndex; - int ligatureLength = g_utf8_strlen(utfForm.c_str() + clusterStart, clusterEnd - clusterStart); + 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, NULL); - XYPOSITION widthTotal = doubleFromPangoUnits(widthLayout); + pango_layout_get_size(layout, &widthLayout, nullptr); + const XYPOSITION widthTotal = floatFromPangoUnits(widthLayout); for (int bytePos=0; bytePospfd) { PangoFontMetrics *metrics = pango_context_get_metrics(pcontext, PFont(font_)->pfd, pango_context_get_language(pcontext)); - ascent = - doubleFromPangoUnits(pango_font_metrics_get_ascent(metrics)); + ascent = std::floor(floatFromPangoUnits( + pango_font_metrics_get_ascent(metrics))); pango_font_metrics_unref(metrics); } if (ascent == 0) { @@ -916,7 +923,8 @@ XYPOSITION SurfaceImpl::Descent(Font &font_) { if (PFont(font_)->pfd) { PangoFontMetrics *metrics = pango_context_get_metrics(pcontext, PFont(font_)->pfd, pango_context_get_language(pcontext)); - int descent = doubleFromPangoUnits(pango_font_metrics_get_descent(metrics)); + const XYPOSITION descent = std::floor(floatFromPangoUnits( + pango_font_metrics_get_descent(metrics))); pango_font_metrics_unref(metrics); return descent; } @@ -961,7 +969,7 @@ Window::~Window() {} void Window::Destroy() { if (wid) { - ListBox *listbox = dynamic_cast(this); + ListBox *listbox = dynamic_cast(this); if (listbox) { gtk_widget_hide(GTK_WIDGET(wid)); // clear up window content @@ -972,7 +980,7 @@ void Window::Destroy() { } else { gtk_widget_destroy(GTK_WIDGET(wid)); } - wid = 0; + wid = nullptr; } } @@ -982,8 +990,8 @@ PRectangle Window::GetPosition() const { if (wid) { GtkAllocation allocation; gtk_widget_get_allocation(PWidget(wid), &allocation); - rc.left = allocation.x; - rc.top = allocation.y; + rc.left = static_cast(allocation.x); + rc.top = static_cast(allocation.y); if (allocation.width > 20) { rc.right = rc.left + allocation.width; rc.bottom = rc.top + allocation.height; @@ -994,10 +1002,10 @@ PRectangle Window::GetPosition() const { void Window::SetPosition(PRectangle rc) { GtkAllocation alloc; - alloc.x = rc.left; - alloc.y = rc.top; - alloc.width = rc.Width(); - alloc.height = rc.Height(); + alloc.x = static_cast(rc.left); + alloc.y = static_cast(rc.top); + alloc.width = static_cast(rc.Width()); + alloc.height = static_cast(rc.Height()); gtk_widget_size_allocate(PWidget(wid), &alloc); } @@ -1011,8 +1019,8 @@ GdkRectangle MonitorRectangleForWidget(GtkWidget *wid) { GdkMonitor *monitor = gdk_display_get_monitor_at_window(pdisplay, wnd); gdk_monitor_get_geometry(monitor, &rcScreen); #else - GdkScreen* screen = gtk_widget_get_screen(wid); - gint monitor_num = gdk_screen_get_monitor_at_window(screen, wnd); + GdkScreen *screen = gtk_widget_get_screen(wid); + const gint monitor_num = gdk_screen_get_monitor_at_window(screen, wnd); gdk_screen_get_monitor_geometry(screen, monitor_num, &rcScreen); #endif return rcScreen; @@ -1021,18 +1029,19 @@ GdkRectangle MonitorRectangleForWidget(GtkWidget *wid) { } void Window::SetPositionRelative(PRectangle rc, const Window *relativeTo) { + const IntegerRectangle irc(rc); int ox = 0; int oy = 0; GdkWindow *wndRelativeTo = WindowFromWidget(PWidget(relativeTo->wid)); gdk_window_get_origin(wndRelativeTo, &ox, &oy); - ox += rc.left; - oy += rc.top; + ox += irc.left; + oy += irc.top; - GdkRectangle rcMonitor = MonitorRectangleForWidget(PWidget(relativeTo->wid)); + const GdkRectangle rcMonitor = MonitorRectangleForWidget(PWidget(relativeTo->wid)); /* do some corrections to fit into screen */ - int sizex = rc.right - rc.left; - int sizey = rc.bottom - rc.top; + const int sizex = irc.Width(); + const int sizey = irc.Height(); if (sizex > rcMonitor.width || ox < rcMonitor.x) ox = rcMonitor.x; /* the best we can do */ else if (ox + sizex > rcMonitor.x + rcMonitor.width) @@ -1065,9 +1074,10 @@ void Window::InvalidateAll() { void Window::InvalidateRectangle(PRectangle rc) { if (wid) { + const IntegerRectangle irc(rc); gtk_widget_queue_draw_area(PWidget(wid), - rc.left, rc.top, - rc.right - rc.left, rc.bottom - rc.top); + irc.left, irc.top, + irc.Width(), irc.Height()); } } @@ -1134,24 +1144,24 @@ PRectangle Window::GetMonitorRect(Point pt) { pt.x + x_offset, pt.y + y_offset); gdk_monitor_get_geometry(monitor, &rect); #else - GdkScreen* screen = gtk_widget_get_screen(PWidget(wid)); - gint monitor_num = gdk_screen_get_monitor_at_point(screen, + 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); gdk_screen_get_monitor_geometry(screen, monitor_num, &rect); #endif rect.x -= x_offset; rect.y -= y_offset; - return PRectangle(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); + return PRectangle::FromInts(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); } -typedef std::map ImageMap; +typedef std::map ImageMap; struct ListImage { const RGBAImage *rgba_data; GdkPixbuf *pixbuf; }; -static void list_image_free(gpointer, gpointer value, gpointer) { +static void list_image_free(gpointer, gpointer value, gpointer) noexcept { ListImage *list_image = static_cast(value); if (list_image->pixbuf) g_object_unref(list_image->pixbuf); @@ -1176,8 +1186,8 @@ class ListBoxX : public ListBox { WindowID list; WindowID scroller; void *pixhash; - GtkCellRenderer* pixbuf_renderer; - GtkCellRenderer* renderer; + GtkCellRenderer *pixbuf_renderer; + GtkCellRenderer *renderer; RGBAImageSet images; int desiredVisibleRows; unsigned int maxItemCharacters; @@ -1188,28 +1198,29 @@ class ListBoxX : public ListBox { public: IListBoxDelegate *delegate; - ListBoxX() : widCached(0), frame(0), list(0), scroller(0), pixhash(NULL), pixbuf_renderer(0), - renderer(0), + ListBoxX() noexcept : widCached(nullptr), frame(nullptr), list(nullptr), scroller(nullptr), + pixhash(nullptr), pixbuf_renderer(nullptr), + renderer(nullptr), desiredVisibleRows(5), maxItemCharacters(0), aveCharWidth(1), #if GTK_CHECK_VERSION(3,0,0) - cssProvider(NULL), + cssProvider(nullptr), #endif delegate(nullptr) { } ~ListBoxX() override { if (pixhash) { - g_hash_table_foreach((GHashTable *) pixhash, list_image_free, NULL); + g_hash_table_foreach((GHashTable *) pixhash, list_image_free, nullptr); g_hash_table_destroy((GHashTable *) pixhash); } if (widCached) { gtk_widget_destroy(GTK_WIDGET(widCached)); - wid = widCached = 0; + wid = widCached = nullptr; } #if GTK_CHECK_VERSION(3,0,0) if (cssProvider) { g_object_unref(cssProvider); - cssProvider = NULL; + cssProvider = nullptr; } #endif } @@ -1247,7 +1258,7 @@ static int treeViewGetRowHeight(GtkTreeView *view) { // version is inaccurate for GTK 3.14. GdkRectangle rect; GtkTreePath *path = gtk_tree_path_new_first(); - gtk_tree_view_get_background_area(view, path, NULL, &rect); + gtk_tree_view_get_background_area(view, path, nullptr, &rect); gtk_tree_path_free(path); return rect.height; #else @@ -1255,10 +1266,10 @@ static int treeViewGetRowHeight(GtkTreeView *view) { int vertical_separator=0; int expander_size=0; GtkTreeViewColumn *column = gtk_tree_view_get_column(view, 0); - gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &row_height); + 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, NULL); + "expander-size", &expander_size, nullptr); row_height += vertical_separator; row_height = std::max(row_height, expander_size); return row_height; @@ -1292,7 +1303,7 @@ static void small_scroller_get_preferred_height(GtkWidget *widget, gint *min, gi GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget)); if (GTK_IS_TREE_VIEW(child)) { GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(child)); - int n_rows = gtk_tree_model_iter_n_children(model, NULL); + int n_rows = gtk_tree_model_iter_n_children(model, nullptr); int row_height = treeViewGetRowHeight(GTK_TREE_VIEW(child)); *min = MAX(1, row_height); @@ -1318,11 +1329,11 @@ static void small_scroller_class_init(SmallScrollerClass *klass) { #endif } -static void small_scroller_init(SmallScroller *){} +static void small_scroller_init(SmallScroller *) {} -static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) { +static gboolean ButtonPress(GtkWidget *, GdkEventButton *ev, gpointer p) { try { - ListBoxX* lb = static_cast(p); + ListBoxX *lb = static_cast(p); if (ev->type == GDK_2BUTTON_PRESS && lb->delegate) { ListBoxEvent event(ListBoxEvent::EventType::doubleClick); lb->delegate->ListNotify(&event); @@ -1335,9 +1346,9 @@ static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) { return FALSE; } -static gboolean ButtonRelease(GtkWidget *, GdkEventButton* ev, gpointer p) { +static gboolean ButtonRelease(GtkWidget *, GdkEventButton *ev, gpointer p) { try { - ListBoxX* lb = static_cast(p); + ListBoxX *lb = static_cast(p); if (ev->type != GDK_2BUTTON_PRESS && lb->delegate) { ListBoxEvent event(ListBoxEvent::EventType::selectionChange); lb->delegate->ListNotify(&event); @@ -1351,9 +1362,9 @@ static gboolean ButtonRelease(GtkWidget *, GdkEventButton* ev, gpointer p) { /* Change the active color to the selected color so the listbox uses the color scheme that it would use if it had the focus. */ -static void StyleSet(GtkWidget *w, GtkStyle*, void*) { +static void StyleSet(GtkWidget *w, GtkStyle *, void *) { - g_return_if_fail(w != NULL); + g_return_if_fail(w != nullptr); /* Copy the selected color to active. Note that the modify calls will cause recursive calls to this function after the value is updated and w->style to @@ -1365,7 +1376,7 @@ static void StyleSet(GtkWidget *w, GtkStyle*, void*) { // The *override* calls are deprecated now, so only call them for older versions of GTK+. #elif GTK_CHECK_VERSION(3,0,0) GtkStyleContext *styleContext = gtk_widget_get_style_context(w); - if (styleContext == NULL) + if (styleContext == nullptr) return; GdkRGBA colourForeSelected; @@ -1376,7 +1387,7 @@ static void StyleSet(GtkWidget *w, GtkStyle*, void*) { gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, &colourForeSelected); styleContext = gtk_widget_get_style_context(w); - if (styleContext == NULL) + if (styleContext == nullptr) return; GdkRGBA colourBaseSelected; @@ -1387,12 +1398,12 @@ static void StyleSet(GtkWidget *w, GtkStyle*, void*) { gtk_widget_override_background_color(w, GTK_STATE_FLAG_ACTIVE, &colourBaseSelected); #else GtkStyle *style = gtk_widget_get_style(w); - if (style == NULL) + if (style == nullptr) return; if (!gdk_color_equal(&style->base[GTK_STATE_SELECTED], &style->base[GTK_STATE_ACTIVE])) gtk_widget_modify_base(w, GTK_STATE_ACTIVE, &style->base[GTK_STATE_SELECTED]); style = gtk_widget_get_style(w); - if (style == NULL) + if (style == nullptr) return; if (!gdk_color_equal(&style->text[GTK_STATE_SELECTED], &style->text[GTK_STATE_ACTIVE])) gtk_widget_modify_text(w, GTK_STATE_ACTIVE, &style->text[GTK_STATE_SELECTED]); @@ -1400,7 +1411,7 @@ static void StyleSet(GtkWidget *w, GtkStyle*, void*) { } void ListBoxX::Create(Window &parent, int, Point, int, bool, int) { - if (widCached != 0) { + if (widCached != nullptr) { wid = widCached; return; } @@ -1413,13 +1424,13 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, int) { wid = widCached = gtk_window_new(GTK_WINDOW_POPUP); - frame = gtk_frame_new(NULL); + frame = gtk_frame_new(nullptr); gtk_widget_show(PWidget(frame)); gtk_container_add(GTK_CONTAINER(GetID()), PWidget(frame)); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT); gtk_container_set_border_width(GTK_CONTAINER(frame), 0); - scroller = g_object_new(small_scroller_get_type(), NULL); + 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); @@ -1431,7 +1442,7 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, int) { gtk_list_store_new(N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING); list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); - g_signal_connect(G_OBJECT(list), "style-set", G_CALLBACK(StyleSet), NULL); + g_signal_connect(G_OBJECT(list), "style-set", G_CALLBACK(StyleSet), nullptr); #if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *styleContext = gtk_widget_get_style_context(GTK_WIDGET(list)); @@ -1466,7 +1477,7 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, int) { gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); if (g_object_class_find_property(G_OBJECT_GET_CLASS(list), "fixed-height-mode")) - g_object_set(G_OBJECT(list), "fixed-height-mode", TRUE, NULL); + g_object_set(G_OBJECT(list), "fixed-height-mode", TRUE, nullptr); GtkWidget *widget = PWidget(list); // No code inside the G_OBJECT macro gtk_container_add(GTK_CONTAINER(PWidget(scroller)), widget); @@ -1496,7 +1507,7 @@ void ListBoxX::SetFont(Font &font) { // On GTK < 3.21.0 the units are incorrectly parsed, so a font size in points // 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) != NULL || // on < 3.21.0 + if (gtk_check_version(3, 21, 0) != nullptr || // on < 3.21.0 pango_font_description_get_size_is_absolute(pfd)) { ssFontSetting << "px; "; } else { @@ -1505,7 +1516,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, NULL); + ssFontSetting.str().c_str(), -1, nullptr); } #else gtk_widget_modify_font(PWidget(list), PFont(font)->pfd); @@ -1543,7 +1554,7 @@ PRectangle ListBoxX::GetDesiredRect() { // This, apparently unnecessary call, ensures gtk_tree_view_column_cell_get_size // returns reasonable values. #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_get_preferred_size(GTK_WIDGET(frame), NULL, &req); + gtk_widget_get_preferred_size(GTK_WIDGET(frame), nullptr, &req); #else gtk_widget_size_request(GTK_WIDGET(frame), &req); #endif @@ -1552,7 +1563,7 @@ PRectangle ListBoxX::GetDesiredRect() { // First calculate height of the clist for our desired visible // row count otherwise it tries to expand to the total # of rows // Get cell height - int row_height = GetRowHeight(); + const int row_height = GetRowHeight(); #if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *styleContextFrame = gtk_widget_get_style_context(PWidget(frame)); GtkStateFlags stateFlagsFrame = gtk_style_context_get_state(styleContextFrame); @@ -1573,7 +1584,7 @@ PRectangle ListBoxX::GetDesiredRect() { gtk_style_context_get_border(styleContextFrameBorder, stateFlagsFrame, &border_border); g_object_unref(styleContextFrameBorder); # else // < 3.20 - if (gtk_check_version(3, 20, 0) == NULL) { + if (gtk_check_version(3, 20, 0) == nullptr) { // default to 1px all around as it's likely what it is, and so we don't miss 2px height // on GTK 3.20 when built against an earlier version. border_border.top = border_border.bottom = border_border.left = border_border.right = 1; @@ -1599,7 +1610,7 @@ PRectangle ListBoxX::GetDesiredRect() { // Add horizontal padding and borders int horizontal_separator=0; gtk_widget_style_get(PWidget(list), - "horizontal-separator", &horizontal_separator, NULL); + "horizontal-separator", &horizontal_separator, nullptr); rc.right += horizontal_separator; #if GTK_CHECK_VERSION(3,0,0) rc.right += (padding.left + padding.right @@ -1615,7 +1626,7 @@ PRectangle ListBoxX::GetDesiredRect() { GtkWidget *vscrollbar = gtk_scrolled_window_get_vscrollbar(GTK_SCROLLED_WINDOW(scroller)); #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_get_preferred_size(vscrollbar, NULL, &req); + gtk_widget_get_preferred_size(vscrollbar, nullptr, &req); #else gtk_widget_size_request(vscrollbar, &req); #endif @@ -1651,32 +1662,32 @@ static void init_pixmap(ListImage *list_image) { list_image->rgba_data->GetWidth(), list_image->rgba_data->GetHeight(), list_image->rgba_data->GetWidth() * 4, - NULL, - NULL); + nullptr, + nullptr); } } #define SPACING 5 void ListBoxX::Append(char *s, int type) { - ListImage *list_image = NULL; + ListImage *list_image = nullptr; if ((type >= 0) && pixhash) { - list_image = static_cast(g_hash_table_lookup((GHashTable *) pixhash - , (gconstpointer) GINT_TO_POINTER(type))); + list_image = static_cast(g_hash_table_lookup((GHashTable *) pixhash, + GINT_TO_POINTER(type))); } GtkTreeIter iter; GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list))); gtk_list_store_append(GTK_LIST_STORE(store), &iter); if (list_image) { - if (NULL == list_image->pixbuf) + if (nullptr == list_image->pixbuf) 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); - gint pixbuf_width = gdk_pixbuf_get_width(list_image->pixbuf); + 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); @@ -1691,7 +1702,7 @@ void ListBoxX::Append(char *s, int type) { gtk_list_store_set(GTK_LIST_STORE(store), &iter, TEXT_COLUMN, s, -1); } - size_t len = strlen(s); + const size_t len = strlen(s); if (maxItemCharacters < len) maxItemCharacters = len; } @@ -1699,7 +1710,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)), NULL); + (GTK_TREE_VIEW(list)), nullptr); return 0; } @@ -1714,12 +1725,12 @@ void ListBoxX::Select(int n) { return; } - bool valid = gtk_tree_model_iter_nth_child(model, &iter, NULL, n) != FALSE; + const bool valid = gtk_tree_model_iter_nth_child(model, &iter, nullptr, n) != FALSE; if (valid) { gtk_tree_selection_select_iter(selection, &iter); // Move the scrollbar to show the selection. - int total = Length(); + const int total = Length(); #if GTK_CHECK_VERSION(3,0,0) GtkAdjustment *adj = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list)); @@ -1727,10 +1738,10 @@ void ListBoxX::Select(int n) { GtkAdjustment *adj = gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list)); #endif - gfloat value = ((gfloat)n / total) * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj)) + 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; // Get cell height - int row_height = GetRowHeight(); + const int row_height = GetRowHeight(); int rows = Length(); if ((rows == 0) || (rows > desiredVisibleRows)) @@ -1738,7 +1749,7 @@ void ListBoxX::Select(int n) { if (rows & 0x1) { // Odd rows to display -- We are now in the middle. // Align it so that we don't chop off rows. - value += (gfloat)row_height / 2.0; + value += static_cast(row_height) / 2.0f; } // Clamp it. value = (value < 0)? 0 : value; @@ -1765,7 +1776,7 @@ int ListBoxX::GetSelection() { selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { GtkTreePath *path = gtk_tree_model_get_path(model, &iter); - int *indices = gtk_tree_path_get_indices(path); + const int *indices = gtk_tree_path_get_indices(path); // Don't free indices. if (indices) index = indices[0]; @@ -1780,7 +1791,7 @@ int ListBoxX::Find(const char *prefix) { gtk_tree_view_get_model(GTK_TREE_VIEW(list)); bool valid = gtk_tree_model_get_iter_first(model, &iter) != FALSE; int i = 0; - while(valid) { + while (valid) { gchar *s; gtk_tree_model_get(model, &iter, TEXT_COLUMN, &s, -1); if (s && (0 == strncmp(prefix, s, strlen(prefix)))) { @@ -1795,10 +1806,10 @@ int ListBoxX::Find(const char *prefix) { } void ListBoxX::GetValue(int n, char *value, int len) { - char *text = NULL; + char *text = nullptr; GtkTreeIter iter; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); - bool valid = gtk_tree_model_iter_nth_child(model, &iter, NULL, n) != FALSE; + const bool valid = gtk_tree_model_iter_nth_child(model, &iter, nullptr, n) != FALSE; if (valid) { gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1); } @@ -1822,12 +1833,12 @@ void ListBoxX::RegisterRGBA(int type, RGBAImage *image) { pixhash = g_hash_table_new(g_direct_hash, g_direct_equal); } ListImage *list_image = static_cast(g_hash_table_lookup((GHashTable *) pixhash, - (gconstpointer) GINT_TO_POINTER(type))); + GINT_TO_POINTER(type))); if (list_image) { // Drop icon already registered if (list_image->pixbuf) g_object_unref(list_image->pixbuf); - list_image->pixbuf = NULL; + list_image->pixbuf = nullptr; list_image->rgba_data = image; } else { list_image = g_new0(ListImage, 1); @@ -1857,10 +1868,10 @@ void ListBoxX::SetDelegate(IListBoxDelegate *lbDelegate) { void ListBoxX::SetList(const char *listText, char separator, char typesep) { Clear(); - int count = strlen(listText) + 1; + const size_t count = strlen(listText) + 1; std::vector words(listText, listText+count); char *startword = &words[0]; - char *numword = NULL; + char *numword = nullptr; int i = 0; for (; words[i]; i++) { if (words[i] == separator) { @@ -1869,7 +1880,7 @@ void ListBoxX::SetList(const char *listText, char separator, char typesep) { *numword = '\0'; Append(startword, numword?atoi(numword + 1):-1); startword = &words[0] + i + 1; - numword = NULL; + numword = nullptr; } else if (words[i] == typesep) { numword = &words[0] + i; } @@ -1881,7 +1892,7 @@ void ListBoxX::SetList(const char *listText, char separator, char typesep) { } } -Menu::Menu() noexcept : mid(0) {} +Menu::Menu() noexcept : mid(nullptr) {} void Menu::CreatePopUp() { Destroy(); @@ -1892,7 +1903,7 @@ void Menu::CreatePopUp() { void Menu::Destroy() { if (mid) g_object_unref(G_OBJECT(mid)); - mid = 0; + mid = nullptr; } #if !GTK_CHECK_VERSION(3,22,0) @@ -1908,12 +1919,12 @@ void Menu::Show(Point pt, Window &w) { gtk_widget_show_all(GTK_WIDGET(widget)); #if GTK_CHECK_VERSION(3,22,0) // Rely on GTK+ to do the right thing with positioning - gtk_menu_popup_at_pointer(widget, NULL); + gtk_menu_popup_at_pointer(widget, nullptr); #else - GdkRectangle rcMonitor = MonitorRectangleForWidget(PWidget(w.GetID())); + const GdkRectangle rcMonitor = MonitorRectangleForWidget(PWidget(w.GetID())); GtkRequisition requisition; #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_get_preferred_size(GTK_WIDGET(widget), NULL, &requisition); + gtk_widget_get_preferred_size(GTK_WIDGET(widget), nullptr, &requisition); #else gtk_widget_size_request(GTK_WIDGET(widget), &requisition); #endif @@ -1923,7 +1934,7 @@ void Menu::Show(Point pt, Window &w) { if ((pt.y + requisition.height) > rcMonitor.y + rcMonitor.height) { pt.y = rcMonitor.y + rcMonitor.height - requisition.height; } - gtk_menu_popup(widget, NULL, NULL, MenuPositionFunc, + 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()); #endif @@ -1931,38 +1942,38 @@ void Menu::Show(Point pt, Window &w) { class DynamicLibraryImpl : public DynamicLibrary { protected: - GModule* m; + GModule *m; public: - explicit DynamicLibraryImpl(const char *modulePath) { + explicit DynamicLibraryImpl(const char *modulePath) noexcept { m = g_module_open(modulePath, G_MODULE_BIND_LAZY); } ~DynamicLibraryImpl() override { - if (m != NULL) + 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 != NULL) { - gpointer fn_address = NULL; - gboolean status = g_module_symbol(m, name, &fn_address); + 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 NULL; + return nullptr; } else { - return NULL; + return nullptr; } } bool IsValid() override { - return m != NULL; + return m != nullptr; } }; DynamicLibrary *DynamicLibrary::Load(const char *modulePath) { - return static_cast( new DynamicLibraryImpl(modulePath) ); + return static_cast(new DynamicLibraryImpl(modulePath)); } ColourDesired Platform::Chrome() { @@ -2017,7 +2028,7 @@ void Platform::DebugPrintf(const char *, ...) {} static bool assertionPopUps = true; bool Platform::ShowAssertionPopUps(bool assertionPopUps_) { - bool ret = assertionPopUps; + const bool ret = assertionPopUps; assertionPopUps = assertionPopUps_; return ret; } diff --git a/scintilla/gtk/ScintillaGTK.cxx b/scintilla/gtk/ScintillaGTK.cxx index 2deac8c75c..a78f00d7ba 100644 --- a/scintilla/gtk/ScintillaGTK.cxx +++ b/scintilla/gtk/ScintillaGTK.cxx @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -29,7 +28,10 @@ #include #endif -#if defined(__WIN32__) || defined(_MSC_VER) +#if defined(_WIN32) +// On Win32 use windows.h to access clipboard (rectangular format) and systems parameters +#undef NOMINMAX +#define NOMINMAX #include #endif @@ -43,6 +45,7 @@ #include "SciLexer.h" #endif #include "StringCopy.h" +#include "CharacterCategory.h" #ifdef SCI_LEXER #include "LexerModule.h" #endif @@ -92,7 +95,7 @@ #define SC_INDICATOR_CONVERTED INDIC_IME+2 #define SC_INDICATOR_UNKNOWN INDIC_IME_MAX -static GdkWindow *WindowFromWidget(GtkWidget *w) { +static GdkWindow *WindowFromWidget(GtkWidget *w) noexcept { return gtk_widget_get_window(w); } @@ -105,7 +108,7 @@ static GdkWindow *WindowFromWidget(GtkWidget *w) { using namespace Scintilla; -static GdkWindow *PWindow(const Window &w) { +static GdkWindow *PWindow(const Window &w) noexcept { GtkWidget *widget = static_cast(w.GetID()); return gtk_widget_get_window(widget); } @@ -113,26 +116,25 @@ static GdkWindow *PWindow(const Window &w) { extern std::string UTF8FromLatin1(const char *s, int len); enum { - COMMAND_SIGNAL, - NOTIFY_SIGNAL, - LAST_SIGNAL + COMMAND_SIGNAL, + NOTIFY_SIGNAL, + LAST_SIGNAL }; static gint scintilla_signals[LAST_SIGNAL] = { 0 }; enum { - TARGET_STRING, - TARGET_TEXT, - TARGET_COMPOUND_TEXT, - TARGET_UTF8_STRING, - TARGET_URI + TARGET_STRING, + TARGET_TEXT, + TARGET_COMPOUND_TEXT, + TARGET_UTF8_STRING, + TARGET_URI }; -GdkAtom ScintillaGTK::atomClipboard = 0; -GdkAtom ScintillaGTK::atomUTF8 = 0; -GdkAtom ScintillaGTK::atomString = 0; -GdkAtom ScintillaGTK::atomUriList = 0; -GdkAtom ScintillaGTK::atomDROPFILES_DND = 0; +GdkAtom ScintillaGTK::atomUTF8 = nullptr; +GdkAtom ScintillaGTK::atomString = nullptr; +GdkAtom ScintillaGTK::atomUriList = nullptr; +GdkAtom ScintillaGTK::atomDROPFILES_DND = nullptr; static const GtkTargetEntry clipboardCopyTargets[] = { { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING }, @@ -149,7 +151,7 @@ static const gint nClipboardPasteTargets = ELEMENTS(clipboardPasteTargets); static const GdkDragAction actionCopyOrMove = static_cast(GDK_ACTION_COPY | GDK_ACTION_MOVE); -static GtkWidget *PWidget(Window &w) { +static GtkWidget *PWidget(const Window &w) noexcept { return static_cast(w.GetID()); } @@ -159,20 +161,25 @@ ScintillaGTK *ScintillaGTK::FromWidget(GtkWidget *widget) { } ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) : - adjustmentv(0), adjustmenth(0), - verticalScrollBarWidth(30), horizontalScrollBarHeight(30), - evbtn(nullptr), capturedMouse(false), dragWasDropped(false), - lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), parentClass(0), - im_context(NULL), lastNonCommonScript(PANGO_SCRIPT_INVALID_CODE), - lastWheelMouseDirection(0), - wheelMouseIntensity(0), - smoothScrollY(0), - smoothScrollX(0), - rgnUpdate(0), - repaintFullWindow(false), - styleIdleID(0), - accessibilityEnabled(SC_ACCESSIBILITY_ENABLED), - accessible(0) { + adjustmentv(nullptr), adjustmenth(nullptr), + verticalScrollBarWidth(30), horizontalScrollBarHeight(30), + evbtn(nullptr), + buttonMouse(0), + capturedMouse(false), dragWasDropped(false), + lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), + parentClass(nullptr), + atomSought(nullptr), + im_context(nullptr), + lastNonCommonScript(PANGO_SCRIPT_INVALID_CODE), + lastWheelMouseDirection(0), + wheelMouseIntensity(0), + smoothScrollY(0), + smoothScrollX(0), + rgnUpdate(nullptr), + repaintFullWindow(false), + styleIdleID(0), + accessibilityEnabled(SC_ACCESSIBILITY_ENABLED), + accessible(nullptr) { sci = sci_; wMain = GTK_WIDGET(sci); @@ -182,7 +189,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")); + ::RegisterClipboardFormat("MSDEVColumnSelect")); // Get intellimouse parameters when running on win32; otherwise use // reasonable default @@ -241,7 +248,7 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { attrs.cursor = cursor; #if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_window(widget, gdk_window_new(gtk_widget_get_parent_window(widget), &attrs, - GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_CURSOR)); + GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_CURSOR)); #if GTK_CHECK_VERSION(3,8,0) gtk_widget_register_window(widget, gtk_widget_get_window(widget)); #else @@ -249,13 +256,13 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { #endif #if !GTK_CHECK_VERSION(3,18,0) gtk_style_context_set_background(gtk_widget_get_style_context(widget), - gtk_widget_get_window(widget)); + gtk_widget_get_window(widget)); #endif gdk_window_show(gtk_widget_get_window(widget)); UnRefCursor(cursor); #else widget->window = gdk_window_new(gtk_widget_get_parent_window(widget), &attrs, - GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR); + GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR); gdk_window_set_user_data(widget->window, widget); widget->style = gtk_style_attach(widget->style, widget->window); gdk_window_set_background(widget->window, &widget->style->bg[GTK_STATE_NORMAL]); @@ -267,15 +274,15 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { im_context = gtk_im_multicontext_new(); g_signal_connect(G_OBJECT(im_context), "commit", - G_CALLBACK(Commit), this); + G_CALLBACK(Commit), this); g_signal_connect(G_OBJECT(im_context), "preedit_changed", - G_CALLBACK(PreeditChanged), this); + G_CALLBACK(PreeditChanged), this); gtk_im_context_set_client_window(im_context, WindowFromWidget(widget)); GtkWidget *widtxt = PWidget(wText); // // No code inside the G_OBJECT macro g_signal_connect_after(G_OBJECT(widtxt), "style_set", - G_CALLBACK(ScintillaGTK::StyleSetText), NULL); + G_CALLBACK(ScintillaGTK::StyleSetText), nullptr); g_signal_connect_after(G_OBJECT(widtxt), "realize", - G_CALLBACK(ScintillaGTK::RealizeText), NULL); + G_CALLBACK(ScintillaGTK::RealizeText), nullptr); gtk_widget_realize(widtxt); gtk_widget_realize(PWidget(scrollbarv)); gtk_widget_realize(PWidget(scrollbarh)); @@ -296,7 +303,7 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { 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); + clipboardCopyTargets, nClipboardCopyTargets); } void ScintillaGTK::Realize(GtkWidget *widget) { @@ -321,7 +328,7 @@ void ScintillaGTK::UnRealizeThis(GtkWidget *widget) { gtk_widget_unrealize(PWidget(wPreedit)); gtk_widget_unrealize(PWidget(wPreeditDraw)); g_object_unref(im_context); - im_context = NULL; + im_context = nullptr; if (GTK_WIDGET_CLASS(parentClass)->unrealize) GTK_WIDGET_CLASS(parentClass)->unrealize(widget); @@ -338,8 +345,8 @@ void ScintillaGTK::UnRealize(GtkWidget *widget) { static void MapWidget(GtkWidget *widget) { if (widget && - gtk_widget_get_visible(GTK_WIDGET(widget)) && - !IS_WIDGET_MAPPED(widget)) { + gtk_widget_get_visible(GTK_WIDGET(widget)) && + !IS_WIDGET_MAPPED(widget)) { gtk_widget_map(widget); } } @@ -389,11 +396,11 @@ void ScintillaGTK::UnMap(GtkWidget *widget) { void ScintillaGTK::ForAll(GtkCallback callback, gpointer callback_data) { try { - (*callback) (PWidget(wText), callback_data); + (*callback)(PWidget(wText), callback_data); if (PWidget(scrollbarv)) - (*callback) (PWidget(scrollbarv), callback_data); + (*callback)(PWidget(scrollbarv), callback_data); if (PWidget(scrollbarh)) - (*callback) (PWidget(scrollbarh), callback_data); + (*callback)(PWidget(scrollbarh), callback_data); } catch (...) { errorStatus = SC_STATUS_FAILURE; } @@ -402,7 +409,7 @@ void ScintillaGTK::ForAll(GtkCallback callback, gpointer callback_data) { void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { ScintillaGTK *sciThis = FromWidget((GtkWidget *)container); - if (callback != NULL && include_internals) { + if (callback && include_internals) { sciThis->ForAll(callback, callback_data); } } @@ -421,7 +428,7 @@ class PreEditString { explicit PreEditString(GtkIMContext *im_context) { gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos); - validUTF8 = g_utf8_validate(str, strlen(str), NULL); + validUTF8 = g_utf8_validate(str, strlen(str), nullptr); uniStr = g_utf8_to_ucs4_fast(str, strlen(str), &uniStrLen); pscript = pango_script_for_unichar(uniStr[0]); } @@ -437,9 +444,9 @@ class PreEditString { gint ScintillaGTK::FocusInThis(GtkWidget *) { try { SetFocusState(true); - if (im_context != NULL) { + if (im_context) { PreEditString pes(im_context); - if (PWidget(wPreedit) != NULL) { + if (PWidget(wPreedit)) { if (strlen(pes.str) > 0) { gtk_widget_show(PWidget(wPreedit)); } else { @@ -464,9 +471,9 @@ gint ScintillaGTK::FocusOutThis(GtkWidget *) { try { SetFocusState(false); - if (PWidget(wPreedit) != NULL) + if (PWidget(wPreedit)) gtk_widget_hide(PWidget(wPreedit)); - if (im_context != NULL) + if (im_context) gtk_im_context_focus_out(im_context); } catch (...) { @@ -486,8 +493,8 @@ void ScintillaGTK::SizeRequest(GtkWidget *widget, GtkRequisition *requisition) { requisition->height = 1; GtkRequisition child_requisition; #if GTK_CHECK_VERSION(3,0,0) - gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarh), NULL, &child_requisition); - gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarv), NULL, &child_requisition); + gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarh), nullptr, &child_requisition); + gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarv), nullptr, &child_requisition); #else gtk_widget_size_request(PWidget(sciThis->scrollbarh), &child_requisition); gtk_widget_size_request(PWidget(sciThis->scrollbarv), &child_requisition); @@ -516,10 +523,10 @@ void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) { gtk_widget_set_allocation(widget, allocation); if (IS_WIDGET_REALIZED(widget)) gdk_window_move_resize(WindowFromWidget(widget), - allocation->x, - allocation->y, - allocation->width, - allocation->height); + allocation->x, + allocation->y, + allocation->width, + allocation->height); sciThis->Resize(allocation->width, allocation->height); @@ -530,7 +537,7 @@ void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) { void ScintillaGTK::Init() { parentClass = reinterpret_cast( - g_type_class_ref(gtk_container_get_type())); + g_type_class_ref(gtk_container_get_type())); gint maskSmooth = 0; #if defined(GDK_WINDOWING_WAYLAND) @@ -544,18 +551,18 @@ void ScintillaGTK::Init() { gtk_widget_set_can_focus(PWidget(wMain), TRUE); gtk_widget_set_sensitive(PWidget(wMain), TRUE); gtk_widget_set_events(PWidget(wMain), - GDK_EXPOSURE_MASK - | GDK_SCROLL_MASK - | maskSmooth - | GDK_STRUCTURE_MASK - | GDK_KEY_PRESS_MASK - | GDK_KEY_RELEASE_MASK - | GDK_FOCUS_CHANGE_MASK - | GDK_LEAVE_NOTIFY_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK); + GDK_EXPOSURE_MASK + | GDK_SCROLL_MASK + | maskSmooth + | GDK_STRUCTURE_MASK + | GDK_KEY_PRESS_MASK + | GDK_KEY_RELEASE_MASK + | GDK_FOCUS_CHANGE_MASK + | GDK_LEAVE_NOTIFY_MASK + | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_POINTER_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK); wText = gtk_drawing_area_new(); gtk_widget_set_parent(PWidget(wText), PWidget(wMain)); @@ -563,15 +570,15 @@ void ScintillaGTK::Init() { gtk_widget_show(widtxt); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(G_OBJECT(widtxt), "draw", - G_CALLBACK(ScintillaGTK::DrawText), this); + G_CALLBACK(ScintillaGTK::DrawText), this); #else g_signal_connect(G_OBJECT(widtxt), "expose_event", - G_CALLBACK(ScintillaGTK::ExposeText), this); + G_CALLBACK(ScintillaGTK::ExposeText), this); #endif #if GTK_CHECK_VERSION(3,0,0) // we need a runtime check because we don't want double buffering when // running on >= 3.9.2 - if (gtk_check_version(3,9,2) != NULL /* on < 3.9.2 */) + if (gtk_check_version(3, 9, 2) != nullptr /* on < 3.9.2 */) #endif { #if !GTK_CHECK_VERSION(3,14,0) @@ -589,7 +596,7 @@ void ScintillaGTK::Init() { #endif gtk_widget_set_can_focus(PWidget(scrollbarv), FALSE); g_signal_connect(G_OBJECT(adjustmentv), "value_changed", - G_CALLBACK(ScrollSignal), this); + G_CALLBACK(ScrollSignal), this); gtk_widget_set_parent(PWidget(scrollbarv), PWidget(wMain)); gtk_widget_show(PWidget(scrollbarv)); @@ -601,15 +608,15 @@ void ScintillaGTK::Init() { #endif gtk_widget_set_can_focus(PWidget(scrollbarh), FALSE); g_signal_connect(G_OBJECT(adjustmenth), "value_changed", - G_CALLBACK(ScrollHSignal), this); + G_CALLBACK(ScrollHSignal), this); gtk_widget_set_parent(PWidget(scrollbarh), PWidget(wMain)); gtk_widget_show(PWidget(scrollbarh)); gtk_widget_grab_focus(PWidget(wMain)); gtk_drag_dest_set(GTK_WIDGET(PWidget(wMain)), - GTK_DEST_DEFAULT_ALL, clipboardPasteTargets, nClipboardPasteTargets, - actionCopyOrMove); + GTK_DEST_DEFAULT_ALL, clipboardPasteTargets, nClipboardPasteTargets, + actionCopyOrMove); /* create pre-edit window */ wPreedit = gtk_window_new(GTK_WINDOW_POPUP); @@ -617,10 +624,10 @@ void ScintillaGTK::Init() { GtkWidget *predrw = PWidget(wPreeditDraw); // No code inside the G_OBJECT macro #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(G_OBJECT(predrw), "draw", - G_CALLBACK(DrawPreedit), this); + G_CALLBACK(DrawPreedit), this); #else g_signal_connect(G_OBJECT(predrw), "expose_event", - G_CALLBACK(ExposePreedit), this); + G_CALLBACK(ExposePreedit), this); #endif gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), predrw); gtk_widget_show(predrw); @@ -630,15 +637,15 @@ void ScintillaGTK::Init() { if (g_object_class_find_property(G_OBJECT_GET_CLASS( G_OBJECT(gtk_settings_get_default())), "gtk-cursor-blink")) { g_object_get(G_OBJECT( - gtk_settings_get_default()), "gtk-cursor-blink", &blinkOn, NULL); + gtk_settings_get_default()), "gtk-cursor-blink", &blinkOn, nullptr); } if (blinkOn && - g_object_class_find_property(G_OBJECT_GET_CLASS( - G_OBJECT(gtk_settings_get_default())), "gtk-cursor-blink-time")) { + g_object_class_find_property(G_OBJECT_GET_CLASS( + G_OBJECT(gtk_settings_get_default())), "gtk-cursor-blink-time")) { gint value; g_object_get(G_OBJECT( - gtk_settings_get_default()), "gtk-cursor-blink-time", &value, NULL); - caret.period = gint(value / 1.75); + gtk_settings_get_default()), "gtk-cursor-blink-time", &value, nullptr); + caret.period = static_cast(value / 1.75); } else { caret.period = 0; } @@ -658,9 +665,9 @@ void ScintillaGTK::Finalise() { FineTickerCancel(tr); } if (accessible) { - gtk_accessible_set_widget(GTK_ACCESSIBLE(accessible), NULL); + gtk_accessible_set_widget(GTK_ACCESSIBLE(accessible), nullptr); g_object_unref(accessible); - accessible = 0; + accessible = nullptr; } ScintillaBase::Finalise(); @@ -682,7 +689,7 @@ 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); + ptStart.x, ptStart.y, ptNow.x, ptNow.y); } void ScintillaGTK::StartDrag() { @@ -692,23 +699,23 @@ void ScintillaGTK::StartDrag() { GtkTargetList *tl = gtk_target_list_new(clipboardCopyTargets, nClipboardCopyTargets); #if GTK_CHECK_VERSION(3,10,0) gtk_drag_begin_with_coordinates(GTK_WIDGET(PWidget(wMain)), - tl, - actionCopyOrMove, - buttonMouse, - evbtn, - -1, -1); + tl, + actionCopyOrMove, + buttonMouse, + evbtn, + -1, -1); #else gtk_drag_begin(GTK_WIDGET(PWidget(wMain)), - tl, - actionCopyOrMove, - buttonMouse, - evbtn); + tl, + actionCopyOrMove, + buttonMouse, + evbtn); #endif } namespace Scintilla { std::string ConvertText(const char *s, size_t len, const char *charSetDest, - const char *charSetSource, bool transliterations, bool silent) { + const char *charSetSource, bool transliterations, bool silent) { // s is not const because of different versions of iconv disagreeing about const std::string destForm; Converter conv(charSetDest, charSetSource, transliterations); @@ -720,7 +727,7 @@ std::string ConvertText(const char *s, size_t len, const char *charSetDest, gsize inLeft = len; char *putf = &destForm[0]; char *pout = putf; - gsize conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); + const gsize conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); if (conversions == sizeFailure) { if (!silent) { if (len == 1) @@ -744,7 +751,7 @@ std::string ConvertText(const char *s, size_t len, const char *charSetDest, // Returns the target converted to UTF8. // Return the length in bytes. Sci::Position ScintillaGTK::TargetAsUTF8(char *text) const { - Sci::Position targetLength = targetEnd - targetStart; + const Sci::Position targetLength = targetEnd - targetStart; if (IsUnicodeMode()) { if (text) { pdoc->GetCharRange(text, targetStart, targetLength); @@ -771,7 +778,7 @@ Sci::Position ScintillaGTK::TargetAsUTF8(char *text) const { // Translates a nul terminated UTF8 string into the document encoding. // Return the length of the result in bytes. Sci::Position ScintillaGTK::EncodedFromUTF8(const char *utf8, char *encoded) const { - Sci::Position inputLength = (lengthForEncode >= 0) ? lengthForEncode : strlen(utf8); + const Sci::Position inputLength = (lengthForEncode >= 0) ? lengthForEncode : strlen(utf8); if (IsUnicodeMode()) { if (encoded) { memcpy(encoded, utf8, inputLength); @@ -799,12 +806,12 @@ Sci::Position ScintillaGTK::EncodedFromUTF8(const char *utf8, char *encoded) con bool ScintillaGTK::ValidCodePage(int codePage) const { return codePage == 0 - || codePage == SC_CP_UTF8 - || codePage == 932 - || codePage == 936 - || codePage == 949 - || codePage == 950 - || codePage == 1361; + || codePage == SC_CP_UTF8 + || codePage == 932 + || codePage == 936 + || codePage == 949 + || codePage == 950 + || codePage == 1361; } sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { @@ -831,7 +838,7 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam case SCI_ENCODEDFROMUTF8: return EncodedFromUTF8(ConstCharPtrFromUPtr(wParam), - CharPtrFromSPtr(lParam)); + CharPtrFromSPtr(lParam)); case SCI_SETRECTANGULARSELECTIONMODIFIER: rectangularSelectionModifier = wParam; @@ -841,15 +848,15 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam return rectangularSelectionModifier; case SCI_SETREADONLY: { - sptr_t ret = ScintillaBase::WndProc(iMessage, wParam, lParam); - if (accessible) { - ScintillaGTKAccessible *sciAccessible = ScintillaGTKAccessible::FromAccessible(accessible); - if (sciAccessible) { - sciAccessible->NotifyReadOnly(); + const sptr_t ret = ScintillaBase::WndProc(iMessage, wParam, lParam); + if (accessible) { + ScintillaGTKAccessible *sciAccessible = ScintillaGTKAccessible::FromAccessible(accessible); + if (sciAccessible) { + sciAccessible->NotifyReadOnly(); + } } + return ret; } - return ret; - } case SCI_GETACCESSIBILITY: return accessibilityEnabled; @@ -867,7 +874,7 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam default: return ScintillaBase::WndProc(iMessage, wParam, lParam); } - } catch (std::bad_alloc&) { + } catch (std::bad_alloc &) { errorStatus = SC_STATUS_BADALLOC; } catch (...) { errorStatus = SC_STATUS_FAILURE; @@ -901,7 +908,7 @@ bool ScintillaGTK::SetIdle(bool on) { if (!idler.state) { idler.state = true; idler.idlerID = GUINT_TO_POINTER( - gdk_threads_add_idle_full(G_PRIORITY_DEFAULT_IDLE, IdleCallback, this, NULL)); + gdk_threads_add_idle_full(G_PRIORITY_DEFAULT_IDLE, IdleCallback, this, nullptr)); } } else { // Stop idler, if it's running @@ -959,11 +966,13 @@ bool ScintillaGTK::PaintContains(PRectangle rc) { } else if (rgnUpdate) { #if GTK_CHECK_VERSION(3,0,0) cairo_rectangle_t grc = {rc.left, rc.top, - rc.right - rc.left, rc.bottom - rc.top}; + rc.right - rc.left, rc.bottom - rc.top + }; contains = CRectListContains(rgnUpdate, grc); #else GdkRectangle grc = {static_cast(rc.left), static_cast(rc.top), - static_cast(rc.right - rc.left), static_cast(rc.bottom - rc.top)}; + static_cast(rc.right - rc.left), static_cast(rc.bottom - rc.top) + }; if (gdk_region_rect_in(rgnUpdate, &grc) != GDK_OVERLAP_RECTANGLE_IN) { contains = false; } @@ -1023,35 +1032,35 @@ void ScintillaGTK::SetHorizontalScrollPos() { bool ScintillaGTK::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) { bool modified = false; - int pageScroll = LinesToScroll(); + const int pageScroll = 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_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_page_increment(adjustmentv, pageScroll); + gtk_adjustment_set_page_size(adjustmentv, nPage); + gtk_adjustment_set_page_increment(adjustmentv, pageScroll); #if !GTK_CHECK_VERSION(3,18,0) gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv)); #endif modified = true; } - PRectangle rcText = GetTextRectangle(); + const PRectangle rcText = GetTextRectangle(); int horizEndPreferred = scrollWidth; if (horizEndPreferred < 0) horizEndPreferred = 0; - unsigned int pageWidth = rcText.Width(); - unsigned int pageIncrement = pageWidth / 3; - unsigned int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth; + const unsigned int pageWidth = static_cast(rcText.Width()); + const unsigned int pageIncrement = pageWidth / 3; + const unsigned int charWidth = 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 || - gtk_adjustment_get_step_increment(adjustmenth) != charWidth) { + gtk_adjustment_get_page_size(adjustmenth) != pageWidth || + gtk_adjustment_get_page_increment(adjustmenth) != pageIncrement || + gtk_adjustment_get_step_increment(adjustmenth) != charWidth) { gtk_adjustment_set_upper(adjustmenth, horizEndPreferred); - gtk_adjustment_set_page_size(adjustmenth, pageWidth); - gtk_adjustment_set_page_increment(adjustmenth, pageIncrement); - gtk_adjustment_set_step_increment(adjustmenth, charWidth); + gtk_adjustment_set_page_size(adjustmenth, pageWidth); + gtk_adjustment_set_page_increment(adjustmenth, pageIncrement); + gtk_adjustment_set_step_increment(adjustmenth, charWidth); #if !GTK_CHECK_VERSION(3,18,0) gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth)); #endif @@ -1065,20 +1074,20 @@ bool ScintillaGTK::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) { } void ScintillaGTK::ReconfigureScrollBars() { - PRectangle rc = wMain.GetClientPosition(); - Resize(rc.Width(), rc.Height()); + const PRectangle rc = wMain.GetClientPosition(); + Resize(static_cast(rc.Width()), static_cast(rc.Height())); } void ScintillaGTK::NotifyChange() { g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0, - Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain)); + Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain)); } void ScintillaGTK::NotifyFocus(bool focus) { if (commandEvents) g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0, - Platform::LongFromTwoShorts - (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain)); + Platform::LongFromTwoShorts + (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain)); Editor::NotifyFocus(focus); } @@ -1086,7 +1095,7 @@ void ScintillaGTK::NotifyParent(SCNotification scn) { scn.nmhdr.hwndFrom = PWidget(wMain); scn.nmhdr.idFrom = GetCtrlID(); g_signal_emit(G_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL], 0, - GetCtrlID(), &scn); + GetCtrlID(), &scn); } void ScintillaGTK::NotifyKey(int key, int modifiers) { @@ -1124,7 +1133,7 @@ class CaseFolderDBCS : public CaseFolderTable { return 1; } else if (*charSet) { std::string sUTF8 = ConvertText(mixed, lenMixed, - "UTF-8", charSet, false); + "UTF-8", charSet, false); if (!sUTF8.empty()) { gchar *mapped = g_utf8_casefold(sUTF8.c_str(), sUTF8.length()); size_t lenMapped = strlen(mapped); @@ -1159,12 +1168,12 @@ CaseFolder *ScintillaGTK::CaseFolderForEncoding() { sCharacter[0] = i; // Silent as some bytes have no assigned character std::string sUTF8 = ConvertText(sCharacter, 1, - "UTF-8", charSetBuffer, false, true); + "UTF-8", charSetBuffer, false, true); if (!sUTF8.empty()) { gchar *mapped = g_utf8_casefold(sUTF8.c_str(), sUTF8.length()); if (mapped) { std::string mappedBack = ConvertText(mapped, strlen(mapped), - charSetBuffer, "UTF-8", false, true); + charSetBuffer, "UTF-8", false, true); if ((mappedBack.length() == 1) && (mappedBack[0] != sCharacter[0])) { pcf->SetTranslation(sCharacter[0], mappedBack[0]); } @@ -1177,7 +1186,7 @@ CaseFolder *ScintillaGTK::CaseFolderForEncoding() { return new CaseFolderDBCS(charSetBuffer); } } - return 0; + return nullptr; } } @@ -1205,8 +1214,8 @@ std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) { if (IsUnicodeMode()) { std::string retMapped(s.length() * maxExpansionCaseConversion, 0); - size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), - (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); + const size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), + (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); retMapped.resize(lenMapped); return retMapped; } @@ -1219,7 +1228,7 @@ std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) { } else { // Change text to UTF-8 std::string sUTF8 = ConvertText(s.c_str(), s.length(), - "UTF-8", charSetBuffer, false); + "UTF-8", charSetBuffer, false); CaseMapper mapper(sUTF8, caseMapping == cmUpper); return ConvertText(mapper.mapped, strlen(mapper.mapped), charSetBuffer, "UTF-8", false); } @@ -1252,37 +1261,47 @@ void ScintillaGTK::Copy() { } } -void ScintillaGTK::Paste() { - atomSought = atomUTF8; - GtkClipboard *clipBoard = - gtk_widget_get_clipboard(GTK_WIDGET(PWidget(wMain)), atomClipboard); - if (clipBoard == NULL) - return; +namespace { - // helper class for the asynchronous paste not to risk calling in a destroyed ScintillaGTK - class Helper : GObjectWatcher { - ScintillaGTK *sci; +// Helper class for the asynchronous paste not to risk calling in a destroyed ScintillaGTK - void Destroyed() override { - sci = 0; - } +class SelectionReceiver : GObjectWatcher { + ScintillaGTK *sci; - public: - Helper(ScintillaGTK *sci_) : - GObjectWatcher(G_OBJECT(PWidget(sci_->wMain))), - sci(sci_) { - } + void Destroyed() override { + sci = nullptr; + } - static void ClipboardReceived(GtkClipboard *, GtkSelectionData *selection_data, gpointer data) { - Helper *self = static_cast(data); - if (self->sci != 0) { - self->sci->ReceivedSelection(selection_data); - } - delete self; +public: + SelectionReceiver(ScintillaGTK *sci_) : + GObjectWatcher(G_OBJECT(sci_->MainObject())), + sci(sci_) { + } + + static void ClipboardReceived(GtkClipboard *, GtkSelectionData *selection_data, gpointer data) { + SelectionReceiver *self = static_cast(data); + if (self->sci) { + self->sci->ReceivedClipboard(selection_data); } - }; + delete self; + } +}; - gtk_clipboard_request_contents(clipBoard, atomSought, Helper::ClipboardReceived, new Helper(this)); +} + +void ScintillaGTK::RequestSelection(GdkAtom atomSelection) { + atomSought = atomUTF8; + GtkClipboard *clipBoard = + gtk_widget_get_clipboard(GTK_WIDGET(PWidget(wMain)), atomSelection); + if (clipBoard) { + gtk_clipboard_request_contents(clipBoard, atomSought, + SelectionReceiver::ClipboardReceived, + new SelectionReceiver(this)); + } +} + +void ScintillaGTK::Paste() { + RequestSelection(GDK_SELECTION_CLIPBOARD); } void ScintillaGTK::CreateCallTipWindow(PRectangle rc) { @@ -1293,23 +1312,25 @@ void ScintillaGTK::CreateCallTipWindow(PRectangle rc) { gtk_container_add(GTK_CONTAINER(PWidget(ct.wCallTip)), widcdrw); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(G_OBJECT(widcdrw), "draw", - G_CALLBACK(ScintillaGTK::DrawCT), &ct); + G_CALLBACK(ScintillaGTK::DrawCT), &ct); #else g_signal_connect(G_OBJECT(widcdrw), "expose_event", - G_CALLBACK(ScintillaGTK::ExposeCT), &ct); + G_CALLBACK(ScintillaGTK::ExposeCT), &ct); #endif g_signal_connect(G_OBJECT(widcdrw), "button_press_event", - G_CALLBACK(ScintillaGTK::PressCT), this); + G_CALLBACK(ScintillaGTK::PressCT), this); gtk_widget_set_events(widcdrw, - GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); + GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); GtkWidget *top = gtk_widget_get_toplevel(static_cast(wMain.GetID())); gtk_window_set_transient_for(GTK_WINDOW(static_cast(PWidget(ct.wCallTip))), - GTK_WINDOW(top)); + GTK_WINDOW(top)); } - gtk_widget_set_size_request(PWidget(ct.wDraw), rc.Width(), rc.Height()); + const int width = static_cast(rc.Width()); + const int height = static_cast(rc.Height()); + gtk_widget_set_size_request(PWidget(ct.wDraw), width, height); ct.wDraw.Show(); if (PWindow(ct.wCallTip)) { - gdk_window_resize(PWindow(ct.wCallTip), rc.Width(), rc.Height()); + gdk_window_resize(PWindow(ct.wCallTip), width, height); } } @@ -1321,7 +1342,7 @@ void ScintillaGTK::AddToPopUp(const char *label, int cmd, bool enabled) { menuItem = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(popup.GetID()), menuItem); g_object_set_data(G_OBJECT(menuItem), "CmdNum", GINT_TO_POINTER(cmd)); - g_signal_connect(G_OBJECT(menuItem),"activate", G_CALLBACK(PopUpCB), this); + g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(PopUpCB), this); if (cmd) { if (menuItem) @@ -1332,7 +1353,7 @@ 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) != NULL)); + (PWindow(wSelection) != nullptr)); } void ScintillaGTK::ClaimSelection() { @@ -1341,12 +1362,12 @@ void ScintillaGTK::ClaimSelection() { 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); + GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); primary.Clear(); } else if (OwnPrimarySelection()) { primarySelection = true; if (primary.Empty()) - gtk_selection_owner_set(NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); + gtk_selection_owner_set(nullptr, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); } else { primarySelection = false; primary.Clear(); @@ -1396,7 +1417,7 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio } else { // Assume buffer is in same encoding as selection selText.Copy(dest, pdoc->dbcsCodePage, - vs.styles[STYLE_DEFAULT].characterSet, isRectangular, false); + vs.styles[STYLE_DEFAULT].characterSet, isRectangular, false); } } else { // UTF-8 const char *charSetBuffer = CharacterSetID(); @@ -1404,39 +1425,59 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio // Convert to locale dest = ConvertText(dest.c_str(), dest.length(), charSetBuffer, "UTF-8", true); selText.Copy(dest, pdoc->dbcsCodePage, - vs.styles[STYLE_DEFAULT].characterSet, isRectangular, false); + vs.styles[STYLE_DEFAULT].characterSet, isRectangular, false); } else { selText.Copy(dest, SC_CP_UTF8, 0, isRectangular, false); } } } +void ScintillaGTK::InsertSelection(GtkSelectionData *selectionData) { + const gint length = gtk_selection_data_get_length(selectionData); + if (length >= 0) { + GdkAtom selection = gtk_selection_data_get_selection(selectionData); + SelectionText selText; + GetGtkSelectionText(selectionData, selText); + + UndoGroup ug(pdoc); + if (selection == GDK_SELECTION_CLIPBOARD) { + ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH); + } + + InsertPasteShape(selText.Data(), selText.Length(), + selText.rectangular ? pasteRectangular : pasteStream); + EnsureCaretVisible(); + } + Redraw(); +} + +GObject *ScintillaGTK::MainObject() const noexcept { + return G_OBJECT(PWidget(wMain)); +} + +void ScintillaGTK::ReceivedClipboard(GtkSelectionData *selection_data) noexcept { + try { + InsertSelection(selection_data); + } catch (...) { + errorStatus = SC_STATUS_FAILURE; + } +} + void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) { try { - if ((SelectionOfGSD(selection_data) == atomClipboard) || - (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY)) { + if ((SelectionOfGSD(selection_data) == GDK_SELECTION_CLIPBOARD) || + (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY)) { if ((atomSought == atomUTF8) && (LengthOfGSD(selection_data) <= 0)) { atomSought = atomString; gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), - SelectionOfGSD(selection_data), atomSought, GDK_CURRENT_TIME); + SelectionOfGSD(selection_data), atomSought, GDK_CURRENT_TIME); } else if ((LengthOfGSD(selection_data) > 0) && - ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8))) { - SelectionText selText; - GetGtkSelectionText(selection_data, selText); - - UndoGroup ug(pdoc); - if (SelectionOfGSD(selection_data) != GDK_SELECTION_PRIMARY) { - ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH); - } - - InsertPasteShape(selText.Data(), selText.Length(), - selText.rectangular ? pasteRectangular : pasteStream); - EnsureCaretVisible(); + ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8))) { + InsertSelection(selection_data); } } // else fprintf(stderr, "Target non string %d %d\n", (int)(selection_data->type), // (int)(atomUTF8)); - Redraw(); } catch (...) { errorStatus = SC_STATUS_FAILURE; } @@ -1507,29 +1548,29 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se gtk_selection_data_set_text(selection_data, textData, len); } else { gtk_selection_data_set(selection_data, - static_cast(GDK_SELECTION_TYPE_STRING), - 8, reinterpret_cast(textData), len); + static_cast(GDK_SELECTION_TYPE_STRING), + 8, reinterpret_cast(textData), len); } } void ScintillaGTK::StoreOnClipboard(SelectionText *clipText) { GtkClipboard *clipBoard = - gtk_widget_get_clipboard(GTK_WIDGET(PWidget(wMain)), atomClipboard); - if (clipBoard == NULL) // Occurs if widget isn't in a toplevel + gtk_widget_get_clipboard(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_CLIPBOARD); + if (clipBoard == nullptr) // Occurs if widget isn't in a toplevel return; if (gtk_clipboard_set_with_data(clipBoard, clipboardCopyTargets, nClipboardCopyTargets, - ClipboardGetSelection, ClipboardClearSelection, clipText)) { + ClipboardGetSelection, ClipboardClearSelection, clipText)) { gtk_clipboard_set_can_store(clipBoard, clipboardCopyTargets, nClipboardCopyTargets); } } void ScintillaGTK::ClipboardGetSelection(GtkClipboard *, GtkSelectionData *selection_data, guint info, void *data) { - GetSelection(selection_data, info, static_cast(data)); + GetSelection(selection_data, info, static_cast(data)); } void ScintillaGTK::ClipboardClearSelection(GtkClipboard *, void *data) { - SelectionText *obj = static_cast(data); + SelectionText *obj = static_cast(data); delete obj; } @@ -1595,9 +1636,9 @@ void ScintillaGTK::Resize(int width, int height) { // These allocations should never produce negative sizes as they would wrap around to huge // unsigned numbers inside GTK+ causing warnings. - bool showSBHorizontal = horizontalScrollBarVisible && !Wrapping(); + const bool showSBHorizontal = horizontalScrollBarVisible && !Wrapping(); - GtkAllocation alloc; + GtkAllocation alloc = {}; if (showSBHorizontal) { gtk_widget_show(GTK_WIDGET(PWidget(scrollbarh))); alloc.x = 0; @@ -1632,7 +1673,7 @@ void ScintillaGTK::Resize(int width, int height) { #if GTK_CHECK_VERSION(3, 0, 0) // please GTK 3.20 and ask wText what size it wants, although we know it doesn't really need // anything special as it's ours. - gtk_widget_get_preferred_size(PWidget(wText), &requisition, NULL); + gtk_widget_get_preferred_size(PWidget(wText), &requisition, nullptr); alloc.width = requisition.width; alloc.height = requisition.height; #endif @@ -1641,10 +1682,12 @@ void ScintillaGTK::Resize(int width, int height) { gtk_widget_size_allocate(GTK_WIDGET(PWidget(wText)), &alloc); } -static void SetAdjustmentValue(GtkAdjustment *object, int value) { +namespace { + +void SetAdjustmentValue(GtkAdjustment *object, int value) { GtkAdjustment *adjustment = GTK_ADJUSTMENT(object); - int maxValue = static_cast( - gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size(adjustment)); + const int maxValue = static_cast( + gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size(adjustment)); if (value > maxValue) value = maxValue; @@ -1653,21 +1696,29 @@ static void SetAdjustmentValue(GtkAdjustment *object, int value) { gtk_adjustment_set_value(adjustment, value); } -static int modifierTranslated(int sciModifier) { +int modifierTranslated(int sciModifier) noexcept { switch (sciModifier) { - case SCMOD_SHIFT: - return GDK_SHIFT_MASK; - case SCMOD_CTRL: - return GDK_CONTROL_MASK; - case SCMOD_ALT: - return GDK_MOD1_MASK; - case SCMOD_SUPER: - return GDK_MOD4_MASK; - default: - return 0; + case SCMOD_SHIFT: + return GDK_SHIFT_MASK; + case SCMOD_CTRL: + return GDK_CONTROL_MASK; + case SCMOD_ALT: + return GDK_MOD1_MASK; + case SCMOD_SUPER: + return GDK_MOD4_MASK; + default: + return 0; } } +Point PointOfEvent(const GdkEventButton *event) noexcept { + // Use floor as want to round in the same direction (-infinity) so + // there is no stickiness crossing 0.0. + return Point(static_cast(std::floor(event->x)), static_cast(std::floor(event->y))); +} + +} + gint ScintillaGTK::PressThis(GdkEventButton *event) { try { //Platform::DebugPrintf("Press %x time=%d state = %x button = %x\n",this,event->time, event->state, event->button); @@ -1680,10 +1731,8 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { } evbtn = gdk_event_copy(reinterpret_cast(event)); buttonMouse = event->button; - Point pt; - pt.x = floor(event->x); - pt.y = floor(event->y); - PRectangle rcClient = GetClientRectangle(); + const Point pt = PointOfEvent(event); + const PRectangle rcClient = GetClientRectangle(); //Platform::DebugPrintf("Press %0d,%0d in %0d,%0d %0d,%0d\n", // pt.x, pt.y, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); if ((pt.x > rcClient.right) || (pt.y > rcClient.bottom)) { @@ -1691,35 +1740,33 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { return FALSE; } - bool shift = (event->state & GDK_SHIFT_MASK) != 0; + const bool shift = (event->state & GDK_SHIFT_MASK) != 0; bool ctrl = (event->state & GDK_CONTROL_MASK) != 0; // On X, instead of sending literal modifiers use the user specified // modifier, defaulting to control instead of alt. // This is because most X window managers grab alt + click for moving - bool alt = (event->state & modifierTranslated(rectangularSelectionModifier)) != 0; + const bool alt = (event->state & modifierTranslated(rectangularSelectionModifier)) != 0; gtk_widget_grab_focus(PWidget(wMain)); if (event->button == 1) { #if PLAT_GTK_MACOSX - bool meta = ctrl; + const bool meta = ctrl; // GDK reports the Command modifer key as GDK_MOD2_MASK for button events, // not GDK_META_MASK like in key events. ctrl = (event->state & GDK_MOD2_MASK) != 0; #else - bool meta = false; + const bool meta = false; #endif ButtonDownWithModifiers(pt, event->time, ModifierFlags(shift, ctrl, alt, meta)); } else if (event->button == 2) { // Grab the primary selection if it exists - SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace()); + const SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace()); if (OwnPrimarySelection() && primary.Empty()) CopySelectionRange(&primary); sel.Clear(); SetSelection(pos, pos); - atomSought = atomUTF8; - gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY, - atomSought, event->time); + RequestSelection(GDK_SELECTION_PRIMARY); } else if (event->button == 3) { if (!PointInSelection(pt)) SetEmptySelection(PositionFromLocation(pt)); @@ -1732,12 +1779,12 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { ContextMenu(Point(pt.x + ox, pt.y + oy)); } else { #if PLAT_GTK_MACOSX - bool meta = ctrl; + const bool meta = ctrl; // GDK reports the Command modifer key as GDK_MOD2_MASK for button events, // not GDK_META_MASK like in key events. ctrl = (event->state & GDK_MOD2_MASK) != 0; #else - bool meta = false; + const bool meta = false; #endif RightButtonDownWithModifiers(pt, event->time, ModifierFlags(shift, ctrl, alt, meta)); return FALSE; @@ -1775,9 +1822,7 @@ gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) { if (!sciThis->HaveMouseCapture()) return FALSE; if (event->button == 1) { - Point pt; - pt.x = int(event->x); - pt.y = int(event->y); + Point pt = PointOfEvent(event); //Platform::DebugPrintf("Up %x %x %d %d %d\n", // sciThis,event->window,event->time, pt.x, pt.y); if (event->window != PWindow(sciThis->wMain)) @@ -1785,9 +1830,9 @@ gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) { // scrollbar, not the drawing window so just repeat the most recent point. pt = sciThis->ptMouseLast; const int modifiers = ModifierFlags( - (event->state & GDK_SHIFT_MASK) != 0, - (event->state & GDK_CONTROL_MASK) != 0, - (event->state & modifierTranslated(sciThis->rectangularSelectionModifier)) != 0); + (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 (...) { @@ -1802,7 +1847,7 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) { ScintillaGTK *sciThis = FromWidget(widget); try { - if (widget == NULL || event == NULL) + if (widget == nullptr || event == nullptr) return FALSE; #if defined(GDK_WINDOWING_WAYLAND) @@ -1811,12 +1856,12 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) { sciThis->smoothScrollY += event->delta_y * smoothScrollFactor; sciThis->smoothScrollX += event->delta_x * smoothScrollFactor;; if (ABS(sciThis->smoothScrollY) >= 1.0) { - const int scrollLines = trunc(sciThis->smoothScrollY); + const int scrollLines = std::trunc(sciThis->smoothScrollY); sciThis->ScrollTo(sciThis->topLine + scrollLines); sciThis->smoothScrollY -= scrollLines; } if (ABS(sciThis->smoothScrollX) >= 1.0) { - const int scrollPixels = trunc(sciThis->smoothScrollX); + const int scrollPixels = std::trunc(sciThis->smoothScrollX); sciThis->HorizontalScrollTo(sciThis->xOffset + scrollPixels); sciThis->smoothScrollX -= scrollPixels; } @@ -1913,7 +1958,7 @@ gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) { if (event->is_hint) { #if GTK_CHECK_VERSION(3,0,0) gdk_window_get_device_position(event->window, - event->device, &x, &y, &state); + event->device, &x, &y, &state); #else gdk_window_get_pointer(event->window, &x, &y, &state); #endif @@ -1924,11 +1969,11 @@ 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); - Point pt(x, y); + const Point pt(static_cast(x), static_cast(y)); const int modifiers = ModifierFlags( - (event->state & GDK_SHIFT_MASK) != 0, - (event->state & GDK_CONTROL_MASK) != 0, - (event->state & modifierTranslated(sciThis->rectangularSelectionModifier)) != 0); + (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; @@ -2090,10 +2135,10 @@ gboolean ScintillaGTK::KeyThis(GdkEventKey *event) { return true; } - bool shift = (event->state & GDK_SHIFT_MASK) != 0; + const bool shift = (event->state & GDK_SHIFT_MASK) != 0; bool ctrl = (event->state & GDK_CONTROL_MASK) != 0; - bool alt = (event->state & GDK_MOD1_MASK) != 0; - bool super = (event->state & GDK_MOD4_MASK) != 0; + const bool alt = (event->state & GDK_MOD1_MASK) != 0; + const bool super = (event->state & GDK_MOD4_MASK) != 0; guint key = event->keyval; if ((ctrl || alt) && (key < 128)) key = toupper(key); @@ -2110,12 +2155,12 @@ gboolean ScintillaGTK::KeyThis(GdkEventKey *event) { bool consumed = false; #if !(PLAT_GTK_MACOSX) - bool meta = false; + const bool meta = false; #else - bool meta = ctrl; + const bool meta = ctrl; ctrl = (event->state & GDK_META_MASK) != 0; #endif - bool added = KeyDownWithModifiers(key, ModifierFlags(shift, ctrl, alt, meta, super), &consumed) != 0; + const bool added = KeyDownWithModifiers(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); @@ -2204,7 +2249,7 @@ bool ScintillaGTK::KoreanIME() { void ScintillaGTK::MoveImeCarets(int pos) { // Move carets relatively by bytes for (size_t r=0; rDecorationSetCurrentIndicator(indicator); for (size_t r=0; rDecorationFillRange(positionInsert - len, 1, len); } } @@ -2229,7 +2274,7 @@ static 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. - glong charactersLen = g_utf8_strlen(u8Str, strlen(u8Str)); + const glong charactersLen = g_utf8_strlen(u8Str, strlen(u8Str)); std::vector indicator(charactersLen, SC_INDICATOR_UNKNOWN); PangoAttrIterator *iterunderline = pango_attr_list_get_iterator(attrs); @@ -2237,9 +2282,9 @@ static std::vector MapImeIndicators(PangoAttrList *attrs, const char *u8Str do { PangoAttribute *attrunderline = pango_attr_iterator_get(iterunderline, PANGO_ATTR_UNDERLINE); if (attrunderline) { - glong start = g_utf8_strlen(u8Str, attrunderline->start_index); - glong end = g_utf8_strlen(u8Str, attrunderline->end_index); - PangoUnderline uline = (PangoUnderline)((PangoAttrInt *)attrunderline)->value; + 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; for (glong i=start; i < end; ++i) { switch (uline) { case PANGO_UNDERLINE_NONE: @@ -2262,10 +2307,10 @@ static std::vector MapImeIndicators(PangoAttrList *attrs, const char *u8Str PangoAttrIterator *itercolor = pango_attr_list_get_iterator(attrs); if (itercolor) { do { - PangoAttribute *backcolor = pango_attr_iterator_get(itercolor, PANGO_ATTR_BACKGROUND); + const PangoAttribute *backcolor = pango_attr_iterator_get(itercolor, PANGO_ATTR_BACKGROUND); if (backcolor) { - glong start = g_utf8_strlen(u8Str, backcolor->start_index); - glong end = g_utf8_strlen(u8Str, backcolor->end_index); + const glong start = g_utf8_strlen(u8Str, backcolor->start_index); + const glong end = g_utf8_strlen(u8Str, backcolor->end_index); for (glong i=start; i < end; ++i) { indicator[i] = SC_INDICATOR_TARGET; // target converted } @@ -2278,10 +2323,10 @@ static std::vector MapImeIndicators(PangoAttrList *attrs, const char *u8Str void ScintillaGTK::SetCandidateWindowPos() { // Composition box accompanies candidate box. - Point pt = PointMainCaret(); + const Point pt = PointMainCaret(); GdkRectangle imeBox = {0}; // No need to set width - imeBox.x = pt.x; // Only need positiion - imeBox.y = pt.y + vs.lineHeight; // underneath the first charater + imeBox.x = static_cast(pt.x); // Only need positiion + imeBox.y = static_cast(pt.y) + vs.lineHeight; // underneath the first charater gtk_im_context_set_cursor_location(im_context, &imeBox); } @@ -2300,7 +2345,7 @@ void ScintillaGTK::CommitThis(char *commitStr) { gunichar *uniStr = g_utf8_to_ucs4_fast(commitStr, strlen(commitStr), &uniStrLen); for (glong i = 0; i < uniStrLen; i++) { gchar u8Char[UTF8MaxBytes+2] = {0}; - gint u8CharLen = g_unichar_to_utf8(uniStr[i], u8Char); + const gint u8CharLen = g_unichar_to_utf8(uniStr[i], u8Char); std::string docChar = u8Char; if (!IsUnicodeMode()) docChar = ConvertText(u8Char, u8CharLen, charSetSource, "UTF-8", true); @@ -2341,7 +2386,7 @@ void ScintillaGTK::PreeditChangedInlineThis() { PreEditString preeditStr(im_context); const char *charSetSource = CharacterSetID(); - if (!preeditStr.validUTF8 || (charSetSource == NULL)) { + if (!preeditStr.validUTF8 || (charSetSource == nullptr)) { ShowCaretAtCurrentPosition(); return; } @@ -2358,11 +2403,11 @@ void ScintillaGTK::PreeditChangedInlineThis() { std::vector indicator = MapImeIndicators(preeditStr.attrs, preeditStr.str); - bool tmpRecordingMacro = recordingMacro; + const bool tmpRecordingMacro = recordingMacro; recordingMacro = false; for (glong i = 0; i < preeditStr.uniStrLen; i++) { gchar u8Char[UTF8MaxBytes+2] = {0}; - gint u8CharLen = g_unichar_to_utf8(preeditStr.uniStr[i], u8Char); + const gint u8CharLen = g_unichar_to_utf8(preeditStr.uniStr[i], u8Char); std::string docChar = u8Char; if (!IsUnicodeMode()) docChar = ConvertText(u8Char, u8CharLen, charSetSource, "UTF-8", true); @@ -2374,8 +2419,8 @@ void ScintillaGTK::PreeditChangedInlineThis() { recordingMacro = tmpRecordingMacro; // Move caret to ime cursor position. - int imeEndToImeCaretU32 = preeditStr.cursor_pos - preeditStr.uniStrLen; - int imeCaretPosDoc = pdoc->GetRelativePosition(CurrentPosition(), imeEndToImeCaretU32); + const int imeEndToImeCaretU32 = preeditStr.cursor_pos - preeditStr.uniStrLen; + const int imeCaretPosDoc = pdoc->GetRelativePosition(CurrentPosition(), imeEndToImeCaretU32); MoveImeCarets(- CurrentPosition() + imeCaretPosDoc); @@ -2437,19 +2482,19 @@ void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) { } } -void ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void*) { - RealizeText(widget, NULL); +void ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void *) { + RealizeText(widget, nullptr); } -void ScintillaGTK::RealizeText(GtkWidget *widget, void*) { +void ScintillaGTK::RealizeText(GtkWidget *widget, void *) { // Set NULL background to avoid automatic clearing so Scintilla responsible for all drawing if (WindowFromWidget(widget)) { #if GTK_CHECK_VERSION(3,22,0) // Appears unnecessary #elif GTK_CHECK_VERSION(3,0,0) - gdk_window_set_background_pattern(WindowFromWidget(widget), NULL); + gdk_window_set_background_pattern(WindowFromWidget(widget), nullptr); #else - gdk_window_set_back_pixmap(WindowFromWidget(widget), NULL, FALSE); + gdk_window_set_back_pixmap(WindowFromWidget(widget), nullptr, FALSE); #endif } } @@ -2463,12 +2508,12 @@ void ScintillaGTK::Dispose(GObject *object) { if (PWidget(sciThis->scrollbarv)) { gtk_widget_unparent(PWidget(sciThis->scrollbarv)); - sciThis->scrollbarv = NULL; + sciThis->scrollbarv = nullptr; } if (PWidget(sciThis->scrollbarh)) { gtk_widget_unparent(PWidget(sciThis->scrollbarh)); - sciThis->scrollbarh = NULL; + sciThis->scrollbarh = nullptr; } scintilla_class_parent_class->dispose(object); @@ -2489,7 +2534,7 @@ void ScintillaGTK::Destroy(GObject *object) { sciThis->Finalise(); delete sciThis; - scio->pscin = 0; + scio->pscin = nullptr; scintilla_class_parent_class->finalize(object); } catch (...) { // Its dead so nowhere to save the status @@ -2505,7 +2550,7 @@ gboolean ScintillaGTK::DrawTextThis(cairo_t *cr) { rcPaint = GetClientRectangle(); - PLATFORM_ASSERT(rgnUpdate == NULL); + PLATFORM_ASSERT(rgnUpdate == nullptr); rgnUpdate = cairo_copy_clip_rectangle_list(cr); if (rgnUpdate && rgnUpdate->status != CAIRO_STATUS_SUCCESS) { // If not successful then ignore @@ -2561,26 +2606,26 @@ gboolean ScintillaGTK::DrawThis(cairo_t *cr) { gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_SCROLLBARS_JUNCTION); gtk_render_background(styleContext, cr, rc.right, rc.bottom, - verticalScrollBarWidth, horizontalScrollBarHeight); + verticalScrollBarWidth, horizontalScrollBarHeight); gtk_render_frame(styleContext, cr, rc.right, rc.bottom, - verticalScrollBarWidth, horizontalScrollBarHeight); + verticalScrollBarWidth, horizontalScrollBarHeight); gtk_style_context_restore(styleContext); } #endif gtk_container_propagate_draw( - GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), cr); + GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), cr); gtk_container_propagate_draw( - GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), cr); + GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), cr); // Starting from the following version, the expose event are not propagated // for double buffered non native windows, so we need to call it ourselves // or keep the default handler #if GTK_CHECK_VERSION(3,0,0) // we want to forward on any >= 3.9.2 runtime - if (gtk_check_version(3,9,2) == NULL) { + if (gtk_check_version(3, 9, 2) == nullptr) { gtk_container_propagate_draw( - GTK_CONTAINER(PWidget(wMain)), PWidget(wText), cr); + GTK_CONTAINER(PWidget(wMain)), PWidget(wText), cr); } #endif } catch (...) { @@ -2600,14 +2645,15 @@ gboolean ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *os try { paintState = painting; - rcPaint.left = ose->area.x; - rcPaint.top = ose->area.y; - rcPaint.right = ose->area.x + ose->area.width; - rcPaint.bottom = ose->area.y + ose->area.height; + rcPaint = PRectangle::FromInts( + ose->area.x, + ose->area.y, + ose->area.x + ose->area.width, + ose->area.y + ose->area.height); - PLATFORM_ASSERT(rgnUpdate == NULL); + PLATFORM_ASSERT(rgnUpdate == nullptr); rgnUpdate = gdk_region_copy(ose->region); - PRectangle rcClient = GetClientRectangle(); + const PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); std::unique_ptr surfaceWindow(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); cairo_t *cr = gdk_cairo_create(PWindow(wText)); @@ -2625,7 +2671,7 @@ gboolean ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *os if (rgnUpdate) { gdk_region_destroy(rgnUpdate); } - rgnUpdate = 0; + rgnUpdate = nullptr; } catch (...) { errorStatus = SC_STATUS_FAILURE; } @@ -2651,9 +2697,9 @@ gboolean ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) { // The text is painted in ExposeText gtk_container_propagate_expose( - GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), ose); + GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), ose); gtk_container_propagate_expose( - GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), ose); + GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), ose); } catch (...) { errorStatus = SC_STATUS_FAILURE; @@ -2680,14 +2726,14 @@ void ScintillaGTK::ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) { } void ScintillaGTK::SelectionReceived(GtkWidget *widget, - GtkSelectionData *selection_data, guint) { + GtkSelectionData *selection_data, guint) { ScintillaGTK *sciThis = FromWidget(widget); //Platform::DebugPrintf("Selection received\n"); sciThis->ReceivedSelection(selection_data); } void ScintillaGTK::SelectionGet(GtkWidget *widget, - GtkSelectionData *selection_data, guint info, guint) { + GtkSelectionData *selection_data, guint info, guint) { ScintillaGTK *sciThis = FromWidget(widget); try { //Platform::DebugPrintf("Selection get\n"); @@ -2713,13 +2759,13 @@ gint ScintillaGTK::SelectionClear(GtkWidget *widget, GdkEventSelection *selectio } gboolean ScintillaGTK::DragMotionThis(GdkDragContext *context, - gint x, gint y, guint dragtime) { + gint x, gint y, guint dragtime) { try { - Point npt(x, y); + const Point npt = Point::FromInts(x, y); SetDragPosition(SPositionFromLocation(npt, false, false, UserVirtualSpace())); GdkDragAction preferredAction = gdk_drag_context_get_suggested_action(context); - GdkDragAction actions = gdk_drag_context_get_actions(context); - SelectionPosition pos = SPositionFromLocation(npt); + const GdkDragAction actions = gdk_drag_context_get_actions(context); + const SelectionPosition pos = SPositionFromLocation(npt); if ((inDragDrop == ddDragging) && (PositionInSelection(pos.Position()))) { // Avoid dragging selection onto itself as that produces a move // with no real effect but which creates undo actions. @@ -2735,7 +2781,7 @@ gboolean ScintillaGTK::DragMotionThis(GdkDragContext *context, } gboolean ScintillaGTK::DragMotion(GtkWidget *widget, GdkDragContext *context, - gint x, gint y, guint dragtime) { + gint x, gint y, guint dragtime) { ScintillaGTK *sciThis = FromWidget(widget); return sciThis->DragMotionThis(context, x, y, dragtime); } @@ -2765,7 +2811,7 @@ void ScintillaGTK::DragEnd(GtkWidget *widget, GdkDragContext * /*context*/) { } gboolean ScintillaGTK::Drop(GtkWidget *widget, GdkDragContext * /*context*/, - gint, gint, guint) { + gint, gint, guint) { ScintillaGTK *sciThis = FromWidget(widget); try { //Platform::DebugPrintf("Drop %x\n", sciThis); @@ -2777,7 +2823,7 @@ gboolean ScintillaGTK::Drop(GtkWidget *widget, GdkDragContext * /*context*/, } void ScintillaGTK::DragDataReceived(GtkWidget *widget, GdkDragContext * /*context*/, - gint, gint, GtkSelectionData *selection_data, guint /*info*/, guint) { + gint, gint, GtkSelectionData *selection_data, guint /*info*/, guint) { ScintillaGTK *sciThis = FromWidget(widget); try { sciThis->ReceivedDrop(selection_data); @@ -2788,14 +2834,14 @@ void ScintillaGTK::DragDataReceived(GtkWidget *widget, GdkDragContext * /*contex } void ScintillaGTK::DragDataGet(GtkWidget *widget, GdkDragContext *context, - GtkSelectionData *selection_data, guint info, guint) { + GtkSelectionData *selection_data, guint info, guint) { ScintillaGTK *sciThis = FromWidget(widget); try { sciThis->dragWasDropped = true; if (!sciThis->sel.Empty()) { sciThis->GetSelection(selection_data, info, &sciThis->drag); } - GdkDragAction action = gdk_drag_context_get_selected_action(context); + const GdkDragAction action = gdk_drag_context_get_selected_action(context); if (action == GDK_ACTION_MOVE) { for (size_t r=0; rsel.Count(); r++) { if (sciThis->posDrop >= sciThis->sel.Range(r).Start()) { @@ -2824,7 +2870,7 @@ gboolean ScintillaGTK::IdleCallback(gpointer pSci) { ScintillaGTK *sciThis = static_cast(pSci); // Idler will be automatically stopped, if there is nothing // to do while idle. - bool ret = sciThis->Idle(); + const bool ret = sciThis->Idle(); if (ret == false) { // FIXME: This will remove the idler from GTK, we don't want to // remove it as it is removed automatically when this function @@ -2850,13 +2896,13 @@ void ScintillaGTK::QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo Editor::QueueIdleWork(items, upTo); if (!styleIdleID) { // Only allow one style needed to be queued - styleIdleID = gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, StyleIdle, this, NULL); + styleIdleID = gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, StyleIdle, this, nullptr); } } void ScintillaGTK::SetDocPointer(Document *document) { - Document *oldDoc = 0; - ScintillaGTKAccessible *sciAccessible = 0; + Document *oldDoc = nullptr; + ScintillaGTKAccessible *sciAccessible = nullptr; if (accessible) { sciAccessible = ScintillaGTKAccessible::FromAccessible(accessible); if (sciAccessible && pdoc) { @@ -2877,7 +2923,7 @@ void ScintillaGTK::SetDocPointer(Document *document) { } void ScintillaGTK::PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis) { - guint action = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuItem), "CmdNum")); + guint const action = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuItem), "CmdNum")); if (action) { sciThis->Command(action); } @@ -2889,9 +2935,7 @@ gboolean ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, Scintil return FALSE; if (event->type != GDK_BUTTON_PRESS) return FALSE; - Point pt; - pt.x = int(event->x); - pt.y = int(event->y); + const Point pt = PointOfEvent(event); sciThis->ct.MouseClick(pt); sciThis->CallTipClick(); } catch (...) { @@ -2935,16 +2979,16 @@ gboolean ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, Cal #endif -AtkObject* ScintillaGTK::GetAccessibleThis(GtkWidget *widget) { +AtkObject *ScintillaGTK::GetAccessibleThis(GtkWidget *widget) { return ScintillaGTKAccessible::WidgetGetAccessibleImpl(widget, &accessible, scintilla_class_parent_class); } -AtkObject* ScintillaGTK::GetAccessible(GtkWidget *widget) { +AtkObject *ScintillaGTK::GetAccessible(GtkWidget *widget) { return FromWidget(widget)->GetAccessibleThis(widget); } sptr_t ScintillaGTK::DirectFunction( - sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { + sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return reinterpret_cast(ptr)->WndProc(iMessage, wParam, lParam); } @@ -2976,19 +3020,19 @@ GType scintilla_get_type() { scintilla_type = g_type_from_name("ScintillaObject"); if (!scintilla_type) { static GTypeInfo scintilla_info = { - (guint16) sizeof (ScintillaObjectClass), - NULL, //(GBaseInitFunc) - NULL, //(GBaseFinalizeFunc) + (guint16) sizeof(ScintillaObjectClass), + nullptr, //(GBaseInitFunc) + nullptr, //(GBaseFinalizeFunc) (GClassInitFunc) scintilla_class_init, - NULL, //(GClassFinalizeFunc) - NULL, //gconstpointer data - (guint16) sizeof (ScintillaObject), + nullptr, //(GClassFinalizeFunc) + nullptr, //gconstpointer data + (guint16) sizeof(ScintillaObject), 0, //n_preallocs (GInstanceInitFunc) scintilla_init, - NULL //(GTypeValueTable*) + nullptr //(GTypeValueTable*) }; scintilla_type = g_type_register_static( - GTK_TYPE_CONTAINER, "ScintillaObject", &scintilla_info, (GTypeFlags) 0); + GTK_TYPE_CONTAINER, "ScintillaObject", &scintilla_info, (GTypeFlags) 0); } } @@ -3002,12 +3046,11 @@ GType scintilla_object_get_type() { return scintilla_get_type(); } -void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class) { +void ScintillaGTK::ClassInit(OBJECT_CLASS *object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class) { Platform_Initialise(); #ifdef SCI_LEXER Scintilla_LinkLexers(); #endif - atomClipboard = gdk_atom_intern("CLIPBOARD", FALSE); atomUTF8 = gdk_atom_intern("UTF8_STRING", FALSE); atomString = GDK_SELECTION_TYPE_STRING; atomUriList = gdk_atom_intern("text/uri-list", FALSE); @@ -3062,35 +3105,35 @@ void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_ static void scintilla_class_init(ScintillaClass *klass) { try { - OBJECT_CLASS *object_class = (OBJECT_CLASS*) klass; - GtkWidgetClass *widget_class = (GtkWidgetClass*) klass; - GtkContainerClass *container_class = (GtkContainerClass*) klass; + OBJECT_CLASS *object_class = (OBJECT_CLASS *) klass; + GtkWidgetClass *widget_class = (GtkWidgetClass *) klass; + GtkContainerClass *container_class = (GtkContainerClass *) klass; - GSignalFlags sigflags = GSignalFlags(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST); + const GSignalFlags sigflags = GSignalFlags(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST); scintilla_signals[COMMAND_SIGNAL] = g_signal_new( - "command", - G_TYPE_FROM_CLASS(object_class), - sigflags, - G_STRUCT_OFFSET(ScintillaClass, command), - NULL, //(GSignalAccumulator) - NULL, //(gpointer) - scintilla_marshal_VOID__INT_OBJECT, - G_TYPE_NONE, - 2, G_TYPE_INT, GTK_TYPE_WIDGET); + "command", + G_TYPE_FROM_CLASS(object_class), + sigflags, + G_STRUCT_OFFSET(ScintillaClass, command), + nullptr, //(GSignalAccumulator) + nullptr, //(gpointer) + scintilla_marshal_VOID__INT_OBJECT, + G_TYPE_NONE, + 2, G_TYPE_INT, GTK_TYPE_WIDGET); scintilla_signals[NOTIFY_SIGNAL] = g_signal_new( - SCINTILLA_NOTIFY, - G_TYPE_FROM_CLASS(object_class), - sigflags, - G_STRUCT_OFFSET(ScintillaClass, notify), - NULL, //(GSignalAccumulator) - NULL, //(gpointer) - scintilla_marshal_VOID__INT_BOXED, - G_TYPE_NONE, - 2, G_TYPE_INT, SCINTILLA_TYPE_NOTIFICATION); - - klass->command = NULL; - klass->notify = NULL; + SCINTILLA_NOTIFY, + G_TYPE_FROM_CLASS(object_class), + sigflags, + G_STRUCT_OFFSET(ScintillaClass, notify), + nullptr, //(GSignalAccumulator) + nullptr, //(gpointer) + scintilla_marshal_VOID__INT_BOXED, + G_TYPE_NONE, + 2, G_TYPE_INT, SCINTILLA_TYPE_NOTIFICATION); + + klass->command = nullptr; + klass->notify = nullptr; scintilla_class_parent_class = G_OBJECT_CLASS(g_type_class_peek_parent(klass)); ScintillaGTK::ClassInit(object_class, widget_class, container_class); } catch (...) { @@ -3107,8 +3150,8 @@ static void scintilla_init(ScintillaObject *sci) { /* legacy name for scintilla_object_new */ GEANY_API_SYMBOL -GtkWidget* scintilla_new() { - GtkWidget *widget = GTK_WIDGET(g_object_new(scintilla_get_type(), NULL)); +GtkWidget *scintilla_new() { + GtkWidget *widget = GTK_WIDGET(g_object_new(scintilla_get_type(), nullptr)); gtk_widget_set_direction(widget, GTK_TEXT_DIR_LTR); return widget; @@ -3141,10 +3184,10 @@ GEANY_API_SYMBOL GType scnotification_get_type(void) { static gsize type_id = 0; if (g_once_init_enter(&type_id)) { - gsize id = (gsize) g_boxed_type_register_static( - g_intern_static_string("SCNotification"), - (GBoxedCopyFunc) copy_, - (GBoxedFreeFunc) free_); + const gsize id = (gsize) g_boxed_type_register_static( + g_intern_static_string("SCNotification"), + (GBoxedCopyFunc) copy_, + (GBoxedFreeFunc) free_); g_once_init_leave(&type_id, id); } return (GType) type_id; diff --git a/scintilla/gtk/ScintillaGTK.h b/scintilla/gtk/ScintillaGTK.h index 7cff34ff38..b878088244 100644 --- a/scintilla/gtk/ScintillaGTK.h +++ b/scintilla/gtk/ScintillaGTK.h @@ -36,7 +36,6 @@ class ScintillaGTK : public ScintillaBase { GtkWidgetClass *parentClass; - static GdkAtom atomClipboard; static GdkAtom atomUTF8; static GdkAtom atomString; static GdkAtom atomUriList; @@ -80,7 +79,7 @@ class ScintillaGTK : public ScintillaBase { ScintillaGTK &operator=(ScintillaGTK &&) = delete; virtual ~ScintillaGTK(); static ScintillaGTK *FromWidget(GtkWidget *widget); - static void ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class); + static void ClassInit(OBJECT_CLASS *object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class); private: void Init(); void Finalise() override; @@ -99,7 +98,7 @@ class ScintillaGTK : public ScintillaBase { TickReason reason; ScintillaGTK *scintilla; guint timer; - TimeThunk() : reason(tickCaret), scintilla(NULL), timer(0) {} + TimeThunk() noexcept : reason(tickCaret), scintilla(nullptr), timer(0) {} }; TimeThunk timers[tickDwell+1]; bool FineTickerRunning(TickReason reason) override; @@ -127,18 +126,24 @@ class ScintillaGTK : public ScintillaBase { int KeyDefault(int key, int modifiers) override; void CopyToClipboard(const SelectionText &selectedText) override; void Copy() override; + void RequestSelection(GdkAtom atomSelection); void Paste() override; void CreateCallTipWindow(PRectangle rc) override; void AddToPopUp(const char *label, int cmd = 0, bool enabled = true) override; bool OwnPrimarySelection(); void ClaimSelection() override; void GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText); + void InsertSelection(GtkSelectionData *selectionData); +public: // Public for SelectionReceiver + GObject *MainObject() const noexcept; + void ReceivedClipboard(GtkSelectionData *selection_data) noexcept; +private: void ReceivedSelection(GtkSelectionData *selection_data); void ReceivedDrop(GtkSelectionData *selection_data); static void GetSelection(GtkSelectionData *selection_data, guint info, SelectionText *text); void StoreOnClipboard(SelectionText *clipText); - static void ClipboardGetSelection(GtkClipboard* clip, GtkSelectionData *selection_data, guint info, void *data); - static void ClipboardClearSelection(GtkClipboard* clip, void *data); + static void ClipboardGetSelection(GtkClipboard *clip, GtkSelectionData *selection_data, guint info, void *data); + static void ClipboardClearSelection(GtkClipboard *clip, void *data); void UnclaimSelection(GdkEventSelection *selection_event); static void PrimarySelection(GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time_stamp, ScintillaGTK *sciThis); @@ -195,8 +200,8 @@ class ScintillaGTK : public ScintillaBase { gboolean ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose); static gboolean ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis); #endif - AtkObject* GetAccessibleThis(GtkWidget *widget); - static AtkObject* GetAccessible(GtkWidget *widget); + AtkObject *GetAccessibleThis(GtkWidget *widget); + static AtkObject *GetAccessible(GtkWidget *widget); bool KoreanIME(); void CommitThis(char *commitStr); @@ -208,27 +213,27 @@ class ScintillaGTK : public ScintillaBase { void DrawImeIndicator(int indicator, int len); void SetCandidateWindowPos(); - static void StyleSetText(GtkWidget *widget, GtkStyle *previous, void*); - static void RealizeText(GtkWidget *widget, void*); + static void StyleSetText(GtkWidget *widget, GtkStyle *previous, void *); + static void RealizeText(GtkWidget *widget, void *); static void Dispose(GObject *object); static void Destroy(GObject *object); static void SelectionReceived(GtkWidget *widget, GtkSelectionData *selection_data, - guint time); + guint time); static void SelectionGet(GtkWidget *widget, GtkSelectionData *selection_data, - guint info, guint time); + guint info, guint time); static gint SelectionClear(GtkWidget *widget, GdkEventSelection *selection_event); gboolean DragMotionThis(GdkDragContext *context, gint x, gint y, guint dragtime); static gboolean DragMotion(GtkWidget *widget, GdkDragContext *context, - gint x, gint y, guint dragtime); + gint x, gint y, guint dragtime); static void DragLeave(GtkWidget *widget, GdkDragContext *context, - guint time); + guint time); static void DragEnd(GtkWidget *widget, GdkDragContext *context); static gboolean Drop(GtkWidget *widget, GdkDragContext *context, - gint x, gint y, guint time); + gint x, gint y, guint time); static void DragDataReceived(GtkWidget *widget, GdkDragContext *context, - gint x, gint y, GtkSelectionData *selection_data, guint info, guint time); + gint x, gint y, GtkSelectionData *selection_data, guint info, guint time); static void DragDataGet(GtkWidget *widget, GdkDragContext *context, - GtkSelectionData *selection_data, guint info, guint time); + GtkSelectionData *selection_data, guint info, guint time); static gboolean TimeOut(gpointer ptt); static gboolean IdleCallback(gpointer pSci); static gboolean StyleIdle(gpointer pSci); @@ -245,7 +250,7 @@ class ScintillaGTK : public ScintillaBase { static gboolean PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis); static sptr_t DirectFunction(sptr_t ptr, - unsigned int iMessage, uptr_t wParam, sptr_t lParam); + unsigned int iMessage, uptr_t wParam, sptr_t lParam); }; // helper class to watch a GObject lifetime and get notified when it dies @@ -256,16 +261,16 @@ class GObjectWatcher { PLATFORM_ASSERT(obj == weakRef); Destroyed(); - weakRef = 0; + weakRef = nullptr; } static void WeakNotify(gpointer data, GObject *obj) { - static_cast(data)->WeakNotifyThis(obj); + static_cast(data)->WeakNotifyThis(obj); } public: GObjectWatcher(GObject *obj) : - weakRef(obj) { + weakRef(obj) { g_object_weak_ref(weakRef, WeakNotify, this); } @@ -278,12 +283,12 @@ class GObjectWatcher { virtual void Destroyed() {} bool IsDestroyed() const { - return weakRef != 0; + return weakRef != nullptr; } }; std::string ConvertText(const char *s, size_t len, const char *charSetDest, - const char *charSetSource, bool transliterations, bool silent=false); + const char *charSetSource, bool transliterations, bool silent=false); } diff --git a/scintilla/gtk/ScintillaGTKAccessible.cxx b/scintilla/gtk/ScintillaGTKAccessible.cxx index 40f5f19840..f9cedcb82f 100644 --- a/scintilla/gtk/ScintillaGTKAccessible.cxx +++ b/scintilla/gtk/ScintillaGTKAccessible.cxx @@ -77,7 +77,10 @@ # include #endif -#if defined(__WIN32__) || defined(_MSC_VER) +#if defined(_WIN32) +// On Win32 use windows.h to access CLIPFORMAT +#undef NOMINMAX +#define NOMINMAX #include #endif @@ -92,6 +95,7 @@ #include "SciLexer.h" #endif #include "StringCopy.h" +#include "CharacterCategory.h" #ifdef SCI_LEXER #include "LexerModule.h" #endif @@ -147,7 +151,7 @@ ScintillaGTKAccessible *ScintillaGTKAccessible::FromAccessible(GtkAccessible *ac // FIXME: do we need the check below? GTK checks that in all methods, so maybe GtkWidget *widget = gtk_accessible_get_widget(accessible); if (! widget) { - return 0; + return nullptr; } return SCINTILLA_OBJECT_ACCESSIBLE_GET_PRIVATE(accessible)->pscin; @@ -163,16 +167,16 @@ ScintillaGTKAccessible::ScintillaGTKAccessible(GtkAccessible *accessible_, GtkWi ScintillaGTKAccessible::~ScintillaGTKAccessible() { if (gtk_accessible_get_widget(accessible)) { - g_signal_handlers_disconnect_matched(sci->sci, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, this); + g_signal_handlers_disconnect_matched(sci->sci, G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this); } } gchar *ScintillaGTKAccessible::GetTextRangeUTF8(Sci::Position startByte, Sci::Position endByte) { - g_return_val_if_fail(startByte >= 0, NULL); + g_return_val_if_fail(startByte >= 0, nullptr); // FIXME: should we swap start/end if necessary? - g_return_val_if_fail(endByte >= startByte, NULL); + g_return_val_if_fail(endByte >= startByte, nullptr); - gchar *utf8Text = NULL; + gchar *utf8Text = nullptr; const char *charSetBuffer; // like TargetAsUTF8, but avoids a double conversion @@ -207,7 +211,7 @@ gchar *ScintillaGTKAccessible::GetText(int startChar, int endChar) { gchar *ScintillaGTKAccessible::GetTextAfterOffset(int charOffset, AtkTextBoundary boundaryType, int *startChar, int *endChar) { - g_return_val_if_fail(charOffset >= 0, NULL); + g_return_val_if_fail(charOffset >= 0, nullptr); Sci::Position startByte, endByte; Sci::Position byteOffset = ByteOffsetFromCharacterOffset(charOffset); @@ -249,7 +253,7 @@ gchar *ScintillaGTKAccessible::GetTextAfterOffset(int charOffset, default: *startChar = *endChar = -1; - return NULL; + return nullptr; } CharacterRangeFromByteRange(startByte, endByte, startChar, endChar); @@ -258,7 +262,7 @@ gchar *ScintillaGTKAccessible::GetTextAfterOffset(int charOffset, gchar *ScintillaGTKAccessible::GetTextBeforeOffset(int charOffset, AtkTextBoundary boundaryType, int *startChar, int *endChar) { - g_return_val_if_fail(charOffset >= 0, NULL); + g_return_val_if_fail(charOffset >= 0, nullptr); Sci::Position startByte, endByte; Sci::Position byteOffset = ByteOffsetFromCharacterOffset(charOffset); @@ -311,7 +315,7 @@ gchar *ScintillaGTKAccessible::GetTextBeforeOffset(int charOffset, default: *startChar = *endChar = -1; - return NULL; + return nullptr; } CharacterRangeFromByteRange(startByte, endByte, startChar, endChar); @@ -320,7 +324,7 @@ gchar *ScintillaGTKAccessible::GetTextBeforeOffset(int charOffset, gchar *ScintillaGTKAccessible::GetTextAtOffset(int charOffset, AtkTextBoundary boundaryType, int *startChar, int *endChar) { - g_return_val_if_fail(charOffset >= 0, NULL); + g_return_val_if_fail(charOffset >= 0, nullptr); Sci::Position startByte, endByte; Sci::Position byteOffset = ByteOffsetFromCharacterOffset(charOffset); @@ -373,7 +377,7 @@ gchar *ScintillaGTKAccessible::GetTextAtOffset(int charOffset, default: *startChar = *endChar = -1; - return NULL; + return nullptr; } CharacterRangeFromByteRange(startByte, endByte, startChar, endChar); @@ -383,7 +387,7 @@ gchar *ScintillaGTKAccessible::GetTextAtOffset(int charOffset, #if ATK_CHECK_VERSION(2, 10, 0) gchar *ScintillaGTKAccessible::GetStringAtOffset(int charOffset, AtkTextGranularity granularity, int *startChar, int *endChar) { - g_return_val_if_fail(charOffset >= 0, NULL); + g_return_val_if_fail(charOffset >= 0, nullptr); Sci::Position startByte, endByte; Sci::Position byteOffset = ByteOffsetFromCharacterOffset(charOffset); @@ -405,7 +409,7 @@ gchar *ScintillaGTKAccessible::GetStringAtOffset(int charOffset, } default: *startChar = *endChar = -1; - return NULL; + return nullptr; } CharacterRangeFromByteRange(startByte, endByte, startChar, endChar); @@ -527,10 +531,10 @@ static AtkAttributeSet *AddTextColorAttribute(AtkAttributeSet *attributes, AtkTe } AtkAttributeSet *ScintillaGTKAccessible::GetAttributesForStyle(unsigned int styleNum) { - AtkAttributeSet *attr_set = NULL; + AtkAttributeSet *attr_set = nullptr; if (styleNum >= sci->vs.styles.size()) - return NULL; + return nullptr; Style &style = sci->vs.styles[styleNum]; attr_set = AddTextAttribute(attr_set, ATK_TEXT_ATTR_FAMILY_NAME, g_strdup(style.fontName)); @@ -547,7 +551,7 @@ AtkAttributeSet *ScintillaGTKAccessible::GetAttributesForStyle(unsigned int styl } AtkAttributeSet *ScintillaGTKAccessible::GetRunAttributes(int charOffset, int *startChar, int *endChar) { - g_return_val_if_fail(charOffset >= -1, NULL); + g_return_val_if_fail(charOffset >= -1, nullptr); Sci::Position byteOffset; if (charOffset == -1) { @@ -557,7 +561,7 @@ AtkAttributeSet *ScintillaGTKAccessible::GetRunAttributes(int charOffset, int *s } int length = sci->pdoc->Length(); - g_return_val_if_fail(byteOffset <= length, NULL); + g_return_val_if_fail(byteOffset <= length, nullptr); const char style = StyleAt(byteOffset, true); // compute the range for this style @@ -583,7 +587,7 @@ gint ScintillaGTKAccessible::GetNSelections() { gchar *ScintillaGTKAccessible::GetSelection(gint selection_num, int *startChar, int *endChar) { if (selection_num < 0 || (unsigned int) selection_num >= sci->sel.Count()) - return NULL; + return nullptr; Sci::Position startByte = sci->sel.Range(selection_num).Start().Position(); Sci::Position endByte = sci->sel.Range(selection_num).End().Position(); @@ -737,7 +741,7 @@ void ScintillaGTKAccessible::PasteText(int charPosition) { Sci::Position bytePosition; void Destroyed() override { - scia = 0; + scia = nullptr; } Helper(ScintillaGTKAccessible *scia_, Sci::Position bytePos_) : @@ -763,7 +767,7 @@ void ScintillaGTKAccessible::PasteText(int charPosition) { static void TextReceivedCallback(GtkClipboard *clipboard, const gchar *text, gpointer data) { Helper *helper = static_cast(data); try { - if (helper->scia != 0) { + if (helper->scia != nullptr) { helper->TextReceived(clipboard, text); } } catch (...) {} @@ -917,20 +921,20 @@ void ScintillaGTKAccessible::Notify(GtkWidget *, gint, SCNotification *nt) { // AtkText gchar *ScintillaGTKAccessible::AtkTextIface::GetText(AtkText *text, int start_offset, int end_offset) { - WRAPPER_METHOD_BODY(text, GetText(start_offset, end_offset), NULL); + WRAPPER_METHOD_BODY(text, GetText(start_offset, end_offset), nullptr); } gchar *ScintillaGTKAccessible::AtkTextIface::GetTextAfterOffset(AtkText *text, int offset, AtkTextBoundary boundary_type, int *start_offset, int *end_offset) { - WRAPPER_METHOD_BODY(text, GetTextAfterOffset(offset, boundary_type, start_offset, end_offset), NULL) + WRAPPER_METHOD_BODY(text, GetTextAfterOffset(offset, boundary_type, start_offset, end_offset), nullptr) } gchar *ScintillaGTKAccessible::AtkTextIface::GetTextBeforeOffset(AtkText *text, int offset, AtkTextBoundary boundary_type, int *start_offset, int *end_offset) { - WRAPPER_METHOD_BODY(text, GetTextBeforeOffset(offset, boundary_type, start_offset, end_offset), NULL) + WRAPPER_METHOD_BODY(text, GetTextBeforeOffset(offset, boundary_type, start_offset, end_offset), nullptr) } gchar *ScintillaGTKAccessible::AtkTextIface::GetTextAtOffset(AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) { - WRAPPER_METHOD_BODY(text, GetTextAtOffset(offset, boundary_type, start_offset, end_offset), NULL) + WRAPPER_METHOD_BODY(text, GetTextAtOffset(offset, boundary_type, start_offset, end_offset), nullptr) } #if ATK_CHECK_VERSION(2, 10, 0) gchar *ScintillaGTKAccessible::AtkTextIface::GetStringAtOffset(AtkText *text, gint offset, AtkTextGranularity granularity, gint *start_offset, gint *end_offset) { - WRAPPER_METHOD_BODY(text, GetStringAtOffset(offset, granularity, start_offset, end_offset), NULL) + WRAPPER_METHOD_BODY(text, GetStringAtOffset(offset, granularity, start_offset, end_offset), nullptr) } #endif gunichar ScintillaGTKAccessible::AtkTextIface::GetCharacterAtOffset(AtkText *text, gint offset) { @@ -952,16 +956,16 @@ void ScintillaGTKAccessible::AtkTextIface::GetCharacterExtents(AtkText *text, gi WRAPPER_METHOD_BODY(text, GetCharacterExtents(offset, x, y, width, height, coords), ) } AtkAttributeSet *ScintillaGTKAccessible::AtkTextIface::GetRunAttributes(AtkText *text, gint offset, gint *start_offset, gint *end_offset) { - WRAPPER_METHOD_BODY(text, GetRunAttributes(offset, start_offset, end_offset), NULL) + WRAPPER_METHOD_BODY(text, GetRunAttributes(offset, start_offset, end_offset), nullptr) } AtkAttributeSet *ScintillaGTKAccessible::AtkTextIface::GetDefaultAttributes(AtkText *text) { - WRAPPER_METHOD_BODY(text, GetDefaultAttributes(), NULL) + WRAPPER_METHOD_BODY(text, GetDefaultAttributes(), nullptr) } gint ScintillaGTKAccessible::AtkTextIface::GetNSelections(AtkText *text) { WRAPPER_METHOD_BODY(text, GetNSelections(), 0) } gchar *ScintillaGTKAccessible::AtkTextIface::GetSelection(AtkText *text, gint selection_num, gint *start_pos, gint *end_pos) { - WRAPPER_METHOD_BODY(text, GetSelection(selection_num, start_pos, end_pos), NULL) + WRAPPER_METHOD_BODY(text, GetSelection(selection_num, start_pos, end_pos), nullptr) } gboolean ScintillaGTKAccessible::AtkTextIface::AddSelection(AtkText *text, gint start, gint end) { WRAPPER_METHOD_BODY(text, AddSelection(start, end), FALSE) @@ -1000,7 +1004,7 @@ static GType scintilla_object_accessible_factory_get_type(void); static void scintilla_object_accessible_init(ScintillaObjectAccessible *accessible); static void scintilla_object_accessible_class_init(ScintillaObjectAccessibleClass *klass); -static gpointer scintilla_object_accessible_parent_class = NULL; +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 @@ -1010,27 +1014,27 @@ static GType scintilla_object_accessible_get_type(GType parent_type G_GNUC_UNUSE if (g_once_init_enter(&type_id_result)) { GTypeInfo tinfo = { 0, /* class size */ - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ + (GBaseInitFunc) nullptr, /* base init */ + (GBaseFinalizeFunc) nullptr, /* base finalize */ (GClassInitFunc) scintilla_object_accessible_class_init, /* class init */ - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ + (GClassFinalizeFunc) nullptr, /* class finalize */ + nullptr, /* class data */ 0, /* instance size */ 0, /* nb preallocs */ (GInstanceInitFunc) scintilla_object_accessible_init, /* instance init */ - NULL /* value table */ + nullptr /* value table */ }; const GInterfaceInfo atk_text_info = { (GInterfaceInitFunc) ScintillaGTKAccessible::AtkTextIface::init, - (GInterfaceFinalizeFunc) NULL, - NULL + (GInterfaceFinalizeFunc) nullptr, + nullptr }; const GInterfaceInfo atk_editable_text_info = { (GInterfaceInitFunc) ScintillaGTKAccessible::AtkEditableTextIface::init, - (GInterfaceFinalizeFunc) NULL, - NULL + (GInterfaceFinalizeFunc) nullptr, + nullptr }; #if HAVE_GTK_A11Y_H @@ -1071,13 +1075,13 @@ static GType scintilla_object_accessible_get_type(GType parent_type G_GNUC_UNUSE } static AtkObject *scintilla_object_accessible_new(GType parent_type, GObject *obj) { - g_return_val_if_fail(SCINTILLA_IS_OBJECT(obj), NULL); + g_return_val_if_fail(SCINTILLA_IS_OBJECT(obj), nullptr); AtkObject *accessible = (AtkObject *) g_object_new(scintilla_object_accessible_get_type(parent_type), #if HAVE_WIDGET_SET_UNSET "widget", obj, #endif - NULL); + nullptr); atk_object_initialize(accessible, obj); return accessible; @@ -1089,7 +1093,7 @@ static AtkObject *scintilla_object_accessible_new(GType parent_type, GObject *ob // @p cache pointer to store the AtkObject between repeated calls. Might or might not be filled. // @p widget_parent_class pointer to the widget's parent class (to chain up method calls). AtkObject *ScintillaGTKAccessible::WidgetGetAccessibleImpl(GtkWidget *widget, AtkObject **cache, gpointer widget_parent_class G_GNUC_UNUSED) { - if (*cache != NULL) { + if (*cache != nullptr) { return *cache; } @@ -1139,7 +1143,7 @@ static AtkStateSet *scintilla_object_accessible_ref_state_set(AtkObject *accessi AtkStateSet *state_set = ATK_OBJECT_CLASS(scintilla_object_accessible_parent_class)->ref_state_set(accessible); GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE(accessible)); - if (widget == NULL) { + 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)) @@ -1159,11 +1163,11 @@ static AtkStateSet *scintilla_object_accessible_ref_state_set(AtkObject *accessi static void scintilla_object_accessible_widget_set(GtkAccessible *accessible) { GtkWidget *widget = gtk_accessible_get_widget(accessible); - if (widget == NULL) + if (widget == nullptr) return; ScintillaObjectAccessiblePrivate *priv = SCINTILLA_OBJECT_ACCESSIBLE_GET_PRIVATE(accessible); - if (priv->pscin != 0) + if (priv->pscin) delete priv->pscin; priv->pscin = new ScintillaGTKAccessible(accessible, widget); } @@ -1171,7 +1175,7 @@ static void scintilla_object_accessible_widget_set(GtkAccessible *accessible) { #if HAVE_WIDGET_SET_UNSET static void scintilla_object_accessible_widget_unset(GtkAccessible *accessible) { GtkWidget *widget = gtk_accessible_get_widget(accessible); - if (widget == NULL) + if (widget == nullptr) return; ScintillaObjectAccessiblePrivate *priv = SCINTILLA_OBJECT_ACCESSIBLE_GET_PRIVATE(accessible); @@ -1195,7 +1199,7 @@ static void scintilla_object_accessible_finalize(GObject *object) { if (priv->pscin) { delete priv->pscin; - priv->pscin = 0; + priv->pscin = nullptr; } G_OBJECT_CLASS(scintilla_object_accessible_parent_class)->finalize(object); @@ -1224,7 +1228,7 @@ static void scintilla_object_accessible_class_init(ScintillaObjectAccessibleClas static void scintilla_object_accessible_init(ScintillaObjectAccessible *accessible) { ScintillaObjectAccessiblePrivate *priv = SCINTILLA_OBJECT_ACCESSIBLE_GET_PRIVATE(accessible); - priv->pscin = 0; + priv->pscin = nullptr; } #if HAVE_GTK_FACTORY diff --git a/scintilla/include/Platform.h b/scintilla/include/Platform.h index 654460901a..8f5417fe09 100644 --- a/scintilla/include/Platform.h +++ b/scintilla/include/Platform.h @@ -108,6 +108,18 @@ class Point { return Point(static_cast(x_), static_cast(y_)); } + bool operator!=(Point other) const noexcept { + return (x != other.x) || (y != other.y); + } + + Point operator+(Point other) const noexcept { + return Point(x + other.x, y + other.y); + } + + Point operator-(Point other) const noexcept { + return Point(x - other.x, y - other.y); + } + // Other automatically defined methods (assignment, copy constructor, destructor) are fine }; diff --git a/scintilla/include/SciLexer.h b/scintilla/include/SciLexer.h index 4613e48de3..ae20985cea 100644 --- a/scintilla/include/SciLexer.h +++ b/scintilla/include/SciLexer.h @@ -139,6 +139,7 @@ #define SCLEX_STATA 124 #define SCLEX_SAS 125 #define SCLEX_NIM 126 +#define SCLEX_CIL 127 #define SCLEX_LPEG 999 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 @@ -1874,6 +1875,17 @@ #define SCE_NIM_NUMERROR 14 #define SCE_NIM_OPERATOR 15 #define SCE_NIM_IDENTIFIER 16 +#define SCE_CIL_DEFAULT 0 +#define SCE_CIL_COMMENT 1 +#define SCE_CIL_COMMENTLINE 2 +#define SCE_CIL_WORD 3 +#define SCE_CIL_WORD2 4 +#define SCE_CIL_WORD3 5 +#define SCE_CIL_STRING 6 +#define SCE_CIL_LABEL 7 +#define SCE_CIL_OPERATOR 8 +#define SCE_CIL_IDENTIFIER 9 +#define SCE_CIL_STRINGEOL 10 /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ #endif diff --git a/scintilla/include/Scintilla.h b/scintilla/include/Scintilla.h index 298103cea2..b4b4f2e7ec 100644 --- a/scintilla/include/Scintilla.h +++ b/scintilla/include/Scintilla.h @@ -135,6 +135,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_MARK_UNDERLINE 29 #define SC_MARK_RGBAIMAGE 30 #define SC_MARK_BOOKMARK 31 +#define SC_MARK_VERTICALBOOKMARK 32 #define SC_MARK_CHARACTER 10000 #define SC_MARKNUM_FOLDEREND 25 #define SC_MARKNUM_FOLDEROPENMID 26 @@ -266,6 +267,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_SETCARETPERIOD 2076 #define SCI_SETWORDCHARS 2077 #define SCI_GETWORDCHARS 2646 +#define SCI_SETCHARACTERCATEGORYOPTIMIZATION 2720 +#define SCI_GETCHARACTERCATEGORYOPTIMIZATION 2721 #define SCI_BEGINUNDOACTION 2078 #define SCI_ENDUNDOACTION 2079 #define INDIC_PLAIN 0 @@ -490,6 +493,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_FOLDDISPLAYTEXT_STANDARD 1 #define SC_FOLDDISPLAYTEXT_BOXED 2 #define SCI_FOLDDISPLAYTEXTSETSTYLE 2701 +#define SCI_FOLDDISPLAYTEXTGETSTYLE 2707 +#define SCI_SETDEFAULTFOLDDISPLAYTEXT 2722 +#define SCI_GETDEFAULTFOLDDISPLAYTEXT 2723 #define SC_FOLDACTION_CONTRACT 0 #define SC_FOLDACTION_EXPAND 1 #define SC_FOLDACTION_TOGGLE 2 @@ -829,6 +835,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define CARETSTYLE_INVISIBLE 0 #define CARETSTYLE_LINE 1 #define CARETSTYLE_BLOCK 2 +#define CARETSTYLE_OVERSTRIKE_BAR 0 +#define CARETSTYLE_OVERSTRIKE_BLOCK 16 +#define CARETSTYLE_INS_MASK 0xF #define SCI_SETCARETSTYLE 2512 #define SCI_GETCARETSTYLE 2513 #define SCI_SETINDICATORCURRENT 2500 diff --git a/scintilla/include/Scintilla.iface b/scintilla/include/Scintilla.iface index 7cbb200203..c009371c10 100644 --- a/scintilla/include/Scintilla.iface +++ b/scintilla/include/Scintilla.iface @@ -304,6 +304,7 @@ val SC_MARK_AVAILABLE=28 val SC_MARK_UNDERLINE=29 val SC_MARK_RGBAIMAGE=30 val SC_MARK_BOOKMARK=31 +val SC_MARK_VERTICALBOOKMARK=32 val SC_MARK_CHARACTER=10000 @@ -610,6 +611,12 @@ set void SetWordChars=2077(, string characters) # Returns the number of characters get int GetWordChars=2646(, stringresult characters) +# Set the number of characters to have directly indexed categories +set void SetCharacterCategoryOptimization=2720(int countCharacters,) + +# Get the number of characters to have directly indexed categories +get int GetCharacterCategoryOptimization=2721(,) + # Start a sequence of actions that is undone and redone as a unit. # May be nested. fun void BeginUndoAction=2078(,) @@ -1227,9 +1234,18 @@ val SC_FOLDDISPLAYTEXT_HIDDEN=0 val SC_FOLDDISPLAYTEXT_STANDARD=1 val SC_FOLDDISPLAYTEXT_BOXED=2 -# Set the style of fold display text +# Set the style of fold display text. set void FoldDisplayTextSetStyle=2701(int style,) +# Get the style of fold display text. +get int FoldDisplayTextGetStyle=2707(,) + +# Set the default fold display text. +fun void SetDefaultFoldDisplayText=2722(, string text) + +# Get the default fold display text. +fun int GetDefaultFoldDisplayText=2723(, stringresult text) + enu FoldAction=SC_FOLDACTION_ val SC_FOLDACTION_CONTRACT=0 val SC_FOLDACTION_EXPAND=1 @@ -2178,6 +2194,9 @@ enu CaretStyle=CARETSTYLE_ val CARETSTYLE_INVISIBLE=0 val CARETSTYLE_LINE=1 val CARETSTYLE_BLOCK=2 +val CARETSTYLE_OVERSTRIKE_BAR=0 +val CARETSTYLE_OVERSTRIKE_BLOCK=16 +val CARETSTYLE_INS_MASK=0xF # Set the style of the caret to be drawn. set void SetCaretStyle=2512(int caretStyle,) @@ -2956,6 +2975,7 @@ val SCLEX_MAXIMA=123 val SCLEX_STATA=124 val SCLEX_SAS=125 val SCLEX_NIM=126 +val SCLEX_CIL=127 val SCLEX_LPEG=999 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a @@ -4929,6 +4949,19 @@ 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 # Events diff --git a/scintilla/lexers/LexCPP.cxx b/scintilla/lexers/LexCPP.cxx index d6637784ad..06d4c0265a 100644 --- a/scintilla/lexers/LexCPP.cxx +++ b/scintilla/lexers/LexCPP.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include "ILexer.h" #include "Scintilla.h" @@ -39,7 +40,7 @@ using namespace Scintilla; namespace { // Use an unnamed namespace to protect the functions and classes from name conflicts -bool IsSpaceEquiv(int state) noexcept { +constexpr bool IsSpaceEquiv(int state) noexcept { return (state <= SCE_C_COMMENTDOC) || // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE (state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) || @@ -86,7 +87,7 @@ bool followsReturnKeyword(const StyleContext &sc, LexAccessor &styler) { return !*s; } -bool IsSpaceOrTab(int ch) noexcept { +constexpr bool IsSpaceOrTab(int ch) noexcept { return ch == ' ' || ch == '\t'; } @@ -145,7 +146,7 @@ void highlightTaskMarker(StyleContext &sc, LexAccessor &styler, if ((isoperator(sc.chPrev) || IsASpace(sc.chPrev)) && markerList.Length()) { const int lengthMarker = 50; char marker[lengthMarker+1] = ""; - const Sci_Position currPos = static_cast(sc.currentPos); + const Sci_Position currPos = sc.currentPos; int i = 0; while (i < lengthMarker) { const char ch = styler.SafeGetCharAt(currPos + i); @@ -173,7 +174,7 @@ struct EscapeSequence { CharacterSet *escapeSetValid; EscapeSequence() { digitsLeft = 0; - escapeSetValid = 0; + escapeSetValid = nullptr; setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef"); setOctDigits = CharacterSet(CharacterSet::setNone, "01234567"); } @@ -226,7 +227,7 @@ std::string GetRestOfLine(LexAccessor &styler, Sci_Position start, bool allowSpa return restOfLine; } -bool IsStreamCommentStyle(int style) noexcept { +constexpr bool IsStreamCommentStyle(int style) noexcept { return style == SCE_C_COMMENT || style == SCE_C_COMMENTDOC || style == SCE_C_COMMENTDOCKEYWORD || @@ -244,12 +245,24 @@ struct PPDefinition { } }; +const int inactiveFlag = 0x40; + class LinePPState { - int state; - int ifTaken; - int level; + // Track the state of preprocessor conditionals to allow showing active and inactive + // code in different styles. + // Only works up to 31 levels of conditional nesting. + + // state is a bit mask with 1 bit per level + // bit is 1 for level if section inactive, so any bits set = inactive style + int state = 0; + // ifTaken is a bit mask with 1 bit per level + // bit is 1 for level if some branch at this level has been taken + int ifTaken = 0; + // level is the nesting level of #if constructs + int level = -1; + static const int maximumNestingLevel = 31; bool ValidLevel() const noexcept { - return level >= 0 && level < 32; + return level >= 0 && level < maximumNestingLevel; } int maskLevel() const noexcept { if (level >= 0) { @@ -259,11 +272,17 @@ class LinePPState { } } public: - LinePPState() : state(0), ifTaken(0), level(-1) { + LinePPState() noexcept { + } + bool IsActive() const noexcept { + return state == 0; } bool IsInactive() const noexcept { return state != 0; } + int ActiveState() const noexcept { + return state ? inactiveFlag : 0; + } bool CurrentIfTaken() const noexcept { return (ifTaken & maskLevel()) != 0; } @@ -369,7 +388,7 @@ const char *const cppWordLists[] = { "Global classes and typedefs", "Preprocessor definitions", "Task marker and error marker keywords", - 0, + nullptr, }; struct OptionSetCPP : public OptionSet { @@ -500,7 +519,8 @@ class LexerCPP : public ILexerWithMetaData { struct SymbolValue { std::string value; std::string arguments; - SymbolValue(const std::string &value_="", const std::string &arguments_="") : value(value_), arguments(arguments_) { + SymbolValue() = default; + SymbolValue(const std::string &value_, const std::string &arguments_) : value(value_), arguments(arguments_) { } SymbolValue &operator = (const std::string &value_) { value = value_; @@ -517,7 +537,6 @@ class LexerCPP : public ILexerWithMetaData { OptionSetCPP osCPP; EscapeSequence escapeSeq; SparseState rawStringTerminators; - enum { activeFlag = 0x40 }; enum { ssIdentifier, ssDocKeyword }; SubStyles subStyles; std::string returnBuffer; @@ -530,14 +549,19 @@ class LexerCPP : public ILexerWithMetaData { setMultOp(CharacterSet::setNone, "*/%"), setRelOp(CharacterSet::setNone, "=!<>"), setLogicalOp(CharacterSet::setNone, "|&"), - subStyles(styleSubable, 0x80, 0x40, activeFlag) { + subStyles(styleSubable, 0x80, 0x40, inactiveFlag) { } + // Deleted so LexerCPP objects can not be copied. + LexerCPP(const LexerCPP &) = delete; + LexerCPP(LexerCPP &&) = delete; + void operator=(const LexerCPP &) = delete; + void operator=(LexerCPP &&) = delete; virtual ~LexerCPP() { } - void SCI_METHOD Release() override { + void SCI_METHOD Release() noexcept override { delete this; } - int SCI_METHOD Version() const override { + int SCI_METHOD Version() const noexcept override { return lvMetaData; } const char * SCI_METHOD PropertyNames() override { @@ -557,11 +581,11 @@ class LexerCPP : public ILexerWithMetaData { 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; - void * SCI_METHOD PrivateCall(int, void *) override { - return 0; + void * SCI_METHOD PrivateCall(int, void *) noexcept override { + return nullptr; } - int SCI_METHOD LineEndTypesSupported() override { + int SCI_METHOD LineEndTypesSupported() noexcept override { return SC_LINE_END_TYPE_UNICODE; } @@ -576,10 +600,10 @@ class LexerCPP : public ILexerWithMetaData { } int SCI_METHOD StyleFromSubStyle(int subStyle) override { const int styleBase = subStyles.BaseStyle(MaskActive(subStyle)); - const int active = subStyle & activeFlag; - return styleBase | active; + const int inactive = subStyle & inactiveFlag; + return styleBase | inactive; } - int SCI_METHOD PrimaryStyleFromStyle(int style) override { + int SCI_METHOD PrimaryStyleFromStyle(int style) noexcept override { return MaskActive(style); } void SCI_METHOD FreeSubStyles() override { @@ -588,16 +612,16 @@ class LexerCPP : public ILexerWithMetaData { void SCI_METHOD SetIdentifiers(int style, const char *identifiers) override { subStyles.SetIdentifiers(style, identifiers); } - int SCI_METHOD DistanceToSecondaryStyles() override { - return activeFlag; + int SCI_METHOD DistanceToSecondaryStyles() noexcept override { + return inactiveFlag; } - const char * SCI_METHOD GetSubStyleBases() override { + const char * SCI_METHOD GetSubStyleBases() noexcept override { return styleSubable; } int SCI_METHOD NamedStyles() override { return std::max(subStyles.LastAllocated() + 1, static_cast(ELEMENTS(lexicalClasses))) + - activeFlag; + inactiveFlag; } const char * SCI_METHOD NameOfStyle(int style) override { if (style >= NamedStyles()) @@ -615,11 +639,11 @@ class LexerCPP : public ILexerWithMetaData { if (firstSubStyle >= 0) { const int lastSubStyle = subStyles.LastAllocated(); if (((style >= firstSubStyle) && (style <= (lastSubStyle))) || - ((style >= firstSubStyle + activeFlag) && (style <= (lastSubStyle + activeFlag)))) { + ((style >= firstSubStyle + inactiveFlag) && (style <= (lastSubStyle + inactiveFlag)))) { int styleActive = style; if (style > lastSubStyle) { returnBuffer = "inactive "; - styleActive -= activeFlag; + styleActive -= inactiveFlag; } const int styleMain = StyleFromSubStyle(styleActive); returnBuffer += lexicalClasses[styleMain].tags; @@ -628,9 +652,9 @@ class LexerCPP : public ILexerWithMetaData { } if (style < static_cast(ELEMENTS(lexicalClasses))) return lexicalClasses[style].tags; - if (style >= activeFlag) { + if (style >= inactiveFlag) { returnBuffer = "inactive "; - const int styleActive = style - activeFlag; + const int styleActive = style - inactiveFlag; if (styleActive < static_cast(ELEMENTS(lexicalClasses))) returnBuffer += lexicalClasses[styleActive].tags; else @@ -654,8 +678,8 @@ class LexerCPP : public ILexerWithMetaData { static ILexer *LexerFactoryCPPInsensitive() { return new LexerCPP(false); } - static int MaskActive(int style) noexcept { - return style & ~activeFlag; + constexpr static int MaskActive(int style) noexcept { + return style & ~inactiveFlag; } void EvaluateTokens(std::vector &tokens, const SymbolTable &preprocessorDefinitions); std::vector Tokenize(const std::string &expr) const; @@ -676,7 +700,7 @@ Sci_Position SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) } Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) { - WordList *wordListN = 0; + WordList *wordListN = nullptr; switch (n) { case 0: wordListN = &keywords; @@ -813,12 +837,12 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1); SparseState rawSTNew(lineCurrent); - int activitySet = preproc.IsInactive() ? activeFlag : 0; + int activitySet = preproc.ActiveState(); const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_C_IDENTIFIER); const WordClassifier &classifierDocKeyWords = subStyles.Classifier(SCE_C_COMMENTDOCKEYWORD); - Sci_Position lineEndNext = styler.LineEnd(lineCurrent); + Sci_PositionU lineEndNext = styler.LineEnd(lineCurrent); for (; sc.More();) { @@ -840,7 +864,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i isIncludePreprocessor = false; inRERange = false; if (preproc.IsInactive()) { - activitySet = activeFlag; + activitySet = inactiveFlag; sc.SetState(sc.state | activitySet); } } @@ -856,7 +880,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i // Handle line continuation generically. if (sc.ch == '\\') { - if (static_cast((sc.currentPos+1)) >= lineEndNext) { + if ((sc.currentPos+1) >= lineEndNext) { lineCurrent++; lineEndNext = styler.LineEnd(lineCurrent); vlls.Add(lineCurrent, preproc); @@ -950,7 +974,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i break; case SCE_C_PREPROCESSOR: if (options.stylingWithinPreprocessor) { - if (IsASpace(sc.ch)) { + if (IsASpace(sc.ch) || (sc.ch == '(')) { sc.SetState(SCE_C_DEFAULT|activitySet); } } else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"') || sc.atLineEnd)) { @@ -1128,7 +1152,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i while ((sc.ch < 0x80) && islower(sc.ch)) sc.Forward(); // gobble regex flags sc.SetState(SCE_C_DEFAULT|activitySet); - } else if (sc.ch == '\\' && (static_cast(sc.currentPos+1) < lineEndNext)) { + } else if (sc.ch == '\\' && ((sc.currentPos+1) < lineEndNext)) { // Gobble up the escaped character sc.Forward(); } else if (sc.ch == '[') { @@ -1265,6 +1289,8 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i isIncludePreprocessor = true; } else { if (options.trackPreprocessor) { + // If #if is nested too deeply (>31 levels) the active/inactive appearance + // will stop reflecting the code. if (sc.Match("ifdef") || sc.Match("ifndef")) { const bool isIfDef = sc.Match("ifdef"); const int startRest = isIfDef ? 5 : 6; @@ -1276,47 +1302,58 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i const bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions); preproc.StartSection(ifGood); } 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.IsInactive() ? activeFlag : 0; + activitySet = preproc.ActiveState(); + // If following is active then show "else" as active if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); - } else if (!preproc.IsInactive()) { + sc.ChangeState(SCE_C_PREPROCESSOR); + } else if (preproc.IsActive()) { + // Active -> inactive + assert(sc.state == SCE_C_PREPROCESSOR); preproc.InvertCurrentLevel(); - activitySet = preproc.IsInactive() ? activeFlag : 0; - if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); + 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) { preproc.InvertCurrentLevel(); - activitySet = preproc.IsInactive() ? activeFlag : 0; + activitySet = preproc.ActiveState(); if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); + sc.ChangeState(SCE_C_PREPROCESSOR); } - } else if (!preproc.IsInactive()) { + } else if (preproc.IsActive()) { + // Active -> inactive + assert(sc.state == SCE_C_PREPROCESSOR); preproc.InvertCurrentLevel(); - activitySet = preproc.IsInactive() ? activeFlag : 0; - if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); + activitySet = preproc.ActiveState(); + // Continue to show "elif" as active as it ends active section. } } else if (sc.Match("endif")) { preproc.EndSection(); - activitySet = preproc.IsInactive() ? activeFlag : 0; + activitySet = preproc.ActiveState(); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); } else if (sc.Match("define")) { - if (options.updatePreprocessor && !preproc.IsInactive()) { + if (options.updatePreprocessor && preproc.IsActive()) { std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true); size_t startName = 0; while ((startName < restOfLine.length()) && IsSpaceOrTab(restOfLine[startName])) startName++; size_t endName = startName; - while ((endName < restOfLine.length()) && setWord.Contains(static_cast(restOfLine[endName]))) + while ((endName < restOfLine.length()) && setWord.Contains(restOfLine[endName])) endName++; std::string key = restOfLine.substr(startName, endName-startName); if ((endName < restOfLine.length()) && (restOfLine.at(endName) == '(')) { @@ -1348,7 +1385,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } } } else if (sc.Match("undef")) { - if (options.updatePreprocessor && !preproc.IsInactive()) { + if (options.updatePreprocessor && preproc.IsActive()) { const std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, false); std::vector tokens = Tokenize(restOfLine); if (tokens.size() >= 1) { @@ -1542,7 +1579,7 @@ void LexerCPP::EvaluateTokens(std::vector &tokens, const SymbolTabl size_t iterations = 0; // Limit number of iterations in case there is a recursive macro. for (size_t i = 0; (i(tokens[i][0]))) { + if (setWordStart.Contains(tokens[i][0])) { SymbolTable::const_iterator it = preprocessorDefinitions.find(tokens[i]); if (it != preprocessorDefinitions.end()) { // Tokenize value @@ -1569,7 +1606,7 @@ void LexerCPP::EvaluateTokens(std::vector &tokens, const SymbolTabl macroTokens.erase(std::remove_if(macroTokens.begin(), macroTokens.end(), OnlySpaceOrTab), macroTokens.end()); for (size_t iMacro = 0; iMacro < macroTokens.size();) { - if (setWordStart.Contains(static_cast(macroTokens[iMacro][0]))) { + if (setWordStart.Contains(macroTokens[iMacro][0])) { std::map::const_iterator itFind = arguments.find(macroTokens[iMacro]); if (itFind != arguments.end()) { // TODO: Possible that value will be expression so should insert tokenized form @@ -1687,9 +1724,9 @@ std::vector LexerCPP::Tokenize(const std::string &expr) const { const char *cp = expr.c_str(); while (*cp) { std::string word; - if (setWord.Contains(static_cast(*cp))) { + if (setWord.Contains(*cp)) { // Identifiers and numbers - while (setWord.Contains(static_cast(*cp))) { + while (setWord.Contains(*cp)) { word += *cp; cp++; } @@ -1698,17 +1735,17 @@ std::vector LexerCPP::Tokenize(const std::string &expr) const { word += *cp; cp++; } - } else if (setRelOp.Contains(static_cast(*cp))) { + } else if (setRelOp.Contains(*cp)) { word += *cp; cp++; - if (setRelOp.Contains(static_cast(*cp))) { + if (setRelOp.Contains(*cp)) { word += *cp; cp++; } - } else if (setLogicalOp.Contains(static_cast(*cp))) { + } else if (setLogicalOp.Contains(*cp)) { word += *cp; cp++; - if (setLogicalOp.Contains(static_cast(*cp))) { + if (setLogicalOp.Contains(*cp)) { word += *cp; cp++; } diff --git a/scintilla/lexers/LexHaskell.cxx b/scintilla/lexers/LexHaskell.cxx index 680a0f2965..bf81995483 100644 --- a/scintilla/lexers/LexHaskell.cxx +++ b/scintilla/lexers/LexHaskell.cxx @@ -26,6 +26,7 @@ #include #include +#include #include #include "ILexer.h" diff --git a/scintilla/lexers/LexTCL.cxx b/scintilla/lexers/LexTCL.cxx index 0948f4880b..1ea6ecf6e8 100644 --- a/scintilla/lexers/LexTCL.cxx +++ b/scintilla/lexers/LexTCL.cxx @@ -128,8 +128,10 @@ static void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int , W continue; case ',': sc.SetState(SCE_TCL_OPERATOR); - if (subParen) + if (subParen) { sc.ForwardSetState(SCE_TCL_SUBSTITUTION); + goto next; // Already forwarded so avoid loop's Forward() + } continue; default : // maybe spaces should be allowed ??? diff --git a/scintilla/lexlib/CharacterCategory.cxx b/scintilla/lexlib/CharacterCategory.cxx index bc2fa23360..19c44cabe2 100644 --- a/scintilla/lexlib/CharacterCategory.cxx +++ b/scintilla/lexlib/CharacterCategory.cxx @@ -7,10 +7,13 @@ // Copyright 2013 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. +#include #include #include +#include "Scintilla.h" // for ptrdiff_t in Position.h #include "CharacterCategory.h" +#include "Position.h" // for Sci::clamp namespace Scintilla { @@ -3790,6 +3793,7 @@ const int catRanges[] = { 33554397, 33554460, 35651549, +35651613, //--Autogenerated -- end of section automatically generated }; @@ -3963,4 +3967,33 @@ bool IsXidContinue(int character) { } } +CharacterCategoryMap::CharacterCategoryMap() noexcept { + Optimize(256); +} + +int CharacterCategoryMap::Size() const noexcept { + return static_cast(dense.size()); +} + +void CharacterCategoryMap::Optimize(int countCharacters) { + const int characters = Sci::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/lexlib/CharacterCategory.h b/scintilla/lexlib/CharacterCategory.h index 767d796702..d1ac391526 100644 --- a/scintilla/lexlib/CharacterCategory.h +++ b/scintilla/lexlib/CharacterCategory.h @@ -28,6 +28,23 @@ bool IsIdContinue(int character); bool IsXidStart(int character); bool IsXidContinue(int character); +class CharacterCategoryMap { +private: + std::vector dense; +public: + CharacterCategoryMap() noexcept; + 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/lexlib/CharacterSet.h b/scintilla/lexlib/CharacterSet.h index 7c2a1fe48d..358f6bed3f 100644 --- a/scintilla/lexlib/CharacterSet.h +++ b/scintilla/lexlib/CharacterSet.h @@ -82,10 +82,9 @@ class CharacterSet { } void AddString(const char *setToAdd) { for (const char *cp=setToAdd; *cp; cp++) { - int val = static_cast(*cp); - assert(val >= 0); - assert(val < size); - bset[val] = true; + const unsigned char uch = *cp; + assert(uch < size); + bset[uch] = true; } } bool Contains(int val) const { @@ -93,6 +92,11 @@ class CharacterSet { if (val < 0) return false; return (val < size) ? bset[val] : valueAfter; } + bool Contains(char ch) const { + // Overload char as char may be signed + const unsigned char uch = ch; + return Contains(uch); + } }; // Functions for classifying characters diff --git a/scintilla/lexlib/StyleContext.cxx b/scintilla/lexlib/StyleContext.cxx index 683e21453e..fe56e53d7b 100644 --- a/scintilla/lexlib/StyleContext.cxx +++ b/scintilla/lexlib/StyleContext.cxx @@ -7,7 +7,6 @@ #include #include -#include #include "ILexer.h" diff --git a/scintilla/scintilla_changes.patch b/scintilla/scintilla_changes.patch index 249c7b0a7b..f28072ea4a 100644 --- a/scintilla/scintilla_changes.patch +++ b/scintilla/scintilla_changes.patch @@ -39,8 +39,8 @@ index 0871ca2..49dc278 100644 /* legacy name for scintilla_object_new */ +GEANY_API_SYMBOL - GtkWidget* scintilla_new() { - GtkWidget *widget = GTK_WIDGET(g_object_new(scintilla_get_type(), NULL)); + GtkWidget *scintilla_new() { + GtkWidget *widget = GTK_WIDGET(g_object_new(scintilla_get_type(), nullptr)); gtk_widget_set_direction(widget, GTK_TEXT_DIR_LTR); @@ -3207,6 +3212,7 @@ GtkWidget* scintilla_new() { return widget; @@ -62,7 +62,7 @@ diff --git scintilla/src/Catalogue.cxx scintilla/src/Catalogue.cxx index ed47aa8..e58f1ab 100644 --- scintilla/src/Catalogue.cxx +++ scintilla/src/Catalogue.cxx -@@ -77,128 +77,50 @@ int Scintilla_LinkLexers() { +@@ -77,129 +77,50 @@ int Scintilla_LinkLexers() { //++Autogenerated -- run scripts/LexGen.py to regenerate //**\(\tLINK_LEXER(\*);\n\) @@ -84,6 +84,7 @@ index ed47aa8..e58f1ab 100644 - LINK_LEXER(lmBlitzBasic); - LINK_LEXER(lmBullant); LINK_LEXER(lmCaml); +- LINK_LEXER(lmCIL); - LINK_LEXER(lmClw); - LINK_LEXER(lmClwNoCase); LINK_LEXER(lmCmake); diff --git a/scintilla/src/CallTip.cxx b/scintilla/src/CallTip.cxx index 2dcf91ea63..18c4549bba 100644 --- a/scintilla/src/CallTip.cxx +++ b/scintilla/src/CallTip.cxx @@ -176,7 +176,7 @@ 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(lround(surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font))); + const int ascent = static_cast(round(surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font))); // For each line... // Draw the definition in three parts: before highlight, highlighted, after highlight diff --git a/scintilla/src/CaseConvert.cxx b/scintilla/src/CaseConvert.cxx index d578759968..c1cfd38e28 100644 --- a/scintilla/src/CaseConvert.cxx +++ b/scintilla/src/CaseConvert.cxx @@ -569,7 +569,7 @@ class CaseConverter : public ICaseConverter { enum { maxConversionLength=6 }; struct ConversionString { char conversion[maxConversionLength+1]; - ConversionString() : conversion{} { + ConversionString() noexcept : conversion{} { } }; // Conversions are initially store in a vector of structs but then decomposed into @@ -591,10 +591,10 @@ class CaseConverter : public ICaseConverter { std::vector conversions; public: - CaseConverter() { + CaseConverter() noexcept { } virtual ~CaseConverter() = default; - bool Initialised() const { + bool Initialised() const noexcept { return !characters.empty(); } void Add(int character, const char *conversion) { @@ -771,7 +771,7 @@ void SetupConversions(enum CaseConversion conversion) { } } -CaseConverter *ConverterForConversion(enum CaseConversion conversion) { +CaseConverter *ConverterForConversion(enum CaseConversion conversion) noexcept { switch (conversion) { case CaseConversionFold: return &caseConvFold; diff --git a/scintilla/src/CaseFolder.cxx b/scintilla/src/CaseFolder.cxx index 0fd29c7bb6..7db4bb6797 100644 --- a/scintilla/src/CaseFolder.cxx +++ b/scintilla/src/CaseFolder.cxx @@ -41,7 +41,7 @@ void CaseFolderTable::SetTranslation(char ch, char chTranslation) { mapping[static_cast(ch)] = chTranslation; } -void CaseFolderTable::StandardASCII() { +void CaseFolderTable::StandardASCII() noexcept { for (size_t iChar=0; iChar= 'A' && iChar <= 'Z') { mapping[iChar] = static_cast(iChar - 'A' + 'a'); diff --git a/scintilla/src/CaseFolder.h b/scintilla/src/CaseFolder.h index 5fa65870e0..eb852a491b 100644 --- a/scintilla/src/CaseFolder.h +++ b/scintilla/src/CaseFolder.h @@ -24,7 +24,7 @@ class CaseFolderTable : public CaseFolder { ~CaseFolderTable() override; size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) override; void SetTranslation(char ch, char chTranslation); - void StandardASCII(); + void StandardASCII() noexcept; }; class ICaseConverter; diff --git a/scintilla/src/CharClassify.cxx b/scintilla/src/CharClassify.cxx index ba8433e62b..5ae47a2ef7 100644 --- a/scintilla/src/CharClassify.cxx +++ b/scintilla/src/CharClassify.cxx @@ -6,10 +6,11 @@ // The License.txt file describes the conditions under which this software may be distributed. #include -#include +#include #include +#include "CharacterSet.h" #include "CharClassify.h" using namespace Scintilla; @@ -25,7 +26,7 @@ void CharClassify::SetDefaultCharClasses(bool includeWordClass) { charClass[ch] = ccNewLine; else if (ch < 0x20 || ch == ' ') charClass[ch] = ccSpace; - else if (includeWordClass && (ch >= 0x80 || isalnum(ch) || ch == '_')) + else if (includeWordClass && (ch >= 0x80 || IsAlphaNumeric(ch) || ch == '_')) charClass[ch] = ccWord; else charClass[ch] = ccPunctuation; diff --git a/scintilla/src/ContractionState.cxx b/scintilla/src/ContractionState.cxx index c5e352180e..47f345ada8 100644 --- a/scintilla/src/ContractionState.cxx +++ b/scintilla/src/ContractionState.cxx @@ -74,7 +74,6 @@ class ContractionState final : public IContractionState { bool HiddenLines() const override; const char *GetFoldDisplayText(Sci::Line lineDoc) const override; - bool GetFoldDisplayTextShown(Sci::Line lineDoc) const override; bool SetFoldDisplayText(Sci::Line lineDoc, const char *text) override; bool GetExpanded(Sci::Line lineDoc) const override; @@ -276,17 +275,12 @@ const char *ContractionState::GetFoldDisplayText(Sci::Line lineDoc) const return foldDisplayTexts->ValueAt(lineDoc).get(); } -template -bool ContractionState::GetFoldDisplayTextShown(Sci::Line lineDoc) const { - return !GetExpanded(lineDoc) && GetFoldDisplayText(lineDoc); -} - template bool ContractionState::SetFoldDisplayText(Sci::Line lineDoc, const char *text) { EnsureData(); const char *foldText = foldDisplayTexts->ValueAt(lineDoc).get(); if (!foldText || !text || 0 != strcmp(text, foldText)) { - UniqueString uns = UniqueStringCopy(text); + UniqueString uns = IsNullOrEmpty(text) ? UniqueString() : UniqueStringCopy(text); foldDisplayTexts->SetValueAt(lineDoc, std::move(uns)); Check(); return true; diff --git a/scintilla/src/ContractionState.h b/scintilla/src/ContractionState.h index 90f5c07845..f9ec7b6454 100644 --- a/scintilla/src/ContractionState.h +++ b/scintilla/src/ContractionState.h @@ -32,7 +32,6 @@ class IContractionState { virtual bool HiddenLines() const=0; virtual const char *GetFoldDisplayText(Sci::Line lineDoc) const=0; - virtual bool GetFoldDisplayTextShown(Sci::Line lineDoc) const=0; virtual bool SetFoldDisplayText(Sci::Line lineDoc, const char *text)=0; virtual bool GetExpanded(Sci::Line lineDoc) const=0; diff --git a/scintilla/src/DBCS.h b/scintilla/src/DBCS.h index ff3f9f22f8..58659ee3ee 100644 --- a/scintilla/src/DBCS.h +++ b/scintilla/src/DBCS.h @@ -10,6 +10,14 @@ namespace Scintilla { +constexpr bool IsDBCSCodePage(int codePage) noexcept { + return codePage == 932 + || codePage == 936 + || codePage == 949 + || codePage == 950 + || codePage == 1361; +} + bool DBCSIsLeadByte(int codePage, char ch) noexcept; } diff --git a/scintilla/src/Document.cxx b/scintilla/src/Document.cxx index 53c5280db8..dd11ae42dc 100644 --- a/scintilla/src/Document.cxx +++ b/scintilla/src/Document.cxx @@ -476,7 +476,7 @@ void Document::ClearLevels() { Levels()->ClearLevels(); } -static bool IsSubordinate(int levelStart, int levelTry) { +static bool IsSubordinate(int levelStart, int levelTry) noexcept { if (levelTry & SC_FOLDLEVELWHITEFLAG) return true; else @@ -1092,7 +1092,7 @@ int Document::DBCSDrawBytes(const char *text, int len) const noexcept { } } -static inline bool IsSpaceOrTab(int ch) noexcept { +static constexpr bool IsSpaceOrTab(int ch) noexcept { return ch == ' ' || ch == '\t'; } @@ -1438,7 +1438,7 @@ void Document::DelCharBack(Sci::Position pos) { } } -static Sci::Position NextTab(Sci::Position pos, Sci::Position tabSize) noexcept { +static constexpr Sci::Position NextTab(Sci::Position pos, Sci::Position tabSize) noexcept { return ((pos / tabSize) + 1) * tabSize; } @@ -1710,7 +1710,7 @@ CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { if (dbcsCodePage && (!UTF8IsAscii(ch))) { if (SC_CP_UTF8 == dbcsCodePage) { // Use hard coded Unicode class - const CharacterCategory cc = CategoriseCharacter(ch); + const CharacterCategory cc = charMap.CategoryFor(ch); switch (cc) { // Separator, Line/Paragraph @@ -2169,6 +2169,14 @@ int Document::GetCharsOfClass(CharClassify::cc characterClass, unsigned char *bu return charClass.GetCharsOfClass(characterClass, buffer); } +void Document::SetCharacterCategoryOptimization(int countCharacters) { + charMap.Optimize(countCharacters); +} + +int Document::CharacterCategoryOptimization() const noexcept { + return charMap.Size(); +} + void SCI_METHOD Document::StartStyling(Sci_Position position, char) { endStyled = position; } @@ -2554,7 +2562,7 @@ Sci::Position Document::WordPartRight(Sci::Position pos) const { return pos; } -static bool IsLineEndChar(char c) noexcept { +static constexpr bool IsLineEndChar(char c) noexcept { return (c == '\n' || c == '\r'); } @@ -3061,16 +3069,9 @@ Sci::Position Cxx11RegexFindText(const Document *doc, Sci::Position minPos, Sci: bool matched = false; if (SC_CP_UTF8 == doc->dbcsCodePage) { - const size_t lenS = strlen(s); - std::vector ws(lenS + 1); -#if WCHAR_T_IS_16 - const size_t outLen = UTF16FromUTF8(s, lenS, &ws[0], lenS); -#else - const size_t outLen = UTF32FromUTF8(s, lenS, reinterpret_cast(&ws[0]), lenS); -#endif - ws[outLen] = 0; + const std::wstring ws = WStringFromUTF8(s, strlen(s)); std::wregex regexp; - regexp.assign(&ws[0], flagsRe); + regexp.assign(ws, flagsRe); matched = MatchOnLines(doc, regexp, resr, search); } else { diff --git a/scintilla/src/Document.h b/scintilla/src/Document.h index 927bbd77c6..adbdc34138 100644 --- a/scintilla/src/Document.h +++ b/scintilla/src/Document.h @@ -126,11 +126,11 @@ struct StyledText { class HighlightDelimiter { public: - HighlightDelimiter() : isEnabled(false) { + HighlightDelimiter() noexcept : isEnabled(false) { Clear(); } - void Clear() { + void Clear() noexcept { beginFoldBlock = -1; endFoldBlock = -1; firstChangeableLineBefore = -1; @@ -164,7 +164,7 @@ class HighlightDelimiter { bool isEnabled; }; -inline int LevelNumber(int level) noexcept { +constexpr int LevelNumber(int level) noexcept { return level & SC_FOLDLEVELNUMBERMASK; } @@ -174,13 +174,13 @@ class LexInterface { ILexer *instance; bool performingStyle; ///< Prevent reentrance public: - explicit LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(nullptr), performingStyle(false) { + explicit LexInterface(Document *pdoc_) noexcept : pdoc(pdoc_), instance(nullptr), performingStyle(false) { } virtual ~LexInterface() { } void Colourise(Sci::Position start, Sci::Position end); virtual int LineEndTypesSupported(); - bool UseContainerLexing() const { + bool UseContainerLexing() const noexcept { return instance == nullptr; } }; @@ -230,6 +230,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { int refCount; CellBuffer cb; CharClassify charClass; + CharacterCategoryMap charMap; std::unique_ptr pcf; Sci::Position endStyled; int styleClock; @@ -444,6 +445,8 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { void SetDefaultCharClasses(bool includeWordClass); void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass); int GetCharsOfClass(CharClassify::cc characterClass, unsigned char *buffer) const; + void SetCharacterCategoryOptimization(int countCharacters); + int CharacterCategoryOptimization() const noexcept; void SCI_METHOD StartStyling(Sci_Position position, char mask) override; bool SCI_METHOD SetStyleFor(Sci_Position length, char style) override; bool SCI_METHOD SetStyles(Sci_Position length, const char *styles) override; @@ -507,6 +510,11 @@ class UndoGroup { pdoc->BeginUndoAction(); } } + // Deleted so UndoGroup objects can not be copied. + UndoGroup(const UndoGroup &) = delete; + UndoGroup(UndoGroup &&) = delete; + void operator=(const UndoGroup &) = delete; + UndoGroup &operator=(UndoGroup &&) = delete; ~UndoGroup() { if (groupNeeded) { pdoc->EndUndoAction(); @@ -573,7 +581,7 @@ class DocWatcher { virtual void NotifyModifyAttempt(Document *doc, void *userData) = 0; virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0; virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0; - virtual void NotifyDeleted(Document *doc, void *userData) = 0; + 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; diff --git a/scintilla/src/EditModel.cxx b/scintilla/src/EditModel.cxx index 7ed7e350d0..99520f3cbd 100644 --- a/scintilla/src/EditModel.cxx +++ b/scintilla/src/EditModel.cxx @@ -24,6 +24,8 @@ #include "ILexer.h" #include "Scintilla.h" +#include "CharacterCategory.h" + #include "Position.h" #include "UniqueString.h" #include "SplitVector.h" @@ -75,3 +77,21 @@ EditModel::~EditModel() { pdoc->Release(); pdoc = nullptr; } + +void EditModel::SetDefaultFoldDisplayText(const char *text) { + defaultFoldDisplayText = IsNullOrEmpty(text) ? UniqueString() : UniqueStringCopy(text); +} + +const char *EditModel::GetDefaultFoldDisplayText() const noexcept { + return defaultFoldDisplayText.get(); +} + +const char *EditModel::GetFoldDisplayText(Sci::Line lineDoc) const { + if (foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_HIDDEN || pcs->GetExpanded(lineDoc)) { + return nullptr; + } + + const char *text = pcs->GetFoldDisplayText(lineDoc); + return text ? text : defaultFoldDisplayText.get(); +} + diff --git a/scintilla/src/EditModel.h b/scintilla/src/EditModel.h index da89c91988..ab5c23cdb9 100644 --- a/scintilla/src/EditModel.h +++ b/scintilla/src/EditModel.h @@ -40,6 +40,7 @@ class EditModel { int foldFlags; int foldDisplayTextStyle; + UniqueString defaultFoldDisplayText; std::unique_ptr pcs; // Hotspot support Range hotspot; @@ -60,7 +61,10 @@ class EditModel { virtual Sci::Line TopLineOfMain() const = 0; virtual Point GetVisibleOriginInMain() const = 0; virtual Sci::Line LinesOnScreen() const = 0; - virtual Range GetHotSpotRange() const = 0; + virtual Range GetHotSpotRange() const noexcept = 0; + void SetDefaultFoldDisplayText(const char *text); + const char *GetDefaultFoldDisplayText() const noexcept; + const char *GetFoldDisplayText(Sci::Line lineDoc) const; }; } diff --git a/scintilla/src/EditView.cxx b/scintilla/src/EditView.cxx index 29ff925011..fa01a03856 100644 --- a/scintilla/src/EditView.cxx +++ b/scintilla/src/EditView.cxx @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -31,6 +30,7 @@ #include "StringCopy.h" #include "CharacterSet.h" +#include "CharacterCategory.h" #include "Position.h" #include "IntegerRectangle.h" #include "UniqueString.h" @@ -64,7 +64,7 @@ static inline bool IsControlCharacter(int ch) { return ch >= 0 && ch < ' '; } -PrintParameters::PrintParameters() { +PrintParameters::PrintParameters() noexcept { magnification = 0; colourMode = SC_PRINT_NORMAL; wrapState = eWrapWord; @@ -194,25 +194,25 @@ EditView::EditView() { EditView::~EditView() { } -bool EditView::SetTwoPhaseDraw(bool twoPhaseDraw) { +bool EditView::SetTwoPhaseDraw(bool twoPhaseDraw) noexcept { const PhasesDraw phasesDrawNew = twoPhaseDraw ? phasesTwo : phasesOne; const bool redraw = phasesDraw != phasesDrawNew; phasesDraw = phasesDrawNew; return redraw; } -bool EditView::SetPhasesDraw(int phases) { +bool EditView::SetPhasesDraw(int phases) noexcept { const PhasesDraw phasesDrawNew = static_cast(phases); const bool redraw = phasesDraw != phasesDrawNew; phasesDraw = phasesDrawNew; return redraw; } -bool EditView::LinesOverlap() const { +bool EditView::LinesOverlap() const noexcept { return phasesDraw == phasesMultiple; } -void EditView::ClearAllTabstops() { +void EditView::ClearAllTabstops() noexcept { ldTabstops.reset(); } @@ -280,7 +280,7 @@ void EditView::AllocateGraphics(const ViewStyle &vsDraw) { pixmapIndentGuideHighlight.reset(Surface::Allocate(vsDraw.technology)); } -static const char *ControlCharacterString(unsigned char ch) { +static const char *ControlCharacterString(unsigned char ch) noexcept { const char * const reps[] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", @@ -649,7 +649,7 @@ Range EditView::RangeDisplayLine(Surface *surface, const EditModel &model, Sci:: SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditModel &model, PointDocument pt, bool canReturnInvalid, bool charPosition, bool virtualSpace, const ViewStyle &vs) { pt.x = pt.x - vs.textStart; - Sci::Line visibleLine = static_cast(floor(pt.y / vs.lineHeight)); + 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); @@ -763,7 +763,7 @@ Sci::Position EditView::StartEndDisplayLine(Surface *surface, const EditModel &m return posRet; } -static ColourDesired SelectionBackground(const ViewStyle &vsDraw, bool main, bool primarySelection) { +static ColourDesired SelectionBackground(const ViewStyle &vsDraw, bool main, bool primarySelection) noexcept { return main ? (primarySelection ? vsDraw.selColours.back : vsDraw.selBackground2) : vsDraw.selAdditionalBackground; @@ -816,7 +816,7 @@ static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle r surface->FillRectangle(rcSegment, textBack); } FontAlias ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font; - const int normalCharHeight = static_cast(ceil(vsDraw.styles[STYLE_CONTROLCHAR].capitalHeight)); + const int normalCharHeight = static_cast(std::ceil(vsDraw.styles[STYLE_CONTROLCHAR].capitalHeight)); PRectangle rcCChar = rcSegment; rcCChar.left = rcCChar.left + 1; rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight; @@ -985,7 +985,7 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle rcSegment.left = rcLine.left; rcSegment.right = rcLine.right; - const bool fillRemainder = !lastSubLine || model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_HIDDEN || !model.pcs->GetFoldDisplayTextShown(line); + const bool fillRemainder = !lastSubLine || !model.GetFoldDisplayText(line); if (fillRemainder) { // Fill the remainder of the line FillLineRemainder(surface, model, vsDraw, ll, line, rcSegment, subLine); @@ -1105,11 +1105,12 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con if (!lastSubLine) return; - if ((model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_HIDDEN) || !model.pcs->GetFoldDisplayTextShown(line)) + const char *text = model.GetFoldDisplayText(line); + if (!text) return; PRectangle rcSegment = rcLine; - const char *foldDisplayText = model.pcs->GetFoldDisplayText(line); + 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)); @@ -1129,7 +1130,6 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con rcSegment.right = rcSegment.left + static_cast(widthFoldDisplayText); const ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); - FontAlias textFont = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].font; ColourDesired textFore = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].fore; if (eolInSelection && (vsDraw.selColours.fore.isSet)) { textFore = (eolInSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground; @@ -1158,11 +1158,11 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con if (phase & drawText) { if (phasesDraw != phasesOne) { - surface->DrawTextTransparent(rcSegment, textFont, + surface->DrawTextTransparent(rcSegment, fontText, rcSegment.top + vsDraw.maxAscent, foldDisplayText, lengthFoldDisplayText, textFore); } else { - surface->DrawTextNoClip(rcSegment, textFont, + surface->DrawTextNoClip(rcSegment, fontText, rcSegment.top + vsDraw.maxAscent, foldDisplayText, lengthFoldDisplayText, textFore, textBack); } @@ -1332,7 +1332,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt for (size_t r = 0; (r model.sel.Range(r).anchor) { + if ((vsDraw.IsBlockCaretStyle() || imeCaretBlockOverride) && !drawDrag && posCaret > model.sel.Range(r).anchor) { if (posCaret.VirtualSpace() > 0) posCaret.SetVirtualSpace(posCaret.VirtualSpace() - 1); else @@ -1351,7 +1351,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt const bool caretBlinkState = (model.caret.active && model.caret.on) || (!additionalCaretsBlink && !mainCaret); const bool caretVisibleState = additionalCaretsVisible || mainCaret; if ((xposCaret >= 0) && (vsDraw.caretWidth > 0) && (vsDraw.caretStyle != CARETSTYLE_INVISIBLE) && - ((model.posDrag.IsValid()) || (caretBlinkState && caretVisibleState))) { + (drawDrag || (caretBlinkState && caretVisibleState))) { bool caretAtEOF = false; bool caretAtEOL = false; bool drawBlockCaret = false; @@ -1375,16 +1375,17 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt if (xposCaret > 0) caretWidthOffset = 0.51f; // Move back so overlaps both character cells. xposCaret += xStart; - if (model.posDrag.IsValid()) { + const ViewStyle::CaretShape caretShape = drawDrag ? ViewStyle::CaretShape::line : vsDraw.CaretShapeForMode(model.inOverstrike); + if (drawDrag) { /* Dragging text, use a line caret */ rcCaret.left = round(xposCaret - caretWidthOffset); rcCaret.right = rcCaret.left + vsDraw.caretWidth; - } else if (model.inOverstrike && drawOverstrikeCaret) { + } else if ((caretShape == ViewStyle::CaretShape::bar) && drawOverstrikeCaret) { /* Overstrike (insert mode), use a modified bar caret */ rcCaret.top = rcCaret.bottom - 2; rcCaret.left = xposCaret + 1; rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1; - } else if ((vsDraw.caretStyle == CARETSTYLE_BLOCK) || imeCaretBlockOverride) { + } else if ((caretShape == ViewStyle::CaretShape::block) || imeCaretBlockOverride) { /* Block caret */ rcCaret.left = xposCaret; if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) { @@ -1711,7 +1712,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi indentCount <= (ll->positions[i + 1] - epsilon) / indentWidth; indentCount++) { if (indentCount > 0) { - const XYPOSITION xIndent = floor(indentCount * indentWidth); + const XYPOSITION xIndent = std::floor(indentCount * indentWidth); DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment, (ll->xHighlightGuide == xIndent)); } @@ -1791,7 +1792,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi indentCount <= (ll->positions[cpos + ts.start + 1] - epsilon) / indentWidth; indentCount++) { if (indentCount > 0) { - const XYPOSITION xIndent = floor(indentCount * indentWidth); + const XYPOSITION xIndent = std::floor(indentCount * indentWidth); DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment, (ll->xHighlightGuide == xIndent)); } @@ -1868,7 +1869,7 @@ void EditView::DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &mode } for (int indentPos = model.pdoc->IndentSize(); indentPos < indentSpace; indentPos += model.pdoc->IndentSize()) { - const XYPOSITION xIndent = floor(indentPos * vsDraw.spaceWidth); + const XYPOSITION xIndent = std::floor(indentPos * vsDraw.spaceWidth); if (xIndent < xStartText) { DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcLine, (ll->xHighlightGuide == xIndent)); @@ -2198,7 +2199,7 @@ void EditView::FillLineRemainder(Surface *surface, const EditModel &model, const // Space (3 space characters) between line numbers and text when printing. #define lineNumberPrintSpace " " -static ColourDesired InvertedLight(ColourDesired orig) { +static ColourDesired InvertedLight(ColourDesired orig) noexcept { unsigned int r = orig.GetRed(); unsigned int g = orig.GetGreen(); unsigned int b = orig.GetBlue(); diff --git a/scintilla/src/EditView.h b/scintilla/src/EditView.h index f649f7c872..3addfbab8e 100644 --- a/scintilla/src/EditView.h +++ b/scintilla/src/EditView.h @@ -14,7 +14,7 @@ struct PrintParameters { int magnification; int colourMode; WrapMode wrapState; - PrintParameters(); + PrintParameters() noexcept; }; /** @@ -54,7 +54,7 @@ class EditView { int tabWidthMinimumPixels; bool hideSelection; - bool drawOverstrikeCaret; + bool drawOverstrikeCaret; // used by the curses platform /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to * the screen. This avoids flashing but is about 30% slower. */ @@ -97,11 +97,11 @@ class EditView { void operator=(EditView &&) = delete; virtual ~EditView(); - bool SetTwoPhaseDraw(bool twoPhaseDraw); - bool SetPhasesDraw(int phases); - bool LinesOverlap() const; + bool SetTwoPhaseDraw(bool twoPhaseDraw) noexcept; + bool SetPhasesDraw(int phases) noexcept; + bool LinesOverlap() const noexcept; - void ClearAllTabstops(); + void ClearAllTabstops() noexcept; XYPOSITION NextTabstopPos(Sci::Line line, XYPOSITION x, XYPOSITION tabWidth) const; bool ClearTabstops(Sci::Line line); bool AddTabstop(Sci::Line line, int x); @@ -165,7 +165,7 @@ class AutoLineLayout { AutoLineLayout(AutoLineLayout &&) = delete; AutoLineLayout &operator=(const AutoLineLayout &) = delete; AutoLineLayout &operator=(AutoLineLayout &&) = delete; - ~AutoLineLayout() { + ~AutoLineLayout() noexcept { llc.Dispose(ll); ll = nullptr; } @@ -175,7 +175,7 @@ class AutoLineLayout { operator LineLayout *() const noexcept { return ll; } - void Set(LineLayout *ll_) { + void Set(LineLayout *ll_) noexcept { llc.Dispose(ll); ll = ll_; } diff --git a/scintilla/src/Editor.cxx b/scintilla/src/Editor.cxx index 7e5be38dff..8f583636d6 100644 --- a/scintilla/src/Editor.cxx +++ b/scintilla/src/Editor.cxx @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -31,6 +30,7 @@ #include "StringCopy.h" #include "CharacterSet.h" +#include "CharacterCategory.h" #include "Position.h" #include "UniqueString.h" #include "SplitVector.h" @@ -59,11 +59,13 @@ using namespace Scintilla; +namespace { + /* return whether this modification represents an operation that may reasonably be deferred (not done now OR [possibly] at all) */ -static bool CanDeferToLastStep(const DocModification &mh) { +bool CanDeferToLastStep(const DocModification &mh) noexcept { if (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) return true; // CAN skip if (!(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO))) @@ -73,7 +75,7 @@ static bool CanDeferToLastStep(const DocModification &mh) { return false; // PRESUMABLY must do } -static bool CanEliminate(const DocModification &mh) { +constexpr bool CanEliminate(const DocModification &mh) noexcept { return (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) != 0; } @@ -82,7 +84,7 @@ static bool CanEliminate(const DocModification &mh) { return whether this modification represents the FINAL step in a [possibly lengthy] multi-step Undo/Redo sequence */ -static bool IsLastStep(const DocModification &mh) { +constexpr bool IsLastStep(const DocModification &mh) noexcept { return (mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)) != 0 && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0 @@ -90,13 +92,15 @@ static bool IsLastStep(const DocModification &mh) { && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0; } -Timer::Timer() : +} + +Timer::Timer() noexcept : ticking(false), ticksToWait(0), tickerID{} {} -Idler::Idler() : +Idler::Idler() noexcept : state(false), idlerID(0) {} -static inline bool IsAllSpacesOrTabs(const char *s, unsigned int len) { +static bool IsAllSpacesOrTabs(const char *s, unsigned int len) noexcept { for (unsigned int i = 0; i < len; i++) { // This is safe because IsSpaceOrTab() will return false for null terminators if (!IsSpaceOrTab(s[i])) @@ -1144,13 +1148,9 @@ slop | strict | jumps | even | Caret can go to the margin | When Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options) { const PRectangle rcClient = GetTextRectangle(); - Point pt = LocationFromPosition(range.caret); - Point ptAnchor = LocationFromPosition(range.anchor); const Point ptOrigin = GetVisibleOriginInMain(); - pt.x += ptOrigin.x; - pt.y += ptOrigin.y; - ptAnchor.x += ptOrigin.x; - ptAnchor.y += ptOrigin.y; + const Point pt = LocationFromPosition(range.caret) + ptOrigin; + const Point ptAnchor = LocationFromPosition(range.anchor) + ptOrigin; const Point ptBottomCaret(pt.x, pt.y + vs.lineHeight - 1); XYScrollPosition newXY(xOffset, topLine); @@ -1355,7 +1355,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran newXY.xOffset = static_cast(pt.x + xOffset - rcClient.left) - 2; } else if (pt.x + xOffset >= rcClient.right + newXY.xOffset) { newXY.xOffset = static_cast(pt.x + xOffset - rcClient.right) + 2; - if ((vs.caretStyle == CARETSTYLE_BLOCK) || view.imeCaretBlockOverride) { + if (vs.IsBlockCaretStyle() || view.imeCaretBlockOverride) { // Ensure we can see a good portion of the block caret newXY.xOffset += static_cast(vs.aveCharWidth); } @@ -1465,7 +1465,7 @@ void Editor::NotifyCaretMove() { void Editor::UpdateSystemCaret() { } -bool Editor::Wrapping() const { +bool Editor::Wrapping() const noexcept { return vs.wrapState != eWrapNone; } @@ -1614,7 +1614,7 @@ void Editor::LinesJoin() { } } -const char *Editor::StringFromEOLMode(int eolMode) { +const char *Editor::StringFromEOLMode(int eolMode) noexcept { if (eolMode == SC_EOL_CRLF) { return "\r\n"; } else if (eolMode == SC_EOL_CR) { @@ -1900,6 +1900,9 @@ void Editor::FilterSelections() { // AddCharUTF inserts an array of bytes which may or may not be in UTF-8. void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { + if (len == 0) { + return; + } FilterSelections(); { UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike); @@ -1970,12 +1973,14 @@ void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { SetLastXChosen(); } - if (treatAsDBCS) { - NotifyChar((static_cast(s[0]) << 8) | - static_cast(s[1])); - } else if (len > 0) { - int byte = static_cast(s[0]); - if ((byte < 0xC0) || (1 == len)) { + int ch = static_cast(s[0]); + if (treatAsDBCS || pdoc->dbcsCodePage != SC_CP_UTF8) { + if (len > 1) { + // DBCS code page or DBCS font character set. + ch = (ch << 8) | static_cast(s[1]); + } + } else { + if ((ch < 0xC0) || (1 == len)) { // 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 @@ -1983,10 +1988,10 @@ void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { } else { unsigned int utf32[1] = { 0 }; UTF32FromUTF8(s, len, utf32, ELEMENTS(utf32)); - byte = utf32[0]; + ch = utf32[0]; } - NotifyChar(byte); } + NotifyChar(ch); if (recordingMacro) { NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast(s)); @@ -2521,8 +2526,10 @@ void Editor::CheckModificationForWrap(DocModification mh) { } } +namespace { + // Move a position so it is still after the same character as before the insertion. -static inline Sci::Position MovePositionForInsertion(Sci::Position position, Sci::Position startInsertion, Sci::Position length) { +Sci::Position MovePositionForInsertion(Sci::Position position, Sci::Position startInsertion, Sci::Position length) noexcept { if (position > startInsertion) { return position + length; } @@ -2531,7 +2538,7 @@ static inline Sci::Position MovePositionForInsertion(Sci::Position position, Sci // 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. -static inline Sci::Position MovePositionForDeletion(Sci::Position position, Sci::Position startDeletion, Sci::Position length) { +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) { @@ -2544,6 +2551,8 @@ static inline Sci::Position MovePositionForDeletion(Sci::Position position, Sci: } } +} + void Editor::NotifyModified(Document *, DocModification mh, void *) { ContainerNeedsUpdate(SC_UPDATE_CONTENT); if (paintState == painting) { @@ -2652,12 +2661,16 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { } if (paintState == notPainting && !CanDeferToLastStep(mh)) { - QueueIdleWork(WorkNeeded::workStyle, pdoc->Length()); + if (SynchronousStylingToVisible()) { + QueueIdleWork(WorkNeeded::workStyle, pdoc->Length()); + } Redraw(); } } else { if (paintState == notPainting && mh.length && !CanEliminate(mh)) { - QueueIdleWork(WorkNeeded::workStyle, mh.position + mh.length); + if (SynchronousStylingToVisible()) { + QueueIdleWork(WorkNeeded::workStyle, mh.position + mh.length); + } InvalidateRange(mh.position, mh.position + mh.length); } } @@ -2712,7 +2725,7 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { } } -void Editor::NotifyDeleted(Document *, void *) { +void Editor::NotifyDeleted(Document *, void *) noexcept { /* Do nothing */ } @@ -2848,7 +2861,7 @@ 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) { +void Editor::ContainerNeedsUpdate(int flags) noexcept { needUpdateUI |= flags; } @@ -3232,7 +3245,7 @@ constexpr short LowShortFromWParam(uptr_t x) { return static_cast(x & 0xffff); } -unsigned int WithExtends(unsigned int iMessage) { +unsigned int WithExtends(unsigned int iMessage) noexcept { switch (iMessage) { case SCI_CHARLEFT: return SCI_CHARLEFTEXTEND; case SCI_CHARRIGHT: return SCI_CHARRIGHTEXTEND; @@ -3259,7 +3272,7 @@ unsigned int WithExtends(unsigned int iMessage) { } } -int NaturalDirection(unsigned int iMessage) { +int NaturalDirection(unsigned int iMessage) noexcept { switch (iMessage) { case SCI_CHARLEFT: case SCI_CHARLEFTEXTEND: @@ -3290,7 +3303,7 @@ int NaturalDirection(unsigned int iMessage) { } } -bool IsRectExtend(unsigned int iMessage, bool isRectMoveExtends) { +bool IsRectExtend(unsigned int iMessage, bool isRectMoveExtends) noexcept { switch (iMessage) { case SCI_CHARLEFTRECTEXTEND: case SCI_CHARRIGHTRECTEXTEND: @@ -3793,6 +3806,7 @@ int Editor::KeyCommand(unsigned int iMessage) { inOverstrike = !inOverstrike; ContainerNeedsUpdate(SC_UPDATE_SELECTION); ShowCaretAtCurrentPosition(); + SetIdle(true); break; case SCI_CANCEL: // Cancel any modes - handled in subclass // Also unselect text @@ -4015,11 +4029,9 @@ void Editor::Indent(bool forwards) { class CaseFolderASCII : public CaseFolderTable { public: - CaseFolderASCII() { + CaseFolderASCII() noexcept { StandardASCII(); } - ~CaseFolderASCII() override { - } }; @@ -4160,10 +4172,11 @@ void Editor::GoToLine(Sci::Line lineNo) { EnsureCaretVisible(); } -static bool Close(Point pt1, Point pt2, Point threshold) { - if (std::abs(pt1.x - pt2.x) > threshold.x) +static bool Close(Point pt1, Point pt2, Point threshold) noexcept { + const Point ptDifference = pt2 - pt1; + if (std::abs(ptDifference.x) > threshold.x) return false; - if (std::abs(pt1.y - pt2.y) > threshold.y) + if (std::abs(ptDifference.y) > threshold.y) return false; return true; } @@ -4253,9 +4266,8 @@ void Editor::DisplayCursor(Window::Cursor c) { } bool Editor::DragThreshold(Point ptStart, Point ptNow) { - const XYPOSITION xMove = ptStart.x - ptNow.x; - const XYPOSITION yMove = ptStart.y - ptNow.y; - const XYPOSITION distanceSquared = xMove * xMove + yMove * yMove; + const Point ptDiff = ptStart - ptNow; + const XYPOSITION distanceSquared = ptDiff.x * ptDiff.x + ptDiff.y * ptDiff.y; return distanceSquared > 16.0f; } @@ -4383,7 +4395,7 @@ bool Editor::PointInSelMargin(Point pt) const { } } -Window::Cursor Editor::GetMarginCursor(Point pt) const { +Window::Cursor Editor::GetMarginCursor(Point pt) const noexcept { int x = 0; for (const MarginStyle &m : vs.ms) { if ((pt.x >= x) && (pt.x < x + m.width)) @@ -4730,12 +4742,12 @@ void Editor::SetHotSpotRange(const Point *pt) { } } -Range Editor::GetHotSpotRange() const { +Range Editor::GetHotSpotRange() const noexcept { return hotspot; } void Editor::ButtonMoveWithModifiers(Point pt, unsigned int, int modifiers) { - if ((ptMouseLast.x != pt.x) || (ptMouseLast.y != pt.y)) { + if (ptMouseLast != pt) { DwellEnd(true); } @@ -4948,6 +4960,8 @@ void Editor::ButtonUpWithModifiers(Point pt, unsigned int curTime, int modifiers } bool Editor::Idle() { + NotifyUpdateUI(); + bool needWrap = Wrapping() && wrapPending.NeedsWrap(); if (needWrap) { @@ -5057,7 +5071,7 @@ void Editor::StyleToPositionInView(Sci::Position pos) { } Sci::Position Editor::PositionAfterMaxStyling(Sci::Position posMax, bool scrolling) const { - if ((idleStyling == SC_IDLESTYLING_NONE) || (idleStyling == SC_IDLESTYLING_AFTERVISIBLE)) { + if (SynchronousStylingToVisible()) { // Both states do not limit styling return posMax; } @@ -5570,11 +5584,11 @@ Sci::Position Editor::ReplaceTarget(bool replacePatterns, const char *text, Sci: return length; } -bool Editor::IsUnicodeMode() const { +bool Editor::IsUnicodeMode() const noexcept { return pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage); } -int Editor::CodePage() const { +int Editor::CodePage() const noexcept { if (pdoc) return pdoc->dbcsCodePage; else @@ -5610,7 +5624,7 @@ void Editor::AddStyledText(const char *buffer, Sci::Position appendLength) { SetEmptySelection(sel.MainCaret() + lengthInserted); } -bool Editor::ValidMargin(uptr_t wParam) const { +bool Editor::ValidMargin(uptr_t wParam) const noexcept { return wParam < vs.ms.size(); } @@ -5739,7 +5753,7 @@ void Editor::SetSelectionNMessage(unsigned int iMessage, uptr_t wParam, sptr_t l ContainerNeedsUpdate(SC_UPDATE_SELECTION); } -sptr_t Editor::StringResult(sptr_t lParam, const char *val) { +sptr_t Editor::StringResult(sptr_t lParam, const char *val) noexcept { const size_t len = val ? strlen(val) : 0; if (lParam) { char *ptr = CharPtrFromSPtr(lParam); @@ -5751,7 +5765,7 @@ sptr_t Editor::StringResult(sptr_t lParam, const char *val) { return len; // Not including NUL } -sptr_t Editor::BytesResult(sptr_t lParam, const unsigned char *val, size_t len) { +sptr_t Editor::BytesResult(sptr_t lParam, const unsigned char *val, size_t len) noexcept { // No NUL termination: len is number of valid/displayed bytes if ((lParam) && (len > 0)) { char *ptr = CharPtrFromSPtr(lParam); @@ -6240,6 +6254,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { pdoc->SetDefaultCharClasses(true); break; + case SCI_SETCHARACTERCATEGORYOPTIMIZATION: + pdoc->SetCharacterCategoryOptimization(static_cast(wParam)); + break; + + case SCI_GETCHARACTERCATEGORYOPTIMIZATION: + return pdoc->CharacterCategoryOptimization(); + case SCI_GETLENGTH: return pdoc->Length(); @@ -7172,6 +7193,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { Redraw(); break; + case SCI_FOLDDISPLAYTEXTGETSTYLE: + return foldDisplayTextStyle; + + case SCI_SETDEFAULTFOLDDISPLAYTEXT: + SetDefaultFoldDisplayText(CharPtrFromSPtr(lParam)); + Redraw(); + break; + + case SCI_GETDEFAULTFOLDDISPLAYTEXT: + return StringResult(lParam, GetDefaultFoldDisplayText()); + case SCI_TOGGLEFOLD: FoldLine(static_cast(wParam), SC_FOLDACTION_TOGGLE); break; @@ -7281,7 +7313,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return vs.caretcolour.AsInteger(); case SCI_SETCARETSTYLE: - if (wParam <= CARETSTYLE_BLOCK) + if (wParam <= (CARETSTYLE_BLOCK | CARETSTYLE_OVERSTRIKE_BLOCK)) vs.caretStyle = static_cast(wParam); else /* Default to the line caret */ @@ -7736,6 +7768,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { inOverstrike = wParam != 0; ContainerNeedsUpdate(SC_UPDATE_SELECTION); ShowCaretAtCurrentPosition(); + SetIdle(true); } break; diff --git a/scintilla/src/Editor.h b/scintilla/src/Editor.h index 55b6f56aa2..e8d1ed48e4 100644 --- a/scintilla/src/Editor.h +++ b/scintilla/src/Editor.h @@ -19,7 +19,7 @@ class Timer { enum {tickSize = 100}; TickerID tickerID; - Timer(); + Timer() noexcept; }; /** @@ -29,7 +29,7 @@ class Idler { bool state; IdlerID idlerID; - Idler(); + Idler() noexcept; }; /** @@ -47,12 +47,12 @@ class WorkNeeded { enum workItems items; Sci::Position upTo; - WorkNeeded() : items(workNone), upTo(0) {} - void Reset() { + WorkNeeded() noexcept : items(workNone), upTo(0) {} + void Reset() noexcept { items = workNone; upTo = 0; } - void Need(workItems items_, Sci::Position pos) { + void Need(workItems items_, Sci::Position pos) noexcept { if ((items_ & workStyle) && (upTo < pos)) upTo = pos; items = static_cast(items | items_); @@ -69,8 +69,8 @@ class SelectionText { bool lineCopy; int codePage; int characterSet; - SelectionText() : rectangular(false), lineCopy(false), codePage(0), characterSet(0) {} - void Clear() { + SelectionText() noexcept : rectangular(false), lineCopy(false), codePage(0), characterSet(0) {} + void Clear() noexcept { s.clear(); rectangular = false; lineCopy = false; @@ -88,16 +88,16 @@ class SelectionText { void Copy(const SelectionText &other) { Copy(other.s, other.codePage, other.characterSet, other.rectangular, other.lineCopy); } - const char *Data() const { + const char *Data() const noexcept { return s.c_str(); } - size_t Length() const { + size_t Length() const noexcept { return s.length(); } - size_t LengthWithTerminator() const { + size_t LengthWithTerminator() const noexcept { return s.length() + 1; } - bool Empty() const { + bool Empty() const noexcept { return s.empty(); } private: @@ -113,22 +113,22 @@ struct WrapPending { enum { lineLarge = 0x7ffffff }; Sci::Line start; // When there are wraps pending, will be in document range Sci::Line end; // May be lineLarge to indicate all of document after start - WrapPending() { + WrapPending() noexcept { start = lineLarge; end = lineLarge; } - void Reset() { + void Reset() noexcept { start = lineLarge; end = lineLarge; } - void Wrapped(Sci::Line line) { + void Wrapped(Sci::Line line) noexcept { if (start == line) start++; } - bool NeedsWrap() const { + bool NeedsWrap() const noexcept { return start < end; } - bool AddRange(Sci::Line lineStart, Sci::Line lineEnd) { + bool AddRange(Sci::Line lineStart, Sci::Line lineEnd) noexcept { const bool neededWrap = NeedsWrap(); bool changed = false; if (start > lineStart) { @@ -260,7 +260,7 @@ class Editor : public EditModel, public DocWatcher { Editor(Editor &&) = delete; Editor &operator=(const Editor &) = delete; Editor &operator=(Editor &&) = delete; - ~Editor() override; + // ~Editor() in public section virtual void Initialise() = 0; virtual void Finalise(); @@ -302,7 +302,7 @@ class Editor : public EditModel, public DocWatcher { PRectangle RectangleFromRange(Range r, int overlap); void InvalidateRange(Sci::Position start, Sci::Position end); - bool UserVirtualSpace() const { + bool UserVirtualSpace() const noexcept { return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0); } Sci::Position CurrentPosition() const; @@ -347,8 +347,8 @@ class Editor : public EditModel, public DocWatcher { struct XYScrollPosition { int xOffset; Sci::Line topLine; - XYScrollPosition(int xOffset_, Sci::Line topLine_) : xOffset(xOffset_), topLine(topLine_) {} - bool operator==(const XYScrollPosition &other) const { + XYScrollPosition(int xOffset_, Sci::Line topLine_) noexcept : xOffset(xOffset_), topLine(topLine_) {} + bool operator==(const XYScrollPosition &other) const noexcept { return (xOffset == other.xOffset) && (topLine == other.topLine); } }; @@ -368,7 +368,7 @@ class Editor : public EditModel, public DocWatcher { virtual void NotifyCaretMove(); virtual void UpdateSystemCaret(); - bool Wrapping() const; + bool Wrapping() const noexcept; void NeedWrapping(Sci::Line docLineStart=0, Sci::Line docLineEnd=WrapPending::lineLarge); bool WrapOneLine(Surface *surface, Sci::Line lineToWrap); enum class WrapScope {wsAll, wsVisible, wsIdle}; @@ -441,13 +441,13 @@ class Editor : public EditModel, public DocWatcher { void NotifySavePoint(Document *document, void *userData, bool atSavePoint) override; void CheckModificationForWrap(DocModification mh); void NotifyModified(Document *document, DocModification mh, void *userData) override; - void NotifyDeleted(Document *document, void *userData) override; + 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); + 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); @@ -495,7 +495,7 @@ class Editor : public EditModel, public DocWatcher { bool PositionInSelection(Sci::Position pos); bool PointInSelection(Point pt); bool PointInSelMargin(Point pt) const; - Window::Cursor GetMarginCursor(Point pt) const; + Window::Cursor GetMarginCursor(Point pt) const noexcept; void TrimAndSetSelection(Sci::Position currentPos_, Sci::Position anchor_); void LineSelection(Sci::Position lineCurrentPos_, Sci::Position lineAnchorPos_, bool wholeLine); void WordSelection(Sci::Position pos); @@ -522,6 +522,9 @@ class Editor : public EditModel, public DocWatcher { 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); + } void IdleStyling(); virtual void IdleWork(); virtual void QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo=0); @@ -552,52 +555,54 @@ class Editor : public EditModel, public DocWatcher { bool PositionIsHotspot(Sci::Position position) const; bool PointIsHotspot(Point pt); void SetHotSpotRange(const Point *pt); - Range GetHotSpotRange() const override; + Range GetHotSpotRange() const noexcept override; void SetHoverIndicatorPosition(Sci::Position position); void SetHoverIndicatorPoint(Point pt); - int CodePage() const; + int CodePage() const noexcept; virtual bool ValidCodePage(int /* codePage */) const { return true; } 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; + 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); - static const char *StringFromEOLMode(int eolMode); + static const char *StringFromEOLMode(int eolMode) noexcept; // Coercion functions for transforming WndProc parameters into pointers - static void *PtrFromSPtr(sptr_t lParam) { + static void *PtrFromSPtr(sptr_t lParam) noexcept { return reinterpret_cast(lParam); } - static const char *ConstCharPtrFromSPtr(sptr_t lParam) { + static const char *ConstCharPtrFromSPtr(sptr_t lParam) noexcept { return static_cast(PtrFromSPtr(lParam)); } - static const unsigned char *ConstUCharPtrFromSPtr(sptr_t lParam) { + static const unsigned char *ConstUCharPtrFromSPtr(sptr_t lParam) noexcept { return static_cast(PtrFromSPtr(lParam)); } - static char *CharPtrFromSPtr(sptr_t lParam) { + static char *CharPtrFromSPtr(sptr_t lParam) noexcept { return static_cast(PtrFromSPtr(lParam)); } - static unsigned char *UCharPtrFromSPtr(sptr_t lParam) { + static unsigned char *UCharPtrFromSPtr(sptr_t lParam) noexcept { return static_cast(PtrFromSPtr(lParam)); } - static void *PtrFromUPtr(uptr_t wParam) { + static void *PtrFromUPtr(uptr_t wParam) noexcept { return reinterpret_cast(wParam); } - static const char *ConstCharPtrFromUPtr(uptr_t wParam) { + static const char *ConstCharPtrFromUPtr(uptr_t wParam) noexcept { return static_cast(PtrFromUPtr(wParam)); } - static sptr_t StringResult(sptr_t lParam, const char *val); - static sptr_t BytesResult(sptr_t lParam, const unsigned char *val, size_t len); + 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; public: + ~Editor() override; + // Public so the COM thunks can access it. - bool IsUnicodeMode() const; + 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); // Public so scintilla_set_id can use it. diff --git a/scintilla/src/ElapsedPeriod.h b/scintilla/src/ElapsedPeriod.h index 1e2c96eb4f..6f8cdabdfa 100644 --- a/scintilla/src/ElapsedPeriod.h +++ b/scintilla/src/ElapsedPeriod.h @@ -15,7 +15,7 @@ class ElapsedPeriod { std::chrono::high_resolution_clock::time_point tp; public: /// Capture the moment - ElapsedPeriod() : tp(std::chrono::high_resolution_clock::now()) { + ElapsedPeriod() noexcept : tp(std::chrono::high_resolution_clock::now()) { } /// Return duration as floating point seconds double Duration(bool reset=false) { diff --git a/scintilla/src/Indicator.cxx b/scintilla/src/Indicator.cxx index 544bd571d1..24cd408205 100644 --- a/scintilla/src/Indicator.cxx +++ b/scintilla/src/Indicator.cxx @@ -25,8 +25,8 @@ using namespace Scintilla; static PRectangle PixelGridAlign(const PRectangle &rc) { // Move left and right side to nearest pixel to avoid blurry visuals - return PRectangle(round(rc.left), floor(rc.top), - round(rc.right), floor(rc.bottom)); + return PRectangle(round(rc.left), std::floor(rc.top), + round(rc.right), std::floor(rc.bottom)); } void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, DrawState drawState, int value) const { @@ -201,10 +201,10 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r surface->FillRectangle(rcComposition, sacDraw.fore); } else if (sacDraw.style == INDIC_POINT || sacDraw.style == INDIC_POINTCHARACTER) { if (rcCharacter.Width() >= 0.1) { - const XYPOSITION pixelHeight = floor(rc.Height() - 1.0f); // 1 pixel onto next line if multiphase + 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 = round(x); - const XYPOSITION iy = floor(rc.top + 1.0f); + const XYPOSITION iy = std::floor(rc.top + 1.0f); Point pts[] = { Point(ix - pixelHeight, iy + pixelHeight), // Left Point(ix + pixelHeight, iy + pixelHeight), // Right diff --git a/scintilla/src/Indicator.h b/scintilla/src/Indicator.h index 7e9a00ce3a..9e5fda2213 100644 --- a/scintilla/src/Indicator.h +++ b/scintilla/src/Indicator.h @@ -13,9 +13,9 @@ namespace Scintilla { struct StyleAndColour { int style; ColourDesired fore; - StyleAndColour() : style(INDIC_PLAIN), fore(0, 0, 0) { + StyleAndColour() noexcept : style(INDIC_PLAIN), fore(0, 0, 0) { } - StyleAndColour(int style_, ColourDesired fore_ = ColourDesired(0, 0, 0)) : style(style_), fore(fore_) { + StyleAndColour(int style_, ColourDesired fore_ = ColourDesired(0, 0, 0)) noexcept : style(style_), fore(fore_) { } bool operator==(const StyleAndColour &other) const { return (style == other.style) && (fore == other.fore); @@ -33,9 +33,9 @@ class Indicator { int fillAlpha; int outlineAlpha; int attributes; - Indicator() : under(false), fillAlpha(30), outlineAlpha(50), attributes(0) { + Indicator() noexcept : under(false), fillAlpha(30), outlineAlpha(50), attributes(0) { } - Indicator(int style_, ColourDesired fore_=ColourDesired(0,0,0), bool under_=false, int fillAlpha_=30, int outlineAlpha_=50) : + 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) { } void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, DrawState drawState, int value) const; diff --git a/scintilla/src/KeyMap.h b/scintilla/src/KeyMap.h index b4299feecb..6f30abf003 100644 --- a/scintilla/src/KeyMap.h +++ b/scintilla/src/KeyMap.h @@ -25,7 +25,7 @@ class KeyModifiers { public: int key; int modifiers; - KeyModifiers(int key_, int modifiers_) : key(key_), modifiers(modifiers_) { + KeyModifiers(int key_, int modifiers_) noexcept : key(key_), modifiers(modifiers_) { } bool operator<(const KeyModifiers &other) const { if (key == other.key) diff --git a/scintilla/src/LineMarker.cxx b/scintilla/src/LineMarker.cxx index ca542be166..d2c906d083 100644 --- a/scintilla/src/LineMarker.cxx +++ b/scintilla/src/LineMarker.cxx @@ -25,41 +25,41 @@ using namespace Scintilla; -LineMarker::~LineMarker() { -} - -LineMarker::LineMarker() { - markType = SC_MARK_CIRCLE; - fore = ColourDesired(0, 0, 0); - back = ColourDesired(0xff, 0xff, 0xff); - backSelected = ColourDesired(0xff, 0x00, 0x00); - alpha = SC_ALPHA_NOALPHA; - customDraw = nullptr; -} - -LineMarker::LineMarker(const LineMarker &) { +LineMarker::LineMarker(const LineMarker &other) { // Defined to avoid pxpm and image being blindly copied, not as a complete copy constructor. - markType = SC_MARK_CIRCLE; - fore = ColourDesired(0, 0, 0); - back = ColourDesired(0xff, 0xff, 0xff); - backSelected = ColourDesired(0xff, 0x00, 0x00); - alpha = SC_ALPHA_NOALPHA; - pxpm.reset(); - image.reset(); - customDraw = nullptr; + markType = other.markType; + fore = other.fore; + back = other.back; + backSelected = other.backSelected; + alpha = other.alpha; + if (other.pxpm) + pxpm.reset(new XPM(*other.pxpm)); + else + pxpm = nullptr; + if (other.image) + image.reset(new RGBAImage(*other.image)); + else + image = nullptr; + customDraw = other.customDraw; } LineMarker &LineMarker::operator=(const LineMarker &other) { // Defined to avoid pxpm and image being blindly copied, not as a complete assignment operator. if (this != &other) { - markType = SC_MARK_CIRCLE; - fore = ColourDesired(0, 0, 0); - back = ColourDesired(0xff, 0xff, 0xff); - backSelected = ColourDesired(0xff, 0x00, 0x00); - alpha = SC_ALPHA_NOALPHA; - pxpm.reset(); - image.reset(); - customDraw = nullptr; + markType = other.markType; + fore = other.fore; + back = other.back; + backSelected = other.backSelected; + alpha = other.alpha; + if (other.pxpm) + pxpm.reset(new XPM(*other.pxpm)); + else + pxpm = nullptr; + if (other.image) + image.reset(new RGBAImage(*other.image)); + else + image = nullptr; + customDraw = other.customDraw; } return *this; } @@ -430,6 +430,16 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac Point::FromInts(ircWhole.left, centreY + halfHeight), }; surface->Polygon(pts, ELEMENTS(pts), fore, back); + } else if (markType == SC_MARK_VERTICALBOOKMARK) { + const int halfWidth = 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), + }; + surface->Polygon(pts, ELEMENTS(pts), fore, back); } else { // SC_MARK_FULLRECT surface->FillRectangle(rcWhole, back); } diff --git a/scintilla/src/LineMarker.h b/scintilla/src/LineMarker.h index 28a63cd3b4..8a15327d2e 100644 --- a/scintilla/src/LineMarker.h +++ b/scintilla/src/LineMarker.h @@ -21,22 +21,26 @@ class LineMarker { public: enum typeOfFold { undefined, head, body, tail, headWithTail }; - int markType; - ColourDesired fore; - ColourDesired back; - ColourDesired backSelected; - int alpha; + 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; std::unique_ptr pxpm; std::unique_ptr image; /** Some platforms, notably PLAT_CURSES, do not support Scintilla's native * Draw function for drawing line markers. Allow those platforms to override * it instead of creating a new method(s) in the Surface class that existing * platforms must implement as empty. */ - DrawLineMarkerFn customDraw; - LineMarker(); - LineMarker(const LineMarker &); - virtual ~LineMarker(); - LineMarker &operator=(const LineMarker &other); + DrawLineMarkerFn customDraw = nullptr; + + LineMarker() noexcept = default; + LineMarker(const LineMarker &other); + LineMarker(LineMarker &&) noexcept = default; + LineMarker &operator=(const LineMarker& other); + LineMarker &operator=(LineMarker&&) noexcept = default; + virtual ~LineMarker() = default; + void SetXPM(const char *textForm); void SetXPM(const char *const *linesForm); void SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage); diff --git a/scintilla/src/MarginView.cxx b/scintilla/src/MarginView.cxx index 3662c7eef0..a2fea70a7c 100644 --- a/scintilla/src/MarginView.cxx +++ b/scintilla/src/MarginView.cxx @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -26,6 +25,7 @@ #include "ILexer.h" #include "Scintilla.h" +#include "CharacterCategory.h" #include "Position.h" #include "IntegerRectangle.h" #include "UniqueString.h" @@ -100,7 +100,7 @@ void DrawWrapMarker(Surface *surface, PRectangle rcPlace, y - 2 * dy); } -MarginView::MarginView() { +MarginView::MarginView() noexcept { wrapMarkerPaddingRight = 3; customDrawWrapMarker = nullptr; } diff --git a/scintilla/src/MarginView.h b/scintilla/src/MarginView.h index 1d5d46caca..4468afa1be 100644 --- a/scintilla/src/MarginView.h +++ b/scintilla/src/MarginView.h @@ -32,7 +32,7 @@ class MarginView { * existing platforms must implement as empty. */ DrawWrapMarkerFn customDrawWrapMarker; - MarginView(); + MarginView() noexcept; void DropGraphics(bool freeObjects); void AllocateGraphics(const ViewStyle &vsDraw); diff --git a/scintilla/src/PerLine.h b/scintilla/src/PerLine.h index bf0968f28a..94dc17a204 100644 --- a/scintilla/src/PerLine.h +++ b/scintilla/src/PerLine.h @@ -17,7 +17,7 @@ namespace Scintilla { struct MarkerHandleNumber { int handle; int number; - MarkerHandleNumber(int handle_, int number_) : handle(handle_), number(number_) {} + MarkerHandleNumber(int handle_, int number_) noexcept : handle(handle_), number(number_) {} }; /** diff --git a/scintilla/src/PositionCache.cxx b/scintilla/src/PositionCache.cxx index 3b3014ab58..b1b55bd500 100644 --- a/scintilla/src/PositionCache.cxx +++ b/scintilla/src/PositionCache.cxx @@ -24,6 +24,7 @@ #include "ILexer.h" #include "Scintilla.h" +#include "CharacterCategory.h" #include "Position.h" #include "UniqueString.h" #include "SplitVector.h" @@ -82,7 +83,7 @@ void LineLayout::Resize(int maxLineLength_) { } } -void LineLayout::Free() { +void LineLayout::Free() noexcept { chars.reset(); styles.reset(); positions.reset(); @@ -283,7 +284,7 @@ void LineLayoutCache::AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesI PLATFORM_ASSERT(cache.size() == lengthForLevel); } -void LineLayoutCache::Deallocate() { +void LineLayoutCache::Deallocate() noexcept { PLATFORM_ASSERT(useCount == 0); cache.clear(); } @@ -301,7 +302,7 @@ void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) { } } -void LineLayoutCache::SetLevel(int level_) { +void LineLayoutCache::SetLevel(int level_) noexcept { allInvalidated = false; if ((level_ != -1) && (level != level_)) { level = level_; @@ -357,7 +358,7 @@ LineLayout *LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, return ret; } -void LineLayoutCache::Dispose(LineLayout *ll) { +void LineLayoutCache::Dispose(LineLayout *ll) noexcept { allInvalidated = false; if (ll) { if (!ll->inCache) { @@ -380,7 +381,7 @@ static unsigned int KeyFromString(const char *charBytes, size_t len) { return k; } -SpecialRepresentations::SpecialRepresentations() { +SpecialRepresentations::SpecialRepresentations() noexcept { const short none = 0; std::fill(startByteHasReprs, std::end(startByteHasReprs), none); } @@ -556,11 +557,11 @@ TextSegment BreakFinder::Next() { } } -bool BreakFinder::More() const { +bool BreakFinder::More() const noexcept { return (subBreak >= 0) || (nextBreak < lineRange.end); } -PositionCacheEntry::PositionCacheEntry() : +PositionCacheEntry::PositionCacheEntry() noexcept : styleNumber(0), len(0), clock(0), positions(nullptr) { } @@ -593,7 +594,7 @@ PositionCacheEntry::~PositionCacheEntry() { Clear(); } -void PositionCacheEntry::Clear() { +void PositionCacheEntry::Clear() noexcept { positions.reset(); styleNumber = 0; len = 0; @@ -613,7 +614,7 @@ bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_, } } -unsigned int PositionCacheEntry::Hash(unsigned int styleNumber_, const char *s, unsigned int len_) { +unsigned int PositionCacheEntry::Hash(unsigned int styleNumber_, const char *s, unsigned int len_) noexcept { unsigned int ret = s[0] << 7; for (unsigned int i=0; i other.clock; } -void PositionCacheEntry::ResetClock() { +void PositionCacheEntry::ResetClock() noexcept { if (clock > 0) { clock = 1; } @@ -646,7 +647,7 @@ PositionCache::~PositionCache() { Clear(); } -void PositionCache::Clear() { +void PositionCache::Clear() noexcept { if (!allClear) { for (PositionCacheEntry &pce : pces) { pce.Clear(); diff --git a/scintilla/src/PositionCache.h b/scintilla/src/PositionCache.h index c3973eba9f..6899ba99f7 100644 --- a/scintilla/src/PositionCache.h +++ b/scintilla/src/PositionCache.h @@ -86,7 +86,7 @@ class LineLayout { void operator=(LineLayout &&) = delete; virtual ~LineLayout(); void Resize(int maxLineLength_); - void Free(); + void Free() noexcept; void Invalidate(validLevel validity_); int LineStart(int line) const; enum class Scope { visibleOnly, includeEnd }; @@ -121,7 +121,7 @@ class LineLayoutCache { void operator=(const LineLayoutCache &) = delete; void operator=(LineLayoutCache &&) = delete; virtual ~LineLayoutCache(); - void Deallocate(); + void Deallocate() noexcept; enum { llcNone=SC_CACHE_NONE, llcCaret=SC_CACHE_CARET, @@ -129,11 +129,11 @@ class LineLayoutCache { llcDocument=SC_CACHE_DOCUMENT }; void Invalidate(LineLayout::validLevel validity_); - void SetLevel(int level_); - int GetLevel() const { return level; } + void SetLevel(int level_) noexcept; + int GetLevel() const noexcept { return level; } LineLayout *Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_, Sci::Line linesOnScreen, Sci::Line linesInDoc); - void Dispose(LineLayout *ll); + void Dispose(LineLayout *ll) noexcept; }; class PositionCacheEntry { @@ -142,7 +142,7 @@ class PositionCacheEntry { unsigned int clock:16; std::unique_ptr positions; public: - 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. @@ -151,11 +151,11 @@ class PositionCacheEntry { void operator=(PositionCacheEntry &&) = delete; ~PositionCacheEntry(); void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, const XYPOSITION *positions_, unsigned int clock_); - void Clear(); + void Clear() noexcept; bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const; - static unsigned int Hash(unsigned int styleNumber_, const char *s, unsigned int len_); - bool NewerThan(const PositionCacheEntry &other) const; - void ResetClock(); + static unsigned int Hash(unsigned int styleNumber_, const char *s, unsigned int len_) noexcept; + bool NewerThan(const PositionCacheEntry &other) const noexcept; + void ResetClock() noexcept; }; class Representation { @@ -171,7 +171,7 @@ class SpecialRepresentations { MapRepresentation mapReprs; short startByteHasReprs[0x100]; public: - SpecialRepresentations(); + SpecialRepresentations() noexcept; void SetRepresentation(const char *charBytes, const char *value); void ClearRepresentation(const char *charBytes); const Representation *RepresentationFromCharacter(const char *charBytes, size_t len) const; @@ -220,7 +220,7 @@ class BreakFinder { void operator=(BreakFinder &&) = delete; ~BreakFinder(); TextSegment Next(); - bool More() const; + bool More() const noexcept; }; class PositionCache { @@ -235,9 +235,9 @@ class PositionCache { void operator=(const PositionCache &) = delete; void operator=(PositionCache &&) = delete; ~PositionCache(); - void Clear(); + void Clear() noexcept; void SetSize(size_t size_); - size_t GetSize() const { return pces.size(); } + size_t GetSize() const noexcept { return pces.size(); } void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber, const char *s, unsigned int len, XYPOSITION *positions, const Document *pdoc); }; diff --git a/scintilla/src/RESearch.h b/scintilla/src/RESearch.h index 285c9dc622..213055daca 100644 --- a/scintilla/src/RESearch.h +++ b/scintilla/src/RESearch.h @@ -11,14 +11,6 @@ namespace Scintilla { -/* - * The following defines are not meant to be changeable. - * They are for readability only. - */ -#define MAXCHR 256 -#define CHRBIT 8 -#define BITBLK MAXCHR/CHRBIT - class CharacterIndexer { public: virtual char CharAt(Sci::Position index) const=0; @@ -38,7 +30,6 @@ class RESearch { int Execute(const CharacterIndexer &ci, Sci::Position lp, Sci::Position endp); enum { MAXTAG=10 }; - enum { MAXNFA=4096 }; enum { NOTFOUND=-1 }; Sci::Position bopat[MAXTAG]; @@ -46,6 +37,14 @@ class RESearch { std::string pat[MAXTAG]; private: + + enum { MAXNFA = 4096 }; + // The following enums are not meant to be changeable. + // They are for readability only. + enum { MAXCHR = 256 }; + enum { CHRBIT = 8 }; + enum { BITBLK = MAXCHR / CHRBIT }; + void ChSet(unsigned char c); void ChSetWithCase(unsigned char c, bool caseSensitive); int GetBackslashExpression(const char *pattern, int &incr); diff --git a/scintilla/src/ScintillaBase.cxx b/scintilla/src/ScintillaBase.cxx index c327206d8b..0c00309b7b 100644 --- a/scintilla/src/ScintillaBase.cxx +++ b/scintilla/src/ScintillaBase.cxx @@ -28,6 +28,7 @@ #endif #include "PropSetSimple.h" +#include "CharacterCategory.h" #ifdef SCI_LEXER #include "LexerModule.h" @@ -275,9 +276,7 @@ void ScintillaBase::AutoCompleteStart(Sci::Position lenEntered, const char *list pt = PointMainCaret(); } if (wMargin.Created()) { - const Point ptOrigin = GetVisibleOriginInMain(); - pt.x += ptOrigin.x; - pt.y += ptOrigin.y; + pt = pt + GetVisibleOriginInMain(); } PRectangle rcac; rcac.left = pt.x - ac.lb->CaretFromEdge(); @@ -462,9 +461,7 @@ void ScintillaBase::CallTipShow(Point pt, const char *defn) { ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back); } if (wMargin.Created()) { - const Point ptOrigin = GetVisibleOriginInMain(); - pt.x += ptOrigin.x; - pt.y += ptOrigin.y; + pt = pt + GetVisibleOriginInMain(); } PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt, vs.lineHeight, diff --git a/scintilla/src/ScintillaBase.h b/scintilla/src/ScintillaBase.h index e886f22e2e..39fb9d411c 100644 --- a/scintilla/src/ScintillaBase.h +++ b/scintilla/src/ScintillaBase.h @@ -57,7 +57,7 @@ class ScintillaBase : public Editor, IListBoxDelegate { ScintillaBase(ScintillaBase &&) = delete; ScintillaBase &operator=(const ScintillaBase &) = delete; ScintillaBase &operator=(ScintillaBase &&) = delete; - ~ScintillaBase() override; + // ~ScintillaBase() in public section void Initialise() override {} void Finalise() override; @@ -94,6 +94,8 @@ class ScintillaBase : public Editor, IListBoxDelegate { void NotifyLexerChanged(Document *doc, void *userData) override; public: + ~ScintillaBase() override; + // Public so scintilla_send_message can use it sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) override; }; diff --git a/scintilla/src/Selection.cxx b/scintilla/src/Selection.cxx index c8c567fcb5..db13a55ad0 100644 --- a/scintilla/src/Selection.cxx +++ b/scintilla/src/Selection.cxx @@ -176,7 +176,7 @@ void SelectionRange::MinimizeVirtualSpace() { } } -Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) { +Selection::Selection() noexcept : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) { AddSelection(SelectionRange(SelectionPosition(0))); } diff --git a/scintilla/src/Selection.h b/scintilla/src/Selection.h index 8f21669611..82fc4aa487 100644 --- a/scintilla/src/Selection.h +++ b/scintilla/src/Selection.h @@ -14,7 +14,7 @@ class SelectionPosition { Sci::Position position; Sci::Position virtualSpace; public: - explicit SelectionPosition(Sci::Position position_=INVALID_POSITION, Sci::Position virtualSpace_=0) : position(position_), virtualSpace(virtualSpace_) { + explicit SelectionPosition(Sci::Position position_=INVALID_POSITION, Sci::Position virtualSpace_=0) noexcept : position(position_), virtualSpace(virtualSpace_) { PLATFORM_ASSERT(virtualSpace < 800000); if (virtualSpace < 0) virtualSpace = 0; @@ -84,15 +84,15 @@ struct SelectionRange { SelectionPosition caret; SelectionPosition anchor; - SelectionRange() : caret(), anchor() { + SelectionRange() noexcept : caret(), anchor() { } - explicit SelectionRange(SelectionPosition single) : caret(single), anchor(single) { + explicit SelectionRange(SelectionPosition single) noexcept : caret(single), anchor(single) { } - explicit SelectionRange(Sci::Position single) : caret(single), anchor(single) { + explicit SelectionRange(Sci::Position single) noexcept : caret(single), anchor(single) { } - SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) : caret(caret_), anchor(anchor_) { + SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) noexcept : caret(caret_), anchor(anchor_) { } - SelectionRange(Sci::Position caret_, Sci::Position anchor_) : caret(caret_), anchor(anchor_) { + SelectionRange(Sci::Position caret_, Sci::Position anchor_) noexcept : caret(caret_), anchor(anchor_) { } bool Empty() const { return anchor == caret; @@ -141,7 +141,7 @@ class Selection { enum selTypes { noSel, selStream, selRectangle, selLines, selThin }; selTypes selType; - Selection(); + Selection() noexcept; ~Selection(); bool IsRectangular() const; Sci::Position MainCaret() const; diff --git a/scintilla/src/Style.cxx b/scintilla/src/Style.cxx index 2cb82616b7..b5f8ca091f 100644 --- a/scintilla/src/Style.cxx +++ b/scintilla/src/Style.cxx @@ -16,27 +16,27 @@ using namespace Scintilla; -FontAlias::FontAlias() { +FontAlias::FontAlias() noexcept { } -FontAlias::FontAlias(const FontAlias &other) : Font() { +FontAlias::FontAlias(const FontAlias &other) noexcept : Font() { SetID(other.fid); } FontAlias::~FontAlias() { - SetID(0); + SetID(FontID{}); // ~Font will not release the actual font resource since it is now 0 } -void FontAlias::MakeAlias(const Font &fontOrigin) { +void FontAlias::MakeAlias(const Font &fontOrigin) noexcept { SetID(fontOrigin.GetID()); } -void FontAlias::ClearFont() { - SetID(0); +void FontAlias::ClearFont() noexcept { + SetID(FontID{}); } -bool FontSpecification::operator==(const FontSpecification &other) const { +bool FontSpecification::operator==(const FontSpecification &other) const noexcept { return fontName == other.fontName && weight == other.weight && italic == other.italic && @@ -45,7 +45,7 @@ bool FontSpecification::operator==(const FontSpecification &other) const { extraFontFlag == other.extraFontFlag; } -bool FontSpecification::operator<(const FontSpecification &other) const { +bool FontSpecification::operator<(const FontSpecification &other) const noexcept { if (fontName != other.fontName) return fontName < other.fontName; if (weight != other.weight) @@ -61,11 +61,11 @@ bool FontSpecification::operator<(const FontSpecification &other) const { return false; } -FontMeasurements::FontMeasurements() { +FontMeasurements::FontMeasurements() noexcept { ClearMeasurements(); } -void FontMeasurements::ClearMeasurements() { +void FontMeasurements::ClearMeasurements() noexcept { ascent = 1; descent = 1; capitalHeight = 1; diff --git a/scintilla/src/Style.h b/scintilla/src/Style.h index 7a497b36ba..1f7f02fe63 100644 --- a/scintilla/src/Style.h +++ b/scintilla/src/Style.h @@ -17,7 +17,7 @@ struct FontSpecification { int size; int characterSet; int extraFontFlag; - FontSpecification() : + FontSpecification() noexcept : fontName(nullptr), weight(SC_WEIGHT_NORMAL), italic(false), @@ -25,22 +25,22 @@ struct FontSpecification { characterSet(0), extraFontFlag(0) { } - bool operator==(const FontSpecification &other) const; - bool operator<(const FontSpecification &other) const; + 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(); + FontAlias() noexcept; // FontAlias objects can not be assigned except for initialization - FontAlias(const FontAlias &); + FontAlias(const FontAlias &) noexcept; FontAlias(FontAlias &&) = delete; FontAlias &operator=(const FontAlias &) = delete; FontAlias &operator=(FontAlias &&) = delete; ~FontAlias() override; - void MakeAlias(const Font &fontOrigin); - void ClearFont(); + void MakeAlias(const Font &fontOrigin) noexcept; + void ClearFont() noexcept; }; struct FontMeasurements { @@ -50,8 +50,8 @@ struct FontMeasurements { XYPOSITION aveCharWidth; XYPOSITION spaceWidth; int sizeZoomed; - FontMeasurements(); - void ClearMeasurements(); + FontMeasurements() noexcept; + void ClearMeasurements() noexcept; }; /** @@ -84,7 +84,7 @@ class Style : public FontSpecification, public FontMeasurements { bool visible_, bool changeable_, bool hotspot_); void ClearTo(const Style &source); void Copy(Font &font_, const FontMeasurements &fm_); - bool IsProtected() const { return !(changeable && visible);} + bool IsProtected() const noexcept { return !(changeable && visible);} }; } diff --git a/scintilla/src/UniConversion.cxx b/scintilla/src/UniConversion.cxx index 6cd6a8ba91..5b75ca63cd 100644 --- a/scintilla/src/UniConversion.cxx +++ b/scintilla/src/UniConversion.cxx @@ -16,7 +16,7 @@ using namespace Scintilla; namespace Scintilla { -size_t UTF8Length(const wchar_t *uptr, size_t tlen) { +size_t UTF8Length(const wchar_t *uptr, size_t tlen) noexcept { size_t len = 0; for (size_t i = 0; i < tlen && uptr[i];) { const unsigned int uch = uptr[i]; @@ -65,7 +65,7 @@ void UTF8FromUTF16(const wchar_t *uptr, size_t tlen, char *putf, size_t len) { putf[k] = '\0'; } -void UTF8FromUTF32Character(int uch, char *putf) { +void UTF8FromUTF32Character(int uch, char *putf) noexcept { size_t k = 0; if (uch < 0x80) { putf[k++] = static_cast(uch); @@ -85,7 +85,7 @@ void UTF8FromUTF32Character(int uch, char *putf) { putf[k] = '\0'; } -size_t UTF16Length(const char *s, size_t len) { +size_t UTF16Length(const char *s, size_t len) noexcept { size_t ulen = 0; for (size_t i = 0; i < len;) { const unsigned char ch = s[i]; @@ -162,6 +162,17 @@ 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 ulen = 0; + for (size_t i = 0; i < len;) { + const unsigned char ch = s[i]; + const unsigned int byteCount = UTF8BytesOfLead[ch]; + i += byteCount; + ulen++; + } + return ulen; +} + size_t UTF32FromUTF8(const char *s, size_t len, unsigned int *tbuf, size_t tlen) { size_t ui = 0; for (size_t i = 0; i < len;) { @@ -215,6 +226,20 @@ 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 ws(len16, 0); + UTF16FromUTF8(s, len, &ws[0], len16); + return ws; +#else + const size_t len32 = UTF32Length(s, len); + std::wstring ws(len32, 0); + UTF32FromUTF8(s, len, reinterpret_cast(&ws[0]), len32); + return ws; +#endif +} + unsigned int UTF16FromUTF32Character(unsigned int val, wchar_t *tbuf) noexcept { if (val < SUPPLEMENTAL_PLANE_FIRST) { tbuf[0] = static_cast(val); diff --git a/scintilla/src/UniConversion.h b/scintilla/src/UniConversion.h index 4bb8875d0e..e8e98df5f2 100644 --- a/scintilla/src/UniConversion.h +++ b/scintilla/src/UniConversion.h @@ -14,12 +14,16 @@ const int UTF8MaxBytes = 4; const int unicodeReplacementChar = 0xFFFD; -size_t UTF8Length(const wchar_t *uptr, size_t tlen); +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); -void UTF8FromUTF32Character(int uch, char *putf); -size_t UTF16Length(const char *s, size_t len); +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); +// 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); unsigned int UTF16FromUTF32Character(unsigned int val, wchar_t *tbuf) noexcept; bool UTF8IsValid(const char *s, size_t len) noexcept; std::string FixInvalidUTF8(const std::string &text); diff --git a/scintilla/src/UniqueString.cxx b/scintilla/src/UniqueString.cxx new file mode 100644 index 0000000000..aadc2ae7e6 --- /dev/null +++ b/scintilla/src/UniqueString.cxx @@ -0,0 +1,55 @@ +// Scintilla source code edit control +/** @file UniqueString.cxx + ** Define an allocator for UniqueString. + **/ +// Copyright 2017 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include + +#include "UniqueString.h" + +namespace Scintilla { + +/// Equivalent to strdup but produces a std::unique_ptr allocation to go +/// into collections. +UniqueString UniqueStringCopy(const char *text) { + if (!text) { + return UniqueString(); + } + const size_t len = strlen(text); + std::unique_ptr upcNew(new char[len + 1]); + memcpy(&upcNew[0], text, len + 1); + return UniqueString(upcNew.release()); +} + +// A set of strings that always returns the same pointer for each string. + +UniqueStringSet::UniqueStringSet() noexcept = default; + +UniqueStringSet::~UniqueStringSet() { + strings.clear(); +} + +void UniqueStringSet::Clear() noexcept { + strings.clear(); +} + +const char *UniqueStringSet::Save(const char *text) { + if (!text) + return nullptr; + + for (const UniqueString &us : strings) { + if (text == us.get()) { + return us.get(); + } + } + + strings.push_back(UniqueStringCopy(text)); + return strings.back().get(); +} + +} diff --git a/scintilla/src/UniqueString.h b/scintilla/src/UniqueString.h index 18c31283e6..f7f7ebbdcb 100644 --- a/scintilla/src/UniqueString.h +++ b/scintilla/src/UniqueString.h @@ -2,6 +2,8 @@ /** @file UniqueString.h ** Define UniqueString, a unique_ptr based string type for storage in containers ** and an allocator for UniqueString. + ** Define UniqueStringSet which holds a set of strings, used to avoid holding many copies + ** of font names. **/ // Copyright 2017 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. @@ -11,19 +13,33 @@ namespace Scintilla { +constexpr bool IsNullOrEmpty(const char *text) noexcept { + return text == nullptr || *text == '\0'; +} + using UniqueString = std::unique_ptr; /// Equivalent to strdup but produces a std::unique_ptr allocation to go /// into collections. -inline UniqueString UniqueStringCopy(const char *text) { - if (!text) { - return UniqueString(); - } - const size_t len = strlen(text); - char *sNew = new char[len + 1]; - std::copy(text, text + len + 1, sNew); - return UniqueString(sNew); -} +UniqueString UniqueStringCopy(const char *text); + +// A set of strings that always returns the same pointer for each string. + +class UniqueStringSet { +private: + std::vector strings; +public: + UniqueStringSet() noexcept; + // UniqueStringSet objects can not be copied. + UniqueStringSet(const UniqueStringSet &) = delete; + UniqueStringSet &operator=(const UniqueStringSet &) = delete; + // UniqueStringSet objects can be moved. + UniqueStringSet(UniqueStringSet &&) = default; + UniqueStringSet &operator=(UniqueStringSet &&) = default; + ~UniqueStringSet(); + void Clear() noexcept; + const char *Save(const char *text); +}; } diff --git a/scintilla/src/ViewStyle.cxx b/scintilla/src/ViewStyle.cxx index 0168556156..a4535abca0 100644 --- a/scintilla/src/ViewStyle.cxx +++ b/scintilla/src/ViewStyle.cxx @@ -28,38 +28,11 @@ using namespace Scintilla; -MarginStyle::MarginStyle(int style_, int width_, int mask_) : +MarginStyle::MarginStyle(int style_, int width_, int mask_) noexcept : style(style_), width(width_), mask(mask_), sensitive(false), cursor(SC_CURSORREVERSEARROW) { } -// A list of the fontnames - avoids wasting space in each style -FontNames::FontNames() { -} - -FontNames::~FontNames() { - Clear(); -} - -void FontNames::Clear() { - names.clear(); -} - -const char *FontNames::Save(const char *name) { - if (!name) - return nullptr; - - for (const UniqueString &nm : names) { - if (strcmp(nm.get(), name) == 0) { - return nm.get(); - } - } - - names.push_back(UniqueStringCopy(name)); - return names.back().get(); -} - -FontRealised::FontRealised() { -} +FontRealised::FontRealised() noexcept = default; FontRealised::~FontRealised() { font.Release(); @@ -373,7 +346,7 @@ void ViewStyle::Refresh(Surface &surface, int tabInChars) { textStart = marginInside ? fixedColumnWidth : leftMarginWidth; } -void ViewStyle::ReleaseAllExtendedStyles() { +void ViewStyle::ReleaseAllExtendedStyles() noexcept { nextExtendedStyle = 256; } @@ -419,11 +392,11 @@ void ViewStyle::SetStyleFontName(int styleIndex, const char *name) { styles[styleIndex].fontName = fontNames.Save(name); } -bool ViewStyle::ProtectionActive() const { +bool ViewStyle::ProtectionActive() const noexcept { return someStylesProtected; } -int ViewStyle::ExternalMarginWidth() const { +int ViewStyle::ExternalMarginWidth() const noexcept { return marginInside ? 0 : fixedColumnWidth; } @@ -438,7 +411,7 @@ int ViewStyle::MarginFromLocation(Point pt) const { return margin; } -bool ViewStyle::ValidStyle(size_t styleIndex) const { +bool ViewStyle::ValidStyle(size_t styleIndex) const noexcept { return styleIndex < styles.size(); } @@ -458,11 +431,11 @@ void ViewStyle::CalcLargestMarkerHeight() { } } -int ViewStyle::GetFrameWidth() const { +int ViewStyle::GetFrameWidth() const noexcept { return Sci::clamp(caretLineFrame, 1, lineHeight / 3); } -bool ViewStyle::IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const { +bool ViewStyle::IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const noexcept { return caretLineFrame && (caretActive || alwaysShowCaretLineBackground) && showCaretLineBackground && (caretLineAlpha == SC_ALPHA_NOALPHA) && lineContainsCaret; } @@ -504,16 +477,16 @@ ColourOptional ViewStyle::Background(int marksOfLine, bool caretActive, bool lin return background; } -bool ViewStyle::SelectionBackgroundDrawn() const { +bool ViewStyle::SelectionBackgroundDrawn() const noexcept { return selColours.back.isSet && ((selAlpha == SC_ALPHA_NOALPHA) || (selAdditionalAlpha == SC_ALPHA_NOALPHA)); } -bool ViewStyle::WhitespaceBackgroundDrawn() const { +bool ViewStyle::WhitespaceBackgroundDrawn() const noexcept { return (viewWhitespace != wsInvisible) && (whitespaceColours.back.isSet); } -bool ViewStyle::WhiteSpaceVisible(bool inIndent) const { +bool ViewStyle::WhiteSpaceVisible(bool inIndent) const noexcept { return (!inIndent && viewWhitespace == wsVisibleAfterIndent) || (inIndent && viewWhitespace == wsVisibleOnlyInIndent) || viewWhitespace == wsVisibleAlways; @@ -526,7 +499,7 @@ ColourDesired ViewStyle::WrapColour() const { return styles[STYLE_DEFAULT].fore; } -bool ViewStyle::SetWrapState(int wrapState_) { +bool ViewStyle::SetWrapState(int wrapState_) noexcept { WrapMode wrapStateWanted; switch (wrapState_) { case SC_WRAP_WORD: @@ -547,30 +520,43 @@ bool ViewStyle::SetWrapState(int wrapState_) { return changed; } -bool ViewStyle::SetWrapVisualFlags(int wrapVisualFlags_) { +bool ViewStyle::SetWrapVisualFlags(int wrapVisualFlags_) noexcept { const bool changed = wrapVisualFlags != wrapVisualFlags_; wrapVisualFlags = wrapVisualFlags_; return changed; } -bool ViewStyle::SetWrapVisualFlagsLocation(int wrapVisualFlagsLocation_) { +bool ViewStyle::SetWrapVisualFlagsLocation(int wrapVisualFlagsLocation_) noexcept { const bool changed = wrapVisualFlagsLocation != wrapVisualFlagsLocation_; wrapVisualFlagsLocation = wrapVisualFlagsLocation_; return changed; } -bool ViewStyle::SetWrapVisualStartIndent(int wrapVisualStartIndent_) { +bool ViewStyle::SetWrapVisualStartIndent(int wrapVisualStartIndent_) noexcept { const bool changed = wrapVisualStartIndent != wrapVisualStartIndent_; wrapVisualStartIndent = wrapVisualStartIndent_; return changed; } -bool ViewStyle::SetWrapIndentMode(int wrapIndentMode_) { +bool ViewStyle::SetWrapIndentMode(int wrapIndentMode_) noexcept { const bool changed = wrapIndentMode != wrapIndentMode_; wrapIndentMode = wrapIndentMode_; return changed; } +bool ViewStyle::IsBlockCaretStyle() const noexcept { + return (caretStyle == CARETSTYLE_BLOCK) || (caretStyle & CARETSTYLE_OVERSTRIKE_BLOCK) != 0; +} + +ViewStyle::CaretShape ViewStyle::CaretShapeForMode(bool inOverstrike) const noexcept { + if (inOverstrike) { + return (caretStyle & CARETSTYLE_OVERSTRIKE_BLOCK) ? CaretShape::block : CaretShape::bar; + } + + const int caret = caretStyle & CARETSTYLE_INS_MASK; + return (caret <= CARETSTYLE_BLOCK) ? static_cast(caret) : CaretShape::line; +} + void ViewStyle::AllocStyles(size_t sizeNew) { size_t i=styles.size(); styles.resize(sizeNew); diff --git a/scintilla/src/ViewStyle.h b/scintilla/src/ViewStyle.h index 800d8cb679..587eb976a8 100644 --- a/scintilla/src/ViewStyle.h +++ b/scintilla/src/ViewStyle.h @@ -20,30 +20,17 @@ class MarginStyle { int mask; bool sensitive; int cursor; - MarginStyle(int style_= SC_MARGIN_SYMBOL, int width_=0, int mask_=0); + MarginStyle(int style_= SC_MARGIN_SYMBOL, int width_=0, int mask_=0) noexcept; }; /** */ -class FontNames { -private: - std::vector names; -public: - FontNames(); - // FontNames objects can not be copied. - FontNames(const FontNames &) = delete; - FontNames(FontNames &&) = delete; - FontNames &operator=(const FontNames &) = delete; - FontNames &operator=(FontNames &&) = delete; - ~FontNames(); - void Clear(); - const char *Save(const char *name); -}; + class FontRealised : public FontMeasurements { public: Font font; - FontRealised(); + FontRealised() noexcept; // FontRealised objects can not be copied. FontRealised(const FontRealised &) = delete; FontRealised(FontRealised &&) = delete; @@ -66,9 +53,9 @@ enum WrapMode { eWrapNone, eWrapWord, eWrapChar, eWrapWhitespace }; class ColourOptional : public ColourDesired { public: bool isSet; - ColourOptional(ColourDesired colour_=ColourDesired(0,0,0), bool isSet_=false) : ColourDesired(colour_), isSet(isSet_) { + ColourOptional(ColourDesired colour_=ColourDesired(0,0,0), bool isSet_=false) noexcept : ColourDesired(colour_), isSet(isSet_) { } - ColourOptional(uptr_t wParam, sptr_t lParam) : ColourDesired(static_cast(lParam)), isSet(wParam != 0) { + ColourOptional(uptr_t wParam, sptr_t lParam) noexcept : ColourDesired(static_cast(lParam)), isSet(wParam != 0) { } }; @@ -80,10 +67,10 @@ struct ForeBackColours { struct EdgeProperties { int column; ColourDesired colour; - EdgeProperties(int column_ = 0, ColourDesired colour_ = ColourDesired(0)) : + EdgeProperties(int column_ = 0, ColourDesired colour_ = ColourDesired(0)) noexcept : column(column_), colour(colour_) { } - EdgeProperties(uptr_t wParam, sptr_t lParam) : + EdgeProperties(uptr_t wParam, sptr_t lParam) noexcept : column(static_cast(wParam)), colour(static_cast(lParam)) { } }; @@ -91,7 +78,7 @@ struct EdgeProperties { /** */ class ViewStyle { - FontNames fontNames; + UniqueStringSet fontNames; FontMap fonts; public: std::vector