summaryrefslogtreecommitdiffstats
path: root/scintilla/src/PerLine.cxx
diff options
context:
space:
mode:
authorXhmikosR <xhmikosr@users.sourceforge.net>2010-10-31 17:17:15 +0000
committerXhmikosR <xhmikosr@users.sourceforge.net>2010-10-31 17:17:15 +0000
commit88a9de8737ca5a2ba239d49e072660fc9c89ab25 (patch)
treeb64f81588eafd28926ffc632c01f6b3c246e218d /scintilla/src/PerLine.cxx
parente5eb2fe35699c79bef11a870fd4c111c040fc22c (diff)
downloadnotepad2-mod-88a9de8737ca5a2ba239d49e072660fc9c89ab25.zip
notepad2-mod-88a9de8737ca5a2ba239d49e072660fc9c89ab25.tar.gz
notepad2-mod-88a9de8737ca5a2ba239d49e072660fc9c89ab25.tar.bz2
add scintilla v2.12 in the svn
git-svn-id: https://notepad2-mod.googlecode.com/svn/trunk@3 28bd50df-7adb-d945-0439-6e466c6a13cc
Diffstat (limited to 'scintilla/src/PerLine.cxx')
-rw-r--r--scintilla/src/PerLine.cxx486
1 files changed, 486 insertions, 0 deletions
diff --git a/scintilla/src/PerLine.cxx b/scintilla/src/PerLine.cxx
new file mode 100644
index 0000000..1de3245
--- /dev/null
+++ b/scintilla/src/PerLine.cxx
@@ -0,0 +1,486 @@
+// Scintilla source code edit control
+/** @file PerLine.cxx
+ ** Manages data associated with each line of the document
+ **/
+// Copyright 1998-2009 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 "Scintilla.h"
+#include "SplitVector.h"
+#include "Partitioning.h"
+#include "CellBuffer.h"
+#include "PerLine.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+MarkerHandleSet::MarkerHandleSet() {
+ root = 0;
+}
+
+MarkerHandleSet::~MarkerHandleSet() {
+ MarkerHandleNumber *mhn = root;
+ while (mhn) {
+ MarkerHandleNumber *mhnToFree = mhn;
+ mhn = mhn->next;
+ delete mhnToFree;
+ }
+ root = 0;
+}
+
+int MarkerHandleSet::Length() const {
+ int c = 0;
+ MarkerHandleNumber *mhn = root;
+ while (mhn) {
+ c++;
+ mhn = mhn->next;
+ }
+ return c;
+}
+
+int MarkerHandleSet::NumberFromHandle(int handle) const {
+ MarkerHandleNumber *mhn = root;
+ while (mhn) {
+ if (mhn->handle == handle) {
+ return mhn->number;
+ }
+ mhn = mhn->next;
+ }
+ return - 1;
+}
+
+int MarkerHandleSet::MarkValue() const {
+ unsigned int m = 0;
+ MarkerHandleNumber *mhn = root;
+ while (mhn) {
+ m |= (1 << mhn->number);
+ mhn = mhn->next;
+ }
+ return m;
+}
+
+bool MarkerHandleSet::Contains(int handle) const {
+ MarkerHandleNumber *mhn = root;
+ while (mhn) {
+ if (mhn->handle == handle) {
+ return true;
+ }
+ mhn = mhn->next;
+ }
+ return false;
+}
+
+bool MarkerHandleSet::InsertHandle(int handle, int markerNum) {
+ MarkerHandleNumber *mhn = new MarkerHandleNumber;
+ if (!mhn)
+ return false;
+ mhn->handle = handle;
+ mhn->number = markerNum;
+ mhn->next = root;
+ root = mhn;
+ return true;
+}
+
+void MarkerHandleSet::RemoveHandle(int handle) {
+ MarkerHandleNumber **pmhn = &root;
+ while (*pmhn) {
+ MarkerHandleNumber *mhn = *pmhn;
+ if (mhn->handle == handle) {
+ *pmhn = mhn->next;
+ delete mhn;
+ return;
+ }
+ pmhn = &((*pmhn)->next);
+ }
+}
+
+bool MarkerHandleSet::RemoveNumber(int markerNum) {
+ bool performedDeletion = false;
+ MarkerHandleNumber **pmhn = &root;
+ while (*pmhn) {
+ MarkerHandleNumber *mhn = *pmhn;
+ if (mhn->number == markerNum) {
+ *pmhn = mhn->next;
+ delete mhn;
+ performedDeletion = true;
+ } else {
+ pmhn = &((*pmhn)->next);
+ }
+ }
+ return performedDeletion;
+}
+
+void MarkerHandleSet::CombineWith(MarkerHandleSet *other) {
+ MarkerHandleNumber **pmhn = &root;
+ while (*pmhn) {
+ pmhn = &((*pmhn)->next);
+ }
+ *pmhn = other->root;
+ other->root = 0;
+}
+
+LineMarkers::~LineMarkers() {
+ Init();
+}
+
+void LineMarkers::Init() {
+ for (int line = 0; line < markers.Length(); line++) {
+ delete markers[line];
+ markers[line] = 0;
+ }
+ markers.DeleteAll();
+}
+
+void LineMarkers::InsertLine(int line) {
+ if (markers.Length()) {
+ markers.Insert(line, 0);
+ }
+}
+
+void LineMarkers::RemoveLine(int line) {
+ // Retain the markers from the deleted line by oring them into the previous line
+ if (markers.Length()) {
+ if (line > 0) {
+ MergeMarkers(line - 1);
+ }
+ markers.Delete(line);
+ }
+}
+
+int LineMarkers::LineFromHandle(int markerHandle) {
+ if (markers.Length()) {
+ for (int line = 0; line < markers.Length(); line++) {
+ if (markers[line]) {
+ if (markers[line]->Contains(markerHandle)) {
+ return line;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
+void LineMarkers::MergeMarkers(int pos) {
+ if (markers[pos + 1] != NULL) {
+ if (markers[pos] == NULL)
+ markers[pos] = new MarkerHandleSet;
+ markers[pos]->CombineWith(markers[pos + 1]);
+ delete markers[pos + 1];
+ markers[pos + 1] = NULL;
+ }
+}
+
+int LineMarkers::MarkValue(int line) {
+ if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line])
+ return markers[line]->MarkValue();
+ else
+ return 0;
+}
+
+int LineMarkers::AddMark(int line, int markerNum, int lines) {
+ handleCurrent++;
+ if (!markers.Length()) {
+ // No existing markers so allocate one element per line
+ markers.InsertValue(0, lines, 0);
+ }
+ if (line >= markers.Length()) {
+ return -1;
+ }
+ if (!markers[line]) {
+ // Need new structure to hold marker handle
+ markers[line] = new MarkerHandleSet();
+ if (!markers[line])
+ return -1;
+ }
+ markers[line]->InsertHandle(handleCurrent, markerNum);
+
+ return handleCurrent;
+}
+
+void LineMarkers::DeleteMark(int line, int markerNum, bool all) {
+ if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) {
+ if (markerNum == -1) {
+ delete markers[line];
+ markers[line] = NULL;
+ } else {
+ bool performedDeletion = markers[line]->RemoveNumber(markerNum);
+ while (all && performedDeletion) {
+ performedDeletion = markers[line]->RemoveNumber(markerNum);
+ }
+ if (markers[line]->Length() == 0) {
+ delete markers[line];
+ markers[line] = NULL;
+ }
+ }
+ }
+}
+
+void LineMarkers::DeleteMarkFromHandle(int markerHandle) {
+ int line = LineFromHandle(markerHandle);
+ if (line >= 0) {
+ markers[line]->RemoveHandle(markerHandle);
+ if (markers[line]->Length() == 0) {
+ delete markers[line];
+ markers[line] = NULL;
+ }
+ }
+}
+
+LineLevels::~LineLevels() {
+}
+
+void LineLevels::Init() {
+ levels.DeleteAll();
+}
+
+void LineLevels::InsertLine(int line) {
+ if (levels.Length()) {
+ int level = SC_FOLDLEVELBASE;
+ if ((line > 0) && (line < levels.Length())) {
+ level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
+ }
+ levels.InsertValue(line, 1, level);
+ }
+}
+
+void LineLevels::RemoveLine(int line) {
+ if (levels.Length()) {
+ // Move up following lines but merge header flag from this line
+ // to line before to avoid a temporary disappearence causing expansion.
+ int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG;
+ levels.Delete(line);
+ if (line == levels.Length()-1) // Last line loses the header flag
+ levels[line-1] &= ~SC_FOLDLEVELHEADERFLAG;
+ else if (line > 0)
+ levels[line-1] |= firstHeader;
+ }
+}
+
+void LineLevels::ExpandLevels(int sizeNew) {
+ levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE);
+}
+
+void LineLevels::ClearLevels() {
+ levels.DeleteAll();
+}
+
+int LineLevels::SetLevel(int line, int level, int lines) {
+ int prev = 0;
+ if ((line >= 0) && (line < lines)) {
+ if (!levels.Length()) {
+ ExpandLevels(lines + 1);
+ }
+ prev = levels[line];
+ if (prev != level) {
+ levels[line] = level;
+ }
+ }
+ return prev;
+}
+
+int LineLevels::GetLevel(int line) {
+ if (levels.Length() && (line >= 0) && (line < levels.Length())) {
+ return levels[line];
+ } else {
+ return SC_FOLDLEVELBASE;
+ }
+}
+
+LineState::~LineState() {
+}
+
+void LineState::Init() {
+ lineStates.DeleteAll();
+}
+
+void LineState::InsertLine(int line) {
+ if (lineStates.Length()) {
+ lineStates.EnsureLength(line);
+ lineStates.Insert(line, 0);
+ }
+}
+
+void LineState::RemoveLine(int line) {
+ if (lineStates.Length() > line) {
+ lineStates.Delete(line);
+ }
+}
+
+int LineState::SetLineState(int line, int state) {
+ lineStates.EnsureLength(line + 1);
+ int stateOld = lineStates[line];
+ lineStates[line] = state;
+ return stateOld;
+}
+
+int LineState::GetLineState(int line) {
+ lineStates.EnsureLength(line + 1);
+ return lineStates[line];
+}
+
+int LineState::GetMaxLineState() {
+ return lineStates.Length();
+}
+
+static int NumberLines(const char *text) {
+ if (text) {
+ int newLines = 0;
+ while (*text) {
+ if (*text == '\n')
+ newLines++;
+ text++;
+ }
+ return newLines+1;
+ } else {
+ return 0;
+ }
+}
+
+// Each allocated LineAnnotation is a char array which starts with an AnnotationHeader
+// and then has text and optional styles.
+
+static const int IndividualStyles = 0x100;
+
+struct AnnotationHeader {
+ short style; // Style IndividualStyles implies array of styles
+ short lines;
+ int length;
+};
+
+LineAnnotation::~LineAnnotation() {
+ ClearAll();
+}
+
+void LineAnnotation::Init() {
+ ClearAll();
+}
+
+void LineAnnotation::InsertLine(int line) {
+ if (annotations.Length()) {
+ annotations.EnsureLength(line);
+ annotations.Insert(line, 0);
+ }
+}
+
+void LineAnnotation::RemoveLine(int line) {
+ if (annotations.Length() && (line < annotations.Length())) {
+ delete []annotations[line];
+ annotations.Delete(line);
+ }
+}
+
+bool LineAnnotation::AnySet() const {
+ return annotations.Length() > 0;
+}
+
+bool LineAnnotation::MultipleStyles(int line) const {
+ if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ return reinterpret_cast<AnnotationHeader *>(annotations[line])->style == IndividualStyles;
+ else
+ return 0;
+}
+
+int LineAnnotation::Style(int line) {
+ if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ return reinterpret_cast<AnnotationHeader *>(annotations[line])->style;
+ else
+ return 0;
+}
+
+const char *LineAnnotation::Text(int line) const {
+ if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ return annotations[line]+sizeof(AnnotationHeader);
+ else
+ return 0;
+}
+
+const unsigned char *LineAnnotation::Styles(int line) const {
+ if (annotations.Length() && (line < annotations.Length()) && annotations[line] && MultipleStyles(line))
+ return reinterpret_cast<unsigned char *>(annotations[line] + sizeof(AnnotationHeader) + Length(line));
+ else
+ return 0;
+}
+
+static char *AllocateAnnotation(int length, int style) {
+ size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0);
+ char *ret = new char[len];
+ memset(ret, 0, len);
+ return ret;
+}
+
+void LineAnnotation::SetText(int line, const char *text) {
+ if (text) {
+ annotations.EnsureLength(line+1);
+ int style = Style(line);
+ if (annotations[line]) {
+ delete []annotations[line];
+ }
+ annotations[line] = AllocateAnnotation(strlen(text), style);
+ AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
+ pah->style = static_cast<short>(style);
+ pah->length = strlen(text);
+ pah->lines = static_cast<short>(NumberLines(text));
+ memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length);
+ } else {
+ if (annotations.Length() && (line < annotations.Length()) && annotations[line]) {
+ delete []annotations[line];
+ annotations[line] = 0;
+ }
+ }
+}
+
+void LineAnnotation::ClearAll() {
+ for (int line = 0; line < annotations.Length(); line++) {
+ delete []annotations[line];
+ annotations[line] = 0;
+ }
+ annotations.DeleteAll();
+}
+
+void LineAnnotation::SetStyle(int line, int style) {
+ annotations.EnsureLength(line+1);
+ if (!annotations[line]) {
+ annotations[line] = AllocateAnnotation(0, style);
+ }
+ reinterpret_cast<AnnotationHeader *>(annotations[line])->style = static_cast<short>(style);
+}
+
+void LineAnnotation::SetStyles(int line, const unsigned char *styles) {
+ annotations.EnsureLength(line+1);
+ if (!annotations[line]) {
+ annotations[line] = AllocateAnnotation(0, IndividualStyles);
+ } else {
+ AnnotationHeader *pahSource = reinterpret_cast<AnnotationHeader *>(annotations[line]);
+ if (pahSource->style != IndividualStyles) {
+ char *allocation = AllocateAnnotation(pahSource->length, IndividualStyles);
+ AnnotationHeader *pahAlloc = reinterpret_cast<AnnotationHeader *>(allocation);
+ pahAlloc->length = pahSource->length;
+ pahAlloc->lines = pahSource->lines;
+ memcpy(allocation + sizeof(AnnotationHeader), annotations[line] + sizeof(AnnotationHeader), pahSource->length);
+ delete []annotations[line];
+ annotations[line] = allocation;
+ }
+ }
+ AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
+ pah->style = IndividualStyles;
+ memcpy(annotations[line] + sizeof(AnnotationHeader) + pah->length, styles, pah->length);
+}
+
+int LineAnnotation::Length(int line) const {
+ if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ return reinterpret_cast<AnnotationHeader *>(annotations[line])->length;
+ else
+ return 0;
+}
+
+int LineAnnotation::Lines(int line) const {
+ if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ return reinterpret_cast<AnnotationHeader *>(annotations[line])->lines;
+ else
+ return 0;
+}