diff options
| -rw-r--r-- | gtk/ScintillaGTK.cxx | 32 | ||||
| -rw-r--r-- | src/Editor.cxx | 63 | ||||
| -rw-r--r-- | src/Editor.h | 2 | ||||
| -rw-r--r-- | win32/ScintillaWin.cxx | 37 | 
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, | 
