diff options
| author | mitchell <unknown> | 2020-04-05 16:00:55 -0400 | 
|---|---|---|
| committer | mitchell <unknown> | 2020-04-05 16:00:55 -0400 | 
| commit | 5f4a3252dfb66b77f6ed4acf0e4bc46a5c678744 (patch) | |
| tree | b7216cc0c52046816f7bc5f060b354dfc010fe58 | |
| parent | b467fbec5c0b13bb71444191b250b50677238361 (diff) | |
| download | scintilla-mirror-5f4a3252dfb66b77f6ed4acf0e4bc46a5c678744.tar.gz | |
Backport: Widen types to size_t to match change from int to position of CallTipSetHlt
in Scintilla.iface.
Backport of changeset 8098:228c9f9aa839.
| -rw-r--r-- | curses/ScintillaCurses.cxx | 1 | ||||
| -rw-r--r-- | gtk/ScintillaGTKAccessible.cxx | 1 | ||||
| -rw-r--r-- | src/CallTip.cxx | 155 | ||||
| -rw-r--r-- | src/CallTip.h | 19 | ||||
| -rw-r--r-- | src/ScintillaBase.cxx | 6 | 
5 files changed, 99 insertions, 83 deletions
| diff --git a/curses/ScintillaCurses.cxx b/curses/ScintillaCurses.cxx index 13b6a4117..21330996e 100644 --- a/curses/ScintillaCurses.cxx +++ b/curses/ScintillaCurses.cxx @@ -8,6 +8,7 @@  #include <stdint.h>  #include <string.h>  #include <math.h> +#include <assert.h>  #include <wchar.h>  #include <stdexcept> diff --git a/gtk/ScintillaGTKAccessible.cxx b/gtk/ScintillaGTKAccessible.cxx index 918df5149..90b41ebc6 100644 --- a/gtk/ScintillaGTKAccessible.cxx +++ b/gtk/ScintillaGTKAccessible.cxx @@ -53,6 +53,7 @@  #include <cstddef>  #include <cstdlib> +#include <cassert>  #include <cstring>  #include <stdexcept> diff --git a/src/CallTip.cxx b/src/CallTip.cxx index 3810e433f..96b54224c 100644 --- a/src/CallTip.cxx +++ b/src/CallTip.cxx @@ -7,6 +7,7 @@  #include <cstddef>  #include <cstdlib> +#include <cassert>  #include <cstring>  #include <cstdio>  #include <cmath> @@ -27,6 +28,10 @@  using namespace Scintilla; +size_t Chunk::Length() const noexcept { +	return end - start; +} +  CallTip::CallTip() noexcept {  	wCallTip = {};  	inCallTipMode = false; @@ -35,8 +40,6 @@ CallTip::CallTip() noexcept {  	rectDown = PRectangle(0,0,0,0);  	lineHeight = 1;  	offsetMain = 0; -	startHighlight = 0; -	endHighlight = 0;  	tabSize = 0;  	above = false;  	useStyleCallTip = false;    // for backwards compatibility @@ -118,62 +121,63 @@ void DrawArrow(Scintilla::Surface *surface, const PRectangle &rc, bool upArrow,  }  // Draw a section of the call tip that does not include \n in one colour. -// The text may include up to numEnds tabs or arrow characters. -void CallTip::DrawChunk(Surface *surface, int &x, const char *s, -	int posStart, int posEnd, int ytext, PRectangle rcClient, -	bool highlight, bool draw) { -	s += posStart; -	const int len = posEnd - posStart; +// The text may include tabs or arrow characters. +int CallTip::DrawChunk(Surface *surface, int x, const char *s, size_t len, +	int ytext, PRectangle rcClient, bool asHighlight, bool draw) { +	if (len == 0) { +		return x; +	}  	// Divide the text into sections that are all text, or that are  	// single arrows or single tab characters (if tabSize > 0). -	int maxEnd = 0; -	constexpr int numEnds = 10; -	int ends[numEnds + 2] {}; -	for (int i=0; i<len; i++) { -		if ((maxEnd < numEnds) && -		        (IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) { -			if (i > 0) -				ends[maxEnd++] = i; -			ends[maxEnd++] = i+1; +	// Start with single element 0 to simplify append checks. +	std::vector<size_t> ends(1); +	for (size_t i=0; i<len; i++) { +		if (IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) { +			if (ends.back() != i) +				ends.push_back(i); +			ends.push_back(i+1);  		}  	} -	ends[maxEnd++] = len; -	int startSeg = 0; -	for (int seg = 0; seg<maxEnd; seg++) { -		const int endSeg = ends[seg]; -		if (endSeg > startSeg) { -			int xEnd; -			if (IsArrowCharacter(s[startSeg])) { -				xEnd = x + widthArrow; -				const bool upArrow = s[startSeg] == '\001'; +	if (ends.back() != len) +		ends.push_back(len); +	ends.erase(ends.begin());	// Remove initial 0. + +	size_t startSeg = 0; +	for (const size_t endSeg : ends) { +		assert(endSeg > 0); +		int xEnd; +		if (IsArrowCharacter(s[startSeg])) { +			xEnd = x + widthArrow; +			const bool upArrow = s[startSeg] == '\001'; +			rcClient.left = static_cast<XYPOSITION>(x); +			rcClient.right = static_cast<XYPOSITION>(xEnd); +			if (draw) { +				DrawArrow(surface, rcClient, upArrow, colourBG, colourUnSel); +			} +			offsetMain = xEnd; +			if (upArrow) { +				rectUp = rcClient; +			} else { +				rectDown = rcClient; +			} +		} else if (IsTabCharacter(s[startSeg])) { +			xEnd = NextTabPos(x); +		} else { +			const char *segText = s + startSeg; +			xEnd = x + static_cast<int>(Sci::lround(surface->WidthText(font, segText, endSeg - startSeg))); +			if (draw) {  				rcClient.left = static_cast<XYPOSITION>(x);  				rcClient.right = static_cast<XYPOSITION>(xEnd); -				if (draw) { -					DrawArrow(surface, rcClient, upArrow, colourBG, colourUnSel); -				} -				offsetMain = xEnd; -				if (upArrow) { -					rectUp = rcClient; -				} else { -					rectDown = rcClient; -				} -			} else if (IsTabCharacter(s[startSeg])) { -				xEnd = NextTabPos(x); -			} else { -				xEnd = x + static_cast<int>(Sci::lround(surface->WidthText(font, s + startSeg, endSeg - startSeg))); -				if (draw) { -					rcClient.left = static_cast<XYPOSITION>(x); -					rcClient.right = static_cast<XYPOSITION>(xEnd); -					surface->DrawTextTransparent(rcClient, font, static_cast<XYPOSITION>(ytext), -										s+startSeg, endSeg - startSeg, -					                             highlight ? colourSel : colourUnSel); -				} +				surface->DrawTextTransparent(rcClient, font, static_cast<XYPOSITION>(ytext), +									segText, endSeg - startSeg, +				                             asHighlight ? colourSel : colourUnSel);  			} -			x = xEnd; -			startSeg = endSeg;  		} +		x = xEnd; +		startSeg = endSeg;  	} +	return x;  }  int CallTip::PaintContents(Surface *surfaceWindow, bool draw) { @@ -189,40 +193,44 @@ int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {  	// Draw the definition in three parts: before highlight, highlighted, after highlight  	int ytext = static_cast<int>(rcClient.top) + ascent + 1;  	rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1; -	const char *chunkVal = val.c_str(); -	bool moreChunks = true; +	const char *remaining = val.c_str();  	int maxWidth = 0; - -	while (moreChunks) { -		const char *chunkEnd = strchr(chunkVal, '\n'); +	size_t lineStart = 0; +	while (*remaining) { +        const char *chunkVal = remaining; +		const char *chunkEnd = strchr(remaining, '\n');  		if (!chunkEnd) {  			chunkEnd = chunkVal + strlen(chunkVal); -			moreChunks = false;  		} -		const int chunkOffset = static_cast<int>(chunkVal - val.c_str()); -		const int chunkLength = static_cast<int>(chunkEnd - chunkVal); -		const int chunkEndOffset = chunkOffset + chunkLength; -		int thisStartHighlight = std::max(startHighlight, chunkOffset); -		thisStartHighlight = std::min(thisStartHighlight, chunkEndOffset); -		thisStartHighlight -= chunkOffset; -		int thisEndHighlight = std::max(endHighlight, chunkOffset); -		thisEndHighlight = std::min(thisEndHighlight, chunkEndOffset); -		thisEndHighlight -= chunkOffset; +		const size_t chunkLength = static_cast<size_t>(chunkEnd - chunkVal); +		remaining += chunkLength; +		if (*remaining) { +			remaining++; // Skip \n +		} + +		const Chunk chunkLine(lineStart, lineStart + chunkLength); +		Chunk chunkHighlight( +			Sci::clamp(highlight.start, chunkLine.start, chunkLine.end), +			Sci::clamp(highlight.end, chunkLine.start, chunkLine.end) +		); +		chunkHighlight.start -= lineStart; +		chunkHighlight.end -= lineStart; +  		rcClient.top = static_cast<XYPOSITION>(ytext - ascent - 1);  		int x = insetX;     // start each line at this inset -		DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight, +		x = DrawChunk(surfaceWindow, x, chunkVal, chunkHighlight.start,  			ytext, rcClient, false, draw); -		DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight, +		x = DrawChunk(surfaceWindow, x, chunkVal + chunkHighlight.start, chunkHighlight.Length(),  			ytext, rcClient, true, draw); -		DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength, +		x = DrawChunk(surfaceWindow, x, chunkVal + chunkHighlight.end, chunkLength - chunkHighlight.end,  			ytext, rcClient, false, draw); -		chunkVal = chunkEnd + 1;  		ytext += lineHeight;  		rcClient.bottom += lineHeight;  		maxWidth = std::max(maxWidth, x); +		lineStart += chunkLength + 1;  	}  	return maxWidth;  } @@ -273,8 +281,7 @@ PRectangle CallTip::CallTipStart(Sci::Position pos, Point pt, int textHeight, co  	surfaceMeasure->Init(wParent.GetID());  	surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);  	surfaceMeasure->SetDBCSMode(codePage); -	startHighlight = 0; -	endHighlight = 0; +	highlight = Chunk();  	inCallTipMode = true;  	posStartCallTip = pos;  	const XYPOSITION deviceHeight = static_cast<XYPOSITION>(surfaceMeasure->DeviceHeightFont(size)); @@ -307,11 +314,11 @@ void CallTip::CallTipCancel() {  	}  } -void CallTip::SetHighlight(int start, int end) { +void CallTip::SetHighlight(size_t start, size_t end) {  	// Avoid flashing by checking something has really changed -	if ((start != startHighlight) || (end != endHighlight)) { -		startHighlight = start; -		endHighlight = (end > start) ? end : start; +	if ((start != highlight.start) || (end != highlight.end)) { +		highlight.start = start; +		highlight.end = (end > start) ? end : start;  		if (wCallTip.Created()) {  			wCallTip.InvalidateAll();  		} @@ -332,7 +339,7 @@ void CallTip::SetPosition(bool aboveText) noexcept {  }  bool CallTip::UseStyleCallTip() const noexcept { -	return useStyleCallTip;  +	return useStyleCallTip;  }  // It might be better to have two access functions for this and to use diff --git a/src/CallTip.h b/src/CallTip.h index a720bd3a3..1a0a317cb 100644 --- a/src/CallTip.h +++ b/src/CallTip.h @@ -10,11 +10,19 @@  namespace Scintilla { +struct Chunk { +	size_t start; +	size_t end; +	Chunk(size_t start_=0, size_t end_=0) noexcept : start(start_), end(end_) { +		assert(start <= end); +	} +	size_t Length() const noexcept; +}; +  /**   */  class CallTip { -	int startHighlight;    // character offset to start and... -	int endHighlight;      // ...end of highlighted text +	Chunk highlight;    // character offset to start and end of highlighted text  	std::string val;  	Font font;  	PRectangle rectUp;      // rectangle of last up angle in the tip @@ -25,9 +33,8 @@ class CallTip {  	bool useStyleCallTip;   // if true, STYLE_CALLTIP should be used  	bool above;		// if true, display calltip above text -	void DrawChunk(Surface *surface, int &x, const char *s, -		int posStart, int posEnd, int ytext, PRectangle rcClient, -		bool highlight, bool draw); +	int DrawChunk(Surface *surface, int x, const char *s, size_t len, +		int ytext, PRectangle rcClient, bool asHighlight, bool draw);  	int PaintContents(Surface *surfaceWindow, bool draw);  	bool IsTabCharacter(char ch) const noexcept;  	int NextTabPos(int x) const noexcept; @@ -71,7 +78,7 @@ public:  	/// Set a range of characters to be displayed in a highlight style.  	/// Commonly used to highlight the current parameter. -	void SetHighlight(int start, int end); +	void SetHighlight(size_t start, size_t end);  	/// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand.  	void SetTabSize(int tabSz) noexcept; diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx index 7c708d0f1..ca67d7475 100644 --- a/src/ScintillaBase.cxx +++ b/src/ScintillaBase.cxx @@ -1005,7 +1005,7 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara  		return ac.GetTypesep();  	case SCI_CALLTIPSHOW: -		CallTipShow(LocationFromPosition(static_cast<Sci::Position>(wParam)), +		CallTipShow(LocationFromPosition(wParam),  			ConstCharPtrFromSPtr(lParam));  		break; @@ -1020,11 +1020,11 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara  		return ct.posStartCallTip;  	case SCI_CALLTIPSETPOSSTART: -		ct.posStartCallTip = static_cast<Sci::Position>(wParam); +		ct.posStartCallTip = wParam;  		break;  	case SCI_CALLTIPSETHLT: -		ct.SetHighlight(static_cast<int>(wParam), static_cast<int>(lParam)); +		ct.SetHighlight(wParam, lParam);  		break;  	case SCI_CALLTIPSETBACK: | 
