diff options
author | nyamatongwe <devnull@localhost> | 2000-04-04 22:57:40 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2000-04-04 22:57:40 +0000 |
commit | 78562c158305d7d238cb12ba4cd186517364b6d9 (patch) | |
tree | 3ab47b5c9c283b7dda0823d062f6010eef2be821 /src | |
parent | cc54b6b2ba9362b9b148b9b256e0a37974c47a53 (diff) | |
download | scintilla-mirror-78562c158305d7d238cb12ba4cd186517364b6d9.tar.gz |
Initial version.
Diffstat (limited to 'src')
-rw-r--r-- | src/DocumentAccessor.cxx | 166 | ||||
-rw-r--r-- | src/DocumentAccessor.h | 71 | ||||
-rw-r--r-- | src/WindowAccessor.cxx | 165 |
3 files changed, 402 insertions, 0 deletions
diff --git a/src/DocumentAccessor.cxx b/src/DocumentAccessor.cxx new file mode 100644 index 000000000..a69f4a445 --- /dev/null +++ b/src/DocumentAccessor.cxx @@ -0,0 +1,166 @@ +// SciTE - Scintilla based Text Editor +// Accessor.cxx - rapid easy access to contents of a Scintilla +// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#include <stdlib.h> +#include <ctype.h> +#include <stdio.h> + +#include "Platform.h" + +#include "PropSet.h" +#include "SVector.h" +#include "Accessor.h" +#include "DocumentAccessor.h" +#include "CellBuffer.h" +#include "Scintilla.h" +#include "Document.h" + +bool DocumentAccessor::InternalIsLeadByte(char ch) { +#if PLAT_GTK + // TODO: support DBCS under GTK+ + return false; +#elif PLAT_WIN + return IsDBCSLeadByteEx(codePage, ch); +#elif PLAT_WX + return false; +#endif +} + +void DocumentAccessor::Fill(int position) { + if (lenDoc == -1) + lenDoc = pdoc->Length(); + startPos = position - slopSize; + if (startPos + bufferSize > lenDoc) + startPos = lenDoc - bufferSize; + if (startPos < 0) + startPos = 0; + endPos = startPos + bufferSize; + if (endPos > lenDoc) + endPos = lenDoc; + + pdoc->GetCharRange(buf, startPos, endPos-startPos); + buf[endPos-startPos] = '\0'; +} + +char DocumentAccessor::StyleAt(int position) { + return pdoc->StyleAt(position); +} + +int DocumentAccessor::GetLine(int position) { + return pdoc->LineFromPosition(position); +} + +int DocumentAccessor::LineStart(int line) { + return pdoc->LineStart(line); +} + +int DocumentAccessor::LevelAt(int line) { + return pdoc->GetLevel(line); +} + +int DocumentAccessor::Length() { + if (lenDoc == -1) + lenDoc = pdoc->Length(); + return lenDoc; +} + +int DocumentAccessor::GetLineState(int line) { + return pdoc->GetLineState(line); +} + +int DocumentAccessor::SetLineState(int line, int state) { + return pdoc->SetLineState(line, state); +} + +void DocumentAccessor::StartAt(unsigned int start, char chMask) { + pdoc->StartStyling(start, chMask); +} + +void DocumentAccessor::StartSegment(unsigned int pos) { + startSeg = pos; +} + +void DocumentAccessor::ColourTo(unsigned int pos, int chAttr) { + // Only perform styling if non empty range + if (pos != startSeg - 1) { + if (pos < startSeg) { + Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos); + } + + if (validLen + (pos - startSeg + 1) >= bufferSize) + Flush(); + if (validLen + (pos - startSeg + 1) >= bufferSize) { + // Too big for buffer so send directly + pdoc->SetStyleFor(pos - startSeg + 1, chAttr); + } else { + if (chAttr != chWhile) + chFlags = 0; + chAttr |= chFlags; + for (unsigned int i = startSeg; i <= pos; i++) { + styleBuf[validLen++] = static_cast<char>(chAttr); + } + } + } + startSeg = pos+1; +} + +void DocumentAccessor::SetLevel(int line, int level) { + pdoc->SetLevel(line, level); +} + +void DocumentAccessor::Flush() { + startPos = 0x7FFFFFFF; + lenDoc = -1; + if (validLen > 0) { + pdoc->SetStyles(validLen, styleBuf); + validLen = 0; + } +} + +int DocumentAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { + int end = Length(); + int spaceFlags = 0; + + // Determines the indentation level of the current line and also checks for consistent + // indentation compared to the previous line. + // Indentation is judged consistent when the indentation whitespace of each line lines + // the same or the indentation of one line is a prefix of the other. + + int pos = LineStart(line); + char ch = (*this)[pos]; + int indent = 0; + bool inPrevPrefix = line > 0; + int posPrev = inPrevPrefix ? LineStart(line-1) : 0; + while ((ch == ' ' || ch == '\t') && (pos < end)) { + if (inPrevPrefix) { + char chPrev = (*this)[posPrev++]; + if (chPrev == ' ' || chPrev == '\t') { + if (chPrev != ch) + spaceFlags |= wsInconsistent; + } else { + inPrevPrefix = false; + } + } + if (ch == ' ') { + spaceFlags |= wsSpace; + indent++; + } else { // Tab + spaceFlags |= wsTab; + if (spaceFlags & wsSpace) + spaceFlags |= wsSpaceTab; + indent = (indent / 8 + 1) * 8; + } + ch = (*this)[++pos]; + } + + *flags = spaceFlags; + indent += SC_FOLDLEVELBASE; + // if completely empty line or the start of a comment... + if (isspace(ch) || (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) ) + return indent | SC_FOLDLEVELWHITEFLAG; + else + return indent; +} + diff --git a/src/DocumentAccessor.h b/src/DocumentAccessor.h new file mode 100644 index 000000000..f0577b355 --- /dev/null +++ b/src/DocumentAccessor.h @@ -0,0 +1,71 @@ +// DocumentAccessor.h - implementation of BufferAccess and StylingAccess on a Scintilla rapid easy access to contents of a Scintilla +// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +class Document; + +class DocumentAccessor : public Accessor { +protected: + // bufferSize is a trade off between time taken to copy the characters and SendMessage overhead + // slopSize positions the buffer before the desired position in case there is some backtracking + enum {bufferSize=4000, slopSize=bufferSize/8}; + char buf[bufferSize+1]; + Document *pdoc; + PropSet &props; + int startPos; + int endPos; + int lenDoc; + int codePage; + + char styleBuf[bufferSize]; + int validLen; + char chFlags; + char chWhile; + unsigned int startSeg; + + bool InternalIsLeadByte(char ch); + void Fill(int position); +public: + DocumentAccessor(Document *pdoc_, PropSet &props_) : + pdoc(pdoc_), props(props_), startPos(0x7FFFFFFF), endPos(0), + lenDoc(-1), codePage(0), validLen(0), chFlags(0) { + } + void SetCodePage(int codePage_) { codePage = codePage_; } + char operator[](int position) { + if (position < startPos || position >= endPos) { + Fill(position); + } + return buf[position - startPos]; + } + char SafeGetCharAt(int position, char chDefault=' ') { + // Safe version of operator[], returning a defined value for invalid position + if (position < startPos || position >= endPos) { + Fill(position); + if (position < startPos || position >= endPos) { + // Position is outside range of document + return chDefault; + } + } + return buf[position - startPos]; + } + bool IsLeadByte(char ch) { + return codePage && InternalIsLeadByte(ch); + } + char StyleAt(int position); + int GetLine(int position); + int LineStart(int line); + int LevelAt(int line); + int Length(); + void Flush(); + int GetLineState(int line); + int SetLineState(int line, int state); + PropSet &GetPropSet() { return props; } + + void StartAt(unsigned int start, char chMask=31); + void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }; + unsigned int GetStartSegment() { return startSeg; } + void StartSegment(unsigned int pos); + void ColourTo(unsigned int pos, int chAttr); + void SetLevel(int line, int level); + int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); +}; diff --git a/src/WindowAccessor.cxx b/src/WindowAccessor.cxx new file mode 100644 index 000000000..0c33acd88 --- /dev/null +++ b/src/WindowAccessor.cxx @@ -0,0 +1,165 @@ +// SciTE - Scintilla based Text Editor +// Accessor.cxx - rapid easy access to contents of a Scintilla +// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#include <stdlib.h> +#include <ctype.h> +#include <stdio.h> + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "WindowAccessor.h" +#include "Scintilla.h" + +bool WindowAccessor::InternalIsLeadByte(char ch) { +#if PLAT_GTK + // TODO: support DBCS under GTK+ + return false; +#elif PLAT_WIN + return IsDBCSLeadByteEx(codePage, ch); +#elif PLAT_WX + return false; +#endif +} + +void WindowAccessor::Fill(int position) { + if (lenDoc == -1) + lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); + startPos = position - slopSize; + if (startPos + bufferSize > lenDoc) + startPos = lenDoc - bufferSize; + if (startPos < 0) + startPos = 0; + endPos = startPos + bufferSize; + if (endPos > lenDoc) + endPos = lenDoc; + + TEXTRANGE tr = {{startPos, endPos}, buf}; + Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr)); +} + +char WindowAccessor::StyleAt(int position) { + return static_cast<char>(Platform::SendScintilla( + id, SCI_GETSTYLEAT, position, 0)); +} + +int WindowAccessor::GetLine(int position) { + return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0); +} + +int WindowAccessor::LineStart(int line) { + return Platform::SendScintilla(id, EM_LINEINDEX, line, 0); +} + +int WindowAccessor::LevelAt(int line) { + return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0); +} + +int WindowAccessor::Length() { + if (lenDoc == -1) + lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); + return lenDoc; +} + +int WindowAccessor::GetLineState(int line) { + return Platform::SendScintilla(id, SCI_GETLINESTATE, line); +} + +int WindowAccessor::SetLineState(int line, int state) { + return Platform::SendScintilla(id, SCI_SETLINESTATE, line, state); +} + +void WindowAccessor::StartAt(unsigned int start, char chMask) { + Platform::SendScintilla(id, SCI_STARTSTYLING, start, chMask); +} + +void WindowAccessor::StartSegment(unsigned int pos) { + startSeg = pos; +} + +void WindowAccessor::ColourTo(unsigned int pos, int chAttr) { + // Only perform styling if non empty range + if (pos != startSeg - 1) { + if (pos < startSeg) { + Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos); + } + + if (validLen + (pos - startSeg + 1) >= bufferSize) + Flush(); + if (validLen + (pos - startSeg + 1) >= bufferSize) { + // Too big for buffer so send directly + Platform::SendScintilla(id, SCI_SETSTYLING, pos - startSeg + 1, chAttr); + } else { + if (chAttr != chWhile) + chFlags = 0; + chAttr |= chFlags; + for (unsigned int i = startSeg; i <= pos; i++) { + styleBuf[validLen++] = chAttr; + } + } + } + startSeg = pos+1; +} + +void WindowAccessor::SetLevel(int line, int level) { + Platform::SendScintilla(id, SCI_SETFOLDLEVEL, line, level); +} + +void WindowAccessor::Flush() { + startPos = 0x7FFFFFFF; + lenDoc = -1; + if (validLen > 0) { + Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen, + reinterpret_cast<LPARAM>(styleBuf)); + validLen = 0; + } +} + +int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { + int end = Length(); + int spaceFlags = 0; + + // Determines the indentation level of the current line and also checks for consistent + // indentation compared to the previous line. + // Indentation is judged consistent when the indentation whitespace of each line lines + // the same or the indentation of one line is a prefix of the other. + + int pos = LineStart(line); + char ch = (*this)[pos]; + int indent = 0; + bool inPrevPrefix = line > 0; + int posPrev = inPrevPrefix ? LineStart(line-1) : 0; + while ((ch == ' ' || ch == '\t') && (pos < end)) { + if (inPrevPrefix) { + char chPrev = (*this)[posPrev++]; + if (chPrev == ' ' || chPrev == '\t') { + if (chPrev != ch) + spaceFlags |= wsInconsistent; + } else { + inPrevPrefix = false; + } + } + if (ch == ' ') { + spaceFlags |= wsSpace; + indent++; + } else { // Tab + spaceFlags |= wsTab; + if (spaceFlags & wsSpace) + spaceFlags |= wsSpaceTab; + indent = (indent / 8 + 1) * 8; + } + ch = (*this)[++pos]; + } + + *flags = spaceFlags; + indent += SC_FOLDLEVELBASE; + // if completely empty line or the start of a comment... + if (isspace(ch) || (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) ) + return indent | SC_FOLDLEVELWHITEFLAG; + else + return indent; +} + |