diff options
| -rw-r--r-- | src/Editor.cxx | 64 | ||||
| -rw-r--r-- | src/Editor.h | 1 | 
2 files changed, 41 insertions, 24 deletions
| diff --git a/src/Editor.cxx b/src/Editor.cxx index 21184d387..f748bacc1 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -85,6 +85,7 @@ LineLayout::LineLayout(int maxLineLength_) :  	edgeColumn(0),  	chars(0),  	styles(0), +	styleBitsSet(0),  	indicators(0),  	positions(0),  	hsStart(0), @@ -1929,39 +1930,39 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou  		posLineEnd = posLineStart + ll->maxLineLength;  	}  	if (ll->validity == LineLayout::llCheckTextAndStyle) { -		int lineLength = 0; -		for (int cid = posLineStart; cid < posLineEnd; cid++) { -			char chDoc = pdoc->CharAt(cid); -			if (vstyle.viewEOL || (!IsEOLChar(chDoc))) { -				lineLength++; +		int lineLength = posLineEnd - posLineStart; +		if (!vstyle.viewEOL) { +			int cid = posLineEnd - 1; +			while ((cid > posLineStart) && IsEOLChar(pdoc->CharAt(cid))) { +				cid--; +				lineLength--;  			}  		}  		if (lineLength == ll->numCharsInLine) { -			int numCharsInLine = 0;  			// See if chars, styles, indicators, are all the same  			bool allSame = true;  			const int styleMask = pdoc->stylingBitsMask;  			// Check base line layout  			char styleByte = 0; -			for (int charInDoc = posLineStart; allSame && (charInDoc < posLineEnd); charInDoc++) { +			int numCharsInLine = 0; +			while (numCharsInLine < lineLength) { +				int charInDoc = numCharsInLine + posLineStart;  				char chDoc = pdoc->CharAt(charInDoc);  				styleByte = pdoc->StyleAt(charInDoc); -				if (vstyle.viewEOL || (!IsEOLChar(chDoc))) { +				allSame = allSame && +					        (ll->styles[numCharsInLine] == static_cast<unsigned char>(styleByte & styleMask)); +				allSame = allSame && +					        (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask)); +				if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed)  					allSame = allSame && -					          (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask)); +						        (ll->chars[numCharsInLine] == chDoc); +				else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)  					allSame = allSame && -					          (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask)); -					if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper) -						allSame = allSame && -						          (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc))); -					else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower) -						allSame = allSame && -						          (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc))); -					else -						allSame = allSame && -						          (ll->chars[numCharsInLine] == chDoc); -					numCharsInLine++; -				} +						        (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc))); +				else	// Style::caseUpper +					allSame = allSame && +						        (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc))); +				numCharsInLine++;  			}  			allSame = allSame && (ll->styles[numCharsInLine] == styleByte);	// For eolFilled  			if (allSame) { @@ -1988,10 +1989,12 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou  		char styleByte = 0;  		int styleMask = pdoc->stylingBitsMask; +		ll->styleBitsSet = 0;  		// Fill base line layout  		for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) {  			char chDoc = pdoc->CharAt(charInDoc);  			styleByte = pdoc->StyleAt(charInDoc); +			ll->styleBitsSet |= styleByte;  			if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {  				ll->chars[numCharsInLine] = chDoc;  				ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask); @@ -2018,6 +2021,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou  		bool lastSegItalics = false;  		Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font; +		int ctrlCharWidth[32] = {0};  		bool isControlNext = IsControlCharacter(ll->chars[0]);  		for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) {  			bool isControl = isControlNext; @@ -2031,9 +2035,13 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou  							ll->positions[charInLine + 1] = ((((startsegx + 2) /  							                                   tabWidth) + 1) * tabWidth) - startsegx;  						} else if (controlCharSymbol < 32) { -							const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]); -							// +3 For a blank on front and rounded edge each side: -							ll->positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3; +							if (ctrlCharWidth[ll->chars[charInLine]] == 0) { +								const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]); +								// +3 For a blank on front and rounded edge each side: +								ctrlCharWidth[ll->chars[charInLine]] = +									surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3; +							} +							ll->positions[charInLine + 1] = ctrlCharWidth[ll->chars[charInLine]];  						} else {  							char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };  							surface->MeasureWidths(ctrlCharsFont, cc, 1, @@ -2422,6 +2430,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  						}  					}  				} +			} else if (rcSegment.left > rcLine.right) { +				break;  			}  			startseg = i + 1;  		} @@ -2584,6 +2594,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  					rcUL.bottom = rcUL.top + 1;  					surface->FillRectangle(rcUL, textFore);  				} +			} else if (rcSegment.left > rcLine.right) { +				break;  			}  			startseg = i + 1;  		} @@ -2592,6 +2604,10 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  	// Draw indicators  	// foreach indicator...  	for (int indicnum = 0, mask = 1 << pdoc->stylingBits; mask < 0x100; indicnum++) { +		if (!(mask & ll->styleBitsSet)) { +			mask <<= 1; +			continue; +		}  		int startPos = -1;  		// foreach style pos in line...  		for (int indicPos = lineStart; indicPos <= lineEnd; indicPos++) { diff --git a/src/Editor.h b/src/Editor.h index 5370f5b2e..f779e21cc 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -64,6 +64,7 @@ public:  	int edgeColumn;  	char *chars;  	unsigned char *styles; +	int styleBitsSet;  	char *indicators;  	int *positions;  	char bracePreviousStyles[2]; | 
