diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Editor.cxx | 79 | ||||
| -rw-r--r-- | src/Editor.h | 24 | 
2 files changed, 63 insertions, 40 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx index 6bfce655a..cc205feb8 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -32,12 +32,14 @@ active(false), on(false), period(500) {}  Timer::Timer() :  ticking(false), ticksToWait(0), tickerID(0) {} -LineLayout::LineLayout(int maxLineLength_, int maxDisplayLines) : -	validity(llInvalid), -	maxLineLength(-1), +LineLayout::LineLayout(int maxLineLength_) : +	lineStarts(0), +	lenLineStarts(0),  	lineNumber(-1),  	inCache(false), +	maxLineLength(-1),  	numCharsInLine(0), +	validity(llInvalid),  	xHighlightGuide(0),  	highlightColumn(0),  	selStart(0), @@ -49,9 +51,7 @@ LineLayout::LineLayout(int maxLineLength_, int maxDisplayLines) :  	indicators(0),  	positions(0),  	widthLine(0), -	lines(1), -	maxDisplayLines(maxDisplayLines), -	lineStarts(0) { +	lines(1) {  		Resize(maxLineLength_);  } @@ -66,7 +66,6 @@ void LineLayout::Resize(int maxLineLength_) {  		styles = new char[maxLineLength_ + 1];  		indicators = new char[maxLineLength_ + 1];  		positions = new int[maxLineLength_ + 1]; -		lineStarts = new int[maxDisplayLines + 1];  		maxLineLength = maxLineLength_;  	}  } @@ -88,6 +87,25 @@ void LineLayout::Invalidate(validLevel validity_) {  	validity = validity_;  } +void LineLayout::SetLineStart(int line, int start) { +	if ((line >= lenLineStarts) && (line != 0)) { +		int newMaxLines = line + 20; +		int *newLineStarts = new int[newMaxLines]; +		if (!newLineStarts)  +			return; +		for (int i=0; i<newMaxLines; i++) { +			if (i < lenLineStarts) +				newLineStarts[i] = lineStarts[i]; +			else +				newLineStarts[i] = 0; +		} +		delete []lineStarts; +		lineStarts = newLineStarts; +		lenLineStarts = newMaxLines; +	} +	lineStarts[line] = start; +} +  LineLayoutCache::LineLayoutCache() :   	level(0), length(0), size(0), cache(0),   	allInvalidated(false), styleClock(-1) { @@ -434,13 +452,13 @@ Point Editor::LocationFromPosition(int pos) {  		int posInLine = pos - posLineStart;  		// In case of very long line put x at arbitrary large position  		if (posInLine > ll->maxLineLength) { -			pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->lineStarts[ll->lines]]; +			pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)];  		}  		for (int subLine=0; subLine<ll->lines; subLine++) { -			if ((posInLine > ll->lineStarts[subLine]) && (posInLine <= ll->lineStarts[subLine+1])) { -				pt.x = ll->positions[posInLine] - ll->positions[ll->lineStarts[subLine]]; +			if ((posInLine > ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine+1))) { +				pt.x = ll->positions[posInLine] - ll->positions[ll->LineStart(subLine)];  			} -			if (posInLine >= ll->lineStarts[subLine]) { +			if (posInLine >= ll->LineStart(subLine)) {  				pt.y += vs.lineHeight;  			}  		} @@ -485,8 +503,8 @@ int Editor::PositionFromLocation(Point pt) {  		int lineStartSet = cs.DisplayFromDoc(lineDoc);  		int subLine = visibleLine - lineStartSet;  		if (subLine < ll->lines) { -			int lineStart = ll->lineStarts[subLine]; -			int lineEnd = ll->lineStarts[subLine+1]; +			int lineStart = ll->LineStart(subLine); +			int lineEnd = ll->LineStart(subLine+1);  			int subLineStart = ll->positions[lineStart];  			for (int i = lineStart; i < lineEnd; i++) {  				if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || @@ -532,8 +550,8 @@ int Editor::PositionFromLocationClose(Point pt) {  		int lineStartSet = cs.DisplayFromDoc(lineDoc);  		int subLine = visibleLine - lineStartSet;  		if (subLine < ll->lines) { -			int lineStart = ll->lineStarts[subLine]; -			int lineEnd = ll->lineStarts[subLine+1]; +			int lineStart = ll->LineStart(subLine); +			int lineEnd = ll->LineStart(subLine+1);  			int subLineStart = ll->positions[lineStart];  			for (int i = lineStart; i < lineEnd; i++) {  				if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || @@ -564,8 +582,8 @@ int Editor::PositionFromLineX(int lineDoc, int x) {  		LayoutLine(lineDoc, surface, vs, ll, wrapWidth);  		retVal = ll->numCharsInLine + posLineStart;  		int subLine = 0; -		int lineStart = ll->lineStarts[subLine]; -		int lineEnd = ll->lineStarts[subLine+1]; +		int lineStart = ll->LineStart(subLine); +		int lineEnd = ll->LineStart(subLine+1);  		int subLineStart = ll->positions[lineStart];  		for (int i = lineStart; i < lineEnd; i++) {  			if (x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || @@ -849,7 +867,7 @@ int Editor::DisplayFromPosition(int pos) {  		int posInLine = pos - posLineStart;  		lineDisplay--; // To make up for first increment ahead.  		for (int subLine=0; subLine<ll->lines; subLine++) { - 			if (posInLine >= ll->lineStarts[subLine]) { + 			if (posInLine >= ll->LineStart(subLine)) {  				lineDisplay++;  			}  		} @@ -1261,7 +1279,6 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou  	if (ll->validity == LineLayout::llInvalid) {  		ll->widthLine = width;  		ll->lines = 1; -		ll->lineStarts[0] = 0;  		int numCharsInLine = 0;  		if (vstyle.edgeState == EDGE_BACKGROUND) {  			ll->edgeColumn = pdoc->FindColumn(line, theEdge); @@ -1361,7 +1378,6 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou  	if (ll->validity == LineLayout::llPositions) {  		if (width == wrapWidthInfinite) {  			ll->lines = 1; -			ll->lineStarts[1] = ll->numCharsInLine;  			ll->widthLine = ll->positions[ll->numCharsInLine];  		} else {  			if (width < 20)	{ // Hard to cope when too narrow, so just assume there is space @@ -1391,12 +1407,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou  						}  					}  					lastLineStart = lastGoodBreak; -					if (ll->lines < ll->maxDisplayLines - 2) { -						ll->lines++; -						ll->lineStarts[ll->lines] = lastGoodBreak; -					} else { -						break; -					} +					ll->lines++; +					ll->SetLineStart(ll->lines, lastGoodBreak);  					startOffset = ll->positions[lastGoodBreak];  					p = lastGoodBreak + 1;  					continue; @@ -1411,7 +1423,6 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou  				p++;  			}  			ll->lines++; -			ll->lineStarts[ll->lines] = ll->numCharsInLine;  		}  		ll->validity = LineLayout::llLines;  	} @@ -1472,13 +1483,13 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis  	int posLineEnd = pdoc->LineStart(line + 1);  	int styleMask = pdoc->stylingBitsMask; -	int startseg = ll->lineStarts[subLine]; +	int startseg = ll->LineStart(subLine);  	int subLineStart = ll->positions[startseg];  	int lineStart = 0;  	int lineEnd = 0;  	if (subLine < ll->lines) { -		lineStart = ll->lineStarts[subLine]; -		lineEnd = ll->lineStarts[subLine+1]; +		lineStart = ll->LineStart(subLine); +		lineEnd = ll->LineStart(subLine+1);  	}  	for (int i = lineStart; i < lineEnd; i++) { @@ -1891,9 +1902,9 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {  				// Draw the Caret  				if (lineDoc == lineCaret) {  					int offset = Platform::Minimum(posCaret - posLineStart, ll->maxLineLength); -					if ((offset >= ll->lineStarts[subLine]) && -						((offset < ll->lineStarts[subLine+1]) || offset == ll->numCharsInLine)) { -						int xposCaret = ll->positions[offset] - ll->positions[ll->lineStarts[subLine]] + xStart; +					if ((offset >= ll->LineStart(subLine)) && +						((offset < ll->LineStart(subLine+1)) || offset == ll->numCharsInLine)) { +						int xposCaret = ll->positions[offset] - ll->positions[ll->LineStart(subLine)] + xStart;  						int widthOverstrikeCaret;  						if (posCaret == pdoc->Length())	{   // At end of document  							widthOverstrikeCaret = vs.aveCharWidth; @@ -2086,7 +2097,7 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {  			// Copy this line and its styles from the document into local arrays  			// and determine the x position at which each character starts. -			LineLayout ll; +			LineLayout ll(8000);  			LayoutLine(line, surfaceMeasure, vsPrint, &ll);  			ll.selStart = -1;  			ll.selEnd = -1; diff --git a/src/Editor.h b/src/Editor.h index a7047ef14..1056a95bb 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -34,13 +34,17 @@ public:  /**   */  class LineLayout { -public: -	enum validLevel { llInvalid, llPositions, llLines } validity; +private: +	friend class LineLayoutCache; +	int *lineStarts; +	int lenLineStarts;  	/// Drawing is only performed for @a maxLineLength characters on each line. -	int maxLineLength;  	int lineNumber;  	bool inCache; +public: +	int maxLineLength;  	int numCharsInLine; +	enum validLevel { llInvalid, llPositions, llLines } validity;  	int xHighlightGuide;  	bool highlightColumn;  	int selStart; @@ -55,14 +59,22 @@ public:  	// Wrapped line support  	int widthLine;  	int lines; -	int maxDisplayLines; -	int *lineStarts; -	LineLayout(int maxLineLength_ = 8000, int maxDisplayLines=100); +	LineLayout(int maxLineLength_);  	virtual ~LineLayout();  	void Resize(int maxLineLength_);  	void Free();  	void Invalidate(validLevel validity_); +	int LineStart(int line) { +		if (line <= 0) { +			return 0; +		} else if ((line >= lines) || !lineStarts) { +			return numCharsInLine; +		} else { +			return lineStarts[line]; +		} +	} +	void SetLineStart(int line, int start);  };  /**  | 
