aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2005-12-04 00:46:47 +0000
committernyamatongwe <devnull@localhost>2005-12-04 00:46:47 +0000
commitb355434c914022ab6a375b7222eabebf691219ed (patch)
tree176af8a6b311cf4e5aefedf63386d5fd517ce58f /src
parent41ababaa126118eb2f8ac892f1f53e172109c7c3 (diff)
downloadscintilla-mirror-b355434c914022ab6a375b7222eabebf691219ed.tar.gz
Optimisations that help for documents with long lines and many
control characters. Set of style bits set maintained in line layout so indicator drawing code can quickly determine if an indicator is drawn at all on a line. Drawing loops exited after reach right hand side of window. Widths of control character symbols cached while laying out line. Small tweaks to avoid overhead inside loops.
Diffstat (limited to 'src')
-rw-r--r--src/Editor.cxx64
-rw-r--r--src/Editor.h1
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];