aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gtk/ScintillaGTK.cxx32
-rw-r--r--src/Editor.cxx63
-rw-r--r--src/Editor.h2
-rw-r--r--win32/ScintillaWin.cxx37
4 files changed, 91 insertions, 43 deletions
diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx
index b3c9b8bd4..c6b0fbf3e 100644
--- a/gtk/ScintillaGTK.cxx
+++ b/gtk/ScintillaGTK.cxx
@@ -129,6 +129,8 @@ class ScintillaGTK : public ScintillaBase {
gint lastWheelMouseDirection;
gint wheelMouseIntensity;
+ GdkRegion *rgnUpdate;
+
// Private so ScintillaGTK objects can not be copied
ScintillaGTK(const ScintillaGTK &) : ScintillaBase() {}
ScintillaGTK &operator=(const ScintillaGTK &) { return * this; }
@@ -153,6 +155,7 @@ private:
virtual bool SetIdle(bool on);
virtual void SetMouseCapture(bool on);
virtual bool HaveMouseCapture();
+ virtual bool PaintContains(PRectangle rc);
void FullPaint();
virtual PRectangle GetClientRectangle();
void SyncPaint(PRectangle rc);
@@ -317,7 +320,8 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
#endif
#endif
lastWheelMouseDirection(0),
- wheelMouseIntensity(0) {
+ wheelMouseIntensity(0),
+ rgnUpdate(0) {
sci = sci_;
wMain = GTK_WIDGET(sci);
@@ -947,6 +951,22 @@ bool ScintillaGTK::HaveMouseCapture() {
return capturedMouse;
}
+bool ScintillaGTK::PaintContains(PRectangle rc) {
+ bool contains = true;
+ if (paintState == painting) {
+ if (!rcPaint.Contains(rc)) {
+ contains = false;
+ } else if (rgnUpdate) {
+ GdkRectangle grc = {rc.left, rc.top,
+ rc.right - rc.left, rc.bottom - rc.top};
+ if (gdk_region_rect_in(rgnUpdate, &grc) != GDK_OVERLAP_RECTANGLE_IN) {
+ contains = false;
+ }
+ }
+ }
+ return contains;
+}
+
// Redraw all of text area. This paint will not be abandoned.
void ScintillaGTK::FullPaint() {
#if GTK_MAJOR_VERSION < 2
@@ -2152,6 +2172,10 @@ gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
rcPaint.right = ose->area.x + ose->area.width;
rcPaint.bottom = ose->area.y + ose->area.height;
+ PLATFORM_ASSERT(rgnUpdate == NULL);
+#if GTK_MAJOR_VERSION >= 2
+ rgnUpdate = gdk_region_copy(ose->region);
+#endif
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
Surface *surfaceWindow = Surface::Allocate();
@@ -2166,6 +2190,12 @@ gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
FullPaint();
}
paintState = notPainting;
+
+ if (rgnUpdate) {
+ g_free(rgnUpdate);
+ }
+ rgnUpdate = 0;
+
return FALSE;
}
diff --git a/src/Editor.cxx b/src/Editor.cxx
index f4ef99b5a..93560abdf 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -3749,8 +3749,13 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
}
if (mh.modificationType & SC_MOD_CHANGEMARKER) {
- if (paintState == notPainting) {
- RedrawSelMargin(mh.line);
+ if ((paintState == notPainting) || !PaintContainsMargin()) {
+ if (mh.modificationType & SC_MOD_CHANGEFOLD) {
+ // Fold changes can affect the drawing of following lines so redraw whole margin
+ RedrawSelMargin();
+ } else {
+ RedrawSelMargin(mh.line);
+ }
}
}
@@ -5372,16 +5377,14 @@ void Editor::SetFocusState(bool focusState) {
}
}
-static bool IsIn(int a, int minimum, int maximum) {
- return (a >= minimum) && (a <= maximum);
+bool Editor::PaintContains(PRectangle rc) {
+ return rcPaint.Contains(rc);
}
-static bool IsOverlap(int mina, int maxa, int minb, int maxb) {
- return
- IsIn(mina, minb, maxb) ||
- IsIn(maxa, minb, maxb) ||
- IsIn(minb, mina, maxa) ||
- IsIn(maxb, mina, maxa);
+bool Editor::PaintContainsMargin() {
+ PRectangle rcSelMargin = GetClientRectangle();
+ rcSelMargin.right = vs.fixedColumnWidth;
+ return PaintContains(rcSelMargin);
}
void Editor::CheckForChangeOutsidePaint(Range r) {
@@ -5390,41 +5393,17 @@ void Editor::CheckForChangeOutsidePaint(Range r) {
if (!r.Valid())
return;
+ PRectangle rcRange = RectangleFromRange(r.start, r.end);
PRectangle rcText = GetTextRectangle();
- // Determine number of lines displayed including a possible partially displayed last line
- int linesDisplayed = (rcText.bottom - rcText.top - 1) / vs.lineHeight + 1;
- int bottomLine = topLine + linesDisplayed - 1;
-
- int lineRangeStart = cs.DisplayFromDoc(pdoc->LineFromPosition(r.start));
- int lineRangeEnd = cs.DisplayFromDoc(pdoc->LineFromPosition(r.end));
- if (!IsOverlap(topLine, bottomLine, lineRangeStart, lineRangeEnd)) {
- //Platform::DebugPrintf("No overlap (%d-%d) with window(%d-%d)\n",
- // lineRangeStart, lineRangeEnd, topLine, bottomLine);
- return;
+ if (rcRange.top < rcText.top) {
+ rcRange.top = rcText.top;
}
-
- // Assert rcPaint contained within or equal to rcText
- if (rcPaint.top > rcText.top) {
- // does range intersect rcText.top .. rcPaint.top
- int paintTopLine = ((rcPaint.top - rcText.top - 1) / vs.lineHeight) + topLine;
- // paintTopLine is the top line of the paint rectangle or the line just above if that line is completely inside the paint rectangle
- if (IsOverlap(topLine, paintTopLine, lineRangeStart, lineRangeEnd)) {
- //Platform::DebugPrintf("Change (%d-%d) in top npv(%d-%d)\n",
- // lineRangeStart, lineRangeEnd, topLine, paintTopLine);
- AbandonPaint();
- return;
- }
+ if (rcRange.bottom > rcText.bottom) {
+ rcRange.bottom = rcText.bottom;
}
- if (rcPaint.bottom < rcText.bottom) {
- // does range intersect rcPaint.bottom .. rcText.bottom
- int paintBottomLine = ((rcPaint.bottom - rcText.top - 1) / vs.lineHeight + 1) + topLine;
- // paintTopLine is the bottom line of the paint rectangle or the line just below if that line is completely inside the paint rectangle
- if (IsOverlap(paintBottomLine, bottomLine, lineRangeStart, lineRangeEnd)) {
- //Platform::DebugPrintf("Change (%d-%d) in bottom npv(%d-%d)\n",
- // lineRangeStart, lineRangeEnd, paintBottomLine, bottomLine);
- AbandonPaint();
- return;
- }
+
+ if (!PaintContains(rcRange)) {
+ AbandonPaint();
}
}
}
diff --git a/src/Editor.h b/src/Editor.h
index 0ac6ec917..1207425dd 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -504,6 +504,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual bool HaveMouseCapture() = 0;
void SetFocusState(bool focusState);
+ virtual bool PaintContains(PRectangle rc);
+ bool PaintContainsMargin();
void CheckForChangeOutsidePaint(Range r);
int BraceMatch(int position, int maxReStyle);
void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index a4c09a0fb..c7f569970 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -147,6 +147,8 @@ class ScintillaWin :
unsigned int linesPerScroll; ///< Intellimouse support
int wheelDelta; ///< Wheel delta from roll
+ HRGN hRgnUpdate;
+
bool hasOKText;
CLIPFORMAT cfColumnSelect;
@@ -183,6 +185,7 @@ class ScintillaWin :
virtual void SetTicking(bool on);
virtual void SetMouseCapture(bool on);
virtual bool HaveMouseCapture();
+ virtual bool PaintContains(PRectangle rc);
virtual void ScrollText(int linesToMove);
virtual void UpdateSystemCaret();
virtual void SetVerticalScrollPos();
@@ -277,6 +280,8 @@ ScintillaWin::ScintillaWin(HWND hwnd) {
linesPerScroll = 0;
wheelDelta = 0; // Wheel delta from roll
+ hRgnUpdate = 0;
+
hasOKText = false;
// There does not seem to be a real standard for indicating that the clipboard
@@ -409,9 +414,12 @@ LRESULT ScintillaWin::WndPaint(uptr_t wParam) {
bool IsOcxCtrl = (wParam != 0); // if wParam != 0, it contains
// a PAINSTRUCT* from the OCX
+ PLATFORM_ASSERT(hRgnUpdate == NULL);
+ hRgnUpdate = ::CreateRectRgn(0, 0, 0, 0);
if (IsOcxCtrl) {
pps = reinterpret_cast<PAINTSTRUCT*>(wParam);
} else {
+ ::GetUpdateRgn(MainHWND(), hRgnUpdate, FALSE);
pps = &ps;
::BeginPaint(MainHWND(), pps);
}
@@ -428,6 +436,11 @@ LRESULT ScintillaWin::WndPaint(uptr_t wParam) {
Paint(surfaceWindow, rcPaint);
surfaceWindow->Release();
}
+ if (hRgnUpdate) {
+ ::DeleteRgn(hRgnUpdate);
+ hRgnUpdate = 0;
+ }
+
if(!IsOcxCtrl)
::EndPaint(MainHWND(), pps);
if (paintState == paintAbandoned) {
@@ -989,6 +1002,30 @@ bool ScintillaWin::HaveMouseCapture() {
//return capturedMouse && (::GetCapture() == MainHWND());
}
+bool ScintillaWin::PaintContains(PRectangle rc) {
+ bool contains = true;
+ if (paintState == painting) {
+ if (!rcPaint.Contains(rc)) {
+ contains = false;
+ } else {
+ // In bounding rectangle so check more accurately using region
+ HRGN hRgnRange = ::CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
+ if (hRgnRange) {
+ HRGN hRgnDest = ::CreateRectRgn(0, 0, 0, 0);
+ if (hRgnDest) {
+ int combination = ::CombineRgn(hRgnDest, hRgnRange, hRgnUpdate, RGN_DIFF);
+ if (combination != NULLREGION) {
+ contains = false;
+ }
+ ::DeleteRgn(hRgnDest);
+ }
+ ::DeleteRgn(hRgnRange);
+ }
+ }
+ }
+ return contains;
+}
+
void ScintillaWin::ScrollText(int linesToMove) {
//Platform::DebugPrintf("ScintillaWin::ScrollText %d\n", linesToMove);
::ScrollWindow(MainHWND(), 0,