Revision: 1629 http://svn.sourceforge.net/geany/?rev=1629&view=rev Author: eht16 Date: 2007-06-18 06:02:34 -0700 (Mon, 18 Jun 2007)
Log Message: ----------- Updated Scintilla to version 1.74.
Modified Paths: -------------- trunk/ChangeLog trunk/scintilla/AutoComplete.cxx trunk/scintilla/AutoComplete.h trunk/scintilla/CallTip.cxx trunk/scintilla/CallTip.h trunk/scintilla/CellBuffer.cxx trunk/scintilla/CellBuffer.h trunk/scintilla/ContractionState.cxx trunk/scintilla/ContractionState.h trunk/scintilla/Document.cxx trunk/scintilla/Document.h trunk/scintilla/DocumentAccessor.cxx trunk/scintilla/DocumentAccessor.h trunk/scintilla/Editor.cxx trunk/scintilla/Editor.h trunk/scintilla/ExternalLexer.cxx trunk/scintilla/ExternalLexer.h trunk/scintilla/Indicator.cxx trunk/scintilla/Indicator.h trunk/scintilla/KeyMap.cxx trunk/scintilla/KeyMap.h trunk/scintilla/KeyWords.cxx trunk/scintilla/LexAsm.cxx trunk/scintilla/LexBash.cxx trunk/scintilla/LexCPP.cxx trunk/scintilla/LexCSS.cxx trunk/scintilla/LexCaml.cxx trunk/scintilla/LexConf.cxx trunk/scintilla/LexCrontab.cxx trunk/scintilla/LexD.cxx trunk/scintilla/LexFortran.cxx trunk/scintilla/LexHTML.cxx trunk/scintilla/LexHaskell.cxx trunk/scintilla/LexLua.cxx trunk/scintilla/LexOthers.cxx trunk/scintilla/LexPascal.cxx trunk/scintilla/LexPerl.cxx trunk/scintilla/LexPython.cxx trunk/scintilla/LexRuby.cxx trunk/scintilla/LexSQL.cxx trunk/scintilla/LexTCL.cxx trunk/scintilla/LexVHDL.cxx trunk/scintilla/LineMarker.cxx trunk/scintilla/LineMarker.h trunk/scintilla/Makefile.am trunk/scintilla/Partitioning.h trunk/scintilla/PlatGTK.cxx trunk/scintilla/PropSet.cxx trunk/scintilla/RESearch.cxx trunk/scintilla/RESearch.h trunk/scintilla/SVector.h trunk/scintilla/ScintillaBase.cxx trunk/scintilla/ScintillaBase.h trunk/scintilla/ScintillaGTK.cxx trunk/scintilla/SplitVector.h trunk/scintilla/Style.cxx trunk/scintilla/Style.h trunk/scintilla/StyleContext.cxx trunk/scintilla/StyleContext.h trunk/scintilla/UniConversion.cxx trunk/scintilla/UniConversion.h trunk/scintilla/ViewStyle.cxx trunk/scintilla/ViewStyle.h trunk/scintilla/WindowAccessor.cxx trunk/scintilla/XPM.cxx trunk/scintilla/XPM.h trunk/scintilla/include/Accessor.h trunk/scintilla/include/KeyWords.h trunk/scintilla/include/Makefile.am trunk/scintilla/include/Platform.h trunk/scintilla/include/PropSet.h trunk/scintilla/include/SString.h trunk/scintilla/include/SciLexer.h trunk/scintilla/include/Scintilla.h trunk/scintilla/include/WindowAccessor.h trunk/scintilla/makefile.win32
Added Paths: ----------- trunk/scintilla/CharacterSet.h trunk/scintilla/Decoration.cxx trunk/scintilla/Decoration.h trunk/scintilla/PositionCache.cxx trunk/scintilla/PositionCache.h trunk/scintilla/RunStyles.cxx trunk/scintilla/RunStyles.h
Removed Paths: ------------- trunk/scintilla/include/Face.py trunk/scintilla/include/HFacer.py trunk/scintilla/include/Scintilla.iface
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/ChangeLog 2007-06-18 13:02:34 UTC (rev 1629) @@ -1,3 +1,8 @@ +2007-06-18 Enrico Tröger enrico.troeger@uvena.de + + * scintilla/*, scintilla/include/*: Updated Scintilla to version 1.74. + + 2007-06-17 Enrico Tröger enrico.troeger@uvena.de
* src/templates.c, src/tools.c: Apply patch from Alexander Rodin to
Modified: trunk/scintilla/AutoComplete.cxx =================================================================== --- trunk/scintilla/AutoComplete.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/AutoComplete.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -14,6 +14,10 @@ #include "PropSet.h" #include "AutoComplete.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + AutoComplete::AutoComplete() : active(false), separator(' '),
Modified: trunk/scintilla/AutoComplete.h =================================================================== --- trunk/scintilla/AutoComplete.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/AutoComplete.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -8,6 +8,10 @@ #ifndef AUTOCOMPLETE_H #define AUTOCOMPLETE_H
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + /** */ class AutoComplete { @@ -67,4 +71,8 @@ void Select(const char *word); };
+#ifdef SCI_NAMESPACE +} #endif + +#endif
Modified: trunk/scintilla/CallTip.cxx =================================================================== --- trunk/scintilla/CallTip.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/CallTip.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -12,7 +12,12 @@
#include "Scintilla.h" #include "CallTip.h" +#include <stdio.h>
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + static const int insetX = 5; // text inset in x from calltip border static const int widthArrow = 14;
@@ -29,8 +34,14 @@ tabSize = 0; useStyleCallTip = false; // for backwards compatibility
+#ifdef __APPLE__ + // proper apple colours for the default + colourBG.desired = ColourDesired(0xff, 0xff, 0xc6); + colourUnSel.desired = ColourDesired(0, 0, 0); +#else colourBG.desired = ColourDesired(0xff, 0xff, 0xff); colourUnSel.desired = ColourDesired(0x80, 0x80, 0x80); +#endif colourSel.desired = ColourDesired(0, 0, 0x80); colourShade.desired = ColourDesired(0, 0, 0); colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0); @@ -170,6 +181,7 @@ char *chunkVal = val; bool moreChunks = true; int maxWidth = 0; + while (moreChunks) { char *chunkEnd = strchr(chunkVal, '\n'); if (chunkEnd == NULL) { @@ -217,6 +229,8 @@ offsetMain = insetX; // initial alignment assuming no arrows PaintContents(surfaceWindow, true);
+#ifndef __APPLE__ + // OSX doesn't put borders on "help tags" // Draw a raised border around the edges of the window surfaceWindow->MoveTo(0, rcClientSize.bottom - 1); surfaceWindow->PenColour(colourShade.allocated); @@ -225,6 +239,7 @@ surfaceWindow->PenColour(colourLight.allocated); surfaceWindow->LineTo(0, 0); surfaceWindow->LineTo(0, rcClientSize.bottom - 1); +#endif }
void CallTip::MouseClick(Point pt) {
Modified: trunk/scintilla/CallTip.h =================================================================== --- trunk/scintilla/CallTip.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/CallTip.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -8,6 +8,10 @@ #ifndef CALLTIP_H #define CALLTIP_H
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + /** */ class CallTip { @@ -76,4 +80,8 @@ void SetForeBack(const ColourPair &fore, const ColourPair &back); };
+#ifdef SCI_NAMESPACE +} #endif + +#endif
Modified: trunk/scintilla/CellBuffer.cxx =================================================================== --- trunk/scintilla/CellBuffer.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/CellBuffer.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -18,6 +18,10 @@ #include "Partitioning.h" #include "CellBuffer.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + MarkerHandleSet::MarkerHandleSet() { root = 0; }
Modified: trunk/scintilla/CellBuffer.h =================================================================== --- trunk/scintilla/CellBuffer.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/CellBuffer.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -8,6 +8,10 @@ #ifndef CELLBUFFER_H #define CELLBUFFER_H
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + /** * This holds the marker identifier and the marker type to display. * MarkerHandleNumbers are members of lists. @@ -228,4 +232,8 @@ void ClearLevels(); };
+#ifdef SCI_NAMESPACE +} #endif + +#endif
Added: trunk/scintilla/CharacterSet.h =================================================================== --- trunk/scintilla/CharacterSet.h (rev 0) +++ trunk/scintilla/CharacterSet.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -0,0 +1,58 @@ +// Scintilla source code edit control +/** @file CharacterSet.h + ** Encapsulates a set of characters. Used to test if a character is within a set. + **/ +// Copyright 2007 by Neil Hodgson neilh@scintilla.org +// The License.txt file describes the conditions under which this software may be distributed. + +class CharacterSet { + int size; + bool valueAfter; + bool *bset; +public: + enum setBase { + setNone=0, + setLower=1, + setUpper=2, + setDigits=4, + setAlpha=setLower|setUpper, + setAlphaNum=setAlpha|setDigits + }; + CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) { + size = size_; + valueAfter = valueAfter_; + bset = new bool[size]; + for (int i=0; i < size; i++) { + bset[i] = false; + } + AddString(initialSet); + if (base & setLower) + AddString("abcdefghijklmnopqrstuvwxyz"); + if (base & setUpper) + AddString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + if (base & setDigits) + AddString("0123456789"); + } + ~CharacterSet() { + delete []bset; + bset = 0; + size = 0; + } + void Add(int val) { + PLATFORM_ASSERT(val >= 0); + PLATFORM_ASSERT(val < size); + bset[val] = true; + } + void AddString(const char *CharacterSet) { + for (const char *cp=CharacterSet; *cp; cp++) { + int val = static_cast<unsigned char>(*cp); + PLATFORM_ASSERT(val >= 0); + PLATFORM_ASSERT(val < size); + bset[val] = true; + } + } + bool Contains(int val) const { + PLATFORM_ASSERT(val >= 0); + return (val < size) ? bset[val] : valueAfter; + } +};
Modified: trunk/scintilla/ContractionState.cxx =================================================================== --- trunk/scintilla/ContractionState.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/ContractionState.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -9,6 +9,10 @@
#include "ContractionState.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + OneLine::OneLine() { displayLine = 0; //docLine = 0;
Modified: trunk/scintilla/ContractionState.h =================================================================== --- trunk/scintilla/ContractionState.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/ContractionState.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -8,6 +8,10 @@ #ifndef CONTRACTIONSTATE_H #define CONTRACTIONSTATE_H
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + /** */ class OneLine { @@ -62,4 +66,8 @@ void ShowAll(); };
+#ifdef SCI_NAMESPACE +} #endif + +#endif
Added: trunk/scintilla/Decoration.cxx =================================================================== --- trunk/scintilla/Decoration.cxx (rev 0) +++ trunk/scintilla/Decoration.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -0,0 +1,188 @@ +/** @file Decoration.cxx + ** Visual elements added over text. + **/ +// Copyright 1998-2007 by Neil Hodgson neilh@scintilla.org +// The License.txt file describes the conditions under which this software may be distributed. + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> + +#include "Platform.h" + +#include "Scintilla.h" +#include "SplitVector.h" +#include "Partitioning.h" +#include "RunStyles.h" +#include "Decoration.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +Decoration::Decoration(int indicator_) : next(0), indicator(indicator_) { +} + +Decoration::~Decoration() { +} + +bool Decoration::Empty() { + return rs.starts->Partitions() == 1; +} + +DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0), + lengthDocument(0), root(0), clickNotified(false) { +} + +DecorationList::~DecorationList() { + Decoration *deco = root; + while (deco) { + Decoration *decoNext = deco->next; + delete deco; + deco = decoNext; + } + root = 0; + current = 0; +} + +Decoration *DecorationList::DecorationFromIndicator(int indicator) { + for (Decoration *deco=root; deco; deco = deco->next) { + if (deco->indicator == indicator) { + return deco; + } + } + return 0; +} + +Decoration *DecorationList::Create(int indicator, int length) { + currentIndicator = indicator; + Decoration *decoNew = new Decoration(indicator); + decoNew->rs.InsertSpace(0, length); + + Decoration *decoPrev = 0; + Decoration *deco = root; + + while (deco && (deco->indicator < indicator)) { + decoPrev = deco; + deco = deco->next; + } + if (decoPrev == 0) { + decoNew->next = root; + root = decoNew; + } else { + decoNew->next = deco; + decoPrev->next = decoNew; + } + return decoNew; +} + +void DecorationList::Delete(int indicator) { + Decoration *decoToDelete = 0; + if (root) { + if (root->indicator == indicator) { + decoToDelete = root; + root = root->next; + } else { + Decoration *deco=root; + while (deco->next && !decoToDelete) { + if (deco->next && deco->next->indicator == indicator) { + decoToDelete = deco->next; + deco->next = decoToDelete->next; + } else { + deco = deco->next; + } + } + } + } + if (decoToDelete) { + delete decoToDelete; + current = 0; + } +} + +void DecorationList::SetCurrentIndicator(int indicator) { + currentIndicator = indicator; + current = DecorationFromIndicator(indicator); + currentValue = 1; +} + +void DecorationList::SetCurrentValue(int value) { + currentValue = value ? value : 1; +} + +bool DecorationList::FillRange(int &position, int value, int &fillLength) { + if (!current) { + current = DecorationFromIndicator(currentIndicator); + if (!current) { + current = Create(currentIndicator, lengthDocument); + } + } + bool changed = current->rs.FillRange(position, value, fillLength); + if (current->Empty()) { + Delete(currentIndicator); + } + return changed; +} + +void DecorationList::InsertSpace(int position, int insertLength) { + lengthDocument += insertLength; + for (Decoration *deco=root; deco; deco = deco->next) { + deco->rs.InsertSpace(position, insertLength); + } +} + +void DecorationList::DeleteRange(int position, int deleteLength) { + lengthDocument -= deleteLength; + Decoration *deco; + for (deco=root; deco; deco = deco->next) { + deco->rs.DeleteRange(position, deleteLength); + } + DeleteAnyEmpty(); +} + +void DecorationList::DeleteAnyEmpty() { + Decoration *deco = root; + while (deco) { + if (deco->Empty()) { + Delete(deco->indicator); + deco = root; + } else { + deco = deco->next; + } + } +} + +int DecorationList::AllOnFor(int position) { + int mask = 0; + for (Decoration *deco=root; deco; deco = deco->next) { + if (deco->rs.ValueAt(position)) { + mask |= 1 << deco->indicator; + } + } + return mask; +} + +int DecorationList::ValueAt(int indicator, int position) { + Decoration *deco = DecorationFromIndicator(indicator); + if (deco) { + return deco->rs.ValueAt(position); + } + return 0; +} + +int DecorationList::Start(int indicator, int position) { + Decoration *deco = DecorationFromIndicator(indicator); + if (deco) { + return deco->rs.StartRun(position); + } + return 0; +} + +int DecorationList::End(int indicator, int position) { + Decoration *deco = DecorationFromIndicator(indicator); + if (deco) { + return deco->rs.EndRun(position); + } + return 0; +}
Added: trunk/scintilla/Decoration.h =================================================================== --- trunk/scintilla/Decoration.h (rev 0) +++ trunk/scintilla/Decoration.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -0,0 +1,64 @@ +/** @file Decoration.h + ** Visual elements added over text. + **/ +// Copyright 1998-2007 by Neil Hodgson neilh@scintilla.org +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef DECORATION_H +#define DECORATION_H + +#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + +class Decoration { +public: + Decoration *next; + RunStyles rs; + int indicator; + + Decoration(int indicator_); + ~Decoration(); + + bool Empty(); +}; + +class DecorationList { + int currentIndicator; + int currentValue; + Decoration *current; + int lengthDocument; + Decoration *DecorationFromIndicator(int indicator); + Decoration *Create(int indicator, int length); + void Delete(int indicator); + void DeleteAnyEmpty(); +public: + Decoration *root; + bool clickNotified; + + DecorationList(); + ~DecorationList(); + + void SetCurrentIndicator(int indicator); + int GetCurrentIndicator() { return currentIndicator; } + + void SetCurrentValue(int value); + int GetCurrentValue() { return currentValue; } + + // Returns true if some values may have changed + bool FillRange(int &position, int value, int &fillLength); + + void InsertSpace(int position, int insertLength); + void DeleteRange(int position, int deleteLength); + + int AllOnFor(int position); + int ValueAt(int indicator, int position); + int Start(int indicator, int position); + int End(int indicator, int position); +}; + +#ifdef SCI_NAMESPACE +} +#endif + +#endif
Modified: trunk/scintilla/Document.cxx =================================================================== --- trunk/scintilla/Document.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/Document.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -16,11 +16,17 @@ #include "SVector.h" #include "SplitVector.h" #include "Partitioning.h" +#include "RunStyles.h" #include "CellBuffer.h" #include "CharClassify.h" +#include "Decoration.h" #include "Document.h" #include "RESearch.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + // This is ASCII specific but is safe with chars >= 0x80 static inline bool isspacechar(unsigned char ch) { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); @@ -55,7 +61,8 @@ stylingMask = 0; endStyled = 0; styleClock = 0; - enteredCount = 0; + enteredModification = 0; + enteredStyling = 0; enteredReadOnlyCount = 0; tabInChars = 8; indentInChars = 0; @@ -263,7 +270,9 @@ if (ch < 0x80) return 1; int len = 2; - if (ch >= (0x80 + 0x40 + 0x20)) + if (ch >= (0x80 + 0x40 + 0x20 + 0x10)) + len = 4; + else if (ch >= (0x80 + 0x40 + 0x20)) len = 3; int lengthDoc = Length(); if ((pos + len) > lengthDoc) @@ -369,10 +378,10 @@ if ((pos + len) > Length()) return false; CheckReadOnly(); - if (enteredCount != 0) { + if (enteredModification != 0) { return false; } else { - enteredCount++; + enteredModification++; if (!cb.IsReadOnly()) { NotifyModified( DocModification( @@ -395,7 +404,7 @@ pos, len, LinesTotal() - prevLinesTotal, text)); } - enteredCount--; + enteredModification--; } return !cb.IsReadOnly(); } @@ -408,10 +417,10 @@ return false; } CheckReadOnly(); - if (enteredCount != 0) { + if (enteredModification != 0) { return false; } else { - enteredCount++; + enteredModification++; if (!cb.IsReadOnly()) { NotifyModified( DocModification( @@ -431,7 +440,7 @@ position, insertLength, LinesTotal() - prevLinesTotal, text)); } - enteredCount--; + enteredModification--; } return !cb.IsReadOnly(); } @@ -439,8 +448,8 @@ int Document::Undo() { int newPos = -1; CheckReadOnly(); - if (enteredCount == 0) { - enteredCount++; + if (enteredModification == 0) { + enteredModification++; if (!cb.IsReadOnly()) { bool startSavePoint = cb.IsSavePoint(); bool multiLine = false; @@ -487,7 +496,7 @@ if (startSavePoint != endSavePoint) NotifySavePoint(endSavePoint); } - enteredCount--; + enteredModification--; } return newPos; } @@ -495,8 +504,8 @@ int Document::Redo() { int newPos = -1; CheckReadOnly(); - if (enteredCount == 0) { - enteredCount++; + if (enteredModification == 0) { + enteredModification++; if (!cb.IsReadOnly()) { bool startSavePoint = cb.IsSavePoint(); bool multiLine = false; @@ -541,7 +550,7 @@ if (startSavePoint != endSavePoint) NotifySavePoint(endSavePoint); } - enteredCount--; + enteredModification--; } return newPos; } @@ -671,7 +680,7 @@ return column; } else { column++; - i = MovePositionOutsideChar(i + 1, 1); + i = MovePositionOutsideChar(i + 1, 1, false); } } } @@ -693,7 +702,7 @@ return position; } else { columnCurrent++; - position = MovePositionOutsideChar(position + 1, 1); + position = MovePositionOutsideChar(position + 1, 1, false); } } } @@ -1275,10 +1284,10 @@ }
bool Document::SetStyleFor(int length, char style) { - if (enteredCount != 0) { + if (enteredStyling != 0) { return false; } else { - enteredCount++; + enteredStyling++; style &= stylingMask; int prevEndStyled = endStyled; if (cb.SetStyleFor(endStyled, length, style, stylingMask)) { @@ -1287,16 +1296,16 @@ NotifyModified(mh); } endStyled += length; - enteredCount--; + enteredStyling--; return true; } }
bool Document::SetStyles(int length, char *styles) { - if (enteredCount != 0) { + if (enteredStyling != 0) { return false; } else { - enteredCount++; + enteredStyling++; bool didChange = false; int startMod = 0; int endMod = 0; @@ -1315,20 +1324,19 @@ startMod, endMod - startMod + 1); NotifyModified(mh); } - enteredCount--; + enteredStyling--; return true; } }
-bool Document::EnsureStyledTo(int pos) { - if (pos > GetEndStyled()) { +void Document::EnsureStyledTo(int pos) { + if ((enteredStyling == 0) && (pos > GetEndStyled())) { IncrementStyleClock(); // Ask the watchers to style, and stop as soon as one responds. for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) { watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos); } } - return pos <= GetEndStyled(); }
void Document::IncrementStyleClock() { @@ -1338,6 +1346,14 @@ } }
+void Document::DecorationFillRange(int position, int value, int fillLength) { + if (decorations.FillRange(position, value, fillLength)) { + DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER, + position, fillLength); + NotifyModified(mh); + } +} + bool Document::AddWatcher(DocWatcher *watcher, void *userData) { for (int i = 0; i < lenWatchers; i++) { if ((watchers[i].watcher == watcher) &&
Modified: trunk/scintilla/Document.h =================================================================== --- trunk/scintilla/Document.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/Document.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -8,6 +8,10 @@ #ifndef DOCUMENT_H #define DOCUMENT_H
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + /** * A Position is a position within a document between two characters or at the beginning or end. * Sometimes used as a character index where it identifies the character after the position. @@ -97,7 +101,8 @@ char stylingMask; int endStyled; int styleClock; - int enteredCount; + int enteredModification; + int enteredStyling; int enteredReadOnlyCount;
WatcherWithUserData *watchers; @@ -121,6 +126,8 @@ bool tabIndents; bool backspaceUnindents;
+ DecorationList decorations; + Document(); virtual ~Document();
@@ -212,9 +219,10 @@ bool SetStyleFor(int length, char style); bool SetStyles(int length, char *styles); int GetEndStyled() { return endStyled; } - bool EnsureStyledTo(int pos); + void EnsureStyledTo(int pos); int GetStyleClock() { return styleClock; } void IncrementStyleClock(); + void DecorationFillRange(int position, int value, int fillLength);
int SetLineState(int line, int state) { return cb.SetLineState(line, state); } int GetLineState(int line) { return cb.GetLineState(line); } @@ -301,4 +309,8 @@ virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0; };
+#ifdef SCI_NAMESPACE +} #endif + +#endif
Modified: trunk/scintilla/DocumentAccessor.cxx =================================================================== --- trunk/scintilla/DocumentAccessor.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/DocumentAccessor.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -18,11 +18,17 @@ #include "DocumentAccessor.h" #include "SplitVector.h" #include "Partitioning.h" +#include "RunStyles.h" #include "CellBuffer.h" #include "Scintilla.h" #include "CharClassify.h" +#include "Decoration.h" #include "Document.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + DocumentAccessor::~DocumentAccessor() { }
@@ -105,8 +111,9 @@ void DocumentAccessor::ColourTo(unsigned int pos, int chAttr) { // Only perform styling if non empty range if (pos != startSeg - 1) { + PLATFORM_ASSERT(pos >= startSeg); if (pos < startSeg) { - Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos); + return; }
if (validLen + (pos - startSeg + 1) >= bufferSize) @@ -187,3 +194,7 @@ return indent; }
+void DocumentAccessor::IndicatorFill(int start, int end, int indicator, int value) { + pdoc->decorations.SetCurrentIndicator(indicator); + pdoc->DecorationFillRange(start, value, end - start); +}
Modified: trunk/scintilla/DocumentAccessor.h =================================================================== --- trunk/scintilla/DocumentAccessor.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/DocumentAccessor.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -6,6 +6,10 @@ // Copyright 1998-2001 by Neil Hodgson neilh@scintilla.org // The License.txt file describes the conditions under which this software may be distributed.
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + class Document;
/** @@ -64,4 +68,9 @@ void ColourTo(unsigned int pos, int chAttr); void SetLevel(int line, int level); int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); + void IndicatorFill(int start, int end, int indicator, int value); }; + +#ifdef SCI_NAMESPACE +} +#endif
Modified: trunk/scintilla/Editor.cxx =================================================================== --- trunk/scintilla/Editor.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/Editor.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -23,15 +23,22 @@ #include "Partitioning.h" #include "CellBuffer.h" #include "KeyMap.h" +#include "RunStyles.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" #include "CharClassify.h" +#include "Decoration.h" #include "Document.h" +#include "PositionCache.h" #include "Editor.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + /* return whether this modification represents an operation that may reasonably be deferred (not done now OR [possibly] at all) @@ -72,268 +79,11 @@ Idler::Idler() : state(false), idlerID(0) {}
-LineLayout::LineLayout(int maxLineLength_) : - lineStarts(0), - lenLineStarts(0), - lineNumber(-1), - inCache(false), - maxLineLength(-1), - numCharsInLine(0), - validity(llInvalid), - xHighlightGuide(0), - highlightColumn(0), - selStart(0), - selEnd(0), - containsCaret(false), - edgeColumn(0), - chars(0), - styles(0), - styleBitsSet(0), - indicators(0), - positions(0), - hsStart(0), - hsEnd(0), - widthLine(wrapWidthInfinite), - lines(1) { - Resize(maxLineLength_); +static inline bool IsControlCharacter(int ch) { + // iscntrl returns true for lots of chars > 127 which are displayable + return ch >= 0 && ch < ' '; }
-LineLayout::~LineLayout() { - Free(); -} - -void LineLayout::Resize(int maxLineLength_) { - if (maxLineLength_ > maxLineLength) { - Free(); - chars = new char[maxLineLength_ + 1]; - styles = new unsigned char[maxLineLength_ + 1]; - indicators = new char[maxLineLength_ + 1]; - // Extra position allocated as sometimes the Windows - // GetTextExtentExPoint API writes an extra element. - positions = new int[maxLineLength_ + 1 + 1]; - maxLineLength = maxLineLength_; - } -} - -void LineLayout::Free() { - delete []chars; - chars = 0; - delete []styles; - styles = 0; - delete []indicators; - indicators = 0; - delete []positions; - positions = 0; - delete []lineStarts; - lineStarts = 0; -} - -void LineLayout::Invalidate(validLevel validity_) { - if (validity > validity_) - validity = validity_; -} - -void LineLayout::SetLineStart(int line, int start) { - if ((line >= lenLineStarts) && (line != 0)) { - int newMaxLines = line + 20; - int *newLineStarts = new int[newMaxLines]; - if (!newLineStarts) - return; - for (int i = 0; i < newMaxLines; i++) { - if (i < lenLineStarts) - newLineStarts[i] = lineStarts[i]; - else - newLineStarts[i] = 0; - } - delete []lineStarts; - lineStarts = newLineStarts; - lenLineStarts = newMaxLines; - } - lineStarts[line] = start; -} - -void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[], - char bracesMatchStyle, int xHighlight) { - if (rangeLine.ContainsCharacter(braces[0])) { - int braceOffset = braces[0] - rangeLine.start; - if (braceOffset < numCharsInLine) { - bracePreviousStyles[0] = styles[braceOffset]; - styles[braceOffset] = bracesMatchStyle; - } - } - if (rangeLine.ContainsCharacter(braces[1])) { - int braceOffset = braces[1] - rangeLine.start; - if (braceOffset < numCharsInLine) { - bracePreviousStyles[1] = styles[braceOffset]; - styles[braceOffset] = bracesMatchStyle; - } - } - if ((braces[0] >= rangeLine.start && braces[1] <= rangeLine.end) || - (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) { - xHighlightGuide = xHighlight; - } -} - -void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[]) { - if (rangeLine.ContainsCharacter(braces[0])) { - int braceOffset = braces[0] - rangeLine.start; - if (braceOffset < numCharsInLine) { - styles[braceOffset] = bracePreviousStyles[0]; - } - } - if (rangeLine.ContainsCharacter(braces[1])) { - int braceOffset = braces[1] - rangeLine.start; - if (braceOffset < numCharsInLine) { - styles[braceOffset] = bracePreviousStyles[1]; - } - } - xHighlightGuide = 0; -} - -LineLayoutCache::LineLayoutCache() : - level(0), length(0), size(0), cache(0), - allInvalidated(false), styleClock(-1), useCount(0) { - Allocate(0); -} - -LineLayoutCache::~LineLayoutCache() { - Deallocate(); -} - -void LineLayoutCache::Allocate(int length_) { - PLATFORM_ASSERT(cache == NULL); - allInvalidated = false; - length = length_; - size = length; - if (size > 1) { - size = (size / 16 + 1) * 16; - } - if (size > 0) { - cache = new LineLayout * [size]; - } - for (int i = 0; i < size; i++) - cache[i] = 0; -} - -void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) { - PLATFORM_ASSERT(useCount == 0); - int lengthForLevel = 0; - if (level == llcCaret) { - lengthForLevel = 1; - } else if (level == llcPage) { - lengthForLevel = linesOnScreen + 1; - } else if (level == llcDocument) { - lengthForLevel = linesInDoc; - } - if (lengthForLevel > size) { - Deallocate(); - Allocate(lengthForLevel); - } else { - if (lengthForLevel < length) { - for (int i = lengthForLevel; i < length; i++) { - delete cache[i]; - cache[i] = 0; - } - } - length = lengthForLevel; - } - PLATFORM_ASSERT(length == lengthForLevel); - PLATFORM_ASSERT(cache != NULL || length == 0); -} - -void LineLayoutCache::Deallocate() { - PLATFORM_ASSERT(useCount == 0); - for (int i = 0; i < length; i++) - delete cache[i]; - delete []cache; - cache = 0; - length = 0; - size = 0; -} - -void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) { - if (cache && !allInvalidated) { - for (int i = 0; i < length; i++) { - if (cache[i]) { - cache[i]->Invalidate(validity_); - } - } - if (validity_ == LineLayout::llInvalid) { - allInvalidated = true; - } - } -} - -void LineLayoutCache::SetLevel(int level_) { - allInvalidated = false; - if ((level_ != -1) && (level != level_)) { - level = level_; - Deallocate(); - } -} - -LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_, - int linesOnScreen, int linesInDoc) { - AllocateForLevel(linesOnScreen, linesInDoc); - if (styleClock != styleClock_) { - Invalidate(LineLayout::llCheckTextAndStyle); - styleClock = styleClock_; - } - allInvalidated = false; - int pos = -1; - LineLayout *ret = 0; - if (level == llcCaret) { - pos = 0; - } else if (level == llcPage) { - if (lineNumber == lineCaret) { - pos = 0; - } else if (length > 1) { - pos = 1 + (lineNumber % (length - 1)); - } - } else if (level == llcDocument) { - pos = lineNumber; - } - if (pos >= 0) { - PLATFORM_ASSERT(useCount == 0); - if (cache && (pos < length)) { - if (cache[pos]) { - if ((cache[pos]->lineNumber != lineNumber) || - (cache[pos]->maxLineLength < maxChars)) { - delete cache[pos]; - cache[pos] = 0; - } - } - if (!cache[pos]) { - cache[pos] = new LineLayout(maxChars); - } - if (cache[pos]) { - cache[pos]->lineNumber = lineNumber; - cache[pos]->inCache = true; - ret = cache[pos]; - useCount++; - } - } - } - - if (!ret) { - ret = new LineLayout(maxChars); - ret->lineNumber = lineNumber; - } - - return ret; -} - -void LineLayoutCache::Dispose(LineLayout *ll) { - allInvalidated = false; - if (ll) { - if (!ll->inCache) { - delete ll; - } else { - useCount--; - } - } -} - Editor::Editor() { ctrlID = 0;
@@ -360,7 +110,7 @@ dwelling = false; ptMouseLast.x = 0; ptMouseLast.y = 0; - inDragDrop = false; + inDragDrop = ddNone; dropWentOutside = false; posDrag = invalidPosition; posDrop = invalidPosition; @@ -444,6 +194,7 @@ hsEnd = -1;
llc.SetLevel(LineLayoutCache::llcCaret); + posCache.SetSize(0x400); }
Editor::~Editor() { @@ -476,6 +227,7 @@ palette.Release(); DropGraphics(); llc.Invalidate(LineLayout::llInvalid); + posCache.Clear(); if (selType == selRectangle) { xStartSelect = XFromPosition(anchor); xEndSelect = XFromPosition(currentPos); @@ -548,11 +300,6 @@ } }
-static inline bool IsControlCharacter(int ch) { - // iscntrl returns true for lots of chars > 127 which are displayable - return ch >= 0 && ch < ' '; -} - const char *ControlCharacterString(unsigned char ch) { const char *reps[] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", @@ -592,6 +339,10 @@ } };
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + /** * Allows to iterate through the lines of a selection. * Althought it can be called for a stream selection, in most cases @@ -670,6 +421,10 @@ } };
+#ifdef SCI_NAMESPACE +} +#endif + Point Editor::LocationFromPosition(int pos) { Point pt; RefreshStyleData(); @@ -724,10 +479,6 @@ posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine)); }
-static inline bool IsEOLChar(char ch) { - return (ch == '\r') || (ch == '\n'); -} - int Editor::PositionFromLocation(Point pt) { RefreshStyleData(); pt.x = pt.x - vs.fixedColumnWidth + xOffset; @@ -750,18 +501,19 @@ int subLine = visibleLine - lineStartSet; if (subLine < ll->lines) { int lineStart = ll->LineStart(subLine); - int lineEnd = ll->LineStart(subLine + 1); + int lineEnd = ll->LineLastVisible(subLine); int subLineStart = ll->positions[lineStart];
if (actualWrapVisualStartIndent != 0) { if (lineStart != 0) // Wrapped pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth; } - for (int i = lineStart; i < lineEnd; i++) { - if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || - IsEOLChar(ll->chars[i])) { + int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd); + while (i < lineEnd) { + if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) { return pdoc->MovePositionOutsideChar(i + posLineStart, 1); } + i++; } return lineEnd + posLineStart; } @@ -799,18 +551,19 @@ int subLine = visibleLine - lineStartSet; if (subLine < ll->lines) { int lineStart = ll->LineStart(subLine); - int lineEnd = ll->LineStart(subLine + 1); + int lineEnd = ll->LineLastVisible(subLine); int subLineStart = ll->positions[lineStart];
if (actualWrapVisualStartIndent != 0) { if (lineStart != 0) // Wrapped pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth; } - for (int i = lineStart; i < lineEnd; i++) { - if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || - IsEOLChar(ll->chars[i])) { + int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd); + while (i < lineEnd) { + if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) { return pdoc->MovePositionOutsideChar(i + posLineStart, 1); } + i++; } if (pt.x < (ll->positions[lineEnd] - subLineStart)) { return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1); @@ -839,19 +592,20 @@ retVal = ll->numCharsInLine + posLineStart; int subLine = 0; int lineStart = ll->LineStart(subLine); - int lineEnd = ll->LineStart(subLine + 1); + int lineEnd = ll->LineLastVisible(subLine); int subLineStart = ll->positions[lineStart];
if (actualWrapVisualStartIndent != 0) { if (lineStart != 0) // Wrapped x -= actualWrapVisualStartIndent * vs.aveCharWidth; } - for (int i = lineStart; i < lineEnd; i++) { - if (x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || - IsEOLChar(ll->chars[i])) { + int i = ll->FindBefore(x + subLineStart, lineStart, lineEnd); + while (i < lineEnd) { + if ((x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) { retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1); break; } + i++; } } return retVal; @@ -1125,7 +879,7 @@ ShowCaretAtCurrentPosition(); // Perform redraw rather than scroll if many lines would be redrawn anyway. #ifndef UNDER_CE - if (abs(linesToMove) <= 10) { + if ((abs(linesToMove) <= 10) && (paintState == notPainting)) { ScrollText(linesToMove); } else { Redraw(); @@ -1439,6 +1193,10 @@ xOffsetNew = pt.x + xOffset - rcClient.left; } else if (pt.x + xOffset >= rcClient.right + xOffsetNew) { xOffsetNew = pt.x + xOffset - rcClient.right + 1; + if (vs.caretStyle == CARETSTYLE_BLOCK) { + // Ensure we can see a good portion of the block caret + xOffsetNew += vs.aveCharWidth; + } } if (xOffsetNew < 0) { xOffsetNew = 0; @@ -1627,6 +1385,7 @@ if (prevNonWS) { // Ensure at least one space separating previous lines pdoc->InsertChar(pos, ' '); + targetEnd++; } } else { prevNonWS = pdoc->CharAt(pos) != ' '; @@ -1910,10 +1669,6 @@ surface->LineTo(xhead, ymid + ydiff); }
-static bool IsSpaceOrTab(char ch) { - return ch == ' ' || ch == '\t'; -} - LineLayout *Editor::RetrieveLineLayout(int lineNumber) { int posLineStart = pdoc->LineStart(lineNumber); int posLineEnd = pdoc->LineStart(lineNumber + 1); @@ -1932,6 +1687,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll, int width) { if (!ll) return; + PLATFORM_ASSERT(line < pdoc->LinesTotal()); PLATFORM_ASSERT(ll->chars != NULL); int posLineStart = pdoc->LineStart(line); @@ -2067,7 +1823,7 @@ ll->positions[charInLine + 1] = vstyle.styles[ll->styles[charInLine]].spaceWidth; } else { lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic; - surface->MeasureWidths(vstyle.styles[ll->styles[charInLine]].font, ll->chars + startseg, + posCache.MeasureWidths(surface, vstyle, ll->styles[charInLine], ll->chars + startseg, lenSeg, ll->positions + startseg + 1); } } @@ -2107,8 +1863,6 @@ } ll->lines = 0; // Calculate line start positions based upon width. - // For now this is simplistic - wraps on byte rather than character and - // in the middle of words. Should search for spaces or style changes. int lastGoodBreak = 0; int lastLineStart = 0; int startOffset = 0; @@ -2173,7 +1927,7 @@ return vsDraw.edgecolour.allocated; if (inHotspot && vsDraw.hotspotBackgroundSet) return vsDraw.hotspotBackground.allocated; - if (overrideBackground) + if (overrideBackground && (styleMain != STYLE_BRACELIGHT) && (styleMain != STYLE_BRACEBAD)) return background; } return vsDraw.styles[styleMain].back.allocated; @@ -2307,6 +2061,73 @@ } }
+void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart, + PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under) { + // Draw decorators + const int posLineStart = pdoc->LineStart(line); + const int lineStart = ll->LineStart(subLine); + const int subLineStart = ll->positions[lineStart]; + const int posLineEnd = posLineStart + lineEnd; + + if (!under) { + // 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++) { + // look for starts... + if (startPos < 0) { + // NOT in indicator run, looking for START + if (indicPos < lineEnd && (ll->indicators[indicPos] & mask)) + startPos = indicPos; + } + // ... or ends + if (startPos >= 0) { + // IN indicator run, looking for END + if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) { + // AT end of indicator run, DRAW it! + PRectangle rcIndic( + ll->positions[startPos] + xStart - subLineStart, + rcLine.top + vsDraw.maxAscent, + ll->positions[indicPos] + xStart - subLineStart, + rcLine.top + vsDraw.maxAscent + 3); + vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine); + // RESET control var + startPos = -1; + } + } + } + mask <<= 1; + } + } + + for (Decoration *deco=pdoc->decorations.root; deco; deco = deco->next) { + if (under == vsDraw.indicators[deco->indicator].under) { + int startPos = posLineStart + subLineStart; + if (!deco->rs.ValueAt(startPos)) { + startPos = deco->rs.EndRun(startPos); + } + while ((startPos < posLineEnd) && (deco->rs.ValueAt(startPos))) { + int endPos = deco->rs.EndRun(startPos); + if (endPos > posLineEnd) + endPos = posLineEnd; + PRectangle rcIndic( + ll->positions[startPos - posLineStart] + xStart - subLineStart, + rcLine.top + vsDraw.maxAscent, + ll->positions[endPos - posLineStart] + xStart - subLineStart, + rcLine.top + vsDraw.maxAscent + 3); + vsDraw.indicators[deco->indicator].Draw(surface, rcIndic, rcLine); + startPos = deco->rs.EndRun(endPos); + } + } + } +} + void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, PRectangle rcLine, LineLayout *ll, int subLine) {
@@ -2373,6 +2194,10 @@ lineEnd = ll->LineStart(subLine + 1); }
+ ColourAllocated wrapColour = vsDraw.styles[STYLE_DEFAULT].fore.allocated; + if (vsDraw.whitespaceForegroundSet) + wrapColour = vsDraw.whitespaceForeground.allocated; + bool drawWrapMarkEnd = false;
if (wrapVisualFlags & SC_WRAPVISUALFLAG_END) { @@ -2396,7 +2221,8 @@ rcPlace.right = rcPlace.left + actualWrapVisualStartIndent * vsDraw.aveCharWidth;
// default bgnd here.. - surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated); + surface->FillRectangle(rcSegment, overrideBackground ? background : + vsDraw.styles[STYLE_DEFAULT].back.allocated);
// main line style would be below but this would be inconsistent with end markers // also would possibly not be the style at wrap point @@ -2410,273 +2236,253 @@ else rcPlace.right = rcPlace.left + vsDraw.aveCharWidth;
- DrawWrapMarker(surface, rcPlace, false, vsDraw.whitespaceForeground.allocated); + DrawWrapMarker(surface, rcPlace, false, wrapColour); }
xStart += actualWrapVisualStartIndent * vsDraw.aveCharWidth; } }
- int i; + // Does not take margin into account but not significant + int xStartVisible = subLineStart - xStart;
+ BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, xStartVisible); + int next = bfBack.First(); + // Background drawing loop - for (i = lineStart; twoPhaseDraw && (i < lineEnd); i++) { + while (twoPhaseDraw && (next < lineEnd)) {
+ startseg = next; + next = bfBack.Next(); + int i = next - 1; int iDoc = i + posLineStart; - // If there is the end of a style run for any reason - if ((ll->styles[i] != ll->styles[i + 1]) || - i == (lineEnd - 1) || - IsControlCharacter(ll->chars[i]) || IsControlCharacter(ll->chars[i + 1]) || - ((ll->selStart != ll->selEnd) && ((iDoc + 1 == ll->selStart) || (iDoc + 1 == ll->selEnd))) || - (i == (ll->edgeColumn - 1))) { - rcSegment.left = ll->positions[startseg] + xStart - subLineStart; - rcSegment.right = ll->positions[i + 1] + xStart - subLineStart; - // Only try to draw if really visible - enhances performance by not calling environment to - // draw strings that are completely past the right side of the window. - if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { - int styleMain = ll->styles[i]; - bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd); - bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); - ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll); - if (ll->chars[i] == '\t') { - // Tab display - if (drawWhitespaceBackground && - (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) - textBack = vsDraw.whitespaceBackground.allocated; - surface->FillRectangle(rcSegment, textBack); - } else if (IsControlCharacter(ll->chars[i])) { - // Control character display - inIndentation = false; - surface->FillRectangle(rcSegment, textBack); - } else { - // Normal text display - surface->FillRectangle(rcSegment, textBack); - if (vsDraw.viewWhitespace != wsInvisible || - (inIndentation && vsDraw.viewIndentationGuides)) { - for (int cpos = 0; cpos <= i - startseg; cpos++) { - if (ll->chars[cpos + startseg] == ' ') { - if (drawWhitespaceBackground && - (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { - PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top, - ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom); - surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground.allocated); - } - } else { - inIndentation = false; + + rcSegment.left = ll->positions[startseg] + xStart - subLineStart; + rcSegment.right = ll->positions[i + 1] + xStart - subLineStart; + // Only try to draw if really visible - enhances performance by not calling environment to + // draw strings that are completely past the right side of the window. + if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { + // Clip to line rectangle, since may have a huge position which will not work with some platforms + rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left); + rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right); + + int styleMain = ll->styles[i]; + bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd); + bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); + ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll); + if (ll->chars[i] == '\t') { + // Tab display + if (drawWhitespaceBackground && + (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) + textBack = vsDraw.whitespaceBackground.allocated; + surface->FillRectangle(rcSegment, textBack); + } else if (IsControlCharacter(ll->chars[i])) { + // Control character display + inIndentation = false; + surface->FillRectangle(rcSegment, textBack); + } else { + // Normal text display + surface->FillRectangle(rcSegment, textBack); + if (vsDraw.viewWhitespace != wsInvisible || + (inIndentation && vsDraw.viewIndentationGuides)) { + for (int cpos = 0; cpos <= i - startseg; cpos++) { + if (ll->chars[cpos + startseg] == ' ') { + if (drawWhitespaceBackground && + (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { + PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top, + ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom); + surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground.allocated); } + } else { + inIndentation = false; } } } - } else if (rcSegment.left > rcLine.right) { - break; } - startseg = i + 1; + } else if (rcSegment.left > rcLine.right) { + break; } }
if (twoPhaseDraw) { DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd, xStart, subLine, subLineStart, overrideBackground, background, - drawWrapMarkEnd, vsDraw.whitespaceForeground.allocated); + drawWrapMarkEnd, wrapColour); }
+ DrawIndicators(surface, vsDraw, line, xStart, rcLine, ll, subLine, lineEnd, true); + + if (vsDraw.edgeState == EDGE_LINE) { + int edgeX = theEdge * vsDraw.spaceWidth; + rcSegment.left = edgeX + xStart; + rcSegment.right = rcSegment.left + 1; + surface->FillRectangle(rcSegment, vsDraw.edgecolour.allocated); + } + inIndentation = subLine == 0; // Do not handle indentation except on first subline. - startseg = ll->LineStart(subLine); // Foreground drawing loop - for (i = lineStart; i < lineEnd; i++) { + BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, xStartVisible); + next = bfFore.First();
+ while (next < lineEnd) { + + startseg = next; + next = bfFore.Next(); + int i = next - 1; + int iDoc = i + posLineStart; - // If there is the end of a style run for any reason - if ((ll->styles[i] != ll->styles[i + 1]) || - i == (lineEnd - 1) || - IsControlCharacter(ll->chars[i]) || IsControlCharacter(ll->chars[i + 1]) || - ((ll->selStart != ll->selEnd) && ((iDoc + 1 == ll->selStart) || (iDoc + 1 == ll->selEnd))) || - (i == (ll->edgeColumn - 1))) { - rcSegment.left = ll->positions[startseg] + xStart - subLineStart; - rcSegment.right = ll->positions[i + 1] + xStart - subLineStart; - // Only try to draw if really visible - enhances performance by not calling environment to - // draw strings that are completely past the right side of the window. - if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { - int styleMain = ll->styles[i]; - ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated; - Font &textFont = vsDraw.styles[styleMain].font; - //hotspot foreground - if (ll->hsStart != -1 && iDoc >= ll->hsStart && iDoc < hsEnd) { - if (vsDraw.hotspotForegroundSet) - textFore = vsDraw.hotspotForeground.allocated; + + rcSegment.left = ll->positions[startseg] + xStart - subLineStart; + rcSegment.right = ll->positions[i + 1] + xStart - subLineStart; + // Only try to draw if really visible - enhances performance by not calling environment to + // draw strings that are completely past the right side of the window. + if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { + int styleMain = ll->styles[i]; + ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated; + Font &textFont = vsDraw.styles[styleMain].font; + //hotspot foreground + if (ll->hsStart != -1 && iDoc >= ll->hsStart && iDoc < hsEnd) { + if (vsDraw.hotspotForegroundSet) + textFore = vsDraw.hotspotForeground.allocated; + } + bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd); + if (inSelection && (vsDraw.selforeset)) { + textFore = vsDraw.selforeground.allocated; + } + bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); + ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll); + if (ll->chars[i] == '\t') { + // Tab display + if (!twoPhaseDraw) { + if (drawWhitespaceBackground && + (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) + textBack = vsDraw.whitespaceBackground.allocated; + surface->FillRectangle(rcSegment, textBack); } - bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd); - if (inSelection && (vsDraw.selforeset)) { - textFore = vsDraw.selforeground.allocated; + if ((vsDraw.viewWhitespace != wsInvisible) || ((inIndentation && vsDraw.viewIndentationGuides))) { + if (vsDraw.whitespaceForegroundSet) + textFore = vsDraw.whitespaceForeground.allocated; + surface->PenColour(textFore); } - bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); - ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll); - if (ll->chars[i] == '\t') { - // Tab display - if (!twoPhaseDraw) { - if (drawWhitespaceBackground && - (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) - textBack = vsDraw.whitespaceBackground.allocated; - surface->FillRectangle(rcSegment, textBack); - } - if ((vsDraw.viewWhitespace != wsInvisible) || ((inIndentation && vsDraw.viewIndentationGuides))) { - if (vsDraw.whitespaceForegroundSet) - textFore = vsDraw.whitespaceForeground.allocated; - surface->PenColour(textFore); - } - if (inIndentation && vsDraw.viewIndentationGuides) { - for (int xIG = ll->positions[i] / indentWidth * indentWidth; xIG < ll->positions[i + 1]; xIG += indentWidth) { - if (xIG >= ll->positions[i] && xIG > 0) { - DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIG + xStart, rcSegment, - (ll->xHighlightGuide == xIG)); - } + if (inIndentation && vsDraw.viewIndentationGuides) { + for (int xIG = ll->positions[i] / indentWidth * indentWidth; xIG < ll->positions[i + 1]; xIG += indentWidth) { + if (xIG >= ll->positions[i] && xIG > 0) { + DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIG + xStart, rcSegment, + (ll->xHighlightGuide == xIG)); } } - if (vsDraw.viewWhitespace != wsInvisible) { - if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { - PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, - rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); - DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); - } + } + if (vsDraw.viewWhitespace != wsInvisible) { + if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { + PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, + rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); + DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); } - } else if (IsControlCharacter(ll->chars[i])) { - // Control character display - inIndentation = false; - if (controlCharSymbol < 32) { - // Draw the character - const char *ctrlChar = ControlCharacterString(ll->chars[i]); - if (!twoPhaseDraw) { - surface->FillRectangle(rcSegment, textBack); - } - int normalCharHeight = surface->Ascent(ctrlCharsFont) - - surface->InternalLeading(ctrlCharsFont); - PRectangle rcCChar = rcSegment; - rcCChar.left = rcCChar.left + 1; - rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight; - rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1; - PRectangle rcCentral = rcCChar; - rcCentral.top++; - rcCentral.bottom--; - surface->FillRectangle(rcCentral, textFore); - PRectangle rcChar = rcCChar; - rcChar.left++; - rcChar.right--; - surface->DrawTextClipped(rcChar, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, ctrlChar, istrlen(ctrlChar), - textBack, textFore); - } else { - char cc[2] = { static_cast<char>(controlCharSymbol), '\0' }; - surface->DrawTextNoClip(rcSegment, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, - cc, 1, textBack, textFore); + } + } else if (IsControlCharacter(ll->chars[i])) { + // Control character display + inIndentation = false; + if (controlCharSymbol < 32) { + // Draw the character + const char *ctrlChar = ControlCharacterString(ll->chars[i]); + if (!twoPhaseDraw) { + surface->FillRectangle(rcSegment, textBack); } + int normalCharHeight = surface->Ascent(ctrlCharsFont) - + surface->InternalLeading(ctrlCharsFont); + PRectangle rcCChar = rcSegment; + rcCChar.left = rcCChar.left + 1; + rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight; + rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1; + PRectangle rcCentral = rcCChar; + rcCentral.top++; + rcCentral.bottom--; + surface->FillRectangle(rcCentral, textFore); + PRectangle rcChar = rcCChar; + rcChar.left++; + rcChar.right--; + surface->DrawTextClipped(rcChar, ctrlCharsFont, + rcSegment.top + vsDraw.maxAscent, ctrlChar, istrlen(ctrlChar), + textBack, textFore); } else { - // Normal text display - if (vsDraw.styles[styleMain].visible) { - if (twoPhaseDraw) { - surface->DrawTextTransparent(rcSegment, textFont, - rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, - i - startseg + 1, textFore); - } else { - surface->DrawTextNoClip(rcSegment, textFont, - rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, - i - startseg + 1, textFore, textBack); - } + char cc[2] = { static_cast<char>(controlCharSymbol), '\0' }; + surface->DrawTextNoClip(rcSegment, ctrlCharsFont, + rcSegment.top + vsDraw.maxAscent, + cc, 1, textBack, textFore); + } + } else { + // Normal text display + if (vsDraw.styles[styleMain].visible) { + if (twoPhaseDraw) { + surface->DrawTextTransparent(rcSegment, textFont, + rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, + i - startseg + 1, textFore); + } else { + surface->DrawTextNoClip(rcSegment, textFont, + rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, + i - startseg + 1, textFore, textBack); } - if (vsDraw.viewWhitespace != wsInvisible || - (inIndentation && vsDraw.viewIndentationGuides)) { - for (int cpos = 0; cpos <= i - startseg; cpos++) { - if (ll->chars[cpos + startseg] == ' ') { - if (vsDraw.viewWhitespace != wsInvisible) { - if (vsDraw.whitespaceForegroundSet) - textFore = vsDraw.whitespaceForeground.allocated; - if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { - int xmid = (ll->positions[cpos + startseg] + ll->positions[cpos + startseg + 1]) / 2; - if (!twoPhaseDraw && drawWhitespaceBackground && - (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { - textBack = vsDraw.whitespaceBackground.allocated; - PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top, ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom); - surface->FillRectangle(rcSpace, textBack); - } - PRectangle rcDot(xmid + xStart - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0); - rcDot.right = rcDot.left + 1; - rcDot.bottom = rcDot.top + 1; - surface->FillRectangle(rcDot, textFore); + } + if (vsDraw.viewWhitespace != wsInvisible || + (inIndentation && vsDraw.viewIndentationGuides)) { + for (int cpos = 0; cpos <= i - startseg; cpos++) { + if (ll->chars[cpos + startseg] == ' ') { + if (vsDraw.viewWhitespace != wsInvisible) { + if (vsDraw.whitespaceForegroundSet) + textFore = vsDraw.whitespaceForeground.allocated; + if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { + int xmid = (ll->positions[cpos + startseg] + ll->positions[cpos + startseg + 1]) / 2; + if (!twoPhaseDraw && drawWhitespaceBackground && + (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { + textBack = vsDraw.whitespaceBackground.allocated; + PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top, ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom); + surface->FillRectangle(rcSpace, textBack); } + PRectangle rcDot(xmid + xStart - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0); + rcDot.right = rcDot.left + 1; + rcDot.bottom = rcDot.top + 1; + surface->FillRectangle(rcDot, textFore); } - if (inIndentation && vsDraw.viewIndentationGuides) { - int startSpace = ll->positions[cpos + startseg]; - if (startSpace > 0 && (startSpace % indentWidth == 0)) { - DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, startSpace + xStart, rcSegment, - (ll->xHighlightGuide == ll->positions[cpos + startseg])); - } + } + if (inIndentation && vsDraw.viewIndentationGuides) { + int startSpace = ll->positions[cpos + startseg]; + if (startSpace > 0 && (startSpace % indentWidth == 0)) { + DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, startSpace + xStart, rcSegment, + (ll->xHighlightGuide == ll->positions[cpos + startseg])); } - } else { - inIndentation = false; } + } else { + inIndentation = false; } } } - if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd ) { - PRectangle rcUL = rcSegment; - rcUL.top = rcUL.top + vsDraw.maxAscent + 1; - rcUL.bottom = rcUL.top + 1; - if (vsDraw.hotspotForegroundSet) - surface->FillRectangle(rcUL, vsDraw.hotspotForeground.allocated); - else - surface->FillRectangle(rcUL, textFore); - } else if (vsDraw.styles[styleMain].underline) { - PRectangle rcUL = rcSegment; - rcUL.top = rcUL.top + vsDraw.maxAscent + 1; - rcUL.bottom = rcUL.top + 1; + } + if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd ) { + PRectangle rcUL = rcSegment; + rcUL.top = rcUL.top + vsDraw.maxAscent + 1; + rcUL.bottom = rcUL.top + 1; + if (vsDraw.hotspotForegroundSet) + surface->FillRectangle(rcUL, vsDraw.hotspotForeground.allocated); + else surface->FillRectangle(rcUL, textFore); - } - } else if (rcSegment.left > rcLine.right) { - break; + } else if (vsDraw.styles[styleMain].underline) { + PRectangle rcUL = rcSegment; + rcUL.top = rcUL.top + vsDraw.maxAscent + 1; + rcUL.bottom = rcUL.top + 1; + surface->FillRectangle(rcUL, textFore); } - startseg = i + 1; + } else if (rcSegment.left > rcLine.right) { + break; } }
- // 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++) { - // look for starts... - if (startPos < 0) { - // NOT in indicator run, looking for START - if (indicPos < lineEnd && (ll->indicators[indicPos] & mask)) - startPos = indicPos; - } - // ... or ends - if (startPos >= 0) { - // IN indicator run, looking for END - if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) { - // AT end of indicator run, DRAW it! - PRectangle rcIndic( - ll->positions[startPos] + xStart - subLineStart, - rcLine.top + vsDraw.maxAscent, - ll->positions[indicPos] + xStart - subLineStart, - rcLine.top + vsDraw.maxAscent + 3); - vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine); - // RESET control var - startPos = -1; - } - } - } - mask <<= 1; - } + DrawIndicators(surface, vsDraw, line, xStart, rcLine, ll, subLine, lineEnd, false); + // End of the drawing of the current line if (!twoPhaseDraw) { DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd, xStart, subLine, subLineStart, overrideBackground, background, - drawWrapMarkEnd, vsDraw.whitespaceForeground.allocated); + drawWrapMarkEnd, wrapColour); } if ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) && (ll->selStart >= 0) && (ll->selEnd >= 0)) { int startPosSel = (ll->selStart < posLineStart) ? posLineStart : ll->selStart; @@ -2684,17 +2490,12 @@ if (startPosSel < endPosSel) { rcSegment.left = xStart + ll->positions[startPosSel - posLineStart] - subLineStart; rcSegment.right = xStart + ll->positions[endPosSel - posLineStart] - subLineStart; + rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left); + rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right); SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha); } }
- if (vsDraw.edgeState == EDGE_LINE) { - int edgeX = theEdge * vsDraw.spaceWidth; - rcSegment.left = edgeX + xStart; - rcSegment.right = rcSegment.left + 1; - surface->FillRectangle(rcSegment, vsDraw.edgecolour.allocated); - } - // Draw any translucent whole line states rcSegment.left = xStart; rcSegment.right = rcLine.right - 1; @@ -2721,6 +2522,61 @@ } }
+void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret) { + + int lineStart = ll->LineStart(subLine); + int posBefore = posCaret; + int posAfter = MovePositionOutsideChar(posCaret+1, 1); + int numCharsToDraw = posAfter - posCaret; + + // Work out where the starting and ending offsets are. We need to + // see if the previous character shares horizontal space, such as a + // glyph / combining character. If so we'll need to draw that too. + int offsetFirstChar = offset; + int offsetLastChar = offset + (posAfter - posCaret); + while ((offsetLastChar - numCharsToDraw) >= lineStart) { + if ((ll->positions[offsetLastChar] - ll->positions[offsetLastChar - numCharsToDraw]) > 0) { + // The char does not share horizontal space + break; + } + // Char shares horizontal space, update the numChars to draw + // Update posBefore to point to the prev char + posBefore = MovePositionOutsideChar(posBefore-1, -1); + numCharsToDraw = posAfter - posBefore; + offsetFirstChar = offset - (posCaret - posBefore); + } + + // See if the next character shares horizontal space, if so we'll + // need to draw that too. + numCharsToDraw = offsetLastChar - offsetFirstChar; + while ((offsetLastChar < ll->LineStart(subLine + 1)) && (offsetLastChar <= ll->numCharsInLine)) { + // Update posAfter to point to the 2nd next char, this is where + // the next character ends, and 2nd next begins. We'll need + // to compare these two + posBefore = posAfter; + posAfter = MovePositionOutsideChar(posAfter+1, 1); + offsetLastChar = offset + (posAfter - posCaret); + if ((ll->positions[offsetLastChar] - ll->positions[offsetLastChar - (posAfter - posBefore)]) > 0) { + // The char does not share horizontal space + break; + } + // Char shares horizontal space, update the numChars to draw + numCharsToDraw = offsetLastChar - offsetFirstChar; + } + + // We now know what to draw, update the caret drawing rectangle + rcCaret.left = ll->positions[offsetFirstChar] - ll->positions[ll->LineStart(subLine)] + xStart; + rcCaret.right = ll->positions[offsetFirstChar+numCharsToDraw] - ll->positions[ll->LineStart(subLine)] + xStart; + + // This character is where the caret block is, we override the colours + // (inversed) for drawing the caret here. + int styleMain = ll->styles[offsetFirstChar]; + surface->DrawTextClipped(rcCaret, vsDraw.styles[styleMain].font, + rcCaret.top + vsDraw.maxAscent, ll->chars + offsetFirstChar, + numCharsToDraw, vsDraw.styles[styleMain].back.allocated, + vsDraw.caretcolour.allocated); +} + void Editor::RefreshPixMaps(Surface *surfaceWindow) { if (!pixmapSelPattern->Initialised()) { const int patternSize = 8; @@ -3022,35 +2878,57 @@ if (lineStart != 0) // Wrapped xposCaret += actualWrapVisualStartIndent * vs.aveCharWidth; } - int widthOverstrikeCaret; - if (posCaret == pdoc->Length()) { // At end of document - widthOverstrikeCaret = vs.aveCharWidth; - } else if ((posCaret - rangeLine.start) >= ll->numCharsInLine) { // At end of line - widthOverstrikeCaret = vs.aveCharWidth; - } else { - widthOverstrikeCaret = ll->positions[offset + 1] - ll->positions[offset]; - } - if (widthOverstrikeCaret < 3) // Make sure its visible - widthOverstrikeCaret = 3; - if (((caret.active && caret.on) || (posDrag >= 0)) && xposCaret >= 0) { + if ((xposCaret >= 0) && (vs.caretWidth > 0) && (vs.caretStyle != CARETSTYLE_INVISIBLE) && + ((posDrag >= 0) || (caret.active && caret.on))) { + bool caretAtEOF = false; + bool caretAtEOL = false; + bool drawBlockCaret = false; + int widthOverstrikeCaret; + int caretWidthOffset = 0; PRectangle rcCaret = rcLine; - int caretWidthOffset = 0; - if ((offset > 0) && (vs.caretWidth > 1)) + + if (posCaret == pdoc->Length()) { // At end of document + caretAtEOF = true; + widthOverstrikeCaret = vs.aveCharWidth; + } else if ((posCaret - rangeLine.start) >= ll->numCharsInLine) { // At end of line + caretAtEOL = true; + widthOverstrikeCaret = vs.aveCharWidth; + } else { + widthOverstrikeCaret = ll->positions[offset + 1] - ll->positions[offset]; + } + if (widthOverstrikeCaret < 3) // Make sure its visible + widthOverstrikeCaret = 3; + + if (offset > 0) caretWidthOffset = 1; // Move back so overlaps both character cells. if (posDrag >= 0) { + /* Dragging text, use a line caret */ rcCaret.left = xposCaret - caretWidthOffset; rcCaret.right = rcCaret.left + vs.caretWidth; - } else { - if (inOverstrike) { - rcCaret.top = rcCaret.bottom - 2; - rcCaret.left = xposCaret + 1; - rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1; + } else if (inOverstrike) { + /* Overstrike (insert mode), use a modified bar caret */ + rcCaret.top = rcCaret.bottom - 2; + rcCaret.left = xposCaret + 1; + rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1; + } else if (vs.caretStyle == CARETSTYLE_BLOCK) { + /* Block caret */ + rcCaret.left = xposCaret; + if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) { + drawBlockCaret = true; + rcCaret.right = xposCaret + widthOverstrikeCaret; } else { - rcCaret.left = xposCaret - caretWidthOffset; - rcCaret.right = rcCaret.left + vs.caretWidth; + rcCaret.right = xposCaret + vs.aveCharWidth; } + } else { + /* Line caret */ + rcCaret.left = xposCaret - caretWidthOffset; + rcCaret.right = rcCaret.left + vs.caretWidth; } - surface->FillRectangle(rcCaret, vs.caretcolour.allocated); + if (drawBlockCaret) { + DrawBlockCaret(surface, vs, ll, subLine, xStart, offset, posCaret, rcCaret); + } else { + surface->FillRectangle(rcCaret, vs.caretcolour.allocated); + } } } } @@ -3129,6 +3007,9 @@ return 0; }
+ // Can't use measurements cached for screen + posCache.Clear(); + ViewStyle vsPrint(vs);
// Modify the view style for printing as do not normally want any of the transient features to be printed @@ -3173,16 +3054,17 @@ vsPrint.styles[STYLE_LINENUMBER].back.desired = ColourDesired(0xff, 0xff, 0xff);
vsPrint.Refresh(*surfaceMeasure); - // Ensure colours are set up - vsPrint.RefreshColourPalette(palette, true); - vsPrint.RefreshColourPalette(palette, false); // Determining width must hapen after fonts have been realised in Refresh int lineNumberWidth = 0; if (lineNumberIndex >= 0) { lineNumberWidth = surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, "99999" lineNumberPrintSpace, 5 + istrlen(lineNumberPrintSpace)); vsPrint.ms[lineNumberIndex].width = lineNumberWidth; + vsPrint.Refresh(*surfaceMeasure); // Recalculate fixedColumnWidth } + // Ensure colours are set up + vsPrint.RefreshColourPalette(palette, true); + vsPrint.RefreshColourPalette(palette, false);
int linePrintStart = pdoc->LineFromPosition(pfr->chrg.cpMin); int linePrintLast = linePrintStart + (pfr->rc.bottom - pfr->rc.top) / vsPrint.lineHeight - 1; @@ -3201,14 +3083,14 @@ // Ensure we are styled to where we are formatting. pdoc->EnsureStyledTo(endPosPrint);
- int xStart = vsPrint.fixedColumnWidth + pfr->rc.left + lineNumberWidth; + int xStart = vsPrint.fixedColumnWidth + pfr->rc.left; int ypos = pfr->rc.top;
int lineDoc = linePrintStart;
int nPrintPos = pfr->chrg.cpMin; int visibleLine = 0; - int widthPrint = pfr->rc.Width() - lineNumberWidth; + int widthPrint = pfr->rc.Width() - vsPrint.fixedColumnWidth; if (printWrapState == eWrapNone) widthPrint = LineLayout::wrapWidthInfinite;
@@ -3230,7 +3112,7 @@ ll.containsCaret = false;
PRectangle rcLine; - rcLine.left = pfr->rc.left + lineNumberWidth; + rcLine.left = pfr->rc.left; rcLine.top = ypos; rcLine.right = pfr->rc.right - 1; rcLine.bottom = ypos + vsPrint.lineHeight; @@ -3259,7 +3141,7 @@ PRectangle rcNumber = rcLine; rcNumber.right = rcNumber.left + lineNumberWidth; // Right justify - rcNumber.left -= surfaceMeasure->WidthText( + rcNumber.left = rcNumber.right - surfaceMeasure->WidthText( vsPrint.styles[STYLE_LINENUMBER].font, number, istrlen(number)); surface->FlushCachedState(); surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font, @@ -3292,6 +3174,9 @@ ++lineDoc; }
+ // Clear cache so measurements are not used for screen + posCache.Clear(); + return nPrintPos; }
@@ -3631,11 +3516,13 @@ NotifyParent(scn); }
-void Editor::NotifyDoubleClick(Point pt, bool) { +void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) { SCNotification scn = {0}; scn.nmhdr.code = SCN_DOUBLECLICK; scn.line = LineFromLocation(pt); scn.position = PositionFromLocationClose(pt); + scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | + (alt ? SCI_ALT : 0); NotifyParent(scn); }
@@ -3669,6 +3556,18 @@ NotifyParent(scn); }
+void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt) { + int mask = pdoc->decorations.AllOnFor(position); + if ((click && mask) || pdoc->decorations.clickNotified) { + SCNotification scn = {0}; + pdoc->decorations.clickNotified = click; + scn.nmhdr.code = click ? SCN_INDICATORCLICK : SCN_INDICATORRELEASE; + scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); + scn.position = position; + NotifyParent(scn); + } +} + bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) { int marginClicked = -1; int x = 0; @@ -3771,8 +3670,10 @@ if (paintState == painting) { CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length)); } - if (mh.modificationType & SC_MOD_CHANGESTYLE) { - pdoc->IncrementStyleClock(); + if (mh.modificationType & (SC_MOD_CHANGESTYLE|SC_MOD_CHANGEINDICATOR)) { + if (mh.modificationType & SC_MOD_CHANGESTYLE) { + pdoc->IncrementStyleClock(); + } if (paintState == notPainting) { if (mh.position < pdoc->LineStart(topLine)) { // Styling performed before this view @@ -3781,7 +3682,9 @@ InvalidateRange(mh.position, mh.position + mh.length); } } - llc.Invalidate(LineLayout::llCheckTextAndStyle); + if (mh.modificationType & SC_MOD_CHANGESTYLE) { + llc.Invalidate(LineLayout::llCheckTextAndStyle); + } } else { // Move selection and brace highlights if (mh.modificationType & SC_MOD_INSERTTEXT) { @@ -3789,11 +3692,13 @@ anchor = MovePositionForInsertion(anchor, mh.position, mh.length); braces[0] = MovePositionForInsertion(braces[0], mh.position, mh.length); braces[1] = MovePositionForInsertion(braces[1], mh.position, mh.length); + pdoc->decorations.InsertSpace(mh.position, mh.length); } else if (mh.modificationType & SC_MOD_DELETETEXT) { currentPos = MovePositionForDeletion(currentPos, mh.position, mh.length); anchor = MovePositionForDeletion(anchor, mh.position, mh.length); braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length); braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length); + pdoc->decorations.DeleteRange(mh.position, mh.length); } if (cs.LinesDisplayed() < cs.LinesInDoc()) { // Some lines are hidden so may need shown. @@ -3863,7 +3768,7 @@
// If client wants to see this modification if (mh.modificationType & modEventMask) { - if ((mh.modificationType & SC_MOD_CHANGESTYLE) == 0) { + if ((mh.modificationType & (SC_MOD_CHANGESTYLE|SC_MOD_CHANGEINDICATOR)) == 0) { // Real modification made to text of document. NotifyChange(); // Send EN_CHANGE } @@ -4019,7 +3924,10 @@ // I consider only the caretYSlop, and ignore the caretYPolicy-- is that a problem? int currentLine = pdoc->LineFromPosition(currentPos); int topStutterLine = topLine + caretYSlop; - int bottomStutterLine = topLine + LinesToScroll() - caretYSlop; + int bottomStutterLine = + pdoc->LineFromPosition(PositionFromLocation( + Point(lastXChosen, direction * vs.lineHeight * LinesToScroll()))) + - caretYSlop - 1;
if (stuttered && (direction < 0 && currentLine > topStutterLine)) { topLineNew = topLine; @@ -4072,32 +3980,23 @@ void Editor::LineTranspose() { int line = pdoc->LineFromPosition(currentPos); if (line > 0) { + pdoc->BeginUndoAction(); int startPrev = pdoc->LineStart(line - 1); int endPrev = pdoc->LineEnd(line - 1); int start = pdoc->LineStart(line); int end = pdoc->LineEnd(line); - int startNext = pdoc->LineStart(line + 1); - if (end < pdoc->Length()) { - end = startNext; - char *thisLine = CopyRange(start, end); - pdoc->DeleteChars(start, end - start); - if (pdoc->InsertString(startPrev, thisLine, end - start)) { - MovePositionTo(startPrev + end - start); - } - delete []thisLine; - } else { - // Last line so line has no line end - char *thisLine = CopyRange(start, end); - char *prevEnd = CopyRange(endPrev, start); - pdoc->DeleteChars(endPrev, end - endPrev); - pdoc->InsertString(startPrev, thisLine, end - start); - if (pdoc->InsertString(startPrev + end - start, prevEnd, start - endPrev)) { - MovePositionTo(startPrev + end - endPrev); - } - delete []thisLine; - delete []prevEnd; - } - + char *line1 = CopyRange(startPrev, endPrev); + int len1 = endPrev - startPrev; + char *line2 = CopyRange(start, end); + int len2 = end - start; + pdoc->DeleteChars(start, len2); + pdoc->DeleteChars(startPrev, len1); + pdoc->InsertString(startPrev, line2, len2); + pdoc->InsertString(start - len1 + len2, line1, len1); + MovePositionTo(start - len1 + len2); + delete []line1; + delete []line2; + pdoc->EndUndoAction(); } }
@@ -4940,6 +4839,13 @@ wMain.SetCursor(static_castWindow::Cursor(cursorMode)); }
+bool Editor::DragThreshold(Point ptStart, Point ptNow) { + int xMove = ptStart.x - ptNow.x; + int yMove = ptStart.y - ptNow.y; + int distanceSquared = xMove * xMove + yMove * yMove; + return distanceSquared > 16; +} + void Editor::StartDrag() { // Always handled by subclasses //SetMouseCapture(true); @@ -4947,8 +4853,8 @@ }
void Editor::DropAt(int position, const char *value, bool moving, bool rectangular) { - //Platform::DebugPrintf("DropAt %d\n", inDragDrop); - if (inDragDrop) + //Platform::DebugPrintf("DropAt %d %d\n", inDragDrop, position); + if (inDragDrop == ddDragging) dropWentOutside = false;
int positionWasInSelection = PositionInSelection(position); @@ -4956,7 +4862,7 @@ bool positionOnEdgeOfSelection = (position == SelectionStart()) || (position == SelectionEnd());
- if ((!inDragDrop) || !(0 == positionWasInSelection) || + if ((inDragDrop != ddDragging) || !(0 == positionWasInSelection) || (positionOnEdgeOfSelection && !moving)) {
int selStart = SelectionStart(); @@ -4965,7 +4871,7 @@ pdoc->BeginUndoAction();
int positionAfterDeletion = position; - if (inDragDrop && moving) { + if ((inDragDrop == ddDragging) && moving) { // Remove dragged out text if (rectangular || selType == selLines) { SelectionLineIterator lineIterator(this); @@ -4999,7 +4905,7 @@ } pdoc->EndUndoAction(); } - } else if (inDragDrop) { + } else if (inDragDrop == ddDragging) { SetEmptySelection(position); } } @@ -5101,17 +5007,19 @@ }
void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { - //Platform::DebugPrintf("Scintilla:ButtonDown %d %d = %d alt=%d\n", curTime, lastClickTime, curTime - lastClickTime, alt); + //Platform::DebugPrintf("ButtonDown %d %d = %d alt=%d %d\n", curTime, lastClickTime, curTime - lastClickTime, alt, inDragDrop); ptMouseLast = pt; int newPos = PositionFromLocation(pt); newPos = MovePositionOutsideChar(newPos, currentPos - newPos); - inDragDrop = false; + inDragDrop = ddNone; moveExtendsSelection = false;
bool processed = NotifyMarginClick(pt, shift, ctrl, alt); if (processed) return;
+ NotifyIndicatorClick(true, newPos, shift, ctrl, alt); + bool inSelMargin = PointInSelMargin(pt); if (shift & !inSelMargin) { SetSelection(newPos); @@ -5151,7 +5059,7 @@ } //Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos); if (doubleClick) { - NotifyDoubleClick(pt, shift); + NotifyDoubleClick(pt, shift, ctrl, alt); if (PositionIsHotspot(newPos)) NotifyHotSpotDoubleClicked(newPos, shift, ctrl, alt); } @@ -5188,16 +5096,22 @@ NotifyHotSpotClicked(newPos, shift, ctrl, alt); } if (!shift) { - inDragDrop = PointInSelection(pt) && !SelectionEmpty(); + if (PointInSelection(pt) && !SelectionEmpty()) + inDragDrop = ddInitial; + else + inDragDrop = ddNone; } - if (inDragDrop) { - SetMouseCapture(false); - SetDragPosition(newPos); - CopySelectionRange(&drag); - StartDrag(); - } else { +#ifdef __APPLE__ + // we need to additionaly check if the mouse moved before we + // decide that we can in fact start a drag session. Currently + // only OSX will return anything but true. + if (inDragDrop == ddInitial && !Platform::WaitMouseMoved(pt)) { + inDragDrop = ddNone; + } +#endif + SetMouseCapture(true); + if (inDragDrop != ddInitial) { SetDragPosition(invalidPosition); - SetMouseCapture(true); if (!shift) { SetEmptySelection(newPos); } @@ -5266,6 +5180,20 @@ if ((ptMouseLast.x != pt.x) || (ptMouseLast.y != pt.y)) { DwellEnd(true); } + + int movePos = PositionFromLocation(pt); + movePos = MovePositionOutsideChar(movePos, currentPos - movePos); + + if (inDragDrop == ddInitial) { + if (DragThreshold(ptMouseLast, pt)) { + SetMouseCapture(false); + SetDragPosition(movePos); + CopySelectionRange(&drag); + StartDrag(); + } + return; + } + ptMouseLast = pt; //Platform::DebugPrintf("Move %d %d\n", pt.x, pt.y); if (HaveMouseCapture()) { @@ -5277,8 +5205,6 @@ autoScrollTimer.ticksToWait = autoScrollDelay;
// Adjust selection - int movePos = PositionFromLocation(pt); - movePos = MovePositionOutsideChar(movePos, currentPos - movePos); if (posDrag >= 0) { SetDragPosition(movePos); } else { @@ -5354,7 +5280,13 @@ }
void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { - //Platform::DebugPrintf("ButtonUp %d\n", HaveMouseCapture()); + //Platform::DebugPrintf("ButtonUp %d %d\n", HaveMouseCapture(), inDragDrop); + int newPos = PositionFromLocation(pt); + newPos = MovePositionOutsideChar(newPos, currentPos - newPos); + if (inDragDrop == ddInitial) { + inDragDrop = ddNone; + SetEmptySelection(newPos); + } if (HaveMouseCapture()) { if (PointInSelMargin(pt)) { DisplayCursor(Window::cursorReverseArrow); @@ -5366,7 +5298,8 @@ SetMouseCapture(false); int newPos = PositionFromLocation(pt); newPos = MovePositionOutsideChar(newPos, currentPos - newPos); - if (inDragDrop) { + NotifyIndicatorClick(false, newPos, false, false, false); + if (inDragDrop == ddDragging) { int selStart = SelectionStart(); int selEnd = SelectionEnd(); if (selStart < selEnd) { @@ -5405,7 +5338,7 @@ if (selType == selStream) { SetLastXChosen(); } - inDragDrop = false; + inDragDrop = ddNone; EnsureCaretVisible(false); } } @@ -6445,6 +6378,13 @@ case SCI_GETLAYOUTCACHE: return llc.GetLevel();
+ case SCI_SETPOSITIONCACHE: + posCache.SetSize(wParam); + break; + + case SCI_GETPOSITIONCACHE: + return posCache.GetSize(); + case SCI_SETSCROLLWIDTH: PLATFORM_ASSERT(wParam > 0); if ((wParam > 0) && (wParam != static_cast<unsigned int >(scrollWidth))) { @@ -6773,7 +6713,73 @@ InvalidateStyleRedraw(); } break; + case SCI_STYLEGETFORE: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].fore.desired.AsLong(); + else + return 0; + case SCI_STYLEGETBACK: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].back.desired.AsLong(); + else + return 0; + case SCI_STYLEGETBOLD: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].bold ? 1 : 0; + else + return 0; + case SCI_STYLEGETITALIC: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].italic ? 1 : 0; + else + return 0; + case SCI_STYLEGETEOLFILLED: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].eolFilled ? 1 : 0; + else + return 0; + case SCI_STYLEGETSIZE: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].size; + else + return 0; + case SCI_STYLEGETFONT: + if (lParam == 0) + return strlen(vs.styles[wParam].fontName);
+ if (wParam <= STYLE_MAX) + strcpy(CharPtrFromSPtr(lParam), vs.styles[wParam].fontName); + break; + case SCI_STYLEGETUNDERLINE: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].underline ? 1 : 0; + else + return 0; + case SCI_STYLEGETCASE: + if (wParam <= STYLE_MAX) + return static_cast<int>(vs.styles[wParam].caseForce); + else + return 0; + case SCI_STYLEGETCHARACTERSET: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].characterSet; + else + return 0; + case SCI_STYLEGETVISIBLE: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].visible ? 1 : 0; + else + return 0; + case SCI_STYLEGETCHANGEABLE: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].changeable ? 1 : 0; + else + return 0; + case SCI_STYLEGETHOTSPOT: + if (wParam <= STYLE_MAX) + return vs.styles[wParam].hotspot ? 1 : 0; + else + return 0; case SCI_STYLERESETDEFAULT: vs.ResetDefaultStyle(); InvalidateStyleRedraw(); @@ -6962,6 +6968,18 @@ case SCI_GETCARETFORE: return vs.caretcolour.desired.AsLong();
+ case SCI_SETCARETSTYLE: + if (wParam >= CARETSTYLE_INVISIBLE && wParam <= CARETSTYLE_BLOCK) + vs.caretStyle = wParam; + else + /* Default to the line caret */ + vs.caretStyle = CARETSTYLE_LINE; + InvalidateStyleRedraw(); + break; + + case SCI_GETCARETSTYLE: + return vs.caretStyle; + case SCI_SETCARETWIDTH: if (wParam <= 0) vs.caretWidth = 0; @@ -7009,6 +7027,47 @@ case SCI_INDICGETFORE: return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fore.desired.AsLong() : 0;
+ case SCI_INDICSETUNDER: + if (wParam <= INDIC_MAX) { + vs.indicators[wParam].under = lParam != 0; + InvalidateStyleRedraw(); + } + break; + + case SCI_INDICGETUNDER: + return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0; + + case SCI_SETINDICATORCURRENT: + pdoc->decorations.SetCurrentIndicator(wParam); + break; + case SCI_GETINDICATORCURRENT: + return pdoc->decorations.GetCurrentIndicator(); + case SCI_SETINDICATORVALUE: + pdoc->decorations.SetCurrentValue(wParam); + break; + case SCI_GETINDICATORVALUE: + return pdoc->decorations.GetCurrentValue(); + + case SCI_INDICATORFILLRANGE: + pdoc->DecorationFillRange(wParam, pdoc->decorations.GetCurrentValue(), lParam); + break; + + case SCI_INDICATORCLEARRANGE: + pdoc->DecorationFillRange(wParam, 0, lParam); + break; + + case SCI_INDICATORALLONFOR: + return pdoc->decorations.AllOnFor(wParam); + + case SCI_INDICATORVALUEAT: + return pdoc->decorations.ValueAt(wParam, lParam); + + case SCI_INDICATORSTART: + return pdoc->decorations.Start(wParam, lParam); + + case SCI_INDICATOREND: + return pdoc->decorations.End(wParam, lParam); + case SCI_LINEDOWN: case SCI_LINEDOWNEXTEND: case SCI_PARADOWN: @@ -7310,22 +7369,34 @@ InvalidateStyleRedraw(); break;
+ case SCI_GETHOTSPOTACTIVEFORE: + return vs.hotspotForeground.desired.AsLong(); + case SCI_SETHOTSPOTACTIVEBACK: vs.hotspotBackgroundSet = wParam != 0; vs.hotspotBackground.desired = ColourDesired(lParam); InvalidateStyleRedraw(); break;
+ case SCI_GETHOTSPOTACTIVEBACK: + return vs.hotspotBackground.desired.AsLong(); + case SCI_SETHOTSPOTACTIVEUNDERLINE: vs.hotspotUnderline = wParam != 0; InvalidateStyleRedraw(); break;
+ case SCI_GETHOTSPOTACTIVEUNDERLINE: + return vs.hotspotUnderline ? 1 : 0; + case SCI_SETHOTSPOTSINGLELINE: vs.hotspotSingleLine = wParam != 0; InvalidateStyleRedraw(); break;
+ case SCI_GETHOTSPOTSINGLELINE: + return vs.hotspotSingleLine ? 1 : 0; + case SCI_SETPASTECONVERTENDINGS: convertPastes = wParam != 0; break;
Modified: trunk/scintilla/Editor.h =================================================================== --- trunk/scintilla/Editor.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/Editor.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -8,6 +8,10 @@ #ifndef EDITOR_H #define EDITOR_H
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + /** */ class Caret { @@ -42,92 +46,6 @@ };
/** - */ -class LineLayout { -private: - friend class LineLayoutCache; - int *lineStarts; - int lenLineStarts; - /// Drawing is only performed for @a maxLineLength characters on each line. - int lineNumber; - bool inCache; -public: - enum { wrapWidthInfinite = 0x7ffffff }; - int maxLineLength; - int numCharsInLine; - enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity; - int xHighlightGuide; - bool highlightColumn; - int selStart; - int selEnd; - bool containsCaret; - int edgeColumn; - char *chars; - unsigned char *styles; - int styleBitsSet; - char *indicators; - int *positions; - char bracePreviousStyles[2]; - - // Hotspot support - int hsStart; - int hsEnd; - - // Wrapped line support - int widthLine; - int lines; - - LineLayout(int maxLineLength_); - virtual ~LineLayout(); - void Resize(int maxLineLength_); - void Free(); - void Invalidate(validLevel validity_); - int LineStart(int line) { - if (line <= 0) { - return 0; - } else if ((line >= lines) || !lineStarts) { - return numCharsInLine; - } else { - return lineStarts[line]; - } - } - void SetLineStart(int line, int start); - void SetBracesHighlight(Range rangeLine, Position braces[], - char bracesMatchStyle, int xHighlight); - void RestoreBracesHighlight(Range rangeLine, Position braces[]); -}; - -/** - */ -class LineLayoutCache { - int level; - int length; - int size; - LineLayout **cache; - bool allInvalidated; - int styleClock; - int useCount; - void Allocate(int length_); - void AllocateForLevel(int linesOnScreen, int linesInDoc); -public: - LineLayoutCache(); - virtual ~LineLayoutCache(); - void Deallocate(); - enum { - llcNone=SC_CACHE_NONE, - llcCaret=SC_CACHE_CARET, - llcPage=SC_CACHE_PAGE, - llcDocument=SC_CACHE_DOCUMENT - }; - void Invalidate(LineLayout::validLevel validity_); - void SetLevel(int level_); - int GetLevel() { return level; } - LineLayout *Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_, - int linesOnScreen, int linesInDoc); - void Dispose(LineLayout *ll); -}; - -/** * Hold a piece of text selected for copying or dragging. * The text is expected to hold a terminating '\0' and this is counted in len. */ @@ -229,6 +147,7 @@ Surface *pixmapIndentGuideHighlight;
LineLayoutCache llc; + PositionCache posCache;
KeyMap kmap;
@@ -246,7 +165,7 @@ bool dwelling; enum { selChar, selWord, selLine } selectionType; Point ptMouseLast; - bool inDragDrop; + enum { ddNone, ddInitial, ddDragging } inDragDrop; bool dropWentOutside; int posDrag; int posDrop; @@ -395,8 +314,11 @@ int line, int lineEnd, int xStart, int subLine, int subLineStart, bool overrideBackground, ColourAllocated background, bool drawWrapMark, ColourAllocated wrapColour); + void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart, + PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under); void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, PRectangle rcLine, LineLayout *ll, int subLine=0); + void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret); void RefreshPixMaps(Surface *surfaceWindow); void Paint(Surface *surfaceWindow, PRectangle rcArea); long FormatRange(bool draw, RangeToFormat *pfr); @@ -413,7 +335,7 @@ virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false); void ClearSelection(); void ClearAll(); - void ClearDocumentStyle(); + void ClearDocumentStyle(); void Cut(); void PasteRectangular(int pos, const char *ptr, int len); virtual void Copy() = 0; @@ -436,11 +358,12 @@ void NotifyMove(int position); void NotifySavePoint(bool isSavePoint); void NotifyModifyAttempt(); - virtual void NotifyDoubleClick(Point pt, bool shift); + virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt); void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt); void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); void NotifyUpdateUI(); void NotifyPainted(); + void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt); bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); void NotifyNeedShown(int pos, int len); void NotifyDwelling(Point pt, bool state); @@ -486,6 +409,7 @@ void CopyText(int length, const char *text); void SetDragPosition(int newPos); virtual void DisplayCursor(Window::Cursor c); + virtual bool DragThreshold(Point ptStart, Point ptNow); virtual void StartDrag(); void DropAt(int position, const char *value, bool moving, bool rectangular); /** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after. @@ -580,4 +504,8 @@ } };
+#ifdef SCI_NAMESPACE +} #endif + +#endif
Modified: trunk/scintilla/ExternalLexer.cxx =================================================================== --- trunk/scintilla/ExternalLexer.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/ExternalLexer.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -21,6 +21,10 @@ #include "KeyWords.h" #include "ExternalLexer.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + LexerManager *LexerManager::theInstance = NULL;
//------------------------------------------
Modified: trunk/scintilla/ExternalLexer.h =================================================================== --- trunk/scintilla/ExternalLexer.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/ExternalLexer.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -10,10 +10,14 @@
#if PLAT_WIN #define EXT_LEXER_DECL __stdcall -#elif PLAT_GTK -#define EXT_LEXER_DECL +#else +#define EXT_LEXER_DECL #endif
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + // External Lexer function definitions... typedef void (EXT_LEXER_DECL *ExtLexerFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle, char *words[], WindowID window, char *props); @@ -92,4 +96,8 @@ ~LMMinder(); };
+#ifdef SCI_NAMESPACE +} #endif + +#endif
Modified: trunk/scintilla/Indicator.cxx =================================================================== --- trunk/scintilla/Indicator.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/Indicator.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -10,6 +10,10 @@ #include "Scintilla.h" #include "Indicator.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine) { surface->PenColour(fore.allocated); int ymid = (rc.bottom + rc.top) / 2;
Modified: trunk/scintilla/Indicator.h =================================================================== --- trunk/scintilla/Indicator.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/Indicator.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -8,15 +8,24 @@ #ifndef INDICATOR_H #define INDICATOR_H
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + /** */ class Indicator { public: int style; + bool under; ColourPair fore; - Indicator() : style(INDIC_PLAIN), fore(ColourDesired(0,0,0)) { + Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)) { } void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine); };
+#ifdef SCI_NAMESPACE +} #endif + +#endif
Modified: trunk/scintilla/KeyMap.cxx =================================================================== --- trunk/scintilla/KeyMap.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/KeyMap.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -11,6 +11,10 @@
#include "KeyMap.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + KeyMap::KeyMap() : kmap(0), len(0), alloc(0) { for (int i = 0; MapDefault[i].key; i++) { AssignCmdKey(MapDefault[i].key,
Modified: trunk/scintilla/KeyMap.h =================================================================== --- trunk/scintilla/KeyMap.h 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/KeyMap.h 2007-06-18 13:02:34 UTC (rev 1629) @@ -8,6 +8,10 @@ #ifndef KEYTOCOMMAND_H #define KEYTOCOMMAND_H
+#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + #define SCI_NORM 0 #define SCI_SHIFT SCMOD_SHIFT #define SCI_CTRL SCMOD_CTRL @@ -40,4 +44,8 @@ unsigned int Find(int key, int modifiers); // 0 returned on failure };
+#ifdef SCI_NAMESPACE +} #endif + +#endif
Modified: trunk/scintilla/KeyWords.cxx =================================================================== --- trunk/scintilla/KeyWords.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/KeyWords.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -19,6 +19,10 @@ #include "Scintilla.h" #include "SciLexer.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + const LexerModule *LexerModule::base = 0; int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
@@ -138,37 +142,37 @@ //++Autogenerated -- run src/LexGen.py to regenerate //**(\tLINK_LEXER(*);\n) LINK_LEXER(lmAsm); + LINK_LEXER(lmASP); LINK_LEXER(lmBash); - LINK_LEXER(lmOMS); + LINK_LEXER(lmBatch); LINK_LEXER(lmCaml); - LINK_LEXER(lmFortran); - LINK_LEXER(lmPython); - LINK_LEXER(lmBatch); + LINK_LEXER(lmConf); + LINK_LEXER(lmCPP); + LINK_LEXER(lmCPPNoCase); + LINK_LEXER(lmCss); + LINK_LEXER(lmD); LINK_LEXER(lmDiff); - LINK_LEXER(lmProps); - LINK_LEXER(lmMake); LINK_LEXER(lmErrorList); + LINK_LEXER(lmFortran); + LINK_LEXER(lmHaskell); + LINK_LEXER(lmHTML); LINK_LEXER(lmLatex); + LINK_LEXER(lmLua); + LINK_LEXER(lmMake); + LINK_LEXER(lmNncrontab); LINK_LEXER(lmNull); + LINK_LEXER(lmOMS); LINK_LEXER(lmPascal); - LINK_LEXER(lmConf); - LINK_LEXER(lmNncrontab); - LINK_LEXER(lmHTML); - LINK_LEXER(lmXML); - LINK_LEXER(lmASP); + LINK_LEXER(lmPerl); LINK_LEXER(lmPHP); LINK_LEXER(lmPHPSCRIPT); - LINK_LEXER(lmCss); - LINK_LEXER(lmCPP); - LINK_LEXER(lmCPPNoCase); - LINK_LEXER(lmPerl); + LINK_LEXER(lmProps); + LINK_LEXER(lmPython); LINK_LEXER(lmRuby); LINK_LEXER(lmSQL); LINK_LEXER(lmTCL); LINK_LEXER(lmVHDL); - LINK_LEXER(lmD); - LINK_LEXER(lmLua); - LINK_LEXER(lmHaskell); + LINK_LEXER(lmXML);
//--Autogenerated -- end of automatically generated section
Modified: trunk/scintilla/LexAsm.cxx =================================================================== --- trunk/scintilla/LexAsm.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/LexAsm.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -23,6 +23,9 @@ #include "Scintilla.h" #include "SciLexer.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif
static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || @@ -30,9 +33,8 @@ }
static inline bool IsAWordStart(const int ch) { - //ch == '$' || return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' || - ch == '%' || ch == '$' || ch == '?'); + ch == '%' || ch == '@' || ch == '$' || ch == '?'); }
static inline bool IsAsmOperator(char ch) { @@ -99,7 +101,6 @@ char s[100]; sc.GetCurrentLowered(s, sizeof(s));
- //printf("-%s--", s); if (cpuInstruction.InList(s)) { sc.ChangeState(SCE_ASM_CPUINSTRUCTION); } else if (mathInstruction.InList(s)) {
Modified: trunk/scintilla/LexBash.cxx =================================================================== --- trunk/scintilla/LexBash.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/LexBash.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -28,6 +28,10 @@
#define HERE_DELIM_MAX 256
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + static inline int translateBashDigit(char ch) { if (ch >= '0' && ch <= '9') { return ch - '0';
Modified: trunk/scintilla/LexCPP.cxx =================================================================== --- trunk/scintilla/LexCPP.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/LexCPP.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -19,46 +19,12 @@ #include "KeyWords.h" #include "Scintilla.h" #include "SciLexer.h" +#include "CharacterSet.h"
-#define SET_LOWER "abcdefghijklmnopqrstuvwxyz" -#define SET_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -#define SET_DIGITS "0123456789" +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif
-class SetOfCharacters { - int size; - bool valueAfter; - bool *bset; -public: - SetOfCharacters(const char *setOfCharacters, int size_=0x80, bool valueAfter_=false) { - size = size_; - valueAfter = valueAfter_; - bset = new bool[size]; - for (int i=0; i < size; i++) { - bset[i] = false; - } - for (const char *cp=setOfCharacters; *cp; cp++) { - int val = static_cast<unsigned char>(*cp); - PLATFORM_ASSERT(val >= 0); - PLATFORM_ASSERT(val < size); - bset[val] = true; - } - } - ~SetOfCharacters() { - delete []bset; - bset = 0; - size = 0; - } - void Add(int val) { - PLATFORM_ASSERT(val >= 0); - PLATFORM_ASSERT(val < size); - bset[val] = true; - } - bool Contains(int val) { - PLATFORM_ASSERT(val >= 0); - return (val < size) ? bset[val] : valueAfter; - } -}; - static bool IsSpaceEquiv(int state) { return (state <= SCE_C_COMMENTDOC) || // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE @@ -76,12 +42,12 @@
bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
- SetOfCharacters setOKBeforeRE("(=,"); + CharacterSet setOKBeforeRE(CharacterSet::setNone, "(=,");
- SetOfCharacters setDoxygen("$@\&<>#{}[]" SET_LOWER); + CharacterSet setDoxygen(CharacterSet::setLower, "$@\&<>#{}[]");
- SetOfCharacters setWordStart("_" SET_LOWER SET_UPPER, 0x80, true); - SetOfCharacters setWord("._" SET_LOWER SET_UPPER SET_DIGITS, 0x80, true); + CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); + CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); if (styler.GetPropertyInt("lexer.cpp.allow.dollars", 1) != 0) { setWordStart.Add('$'); setWord.Add('$');
Modified: trunk/scintilla/LexCSS.cxx =================================================================== --- trunk/scintilla/LexCSS.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/LexCSS.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -22,7 +22,11 @@ #include "Scintilla.h" #include "SciLexer.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif
+ static inline bool IsAWordChar(const unsigned int ch) { return (isalnum(ch) || ch == '-' || ch == '_' || ch >= 161); // _ is not in fact correct CSS word-character }
Modified: trunk/scintilla/LexCaml.cxx =================================================================== --- trunk/scintilla/LexCaml.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/LexCaml.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -42,6 +42,10 @@ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */ };
+#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + #ifdef BUILD_AS_EXTERNAL_LEXER /* (actually seems to work!)
Modified: trunk/scintilla/LexConf.cxx =================================================================== --- trunk/scintilla/LexConf.cxx 2007-06-17 17:56:48 UTC (rev 1628) +++ trunk/scintilla/LexConf.cxx 2007-06-18 13:02:34 UTC (rev 1629) @@ -23,6 +23,10 @@ #include "Scintilla.h" #include "SciLexer.h"
+#ifdef SCI_NAMESPACE +using namespace Scintilla;
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.