diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ContractionState.cxx | 346 | ||||
-rw-r--r-- | src/ContractionState.h | 43 | ||||
-rw-r--r-- | src/Editor.cxx | 6 | ||||
-rw-r--r-- | src/PositionCache.cxx | 6 | ||||
-rw-r--r-- | src/RunStyles.cxx | 5 | ||||
-rw-r--r-- | src/RunStyles.h | 1 | ||||
-rw-r--r-- | src/ScintillaBase.cxx | 4 |
7 files changed, 183 insertions, 228 deletions
diff --git a/src/ContractionState.cxx b/src/ContractionState.cxx index b44b4e742..4e289a155 100644 --- a/src/ContractionState.cxx +++ b/src/ContractionState.cxx @@ -1,293 +1,249 @@ // Scintilla source code edit control /** @file ContractionState.cxx - ** Manages visibility of lines for folding. + ** Manages visibility of lines for folding and wrapping. **/ -// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> +// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. +#include <string.h> + #include "Platform.h" +#include "SplitVector.h" +#include "Partitioning.h" +#include "RunStyles.h" #include "ContractionState.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif -OneLine::OneLine() { - displayLine = 0; - //docLine = 0; - visible = true; - height = 1; - expanded = true; -} - -ContractionState::ContractionState() { - lines = 0; - size = 0; - linesInDoc = 1; - linesInDisplay = 1; - valid = false; - docLines = 0; - sizeDocLines = 0; +ContractionState::ContractionState() : visible(0), expanded(0), heights(0), displayLines(0), linesInDocument(1) { + //InsertLine(0); } ContractionState::~ContractionState() { Clear(); } -void ContractionState::MakeValid() const { - if (!valid) { - // Could be cleverer by keeping the index of the last still valid entry - // rather than invalidating all. - linesInDisplay = 0; - for (int lineInDoc=0; lineInDoc<linesInDoc; lineInDoc++) { - lines[lineInDoc].displayLine = linesInDisplay; - if (lines[lineInDoc].visible) { - linesInDisplay += lines[lineInDoc].height; - } - } - if (sizeDocLines < linesInDisplay) { - delete []docLines; - int *docLinesNew = new int[linesInDisplay + growSize]; - if (!docLinesNew) { - docLines = 0; - sizeDocLines = 0; - return; - } - docLines = docLinesNew; - sizeDocLines = linesInDisplay + growSize; - } - - int lineInDisplay=0; - for (int line=0; line<linesInDoc; line++) { - if (lines[line].visible) { - for (int linePiece=0; linePiece<lines[line].height; linePiece++) { - docLines[lineInDisplay] = line; - lineInDisplay++; - } - } - } - valid = true; +void ContractionState::EnsureData() { + if (OneToOne()) { + visible = new RunStyles(); + expanded = new RunStyles(); + heights = new RunStyles(); + displayLines = new Partitioning(4); + InsertLines(0, linesInDocument); } } void ContractionState::Clear() { - delete []lines; - lines = 0; - size = 0; - linesInDoc = 1; - linesInDisplay = 1; - delete []docLines; - docLines = 0; - sizeDocLines = 0; + delete visible; + visible = 0; + delete expanded; + expanded = 0; + delete heights; + heights = 0; + delete displayLines; + displayLines = 0; + linesInDocument = 1; } int ContractionState::LinesInDoc() const { - return linesInDoc; + if (OneToOne()) { + return linesInDocument; + } else { + return displayLines->Partitions() - 1; + } } int ContractionState::LinesDisplayed() const { - if (size != 0) { - MakeValid(); + if (OneToOne()) { + return linesInDocument; + } else { + return displayLines->PositionFromPartition(LinesInDoc()); } - return linesInDisplay; } int ContractionState::DisplayFromDoc(int lineDoc) const { - if (size == 0) { + if (OneToOne()) { return lineDoc; + } else { + if (lineDoc > displayLines->Partitions()) + lineDoc = displayLines->Partitions(); + return displayLines->PositionFromPartition(lineDoc); } - MakeValid(); - if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { - return lines[lineDoc].displayLine; - } - return -1; } int ContractionState::DocFromDisplay(int lineDisplay) const { - if (lineDisplay <= 0) - return 0; - if (lineDisplay >= linesInDisplay) - return linesInDoc; - if (size == 0) + if (OneToOne()) { return lineDisplay; - MakeValid(); - if (docLines) { // Valid allocation - return docLines[lineDisplay]; } else { - return 0; + if (lineDisplay <= 0) { + return 0; + } + if (lineDisplay > LinesDisplayed()) { + return displayLines->PartitionFromPosition(LinesDisplayed()); + } + int lineDoc = displayLines->PartitionFromPosition(lineDisplay); + PLATFORM_ASSERT(GetVisible(lineDoc)); + return lineDoc; } } -void ContractionState::Grow(int sizeNew) { - OneLine *linesNew = new OneLine[sizeNew]; - if (linesNew) { - int i = 0; - for (; i < size; i++) { - linesNew[i] = lines[i]; - } - for (; i < sizeNew; i++) { - linesNew[i].displayLine = i; - } - delete []lines; - lines = linesNew; - size = sizeNew; - valid = false; +void ContractionState::InsertLine(int lineDoc) { + if (OneToOne()) { + linesInDocument++; } else { - Platform::DebugPrintf("No memory available\n"); - // TODO: Blow up + visible->InsertSpace(lineDoc, 1); + visible->SetValueAt(lineDoc, 1); + expanded->InsertSpace(lineDoc, 1); + expanded->SetValueAt(lineDoc, 1); + heights->InsertSpace(lineDoc, 1); + heights->SetValueAt(lineDoc, 1); + int lineDisplay = DisplayFromDoc(lineDoc); + displayLines->InsertPartition(lineDoc, lineDisplay); + displayLines->InsertText(lineDoc, 1); } } void ContractionState::InsertLines(int lineDoc, int lineCount) { - if (size == 0) { - linesInDoc += lineCount; - linesInDisplay += lineCount; - return; + for (int l = 0; l < lineCount; l++) { + InsertLine(lineDoc + l); } - //Platform::DebugPrintf("InsertLine[%d] = %d\n", lineDoc); - if ((linesInDoc + lineCount + 2) >= size) { - Grow(linesInDoc + lineCount + growSize); - } - linesInDoc += lineCount; - for (int i = linesInDoc; i >= lineDoc + lineCount; i--) { - lines[i].visible = lines[i - lineCount].visible; - lines[i].height = lines[i - lineCount].height; - linesInDisplay += lines[i].height; - lines[i].expanded = lines[i - lineCount].expanded; - } - for (int d=0;d<lineCount;d++) { - lines[lineDoc+d].visible = true; // Should inherit visibility from context ? - lines[lineDoc+d].height = 1; - lines[lineDoc+d].expanded = true; + Check(); +} + +void ContractionState::DeleteLine(int lineDoc) { + if (OneToOne()) { + linesInDocument--; + } else { + if (GetVisible(lineDoc)) { + displayLines->InsertText(lineDoc, -heights->ValueAt(lineDoc)); + } + displayLines->RemovePartition(lineDoc); + visible->DeleteRange(lineDoc, 1); + expanded->DeleteRange(lineDoc, 1); + heights->DeleteRange(lineDoc, 1); } - valid = false; } void ContractionState::DeleteLines(int lineDoc, int lineCount) { - if (size == 0) { - linesInDoc -= lineCount; - linesInDisplay -= lineCount; - return; - } - int deltaDisplayed = 0; - for (int d=0;d<lineCount;d++) { - if (lines[lineDoc+d].visible) - deltaDisplayed -= lines[lineDoc+d].height; + for (int l = 0; l < lineCount; l++) { + DeleteLine(lineDoc); } - for (int i = lineDoc; i < linesInDoc-lineCount; i++) { - if (i != 0) // Line zero is always visible - lines[i].visible = lines[i + lineCount].visible; - lines[i].expanded = lines[i + lineCount].expanded; - lines[i].height = lines[i + lineCount].height; - } - linesInDoc -= lineCount; - linesInDisplay += deltaDisplayed; - valid = false; + Check(); } bool ContractionState::GetVisible(int lineDoc) const { - if (size == 0) + if (OneToOne()) { return true; - if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { - return lines[lineDoc].visible; } else { - return false; + if (lineDoc >= visible->Length()) + return true; + return visible->ValueAt(lineDoc) == 1; } } -bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) { - if (lineDocStart == 0) - lineDocStart++; - if (lineDocStart > lineDocEnd) +bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible_) { + if (OneToOne() && visible_) { return false; - if (size == 0) { - Grow(linesInDoc + growSize); - } - // TODO: modify docLine members to mirror displayLine - int delta = 0; - // Change lineDocs - if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < linesInDoc)) { - for (int line=lineDocStart; line <= lineDocEnd; line++) { - if (lines[line].visible != visible) { - delta += visible ? lines[line].height : -lines[line].height; - lines[line].visible = visible; - valid = false; + } else { + EnsureData(); + int delta = 0; + Check(); + if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < LinesInDoc())) { + for (int line = lineDocStart; line <= lineDocEnd; line++) { + if (GetVisible(line) != visible_) { + int difference = visible_ ? heights->ValueAt(line) : -heights->ValueAt(line); + visible->SetValueAt(line, visible_ ? 1 : 0); + displayLines->InsertText(line, difference); + delta += difference; + } } + } else { + return false; } + Check(); + return delta != 0; } - linesInDisplay += delta; - return delta != 0; } bool ContractionState::GetExpanded(int lineDoc) const { - if (size == 0) + if (OneToOne()) { return true; - if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { - return lines[lineDoc].expanded; } else { - return false; + Check(); + return expanded->ValueAt(lineDoc) == 1; } } -bool ContractionState::SetExpanded(int lineDoc, bool expanded) { - if (size == 0) { - if (expanded) { - // If in completely expanded state then setting - // one line to expanded has no effect. - return false; - } - Grow(linesInDoc + growSize); - } - if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { - if (lines[lineDoc].expanded != expanded) { - lines[lineDoc].expanded = expanded; +bool ContractionState::SetExpanded(int lineDoc, bool expanded_) { + if (OneToOne() && expanded_) { + return false; + } else { + EnsureData(); + if (expanded_ != (expanded->ValueAt(lineDoc) == 1)) { + expanded->SetValueAt(lineDoc, expanded_ ? 1 : 0); + Check(); return true; + } else { + Check(); + return false; } } - return false; } int ContractionState::GetHeight(int lineDoc) const { - if (size == 0) + if (OneToOne()) { return 1; - if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { - return lines[lineDoc].height; } else { - return 1; + return heights->ValueAt(lineDoc); } } // Set the number of display lines needed for this line. // Return true if this is a change. bool ContractionState::SetHeight(int lineDoc, int height) { - if (lineDoc > linesInDoc) + if (OneToOne() && (height == 1)) { return false; - if (size == 0) { - if (height == 1) { - // If in completely expanded state then all lines - // assumed to have height of one so no effect here. + } else { + EnsureData(); + if (GetHeight(lineDoc) != height) { + if (GetVisible(lineDoc)) { + displayLines->InsertText(lineDoc, height - GetHeight(lineDoc)); + } + heights->SetValueAt(lineDoc, height); + Check(); + return true; + } else { + Check(); return false; } - Grow(linesInDoc + growSize); - } - if (lines[lineDoc].height != height) { - lines[lineDoc].height = height; - valid = false; - return true; - } else { - return false; } } void ContractionState::ShowAll() { - delete []lines; - lines = 0; - size = 0; + Clear(); +} - delete []docLines; - docLines = 0; - sizeDocLines = 0; +// Debugging checks - linesInDisplay = linesInDoc; +void ContractionState::Check() const { +#ifdef CHECK_CORRECTNESS + for (int vline = 0;vline < LinesDisplayed(); vline++) { + const int lineDoc = DocFromDisplay(vline); + PLATFORM_ASSERT(GetVisible(lineDoc)); + } + for (int lineDoc = 0;lineDoc < LinesInDoc(); lineDoc++) { + const int displayThis = DisplayFromDoc(lineDoc); + const int displayNext = DisplayFromDoc(lineDoc + 1); + const int height = displayNext - displayThis; + PLATFORM_ASSERT(height >= 0); + if (GetVisible(lineDoc)) { + PLATFORM_ASSERT(GetHeight(lineDoc) == height); + } else { + PLATFORM_ASSERT(0 == height); + } + } +#endif } diff --git a/src/ContractionState.h b/src/ContractionState.h index dbee69db7..ba6297512 100644 --- a/src/ContractionState.h +++ b/src/ContractionState.h @@ -1,8 +1,8 @@ // Scintilla source code edit control /** @file ContractionState.h - ** Manages visibility of lines for folding. + ** Manages visibility of lines for folding and wrapping. **/ -// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> +// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef CONTRACTIONSTATE_H @@ -14,31 +14,21 @@ namespace Scintilla { /** */ -class OneLine { -public: - int displayLine; ///< Position within set of visible lines - //int docLine; ///< Inverse of @a displayLine - int height; ///< Number of display lines needed to show all of the line - bool visible; - bool expanded; +class ContractionState { + // These contain 1 element for every document line. + RunStyles *visible; + RunStyles *expanded; + RunStyles *heights; + Partitioning *displayLines; + int linesInDocument; - OneLine(); - virtual ~OneLine() {} -}; + void EnsureData(); -/** - */ -class ContractionState { - void Grow(int sizeNew); - enum { growSize = 4000 }; - int linesInDoc; - mutable int linesInDisplay; - mutable OneLine *lines; - int size; - mutable int *docLines; - mutable int sizeDocLines; - mutable bool valid; - void MakeValid() const; + bool OneToOne() const { + // True when each document line is exactly one display line so need for + // complex data structures. + return visible == 0; + } public: ContractionState(); @@ -51,7 +41,9 @@ public: int DisplayFromDoc(int lineDoc) const; int DocFromDisplay(int lineDisplay) const; + void InsertLine(int lineDoc); void InsertLines(int lineDoc, int lineCount); + void DeleteLine(int lineDoc); void DeleteLines(int lineDoc, int lineCount); bool GetVisible(int lineDoc) const; @@ -64,6 +56,7 @@ public: bool SetHeight(int lineDoc, int height); void ShowAll(); + void Check() const; }; #ifdef SCI_NAMESPACE diff --git a/src/Editor.cxx b/src/Editor.cxx index a8b6d6509..9d9b4b4f2 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -17,13 +17,13 @@ #endif #include "Scintilla.h" -#include "ContractionState.h" -#include "SVector.h" #include "SplitVector.h" #include "Partitioning.h" +#include "RunStyles.h" +#include "ContractionState.h" +#include "SVector.h" #include "CellBuffer.h" #include "KeyMap.h" -#include "RunStyles.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index 354dddd1a..8e30f5922 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -14,13 +14,13 @@ #include "Scintilla.h" -#include "ContractionState.h" -#include "SVector.h" #include "SplitVector.h" #include "Partitioning.h" +#include "RunStyles.h" +#include "ContractionState.h" +#include "SVector.h" #include "CellBuffer.h" #include "KeyMap.h" -#include "RunStyles.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" diff --git a/src/RunStyles.cxx b/src/RunStyles.cxx index 13d48244b..dfff75412 100644 --- a/src/RunStyles.cxx +++ b/src/RunStyles.cxx @@ -151,6 +151,11 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) { return true; } +void RunStyles::SetValueAt(int position, int value) { + int len = 1; + FillRange(position, value, len); +} + void RunStyles::InsertSpace(int position, int insertLength) { int runStart = RunFromPosition(position); if (starts->PositionFromPartition(runStart) == position) { diff --git a/src/RunStyles.h b/src/RunStyles.h index f3f9fe314..bbf20b262 100644 --- a/src/RunStyles.h +++ b/src/RunStyles.h @@ -30,6 +30,7 @@ public: int EndRun(int position); // Returns true if some values may have changed bool FillRange(int &position, int value, int &fillLength); + void SetValueAt(int position, int value); void InsertSpace(int position, int insertLength); void DeleteAll(); void DeleteRange(int position, int deleteLength); diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx index 9cb0b4f1e..d72f86bc3 100644 --- a/src/ScintillaBase.cxx +++ b/src/ScintillaBase.cxx @@ -20,11 +20,11 @@ #include "DocumentAccessor.h" #include "KeyWords.h" #endif -#include "ContractionState.h" -#include "SVector.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" +#include "ContractionState.h" +#include "SVector.h" #include "CellBuffer.h" #include "CallTip.h" #include "KeyMap.h" |