diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Editor.cxx | 323 | ||||
| -rw-r--r-- | src/Editor.h | 1 | ||||
| -rw-r--r-- | src/PositionCache.h | 9 | ||||
| -rw-r--r-- | src/ViewStyle.cxx | 20 | ||||
| -rw-r--r-- | src/ViewStyle.h | 7 | 
5 files changed, 187 insertions, 173 deletions
| diff --git a/src/Editor.cxx b/src/Editor.cxx index 73068e330..3aa949f77 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -112,7 +112,6 @@ Editor::Editor() {  	printColourMode = SC_PRINT_NORMAL;  	printWrapState = eWrapWord;  	cursorMode = SC_CURSORNORMAL; -	controlCharSymbol = 0;	/* Draw the control characters */  	hasFocus = false;  	hideSelection = false; @@ -354,7 +353,7 @@ void Editor::RefreshStyleData() {  		stylesValid = true;  		AutoSurface surface(this);  		if (surface) { -			vs.Refresh(*surface); +			vs.Refresh(*surface, pdoc->tabInChars);  		}  		SetScrollBars();  		SetRectangularRange(); @@ -2275,63 +2274,52 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou  		// Layout the line, determining the position of each character,  		// with an extra element at the end for the end of the line. -		int startseg = 0;	// Start of the current segment, in char. number -		XYACCUMULATOR startsegx = 0;	// Start of the current segment, in pixels  		ll->positions[0] = 0; -		XYPOSITION tabWidth = vstyle.spaceWidth * pdoc->tabInChars;  		bool lastSegItalics = false;  		BreakFinder bfLayout(ll, 0, numCharsInLine, posLineStart, 0, false, pdoc, &reprs);  		while (bfLayout.More()) { -			TextSegment ts = bfLayout.Next(); -			startseg = ts.start; - -			ll->positions[startseg] = 0; -			if (vstyle.styles[ll->styles[startseg]].visible) { -				if (ts.repr) { -					if (ll->chars[startseg] == '\t') { -						// Tab is a special case of repr, taking a variable amount of space -						ll->positions[startseg + 1] = -							((static_cast<int>((startsegx + 2) / tabWidth) + 1) * tabWidth) - startsegx; -					} else if (controlCharSymbol < 32) { -						XYPOSITION positionsRepr[256];	// Should expand when needed -						posCache.MeasureWidths(surface, vstyle, STYLE_CONTROLCHAR, ts.repr->stringRep.c_str(), -							static_cast<unsigned int>(ts.repr->stringRep.length()), positionsRepr, pdoc); -						XYPOSITION endRepr = positionsRepr[ts.repr->stringRep.length()-1] + 3; -						for (int ii=0; ii < ts.length; ii++) -							ll->positions[startseg + 1 + ii] = endRepr; +			const TextSegment ts = bfLayout.Next(); + +			std::fill(&ll->positions[ts.start+1], &ll->positions[ts.end()+1], 0.0f); +			if (vstyle.styles[ll->styles[ts.start]].visible) { +				if (ts.representation) { +					XYPOSITION representationWidth = vstyle.controlCharWidth; +					if (ll->chars[ts.start] == '\t') { +						// Tab is a special case of representation, taking a variable amount of space +						representationWidth = +							((static_cast<int>((ll->positions[ts.start] + 2) / vstyle.tabWidth) + 1) * vstyle.tabWidth) - ll->positions[ts.start];  					} else { -						char cc[2] = { static_cast<char>(controlCharSymbol), '\0' }; -						surface->MeasureWidths(vstyle.styles[STYLE_CONTROLCHAR].font, cc, 1, -							    ll->positions + startseg + 1); - 					} -					lastSegItalics = false; +						if (representationWidth <= 0.0) { +							XYPOSITION positionsRepr[256];	// Should expand when needed +							posCache.MeasureWidths(surface, vstyle, STYLE_CONTROLCHAR, ts.representation->stringRep.c_str(), +								static_cast<unsigned int>(ts.representation->stringRep.length()), positionsRepr, pdoc); +							representationWidth = positionsRepr[ts.representation->stringRep.length()-1] + ctrlCharPadding; + 						} +					} +					for (int ii=0; ii < ts.length; ii++) +						ll->positions[ts.start + 1 + ii] = representationWidth;  				} else { -					if ((ts.length == 1) && (' ' == ll->chars[startseg])) { -						lastSegItalics = false; +					if ((ts.length == 1) && (' ' == ll->chars[ts.start])) {  						// Over half the segments are single characters and of these about half are space characters. -						ll->positions[startseg + 1] = vstyle.styles[ll->styles[startseg]].spaceWidth; +						ll->positions[ts.start + 1] = vstyle.styles[ll->styles[ts.start]].spaceWidth;  					} else { -						lastSegItalics = vstyle.styles[ll->styles[startseg]].italic; -						posCache.MeasureWidths(surface, vstyle, ll->styles[startseg], ll->chars + startseg, -							    ts.length, ll->positions + startseg + 1, pdoc); +						posCache.MeasureWidths(surface, vstyle, ll->styles[ts.start], ll->chars + ts.start, +							    ts.length, ll->positions + ts.start + 1, pdoc);  					}  				} -			} else {    // invisible -				for (int posToZero = startseg; posToZero <= (startseg + ts.length); posToZero++) { -					ll->positions[posToZero] = 0; -				} +				lastSegItalics = (!ts.representation) && ((ll->chars[ts.end()-1] != ' ') && vstyle.styles[ll->styles[ts.start]].italic);  			} -			for (int posToIncrease = startseg; posToIncrease <= (startseg + ts.length); posToIncrease++) { -				ll->positions[posToIncrease] += startsegx; + +			for (int posToIncrease = ts.start+1; posToIncrease <= ts.end(); posToIncrease++) { +				ll->positions[posToIncrease] += ll->positions[ts.start];  			} -			startsegx = ll->positions[startseg + ts.length];  		}  		// Small hack to make lines that end with italics not cut off the edge of the last character -		if ((startseg > 0) && lastSegItalics) { -			ll->positions[startseg] += lastSegItalicsOffset; +		if (lastSegItalics) { +			ll->positions[numCharsInLine] += lastSegItalicsOffset;  		}  		ll->numCharsInLine = numCharsInLine;  		ll->numCharsBeforeEOL = numCharsBeforeEOL; @@ -2821,6 +2809,11 @@ void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int x  void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,          PRectangle rcLine, LineLayout *ll, int subLine) { +	if (subLine >= ll->lines) { +		DrawAnnotation(surface, vsDraw, line, xStart, rcLine, ll, subLine); +		return; // No further drawing +	} +  	PRectangle rcSegment = rcLine;  	// Using one font for all control characters so it can be controlled independently to ensure @@ -2867,21 +2860,17 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  		}  	} -	bool drawWhitespaceBackground = (vsDraw.viewWhitespace != wsInvisible) && +	const bool drawWhitespaceBackground = (vsDraw.viewWhitespace != wsInvisible) &&  	        (!overrideBackground) && (vsDraw.whitespaceBackgroundSet);  	bool inIndentation = subLine == 0;	// Do not handle indentation except on first subline.  	const XYPOSITION indentWidth = pdoc->IndentSize() * vsDraw.spaceWidth;  	const XYPOSITION epsilon = 0.0001f;	// A small nudge to avoid floating point precision issues -	int posLineStart = pdoc->LineStart(line); +	const int posLineStart = pdoc->LineStart(line); -	int startseg = ll->LineStart(subLine); -	XYACCUMULATOR subLineStart = ll->positions[startseg]; -	if (subLine >= ll->lines) { -		DrawAnnotation(surface, vsDraw, line, xStart, rcLine, ll, subLine); -		return; // No further drawing -	} +	const int startseg = ll->LineStart(subLine); +	const XYACCUMULATOR subLineStart = ll->positions[startseg];  	int lineStart = 0;  	int lineEnd = 0;  	if (subLine < ll->lines) { @@ -2892,9 +2881,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  		}  	} -	ColourDesired wrapColour = vsDraw.styles[STYLE_DEFAULT].fore; -	if (vsDraw.whitespaceForegroundSet) -		wrapColour = vsDraw.whitespaceForeground; +	const ColourDesired wrapColour = vsDraw.WrapColour();  	bool drawWrapMarkEnd = false; @@ -2941,76 +2928,76 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  		}  	} -	bool selBackDrawn = vsDraw.selbackset && +	const bool selBackDrawn = vsDraw.selbackset &&  		((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA));  	// Does not take margin into account but not significant -	int xStartVisible = static_cast<int>(subLineStart) - xStart; +	const int xStartVisible = static_cast<int>(subLineStart) - xStart;  	ll->psel = &sel; -	BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, xStartVisible, selBackDrawn, pdoc, &reprs); - -	// Background drawing loop -	while (twoPhaseDraw && bfBack.More()) { - -		TextSegment ts = bfBack.Next(); -		startseg = ts.start; -		int i = ts.start + ts.length - 1; -		int iDoc = i + posLineStart; - -		rcSegment.left = ll->positions[startseg] + xStart - subLineStart; -		rcSegment.right = ll->positions[i + 1] + xStart - subLineStart; -		// Only try to draw if really visible - enhances performance by not calling environment to -		// draw strings that are completely past the right side of the window. -		if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { -			// Clip to line rectangle, since may have a huge position which will not work with some platforms -			if (rcSegment.left < rcLine.left) -				rcSegment.left = rcLine.left; -			if (rcSegment.right > rcLine.right) -				rcSegment.right = rcLine.right; - -			int styleMain = ll->styles[i]; -			const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc); -			bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); -			ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll); -			if (ll->chars[i] == '\t') { -				// Tab display -				if (drawWhitespaceBackground && -				        (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) -					textBack = vsDraw.whitespaceBackground; -				surface->FillRectangle(rcSegment, textBack); -			} else if (IsControlCharacter(ll->chars[i])) { -				// Control character display -				inIndentation = false; -				surface->FillRectangle(rcSegment, textBack); -			} else { -				// Normal text display -				surface->FillRectangle(rcSegment, textBack); -				if (vsDraw.viewWhitespace != wsInvisible || -				        (inIndentation && vsDraw.viewIndentationGuides == ivReal)) { -					for (int cpos = 0; cpos <= i - startseg; cpos++) { -						if (ll->chars[cpos + startseg] == ' ') { -							if (drawWhitespaceBackground && -							        (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { -								PRectangle rcSpace(ll->positions[cpos + startseg] + xStart - subLineStart, -									rcSegment.top, -									ll->positions[cpos + startseg + 1] + xStart - subLineStart, -									rcSegment.bottom); -								surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground); +	if (twoPhaseDraw) { +		BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, xStartVisible, selBackDrawn, pdoc, &reprs); + +		// Background drawing loop +		while (bfBack.More()) { + +			const TextSegment ts = bfBack.Next(); +			const int i = ts.end() - 1; +			const int iDoc = i + posLineStart; + +			rcSegment.left = ll->positions[ts.start] + xStart - subLineStart; +			rcSegment.right = ll->positions[ts.end()] + xStart - subLineStart; +			// Only try to draw if really visible - enhances performance by not calling environment to +			// draw strings that are completely past the right side of the window. +			if (rcSegment.Intersects(rcLine)) { +				// Clip to line rectangle, since may have a huge position which will not work with some platforms +				if (rcSegment.left < rcLine.left) +					rcSegment.left = rcLine.left; +				if (rcSegment.right > rcLine.right) +					rcSegment.right = rcLine.right; + +				const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc); +				const bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); +				ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, +					inHotspot, ll->styles[i], i, ll); +				if (ts.representation) { +					if (ll->chars[i] == '\t') { +						// Tab display +						if (drawWhitespaceBackground && +								(!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) +							textBack = vsDraw.whitespaceBackground; +					} else { +						// Blob display +						inIndentation = false; +					} +					surface->FillRectangle(rcSegment, textBack); +				} else { +					// Normal text display +					surface->FillRectangle(rcSegment, textBack); +					if (vsDraw.viewWhitespace != wsInvisible || +							(inIndentation && vsDraw.viewIndentationGuides == ivReal)) { +						for (int cpos = 0; cpos <= i - ts.start; cpos++) { +							if (ll->chars[cpos + ts.start] == ' ') { +								if (drawWhitespaceBackground && +										(!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { +									PRectangle rcSpace(ll->positions[cpos + ts.start] + xStart - subLineStart, +										rcSegment.top, +										ll->positions[cpos + ts.start + 1] + xStart - subLineStart, +										rcSegment.bottom); +									surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground); +								} +							} else { +								inIndentation = false;  							} -						} else { -							inIndentation = false;  						}  					}  				} +			} else if (rcSegment.left > rcLine.right) { +				break;  			} -		} else if (rcSegment.left > rcLine.right) { -			break;  		} -	} -	if (twoPhaseDraw) {  		DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd,  		        xStart, subLine, subLineStart, overrideBackground, background,  		        drawWrapMarkEnd, wrapColour); @@ -3047,16 +3034,15 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  	while (bfFore.More()) { -		TextSegment ts = bfFore.Next(); -		startseg = ts.start; -		int i = ts.start + ts.length - 1; -		int iDoc = i + posLineStart; +		const TextSegment ts = bfFore.Next(); +		const int i = ts.end() - 1; +		const int iDoc = i + posLineStart; -		rcSegment.left = ll->positions[startseg] + xStart - subLineStart; -		rcSegment.right = ll->positions[i + 1] + xStart - subLineStart; +		rcSegment.left = ll->positions[ts.start] + xStart - subLineStart; +		rcSegment.right = ll->positions[ts.end()] + xStart - subLineStart;  		// Only try to draw if really visible - enhances performance by not calling environment to  		// draw strings that are completely past the right side of the window. -		if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { +		if (rcSegment.Intersects(rcLine)) {  			int styleMain = ll->styles[i];  			ColourDesired textFore = vsDraw.styles[styleMain].fore;  			Font &textFont = vsDraw.styles[styleMain].font; @@ -3069,75 +3055,77 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  			if (inSelection && (vsDraw.selforeset)) {  				textFore = (inSelection == 1) ? vsDraw.selforeground : vsDraw.selAdditionalForeground;  			} -			bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); +			const bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);  			ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll); -			if (ll->chars[i] == '\t') { -				// Tab display -				if (!twoPhaseDraw) { -					if (drawWhitespaceBackground && -					        (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) -						textBack = vsDraw.whitespaceBackground; -					surface->FillRectangle(rcSegment, textBack); -				} -				if (inIndentation && vsDraw.viewIndentationGuides == ivReal) { -					for (int indentCount = (ll->positions[i] + epsilon) / indentWidth; -						indentCount <= (ll->positions[i + 1] - epsilon) / indentWidth; -						indentCount++) { -						if (indentCount > 0) { -							int xIndent = indentCount * indentWidth; -							DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment, -								    (ll->xHighlightGuide == xIndent)); +			if (ts.representation) { +				if (ll->chars[i] == '\t') { +					// Tab display +					if (!twoPhaseDraw) { +						if (drawWhitespaceBackground && +								(!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) +							textBack = vsDraw.whitespaceBackground; +						surface->FillRectangle(rcSegment, textBack); +					} +					if (inIndentation && vsDraw.viewIndentationGuides == ivReal) { +						for (int indentCount = (ll->positions[i] + epsilon) / indentWidth; +							indentCount <= (ll->positions[i + 1] - epsilon) / indentWidth; +							indentCount++) { +							if (indentCount > 0) { +								int xIndent = indentCount * indentWidth; +								DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment, +										(ll->xHighlightGuide == xIndent)); +							}  						}  					} -				} -				if (vsDraw.viewWhitespace != wsInvisible) { -					if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { -						if (vsDraw.whitespaceForegroundSet) -							textFore = vsDraw.whitespaceForeground; -						surface->PenColour(textFore); -						PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, -						        rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); -						DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); +					if (vsDraw.viewWhitespace != wsInvisible) { +						if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { +							if (vsDraw.whitespaceForegroundSet) +								textFore = vsDraw.whitespaceForeground; +							surface->PenColour(textFore); +							PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, +									rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); +							DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); +						}  					} -				} -			} else if (ts.repr) { -				inIndentation = false; -				if (controlCharSymbol < 32) { -					DrawTextBlob(surface, vsDraw, rcSegment, ts.repr->stringRep.c_str(), textBack, textFore, twoPhaseDraw);  				} else { -					char cc[2] = { static_cast<char>(controlCharSymbol), '\0' }; -					surface->DrawTextNoClip(rcSegment, ctrlCharsFont, -					        rcSegment.top + vsDraw.maxAscent, -					        cc, 1, textBack, textFore); +					inIndentation = false; +					if (vsDraw.controlCharSymbol >= 32) { +						char cc[2] = { static_cast<char>(vsDraw.controlCharSymbol), '\0' }; +						surface->DrawTextNoClip(rcSegment, ctrlCharsFont, +								rcSegment.top + vsDraw.maxAscent, +								cc, 1, textBack, textFore); +					} else { +						DrawTextBlob(surface, vsDraw, rcSegment, ts.representation->stringRep.c_str(), textBack, textFore, twoPhaseDraw); +					}  				}  			} else {  				// Normal text display  				if (vsDraw.styles[styleMain].visible) {  					if (twoPhaseDraw) {  						surface->DrawTextTransparent(rcSegment, textFont, -						        rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, -						        i - startseg + 1, textFore); +						        rcSegment.top + vsDraw.maxAscent, ll->chars + ts.start, +						        i - ts.start + 1, textFore);  					} else {  						surface->DrawTextNoClip(rcSegment, textFont, -						        rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, -						        i - startseg + 1, textFore, textBack); +						        rcSegment.top + vsDraw.maxAscent, ll->chars + ts.start, +						        i - ts.start + 1, textFore, textBack);  					}  				}  				if (vsDraw.viewWhitespace != wsInvisible ||  				        (inIndentation && vsDraw.viewIndentationGuides != ivNone)) { -					for (int cpos = 0; cpos <= i - startseg; cpos++) { -						if (ll->chars[cpos + startseg] == ' ') { +					for (int cpos = 0; cpos <= i - ts.start; cpos++) { +						if (ll->chars[cpos + ts.start] == ' ') {  							if (vsDraw.viewWhitespace != wsInvisible) {  								if (vsDraw.whitespaceForegroundSet)  									textFore = vsDraw.whitespaceForeground;  								if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { -									XYPOSITION xmid = (ll->positions[cpos + startseg] + ll->positions[cpos + startseg + 1]) / 2; +									XYPOSITION xmid = (ll->positions[cpos + ts.start] + ll->positions[cpos + ts.start + 1]) / 2;  									if (!twoPhaseDraw && drawWhitespaceBackground &&  									        (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) {  										textBack = vsDraw.whitespaceBackground; -										PRectangle rcSpace(ll->positions[cpos + startseg] + xStart - subLineStart, +										PRectangle rcSpace(ll->positions[cpos + ts.start] + xStart - subLineStart,  											rcSegment.top, -											ll->positions[cpos + startseg + 1] + xStart - subLineStart, +											ll->positions[cpos + ts.start + 1] + xStart - subLineStart,  											rcSegment.bottom);  										surface->FillRectangle(rcSpace, textBack);  									} @@ -3148,8 +3136,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  								}  							}  							if (inIndentation && vsDraw.viewIndentationGuides == ivReal) { -								for (int indentCount = (ll->positions[cpos + startseg] + epsilon) / indentWidth; -									indentCount <= (ll->positions[cpos + startseg + 1] - epsilon) / indentWidth; +								for (int indentCount = (ll->positions[cpos + ts.start] + epsilon) / indentWidth; +									indentCount <= (ll->positions[cpos + ts.start + 1] - epsilon) / indentWidth;  									indentCount++) {  									if (indentCount > 0) {  										int xIndent = indentCount * indentWidth; @@ -3854,14 +3842,14 @@ long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {  	vsPrint.leftMarginWidth = 0;  	vsPrint.rightMarginWidth = 0; -	vsPrint.Refresh(*surfaceMeasure); +	vsPrint.Refresh(*surfaceMeasure, pdoc->tabInChars);  	// Determining width must hapen after fonts have been realised in Refresh  	int lineNumberWidth = 0;  	if (lineNumberIndex >= 0) {  		lineNumberWidth = surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font,  		        "99999" lineNumberPrintSpace, 5 + istrlen(lineNumberPrintSpace));  		vsPrint.ms[lineNumberIndex].width = lineNumberWidth; -		vsPrint.Refresh(*surfaceMeasure);	// Recalculate fixedColumnWidth +		vsPrint.Refresh(*surfaceMeasure, pdoc->tabInChars);	// Recalculate fixedColumnWidth  	}  	int linePrintStart = pdoc->LineFromPosition(pfr->chrg.cpMin); @@ -9173,11 +9161,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {  		return cursorMode;  	case SCI_SETCONTROLCHARSYMBOL: -		controlCharSymbol = wParam; +		vs.controlCharSymbol = wParam; +		InvalidateStyleRedraw();  		break;  	case SCI_GETCONTROLCHARSYMBOL: -		return controlCharSymbol; +		return vs.controlCharSymbol;  	case SCI_SETREPRESENTATION:  		reprs.SetRepresentation(reinterpret_cast<const char *>(wParam), CharPtrFromSPtr(lParam)); diff --git a/src/Editor.h b/src/Editor.h index 52d38afc4..1a74a86db 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -186,7 +186,6 @@ protected:	// ScintillaBase subclass needs access to much of Editor  	int printColourMode;  	int printWrapState;  	int cursorMode; -	int controlCharSymbol;  	// Highlight current folding block  	HighlightDelimiter highlightDelimiter; diff --git a/src/PositionCache.h b/src/PositionCache.h index a0b805743..6d14cf0a3 100644 --- a/src/PositionCache.h +++ b/src/PositionCache.h @@ -137,9 +137,12 @@ public:  struct TextSegment {  	int start;  	int length; -	Representation *repr; -	TextSegment(int start_=0, int length_=0, Representation *repr_=0) : -		start(start_), length(length_), repr(repr_) { +	Representation *representation; +	TextSegment(int start_=0, int length_=0, Representation *representation_=0) : +		start(start_), length(length_), representation(representation_) { +	} +	int end() const { +		return start + length;  	}  }; diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx index 8d2a60e14..2c2ac0e66 100644 --- a/src/ViewStyle.cxx +++ b/src/ViewStyle.cxx @@ -131,6 +131,8 @@ ViewStyle::ViewStyle(const ViewStyle &source) {  	whitespaceForeground = source.whitespaceForeground;  	whitespaceBackgroundSet = source.whitespaceBackgroundSet;  	whitespaceBackground = source.whitespaceBackground; +	controlCharSymbol = source.controlCharSymbol; +	controlCharWidth = source.controlCharWidth;  	selbar = source.selbar;  	selbarlight = source.selbarlight;  	caretcolour = source.caretcolour; @@ -204,6 +206,7 @@ void ViewStyle::Init(size_t stylesSize_) {  	maxDescent = 1;  	aveCharWidth = 8;  	spaceWidth = 8; +	tabWidth = spaceWidth * 8;  	selforeset = false;  	selforeground = ColourDesired(0xff, 0, 0); @@ -225,6 +228,8 @@ void ViewStyle::Init(size_t stylesSize_) {  	whitespaceForeground = ColourDesired(0, 0, 0);  	whitespaceBackgroundSet = false;  	whitespaceBackground = ColourDesired(0xff, 0xff, 0xff); +	controlCharSymbol = 0;	/* Draw the control characters */ +	controlCharWidth = 0;  	selbar = Platform::Chrome();  	selbarlight = Platform::ChromeHighlight();  	styles[STYLE_LINENUMBER].fore = ColourDesired(0, 0, 0); @@ -286,7 +291,7 @@ void ViewStyle::Init(size_t stylesSize_) {  	braceBadLightIndicator = 0;  } -void ViewStyle::Refresh(Surface &surface) { +void ViewStyle::Refresh(Surface &surface, int tabInChars) {  	for (FontMap::iterator it = fonts.begin(); it != fonts.end(); ++it) {  		delete it->second;  	} @@ -332,6 +337,12 @@ void ViewStyle::Refresh(Surface &surface) {  	aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;  	spaceWidth = styles[STYLE_DEFAULT].spaceWidth; +	tabWidth = spaceWidth * tabInChars; + +	controlCharWidth = 0.0; +	if (controlCharSymbol >= 32) { +		controlCharWidth = surface.WidthChar(styles[STYLE_CONTROLCHAR].font, controlCharSymbol); +	}  	fixedColumnWidth = marginInside ? leftMarginWidth : 0;  	maskInLine = 0xffffffff; @@ -409,6 +420,13 @@ void ViewStyle::CalcLargestMarkerHeight() {  	}  } +ColourDesired ViewStyle::WrapColour() const { +	if (whitespaceForegroundSet) +		return whitespaceForeground; +	else +		return styles[STYLE_DEFAULT].fore; +} +  void ViewStyle::AllocStyles(size_t sizeNew) {  	size_t i=styles.size();  	styles.resize(sizeNew); diff --git a/src/ViewStyle.h b/src/ViewStyle.h index 5593c0b47..8a05cd393 100644 --- a/src/ViewStyle.h +++ b/src/ViewStyle.h @@ -73,6 +73,7 @@ public:  	unsigned int maxDescent;  	XYPOSITION aveCharWidth;  	XYPOSITION spaceWidth; +	XYPOSITION tabWidth;  	bool selforeset;  	ColourDesired selforeground;  	ColourDesired selAdditionalForeground; @@ -87,6 +88,8 @@ public:  	ColourDesired whitespaceForeground;  	bool whitespaceBackgroundSet;  	ColourDesired whitespaceBackground; +	int controlCharSymbol; +	XYPOSITION controlCharWidth;  	ColourDesired selbar;  	ColourDesired selbarlight;  	bool foldmarginColourSet; @@ -139,7 +142,7 @@ public:  	ViewStyle(const ViewStyle &source);  	~ViewStyle();  	void Init(size_t stylesSize_=64); -	void Refresh(Surface &surface); +	void Refresh(Surface &surface, int tabInChars);  	void ReleaseAllExtendedStyles();  	int AllocateExtendedStyles(int numberStyles);  	void EnsureStyle(size_t index); @@ -149,6 +152,8 @@ public:  	bool ProtectionActive() const;  	bool ValidStyle(size_t styleIndex) const;  	void CalcLargestMarkerHeight(); +	ColourDesired WrapColour() const; +  private:  	void AllocStyles(size_t sizeNew);  	void CreateFont(const FontSpecification &fs); | 
