diff options
author | nyamatongwe <unknown> | 2005-12-04 00:46:47 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2005-12-04 00:46:47 +0000 |
commit | 8a99dc9ffbd5f9fa76ed360b4ca50a20bb17af48 (patch) | |
tree | 176af8a6b311cf4e5aefedf63386d5fd517ce58f /src | |
parent | 4274534092afaf689584347096f6aa847379a623 (diff) | |
download | scintilla-mirror-8a99dc9ffbd5f9fa76ed360b4ca50a20bb17af48.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.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]; |