From 10cf4beef4d7293d6d382fe4b3216da48fa87fa1 Mon Sep 17 00:00:00 2001 From: nyamatongwe Date: Sat, 25 Sep 2010 18:02:59 +1000 Subject: Optimization of line layout by minimizing calls in Editor::LayoutLine and avoiding case force processing unless at least one style uses a case force option. --- src/CellBuffer.cxx | 13 +++++++++++++ src/CellBuffer.h | 1 + src/Document.h | 3 +++ src/Editor.cxx | 38 +++++++++++++++++++++----------------- src/ViewStyle.cxx | 6 ++++++ src/ViewStyle.h | 1 + 6 files changed, 45 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx index de1605837..19f6670f6 100644 --- a/src/CellBuffer.cxx +++ b/src/CellBuffer.cxx @@ -358,6 +358,19 @@ char CellBuffer::StyleAt(int position) const { return style.ValueAt(position); } +void CellBuffer::GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const { + if (lengthRetrieve < 0) + return; + if (position < 0) + return; + if ((position + lengthRetrieve) > style.Length()) { + Platform::DebugPrintf("Bad GetStyleRange %d for %d of %d\n", position, + lengthRetrieve, style.Length()); + return; + } + style.GetRange(reinterpret_cast(buffer), position, lengthRetrieve); +} + const char *CellBuffer::BufferPointer() { return substance.BufferPointer(); } diff --git a/src/CellBuffer.h b/src/CellBuffer.h index d485695a9..a82a3973b 100644 --- a/src/CellBuffer.h +++ b/src/CellBuffer.h @@ -155,6 +155,7 @@ public: char CharAt(int position) const; void GetCharRange(char *buffer, int position, int lengthRetrieve) const; char StyleAt(int position) const; + void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const; const char *BufferPointer(); int Length() const; diff --git a/src/Document.h b/src/Document.h index d58c5efe5..78f00a766 100644 --- a/src/Document.h +++ b/src/Document.h @@ -278,6 +278,9 @@ public: cb.GetCharRange(buffer, position, lengthRetrieve); } char SCI_METHOD StyleAt(int position) const { return cb.StyleAt(position); } + void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const { + cb.GetStyleRange(buffer, position, lengthRetrieve); + } int GetMark(int line); int AddMark(int line, int markerNum); void AddMarkSet(int line, int valueSet); diff --git a/src/Editor.cxx b/src/Editor.cxx index bca458037..836f3919a 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -2022,8 +2022,6 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou if (ll->validity == LineLayout::llInvalid) { ll->widthLine = LineLayout::wrapWidthInfinite; ll->lines = 1; - int numCharsInLine = 0; - int numCharsBeforeEOL = 0; if (vstyle.edgeState == EDGE_BACKGROUND) { ll->edgeColumn = pdoc->FindColumn(line, theEdge); if (ll->edgeColumn >= posLineStart) { @@ -2034,24 +2032,30 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou } char styleByte = 0; - int styleMask = pdoc->stylingBitsMask; + const 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); + const int lineLength = posLineEnd - posLineStart; + pdoc->GetCharRange(ll->chars, posLineStart, lineLength); + pdoc->GetStyleRange(ll->styles, posLineStart, lineLength); + int numCharsBeforeEOL = lineLength; + while ((numCharsBeforeEOL > 0) && IsEOLChar(ll->chars[numCharsBeforeEOL-1])) { + numCharsBeforeEOL--; + } + const int numCharsInLine = (vstyle.viewEOL) ? lineLength : numCharsBeforeEOL; + for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) { + styleByte = ll->styles[charInLine]; ll->styleBitsSet |= styleByte; - if (vstyle.viewEOL || (!IsEOLChar(chDoc))) { - ll->chars[numCharsInLine] = chDoc; - ll->styles[numCharsInLine] = static_cast(styleByte & styleMask); - ll->indicators[numCharsInLine] = static_cast(styleByte & ~styleMask); - if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper) - ll->chars[numCharsInLine] = static_cast(toupper(chDoc)); - else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower) - ll->chars[numCharsInLine] = static_cast(tolower(chDoc)); - numCharsInLine++; - if (!IsEOLChar(chDoc)) - numCharsBeforeEOL++; + ll->styles[numCharsInLine] = static_cast(styleByte & styleMask); + ll->indicators[numCharsInLine] = static_cast(styleByte & ~styleMask); + } + if (vstyle.someStylesForceCase) { + for (int charInLine = 0; charInLinechars[charInLine]; + if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseUpper) + ll->chars[charInLine] = static_cast(toupper(chDoc)); + else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseLower) + ll->chars[charInLine] = static_cast(tolower(chDoc)); } } ll->xHighlightGuide = 0; diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx index d29ee8612..1b315d17e 100644 --- a/src/ViewStyle.cxx +++ b/src/ViewStyle.cxx @@ -129,6 +129,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) { caretStyle = source.caretStyle; caretWidth = source.caretWidth; someStylesProtected = false; + someStylesForceCase = false; leftMarginWidth = source.leftMarginWidth; rightMarginWidth = source.rightMarginWidth; for (int i=0; i < margins; i++) { @@ -213,6 +214,7 @@ void ViewStyle::Init(size_t stylesSize_) { caretStyle = CARETSTYLE_LINE; caretWidth = 1; someStylesProtected = false; + someStylesForceCase = false; hotspotForegroundSet = false; hotspotForeground.desired = ColourDesired(0, 0, 0xff); @@ -295,6 +297,7 @@ void ViewStyle::Refresh(Surface &surface) { maxAscent = styles[STYLE_DEFAULT].ascent; maxDescent = styles[STYLE_DEFAULT].descent; someStylesProtected = false; + someStylesForceCase = false; for (unsigned int i=0; i