SF.net SVN: geany: [2086] trunk
eht16 at users.sourceforge.net
eht16 at xxxxx
Sun Dec 2 11:58:18 UTC 2007
Revision: 2086
http://geany.svn.sourceforge.net/geany/?rev=2086&view=rev
Author: eht16
Date: 2007-12-02 03:58:17 -0800 (Sun, 02 Dec 2007)
Log Message:
-----------
Updated Scintilla to version 1.75.
Modified Paths:
--------------
trunk/ChangeLog
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/Editor.cxx
trunk/scintilla/Editor.h
trunk/scintilla/LexBash.cxx
trunk/scintilla/LexCPP.cxx
trunk/scintilla/LexHTML.cxx
trunk/scintilla/LexHaskell.cxx
trunk/scintilla/LexOthers.cxx
trunk/scintilla/LexPerl.cxx
trunk/scintilla/LexPython.cxx
trunk/scintilla/LexSQL.cxx
trunk/scintilla/Partitioning.h
trunk/scintilla/PlatGTK.cxx
trunk/scintilla/PositionCache.cxx
trunk/scintilla/PositionCache.h
trunk/scintilla/PropSet.cxx
trunk/scintilla/RunStyles.cxx
trunk/scintilla/RunStyles.h
trunk/scintilla/ScintillaBase.cxx
trunk/scintilla/ScintillaGTK.cxx
trunk/scintilla/SplitVector.h
trunk/scintilla/ViewStyle.cxx
trunk/scintilla/ViewStyle.h
trunk/scintilla/include/Platform.h
trunk/scintilla/include/PropSet.h
trunk/scintilla/include/SciLexer.h
trunk/scintilla/include/Scintilla.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/ChangeLog 2007-12-02 11:58:17 UTC (rev 2086)
@@ -7,6 +7,7 @@
Make path entry of filebrowser plugin editable.
Add "Open with" and "Find in Files" popup menu items to filebrowser
plugin and add configuration dialog.
+ * scintilla/*, scintilla/include/*: Updated Scintilla to version 1.75.
2007-12-01 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
Modified: trunk/scintilla/CellBuffer.cxx
===================================================================
--- trunk/scintilla/CellBuffer.cxx 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/CellBuffer.cxx 2007-12-02 11:58:17 UTC (rev 2086)
@@ -13,7 +13,6 @@
#include "Platform.h"
#include "Scintilla.h"
-#include "SVector.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "CellBuffer.h"
@@ -472,6 +471,7 @@
}
void UndoHistory::EndUndoAction() {
+ PLATFORM_ASSERT(undoSequenceDepth > 0);
EnsureUndoRoom();
undoSequenceDepth--;
if (0 == undoSequenceDepth) {
@@ -563,7 +563,7 @@
CellBuffer::~CellBuffer() {
}
-char CellBuffer::CharAt(int position) {
+char CellBuffer::CharAt(int position) const {
return substance.ValueAt(position);
}
@@ -653,7 +653,7 @@
return data;
}
-int CellBuffer::Length() {
+int CellBuffer::Length() const {
return substance.Length();
}
@@ -662,11 +662,11 @@
style.ReAllocate(newSize);
}
-int CellBuffer::Lines() {
+int CellBuffer::Lines() const {
return lv.Lines();
}
-int CellBuffer::LineStart(int line) {
+int CellBuffer::LineStart(int line) const {
if (line < 0)
return 0;
else if (line >= Lines())
@@ -726,6 +726,20 @@
// Without undo
+void CellBuffer::InsertLine(int line, int position) {
+ lv.InsertLine(line, position);
+ if (lineStates.Length()) {
+ lineStates.Insert(line, 0);
+ }
+}
+
+void CellBuffer::RemoveLine(int line) {
+ lv.RemoveLine(line);
+ if (lineStates.Length()) {
+ lineStates.Delete(line);
+ }
+}
+
void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) {
if (insertLength == 0)
return;
@@ -741,21 +755,21 @@
char chAfter = substance.ValueAt(position + insertLength);
if (chPrev == '\r' && chAfter == '\n') {
// Splitting up a crlf pair at position
- lv.InsertLine(lineInsert, position);
+ InsertLine(lineInsert, position);
lineInsert++;
}
char ch = ' ';
for (int i = 0; i < insertLength; i++) {
ch = s[i];
if (ch == '\r') {
- lv.InsertLine(lineInsert, (position + i) + 1);
+ InsertLine(lineInsert, (position + i) + 1);
lineInsert++;
} else if (ch == '\n') {
if (chPrev == '\r') {
// Patch up what was end of line
lv.SetLineStart(lineInsert - 1, (position + i) + 1);
} else {
- lv.InsertLine(lineInsert, (position + i) + 1);
+ InsertLine(lineInsert, (position + i) + 1);
lineInsert++;
}
}
@@ -765,7 +779,7 @@
if (chAfter == '\n') {
if (ch == '\r') {
// End of line already in buffer so drop the newly created one
- lv.RemoveLine(lineInsert - 1);
+ RemoveLine(lineInsert - 1);
}
}
}
@@ -800,13 +814,13 @@
chNext = substance.ValueAt(position + i + 1);
if (ch == '\r') {
if (chNext != '\n') {
- lv.RemoveLine(lineRemove);
+ RemoveLine(lineRemove);
}
} else if (ch == '\n') {
if (ignoreNL) {
ignoreNL = false; // Further \n are real deletions
} else {
- lv.RemoveLine(lineRemove);
+ RemoveLine(lineRemove);
}
}
@@ -817,7 +831,7 @@
char chAfter = substance.ValueAt(position + deleteLength);
if (chBefore == '\r' && chAfter == '\n') {
// Using lineRemove-1 as cr ended line before start of deletion
- lv.RemoveLine(lineRemove - 1);
+ RemoveLine(lineRemove - 1);
lv.SetLineStart(lineRemove - 1, position + 1);
}
}
@@ -892,12 +906,14 @@
}
int CellBuffer::SetLineState(int line, int state) {
+ lineStates.EnsureLength(line + 1);
int stateOld = lineStates[line];
lineStates[line] = state;
return stateOld;
}
int CellBuffer::GetLineState(int line) {
+ lineStates.EnsureLength(line + 1);
return lineStates[line];
}
Modified: trunk/scintilla/CellBuffer.h
===================================================================
--- trunk/scintilla/CellBuffer.h 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/CellBuffer.h 2007-12-02 11:58:17 UTC (rev 2086)
@@ -67,11 +67,11 @@
void InsertLine(int line, int position);
void SetLineStart(int line, int position);
void RemoveLine(int line);
- int Lines() {
+ int Lines() const {
return starts.Partitions();
}
int LineFromPosition(int pos);
- int LineStart(int line) {
+ int LineStart(int line) const {
return starts.PositionFromPartition(line);
}
@@ -160,7 +160,7 @@
LineVector lv;
- SVector lineStates;
+ SplitVector<int> lineStates;
public:
@@ -168,15 +168,17 @@
~CellBuffer();
/// Retrieving positions outside the range of the buffer works and returns 0
- char CharAt(int position);
+ char CharAt(int position) const;
void GetCharRange(char *buffer, int position, int lengthRetrieve);
char StyleAt(int position);
- int Length();
+ int Length() const;
void Allocate(int newSize);
- int Lines();
- int LineStart(int line);
+ int Lines() const;
+ int LineStart(int line) const;
int LineFromPosition(int pos) { return lv.LineFromPosition(pos); }
+ void InsertLine(int line, int position);
+ void RemoveLine(int line);
const char *InsertString(int position, const char *s, int insertLength, bool &startSequence);
/// Setting styles for positions outside the range of the buffer is safe and has no effect.
Modified: trunk/scintilla/ContractionState.cxx
===================================================================
--- trunk/scintilla/ContractionState.cxx 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/ContractionState.cxx 2007-12-02 11:58:17 UTC (rev 2086)
@@ -1,293 +1,251 @@
// Scintilla source code edit control
/** @file ContractionState.cxx
- ** Manages visibility of lines for folding.
+ ** Manages visibility of lines for folding and wrapping.
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh at scintilla.org>
+// Copyright 1998-2007 by Neil Hodgson <neilh at scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+#include <string.h>
+
#include "Platform.h"
+#include "SplitVector.h"
+#include "Partitioning.h"
+#include "RunStyles.h"
#include "ContractionState.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
-OneLine::OneLine() {
- displayLine = 0;
- //docLine = 0;
- visible = true;
- height = 1;
- expanded = true;
+ContractionState::ContractionState() : visible(0), expanded(0), heights(0), displayLines(0), linesInDocument(1) {
+ //InsertLine(0);
}
-ContractionState::ContractionState() {
- lines = 0;
- size = 0;
- linesInDoc = 1;
- linesInDisplay = 1;
- valid = false;
- docLines = 0;
- sizeDocLines = 0;
-}
-
ContractionState::~ContractionState() {
Clear();
}
-void ContractionState::MakeValid() const {
- if (!valid) {
- // Could be cleverer by keeping the index of the last still valid entry
- // rather than invalidating all.
- linesInDisplay = 0;
- for (int lineInDoc=0; lineInDoc<linesInDoc; lineInDoc++) {
- lines[lineInDoc].displayLine = linesInDisplay;
- if (lines[lineInDoc].visible) {
- linesInDisplay += lines[lineInDoc].height;
- }
- }
- if (sizeDocLines < linesInDisplay) {
- delete []docLines;
- int *docLinesNew = new int[linesInDisplay + growSize];
- if (!docLinesNew) {
- docLines = 0;
- sizeDocLines = 0;
- return;
- }
- docLines = docLinesNew;
- sizeDocLines = linesInDisplay + growSize;
- }
-
- int lineInDisplay=0;
- for (int line=0; line<linesInDoc; line++) {
- if (lines[line].visible) {
- for (int linePiece=0; linePiece<lines[line].height; linePiece++) {
- docLines[lineInDisplay] = line;
- lineInDisplay++;
- }
- }
- }
- valid = true;
+void ContractionState::EnsureData() {
+ if (OneToOne()) {
+ visible = new RunStyles();
+ expanded = new RunStyles();
+ heights = new RunStyles();
+ displayLines = new Partitioning(4);
+ InsertLines(0, linesInDocument);
}
}
void ContractionState::Clear() {
- delete []lines;
- lines = 0;
- size = 0;
- linesInDoc = 1;
- linesInDisplay = 1;
- delete []docLines;
- docLines = 0;
- sizeDocLines = 0;
+ delete visible;
+ visible = 0;
+ delete expanded;
+ expanded = 0;
+ delete heights;
+ heights = 0;
+ delete displayLines;
+ displayLines = 0;
+ linesInDocument = 1;
}
int ContractionState::LinesInDoc() const {
- return linesInDoc;
+ if (OneToOne()) {
+ return linesInDocument;
+ } else {
+ return displayLines->Partitions() - 1;
+ }
}
int ContractionState::LinesDisplayed() const {
- if (size != 0) {
- MakeValid();
+ if (OneToOne()) {
+ return linesInDocument;
+ } else {
+ return displayLines->PositionFromPartition(LinesInDoc());
}
- return linesInDisplay;
}
int ContractionState::DisplayFromDoc(int lineDoc) const {
- if (size == 0) {
+ if (OneToOne()) {
return lineDoc;
+ } else {
+ if (lineDoc > displayLines->Partitions())
+ lineDoc = displayLines->Partitions();
+ return displayLines->PositionFromPartition(lineDoc);
}
- MakeValid();
- if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
- return lines[lineDoc].displayLine;
- }
- return -1;
}
int ContractionState::DocFromDisplay(int lineDisplay) const {
- if (lineDisplay <= 0)
- return 0;
- if (lineDisplay >= linesInDisplay)
- return linesInDoc;
- if (size == 0)
+ if (OneToOne()) {
return lineDisplay;
- MakeValid();
- if (docLines) { // Valid allocation
- return docLines[lineDisplay];
} else {
- return 0;
+ if (lineDisplay <= 0) {
+ return 0;
+ }
+ if (lineDisplay > LinesDisplayed()) {
+ return displayLines->PartitionFromPosition(LinesDisplayed());
+ }
+ int lineDoc = displayLines->PartitionFromPosition(lineDisplay);
+ PLATFORM_ASSERT(GetVisible(lineDoc));
+ return lineDoc;
}
}
-void ContractionState::Grow(int sizeNew) {
- OneLine *linesNew = new OneLine[sizeNew];
- if (linesNew) {
- int i = 0;
- for (; i < size; i++) {
- linesNew[i] = lines[i];
- }
- for (; i < sizeNew; i++) {
- linesNew[i].displayLine = i;
- }
- delete []lines;
- lines = linesNew;
- size = sizeNew;
- valid = false;
+void ContractionState::InsertLine(int lineDoc) {
+ if (OneToOne()) {
+ linesInDocument++;
} else {
- Platform::DebugPrintf("No memory available\n");
- // TODO: Blow up
+ visible->InsertSpace(lineDoc, 1);
+ visible->SetValueAt(lineDoc, 1);
+ expanded->InsertSpace(lineDoc, 1);
+ expanded->SetValueAt(lineDoc, 1);
+ heights->InsertSpace(lineDoc, 1);
+ heights->SetValueAt(lineDoc, 1);
+ int lineDisplay = DisplayFromDoc(lineDoc);
+ displayLines->InsertPartition(lineDoc, lineDisplay);
+ displayLines->InsertText(lineDoc, 1);
}
}
void ContractionState::InsertLines(int lineDoc, int lineCount) {
- if (size == 0) {
- linesInDoc += lineCount;
- linesInDisplay += lineCount;
- return;
+ for (int l = 0; l < lineCount; l++) {
+ InsertLine(lineDoc + l);
}
- //Platform::DebugPrintf("InsertLine[%d] = %d\n", lineDoc);
- if ((linesInDoc + lineCount + 2) >= size) {
- Grow(linesInDoc + lineCount + growSize);
+ Check();
+}
+
+void ContractionState::DeleteLine(int lineDoc) {
+ if (OneToOne()) {
+ linesInDocument--;
+ } else {
+ if (GetVisible(lineDoc)) {
+ displayLines->InsertText(lineDoc, -heights->ValueAt(lineDoc));
+ }
+ displayLines->RemovePartition(lineDoc);
+ visible->DeleteRange(lineDoc, 1);
+ expanded->DeleteRange(lineDoc, 1);
+ heights->DeleteRange(lineDoc, 1);
}
- linesInDoc += lineCount;
- for (int i = linesInDoc; i >= lineDoc + lineCount; i--) {
- lines[i].visible = lines[i - lineCount].visible;
- lines[i].height = lines[i - lineCount].height;
- linesInDisplay += lines[i].height;
- lines[i].expanded = lines[i - lineCount].expanded;
- }
- for (int d=0;d<lineCount;d++) {
- lines[lineDoc+d].visible = true; // Should inherit visibility from context ?
- lines[lineDoc+d].height = 1;
- lines[lineDoc+d].expanded = true;
- }
- valid = false;
}
void ContractionState::DeleteLines(int lineDoc, int lineCount) {
- if (size == 0) {
- linesInDoc -= lineCount;
- linesInDisplay -= lineCount;
- return;
+ for (int l = 0; l < lineCount; l++) {
+ DeleteLine(lineDoc);
}
- int deltaDisplayed = 0;
- for (int d=0;d<lineCount;d++) {
- if (lines[lineDoc+d].visible)
- deltaDisplayed -= lines[lineDoc+d].height;
- }
- for (int i = lineDoc; i < linesInDoc-lineCount; i++) {
- if (i != 0) // Line zero is always visible
- lines[i].visible = lines[i + lineCount].visible;
- lines[i].expanded = lines[i + lineCount].expanded;
- lines[i].height = lines[i + lineCount].height;
- }
- linesInDoc -= lineCount;
- linesInDisplay += deltaDisplayed;
- valid = false;
+ Check();
}
bool ContractionState::GetVisible(int lineDoc) const {
- if (size == 0)
+ if (OneToOne()) {
return true;
- if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
- return lines[lineDoc].visible;
} else {
- return false;
+ if (lineDoc >= visible->Length())
+ return true;
+ return visible->ValueAt(lineDoc) == 1;
}
}
-bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) {
- if (lineDocStart == 0)
- lineDocStart++;
- if (lineDocStart > lineDocEnd)
+bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible_) {
+ if (OneToOne() && visible_) {
return false;
- if (size == 0) {
- Grow(linesInDoc + growSize);
- }
- // TODO: modify docLine members to mirror displayLine
- int delta = 0;
- // Change lineDocs
- if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < linesInDoc)) {
- for (int line=lineDocStart; line <= lineDocEnd; line++) {
- if (lines[line].visible != visible) {
- delta += visible ? lines[line].height : -lines[line].height;
- lines[line].visible = visible;
- valid = false;
+ } else {
+ EnsureData();
+ int delta = 0;
+ Check();
+ if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < LinesInDoc())) {
+ for (int line = lineDocStart; line <= lineDocEnd; line++) {
+ if (GetVisible(line) != visible_) {
+ int difference = visible_ ? heights->ValueAt(line) : -heights->ValueAt(line);
+ visible->SetValueAt(line, visible_ ? 1 : 0);
+ displayLines->InsertText(line, difference);
+ delta += difference;
+ }
}
+ } else {
+ return false;
}
+ Check();
+ return delta != 0;
}
- linesInDisplay += delta;
- return delta != 0;
}
bool ContractionState::GetExpanded(int lineDoc) const {
- if (size == 0)
+ if (OneToOne()) {
return true;
- if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
- return lines[lineDoc].expanded;
} else {
- return false;
+ Check();
+ return expanded->ValueAt(lineDoc) == 1;
}
}
-bool ContractionState::SetExpanded(int lineDoc, bool expanded) {
- if (size == 0) {
- if (expanded) {
- // If in completely expanded state then setting
- // one line to expanded has no effect.
+bool ContractionState::SetExpanded(int lineDoc, bool expanded_) {
+ if (OneToOne() && expanded_) {
+ return false;
+ } else {
+ EnsureData();
+ if (expanded_ != (expanded->ValueAt(lineDoc) == 1)) {
+ expanded->SetValueAt(lineDoc, expanded_ ? 1 : 0);
+ Check();
+ return true;
+ } else {
+ Check();
return false;
}
- Grow(linesInDoc + growSize);
}
- if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
- if (lines[lineDoc].expanded != expanded) {
- lines[lineDoc].expanded = expanded;
- return true;
- }
- }
- return false;
}
int ContractionState::GetHeight(int lineDoc) const {
- if (size == 0)
+ if (OneToOne()) {
return 1;
- if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
- return lines[lineDoc].height;
} else {
- return 1;
+ return heights->ValueAt(lineDoc);
}
}
// Set the number of display lines needed for this line.
// Return true if this is a change.
bool ContractionState::SetHeight(int lineDoc, int height) {
- if (lineDoc > linesInDoc)
+ if (OneToOne() && (height == 1)) {
return false;
- if (size == 0) {
- if (height == 1) {
- // If in completely expanded state then all lines
- // assumed to have height of one so no effect here.
+ } else {
+ EnsureData();
+ if (GetHeight(lineDoc) != height) {
+ if (GetVisible(lineDoc)) {
+ displayLines->InsertText(lineDoc, height - GetHeight(lineDoc));
+ }
+ heights->SetValueAt(lineDoc, height);
+ Check();
+ return true;
+ } else {
+ Check();
return false;
}
- Grow(linesInDoc + growSize);
}
- if (lines[lineDoc].height != height) {
- lines[lineDoc].height = height;
- valid = false;
- return true;
- } else {
- return false;
- }
}
void ContractionState::ShowAll() {
- delete []lines;
- lines = 0;
- size = 0;
+ int lines = LinesInDoc();
+ Clear();
+ linesInDocument = lines;
+}
- delete []docLines;
- docLines = 0;
- sizeDocLines = 0;
+// Debugging checks
- linesInDisplay = linesInDoc;
+void ContractionState::Check() const {
+#ifdef CHECK_CORRECTNESS
+ for (int vline = 0;vline < LinesDisplayed(); vline++) {
+ const int lineDoc = DocFromDisplay(vline);
+ PLATFORM_ASSERT(GetVisible(lineDoc));
+ }
+ for (int lineDoc = 0;lineDoc < LinesInDoc(); lineDoc++) {
+ const int displayThis = DisplayFromDoc(lineDoc);
+ const int displayNext = DisplayFromDoc(lineDoc + 1);
+ const int height = displayNext - displayThis;
+ PLATFORM_ASSERT(height >= 0);
+ if (GetVisible(lineDoc)) {
+ PLATFORM_ASSERT(GetHeight(lineDoc) == height);
+ } else {
+ PLATFORM_ASSERT(0 == height);
+ }
+ }
+#endif
}
Modified: trunk/scintilla/ContractionState.h
===================================================================
--- trunk/scintilla/ContractionState.h 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/ContractionState.h 2007-12-02 11:58:17 UTC (rev 2086)
@@ -1,8 +1,8 @@
// Scintilla source code edit control
/** @file ContractionState.h
- ** Manages visibility of lines for folding.
+ ** Manages visibility of lines for folding and wrapping.
**/
-// Copyright 1998-2001 by Neil Hodgson <neilh at scintilla.org>
+// Copyright 1998-2007 by Neil Hodgson <neilh at scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CONTRACTIONSTATE_H
@@ -14,31 +14,21 @@
/**
*/
-class OneLine {
-public:
- int displayLine; ///< Position within set of visible lines
- //int docLine; ///< Inverse of @a displayLine
- int height; ///< Number of display lines needed to show all of the line
- bool visible;
- bool expanded;
+class ContractionState {
+ // These contain 1 element for every document line.
+ RunStyles *visible;
+ RunStyles *expanded;
+ RunStyles *heights;
+ Partitioning *displayLines;
+ int linesInDocument;
- OneLine();
- virtual ~OneLine() {}
-};
+ void EnsureData();
-/**
- */
-class ContractionState {
- void Grow(int sizeNew);
- enum { growSize = 4000 };
- int linesInDoc;
- mutable int linesInDisplay;
- mutable OneLine *lines;
- int size;
- mutable int *docLines;
- mutable int sizeDocLines;
- mutable bool valid;
- void MakeValid() const;
+ bool OneToOne() const {
+ // True when each document line is exactly one display line so need for
+ // complex data structures.
+ return visible == 0;
+ }
public:
ContractionState();
@@ -51,7 +41,9 @@
int DisplayFromDoc(int lineDoc) const;
int DocFromDisplay(int lineDisplay) const;
+ void InsertLine(int lineDoc);
void InsertLines(int lineDoc, int lineCount);
+ void DeleteLine(int lineDoc);
void DeleteLines(int lineDoc, int lineCount);
bool GetVisible(int lineDoc) const;
@@ -64,6 +56,7 @@
bool SetHeight(int lineDoc, int height);
void ShowAll();
+ void Check() const;
};
#ifdef SCI_NAMESPACE
Modified: trunk/scintilla/Document.cxx
===================================================================
--- trunk/scintilla/Document.cxx 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/Document.cxx 2007-12-02 11:58:17 UTC (rev 2086)
@@ -13,7 +13,6 @@
#include "Platform.h"
#include "Scintilla.h"
-#include "SVector.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
@@ -113,7 +112,6 @@
int Document::AddMark(int line, int markerNum) {
int prev = cb.AddMark(line, markerNum);
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
- mh.line = line;
NotifyModified(mh);
return prev;
}
@@ -124,14 +122,12 @@
if (m & 1)
cb.AddMark(line, i);
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
- mh.line = line;
NotifyModified(mh);
}
void Document::DeleteMark(int line, int markerNum) {
cb.DeleteMark(line, markerNum);
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
- mh.line = line;
NotifyModified(mh);
}
@@ -149,11 +145,11 @@
NotifyModified(mh);
}
-int Document::LineStart(int line) {
+int Document::LineStart(int line) const {
return cb.LineStart(line);
}
-int Document::LineEnd(int line) {
+int Document::LineEnd(int line) const {
if (line == LinesTotal() - 1) {
return LineStart(line + 1);
} else {
@@ -191,8 +187,7 @@
int prev = cb.SetLevel(line, level);
if (prev != level) {
DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,
- LineStart(line), 0, 0, 0);
- mh.line = line;
+ LineStart(line), 0, 0, 0, line);
mh.foldLevelNow = level;
mh.foldLevelPrev = prev;
NotifyModified(mh);
@@ -292,6 +287,55 @@
}
}
+static bool IsTrailByte(int ch) {
+ return (ch >= 0x80) && (ch < (0x80 + 0x40));
+}
+
+static int BytesFromLead(int leadByte) {
+ if (leadByte > 0xF4) {
+ // Characters longer than 4 bytes not possible in current UTF-8
+ return 0;
+ } else if (leadByte >= 0xF0) {
+ return 4;
+ } else if (leadByte >= 0xE0) {
+ return 3;
+ } else if (leadByte >= 0xC2) {
+ return 2;
+ }
+ return 0;
+}
+
+bool Document::InGoodUTF8(int pos, int &start, int &end) {
+ int lead = pos;
+ while ((lead>0) && (pos-lead < 4) && IsTrailByte(static_cast<unsigned char>(cb.CharAt(lead-1))))
+ lead--;
+ start = 0;
+ if (lead > 0) {
+ start = lead-1;
+ }
+ int leadByte = static_cast<unsigned char>(cb.CharAt(start));
+ int bytes = BytesFromLead(leadByte);
+ if (bytes == 0) {
+ return false;
+ } else {
+ int trailBytes = bytes - 1;
+ int len = pos - lead + 1;
+ if (len > trailBytes)
+ // pos too far from lead
+ return false;
+ // Check that there are enough trails for this lead
+ int trail = pos + 1;
+ while ((trail-lead<trailBytes) && (trail < Length())) {
+ if (!IsTrailByte(static_cast<unsigned char>(cb.CharAt(trail)))) {
+ return false;
+ }
+ trail++;
+ }
+ end = start + bytes;
+ return true;
+ }
+}
+
// Normalise a position so that it is not halfway through a two byte character.
// This can occur in two situations -
// When lines are terminated with \r\n pairs which should be treated as one character.
@@ -318,13 +362,14 @@
if (dbcsCodePage) {
if (SC_CP_UTF8 == dbcsCodePage) {
unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
- while ((pos > 0) && (pos < Length()) && (ch >= 0x80) && (ch < (0x80 + 0x40))) {
- // ch is a trail byte
+ int startUTF = pos;
+ int endUTF = pos;
+ if (IsTrailByte(ch) && InGoodUTF8(pos, startUTF, endUTF)) {
+ // ch is a trail byte within a UTF-8 character
if (moveDir > 0)
- pos++;
+ pos = endUTF;
else
- pos--;
- ch = static_cast<unsigned char>(cb.CharAt(pos));
+ pos = startUTF;
}
} else {
// Anchor DBCS calculations at start of line because start of line can
@@ -652,7 +697,7 @@
}
}
-int Document::GetLineIndentPosition(int line) {
+int Document::GetLineIndentPosition(int line) const {
if (line < 0)
return 0;
int pos = LineStart(line);
@@ -793,7 +838,7 @@
EndUndoAction();
}
-bool Document::IsWhiteLine(int line) {
+bool Document::IsWhiteLine(int line) const {
int currentChar = LineStart(line);
int endLine = LineEnd(line);
while (currentChar < endLine) {
@@ -1238,7 +1283,7 @@
return substituted;
}
-int Document::LinesTotal() {
+int Document::LinesTotal() const {
return cb.Lines();
}
@@ -1271,11 +1316,7 @@
void Document::SetStylingBits(int bits) {
stylingBits = bits;
- stylingBitsMask = 0;
- for (int bit = 0; bit < stylingBits; bit++) {
- stylingBitsMask <<= 1;
- stylingBitsMask |= 1;
- }
+ stylingBitsMask = (1 << stylingBits) - 1;
}
void Document::StartStyling(int position, char mask) {
@@ -1339,13 +1380,19 @@
}
}
-void Document::IncrementStyleClock() {
- styleClock++;
- if (styleClock > 0x100000) {
- styleClock = 0;
+int Document::SetLineState(int line, int state) {
+ int statePrevious = cb.SetLineState(line, state);
+ if (state != statePrevious) {
+ DocModification mh(SC_MOD_CHANGELINESTATE, 0, 0, 0, 0, line);
+ NotifyModified(mh);
}
+ return statePrevious;
}
+void Document::IncrementStyleClock() {
+ styleClock = (styleClock + 1) % 0x100000;
+}
+
void Document::DecorationFillRange(int position, int value, int fillLength) {
if (decorations.FillRange(position, value, fillLength)) {
DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER,
@@ -1411,6 +1458,11 @@
}
void Document::NotifyModified(DocModification mh) {
+ if (mh.modificationType & SC_MOD_INSERTTEXT) {
+ decorations.InsertSpace(mh.position, mh.length);
+ } else if (mh.modificationType & SC_MOD_DELETETEXT) {
+ decorations.DeleteRange(mh.position, mh.length);
+ }
for (int i = 0; i < lenWatchers; i++) {
watchers[i].watcher->NotifyModified(this, mh, watchers[i].userData);
}
Modified: trunk/scintilla/Document.h
===================================================================
--- trunk/scintilla/Document.h 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/Document.h 2007-12-02 11:58:17 UTC (rev 2086)
@@ -138,10 +138,12 @@
int ClampPositionIntoDocument(int pos);
bool IsCrLf(int pos);
int LenChar(int pos);
+ bool InGoodUTF8(int pos, int &start, int &end);
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
// Gateways to modifying document
void ModifiedAt(int pos);
+ void CheckReadOnly();
bool DeleteChars(int pos, int len);
bool InsertString(int position, const char *s, int insertLength);
int Undo();
@@ -160,7 +162,7 @@
int GetLineIndentation(int line);
void SetLineIndentation(int line, int indent);
- int GetLineIndentPosition(int line);
+ int GetLineIndentPosition(int line) const;
int GetColumn(int position);
int FindColumn(int line, int column);
void Indent(bool forwards, int lineBottom, int lineTop);
@@ -187,8 +189,8 @@
void DeleteMarkFromHandle(int markerHandle);
void DeleteAllMarks(int markerNum);
int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); }
- int LineStart(int line);
- int LineEnd(int line);
+ int LineStart(int line) const;
+ int LineEnd(int line) const;
int LineEndPosition(int position);
int VCHomePosition(int position);
@@ -202,13 +204,13 @@
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);
int NextWordStart(int pos, int delta);
int NextWordEnd(int pos, int delta);
- int Length() { return cb.Length(); }
+ int Length() const { return cb.Length(); }
void Allocate(int newSize) { cb.Allocate(newSize); }
long FindText(int minPos, int maxPos, const char *s,
bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length);
long FindText(int iMessage, unsigned long wParam, long lParam);
const char *SubstituteByPosition(const char *text, int *length);
- int LinesTotal();
+ int LinesTotal() const;
void ChangeCase(Range r, bool makeUpperCase);
@@ -224,7 +226,7 @@
void IncrementStyleClock();
void DecorationFillRange(int position, int value, int fillLength);
- int SetLineState(int line, int state) { return cb.SetLineState(line, state); }
+ int SetLineState(int line, int state);
int GetLineState(int line) { return cb.GetLineState(line); }
int GetMaxLineState() { return cb.GetMaxLineState(); }
@@ -237,15 +239,13 @@
int WordPartLeft(int pos);
int WordPartRight(int pos);
int ExtendStyleRange(int pos, int delta, bool singleLine = false);
- bool IsWhiteLine(int line);
+ bool IsWhiteLine(int line) const;
int ParaUp(int pos);
int ParaDown(int pos);
int IndentSize() { return actualIndentInChars; }
int BraceMatch(int position, int maxReStyle);
private:
- void CheckReadOnly();
-
CharClassify::cc WordCharClass(unsigned char ch);
bool IsWordStartAt(int pos);
bool IsWordEndAt(int pos);
Modified: trunk/scintilla/DocumentAccessor.cxx
===================================================================
--- trunk/scintilla/DocumentAccessor.cxx 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/DocumentAccessor.cxx 2007-12-02 11:58:17 UTC (rev 2086)
@@ -13,7 +13,6 @@
#include "Platform.h"
#include "PropSet.h"
-#include "SVector.h"
#include "Accessor.h"
#include "DocumentAccessor.h"
#include "SplitVector.h"
Modified: trunk/scintilla/Editor.cxx
===================================================================
--- trunk/scintilla/Editor.cxx 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/Editor.cxx 2007-12-02 11:58:17 UTC (rev 2086)
@@ -17,13 +17,12 @@
#endif
#include "Scintilla.h"
-#include "ContractionState.h"
-#include "SVector.h"
#include "SplitVector.h"
#include "Partitioning.h"
+#include "RunStyles.h"
+#include "ContractionState.h"
#include "CellBuffer.h"
#include "KeyMap.h"
-#include "RunStyles.h"
#include "Indicator.h"
#include "XPM.h"
#include "LineMarker.h"
@@ -44,9 +43,9 @@
may reasonably be deferred (not done now OR [possibly] at all)
*/
static bool CanDeferToLastStep(const DocModification& mh) {
- if (mh.modificationType & (SC_MOD_BEFOREINSERT|SC_MOD_BEFOREDELETE))
+ if (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE))
return true; // CAN skip
- if (!(mh.modificationType & (SC_PERFORMED_UNDO|SC_PERFORMED_REDO)))
+ if (!(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)))
return false; // MUST do
if (mh.modificationType & SC_MULTISTEPUNDOREDO)
return true; // CAN skip
@@ -55,7 +54,7 @@
static bool CanEliminate(const DocModification& mh) {
return
- (mh.modificationType & (SC_MOD_BEFOREINSERT|SC_MOD_BEFOREDELETE)) != 0;
+ (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) != 0;
}
/*
@@ -64,20 +63,20 @@
*/
static bool IsLastStep(const DocModification& mh) {
return
- (mh.modificationType & (SC_PERFORMED_UNDO|SC_PERFORMED_REDO)) != 0
- && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0
- && (mh.modificationType & SC_LASTSTEPINUNDOREDO) != 0
- && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0;
+ (mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)) != 0
+ && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0
+ && (mh.modificationType & SC_LASTSTEPINUNDOREDO) != 0
+ && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0;
}
Caret::Caret() :
-active(false), on(false), period(500) {}
+ active(false), on(false), period(500) {}
Timer::Timer() :
-ticking(false), ticksToWait(0), tickerID(0) {}
+ ticking(false), ticksToWait(0), tickerID(0) {}
Idler::Idler() :
-state(false), idlerID(0) {}
+ state(false), idlerID(0) {}
static inline bool IsControlCharacter(int ch) {
// iscntrl returns true for lots of chars > 127 which are displayable
@@ -138,6 +137,8 @@
xCaretMargin = 50;
horizontalScrollBarVisible = true;
scrollWidth = 2000;
+ trackLineWidth = false;
+ lineWidthMaxSeen = 0;
verticalScrollBarVisible = true;
endAtLastLine = true;
caretSticky = false;
@@ -914,13 +915,13 @@
Point pt = LocationFromPosition(currentPos);
if (pt.y < rcClient.top) {
MovePositionTo(PositionFromLocation(
- Point(lastXChosen, rcClient.top)),
- noSel, ensureVisible);
+ Point(lastXChosen, rcClient.top)),
+ noSel, ensureVisible);
} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;
MovePositionTo(PositionFromLocation(
- Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
- noSel, ensureVisible);
+ Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
+ noSel, ensureVisible);
}
}
@@ -1205,7 +1206,7 @@
xOffset = xOffsetNew;
if (xOffsetNew > 0) {
PRectangle rcText = GetTextRectangle();
- if (horizontalScrollBarVisible == true &&
+ if (horizontalScrollBarVisible &&
rcText.Width() + xOffset > scrollWidth) {
scrollWidth = xOffset + rcText.Width();
SetScrollBars();
@@ -1262,6 +1263,16 @@
}
}
+bool Editor::WrapOneLine(Surface *surface, int lineToWrap) {
+ AutoLineLayout ll(llc, RetrieveLineLayout(lineToWrap));
+ int linesWrapped = 1;
+ if (ll) {
+ LayoutLine(lineToWrap, surface, vs, ll, wrapWidth);
+ linesWrapped = ll->lines;
+ }
+ return cs.SetHeight(lineToWrap, linesWrapped);
+}
+
// Check if wrapping needed and perform any needed wrapping.
// fullwrap: if true, all lines which need wrapping will be done,
// in this single call.
@@ -1283,9 +1294,9 @@
}
}
if (!fullWrap && priorityWrapLineStart >= 0 &&
- // .. and if the paint window is outside pending wraps
- (((priorityWrapLineStart + linesInOneCall) < wrapStart) ||
- (priorityWrapLineStart > wrapEnd))) {
+ // .. and if the paint window is outside pending wraps
+ (((priorityWrapLineStart + linesInOneCall) < wrapStart) ||
+ (priorityWrapLineStart > wrapEnd))) {
// No priority wrap pending
return false;
}
@@ -1338,13 +1349,7 @@
// Platform::DebugPrintf("Wraplines: full = %d, priorityStart = %d (wrapping: %d to %d)\n", fullWrap, priorityWrapLineStart, lineToWrap, lastLineToWrap);
// Platform::DebugPrintf("Pending wraps: %d to %d\n", wrapStart, wrapEnd);
while (lineToWrap < lastLineToWrap) {
- AutoLineLayout ll(llc, RetrieveLineLayout(lineToWrap));
- int linesWrapped = 1;
- if (ll) {
- LayoutLine(lineToWrap, surface, vs, ll, wrapWidth);
- linesWrapped = ll->lines;
- }
- if (cs.SetHeight(lineToWrap, linesWrapped)) {
+ if (WrapOneLine(surface, lineToWrap)) {
wrapOccurred = true;
}
lineToWrap++;
@@ -1423,7 +1428,7 @@
LayoutLine(line, surface, vs, ll, pixelWidth);
for (int subLine = 1; subLine < ll->lines; subLine++) {
pdoc->InsertCString(posLineStart + (subLine - 1) * strlen(eol) +
- ll->LineStart(subLine), eol);
+ ll->LineStart(subLine), eol);
targetEnd += static_cast<int>(strlen(eol));
}
}
@@ -1524,9 +1529,9 @@
// Old code does not know about new markers needed to distinguish all cases
int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID,
- SC_MARKNUM_FOLDEROPEN);
+ SC_MARKNUM_FOLDEROPEN);
int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND,
- SC_MARKNUM_FOLDER);
+ SC_MARKNUM_FOLDER);
while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) {
@@ -1611,11 +1616,11 @@
if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS) {
int lev = pdoc->GetLevel(lineDoc);
sprintf(number, "%c%c %03X %03X",
- (lev & SC_FOLDLEVELHEADERFLAG) ? 'H' : '_',
- (lev & SC_FOLDLEVELWHITEFLAG) ? 'W' : '_',
- lev & SC_FOLDLEVELNUMBERMASK,
- lev >> 16
- );
+ (lev & SC_FOLDLEVELHEADERFLAG) ? 'H' : '_',
+ (lev & SC_FOLDLEVELWHITEFLAG) ? 'W' : '_',
+ lev & SC_FOLDLEVELNUMBERMASK,
+ lev >> 16
+ );
}
PRectangle rcNumber = rcMarker;
// Right justify
@@ -1623,9 +1628,9 @@
int xpos = rcNumber.right - width - 3;
rcNumber.left = xpos;
surface->DrawTextNoClip(rcNumber, vs.styles[STYLE_LINENUMBER].font,
- rcNumber.top + vs.maxAscent, number, istrlen(number),
- vs.styles[STYLE_LINENUMBER].fore.allocated,
- vs.styles[STYLE_LINENUMBER].back.allocated);
+ rcNumber.top + vs.maxAscent, number, istrlen(number),
+ vs.styles[STYLE_LINENUMBER].fore.allocated,
+ vs.styles[STYLE_LINENUMBER].back.allocated);
}
if (marks) {
@@ -1675,10 +1680,65 @@
PLATFORM_ASSERT(posLineEnd >= posLineStart);
int lineCaret = pdoc->LineFromPosition(currentPos);
return llc.Retrieve(lineNumber, lineCaret,
- posLineEnd - posLineStart, pdoc->GetStyleClock(),
- LinesOnScreen() + 1, pdoc->LinesTotal());
+ posLineEnd - posLineStart, pdoc->GetStyleClock(),
+ LinesOnScreen() + 1, pdoc->LinesTotal());
}
+static bool GoodTrailByte(int v) {
+ return (v >= 0x80) && (v < 0xc0);
+}
+
+bool BadUTF(const char *s, int len, int &trailBytes) {
+ if (trailBytes) {
+ trailBytes--;
+ return false;
+ }
+ const unsigned char *us = reinterpret_cast<const unsigned char *>(s);
+ if (*us < 0x80) {
+ // Single bytes easy
+ return false;
+ } else if (*us > 0xF4) {
+ // Characters longer than 4 bytes not possible in current UTF-8
+ return true;
+ } else if (*us >= 0xF0) {
+ // 4 bytes
+ if (len < 4)
+ return true;
+ if (GoodTrailByte(us[1]) && GoodTrailByte(us[2]) && GoodTrailByte(us[3])) {
+ trailBytes = 3;
+ return false;
+ } else {
+ return true;
+ }
+ } else if (*us >= 0xE0) {
+ // 3 bytes
+ if (len < 3)
+ return true;
+ if (GoodTrailByte(us[1]) && GoodTrailByte(us[2])) {
+ trailBytes = 2;
+ return false;
+ } else {
+ return true;
+ }
+ } else if (*us >= 0xC2) {
+ // 2 bytes
+ if (len < 2)
+ return true;
+ if (GoodTrailByte(us[1])) {
+ trailBytes = 1;
+ return false;
+ } else {
+ return true;
+ }
+ } else if (*us >= 0xC0) {
+ // Overlong encoding
+ return true;
+ } else {
+ // Trail byte
+ return true;
+ }
+}
+
/**
* Fill in the LineLayout data for the given line.
* Copy the given @a line and its styles from the document into local arrays.
@@ -1717,18 +1777,18 @@
char chDoc = pdoc->CharAt(charInDoc);
styleByte = pdoc->StyleAt(charInDoc);
allSame = allSame &&
- (ll->styles[numCharsInLine] == static_cast<unsigned char>(styleByte & styleMask));
+ (ll->styles[numCharsInLine] == static_cast<unsigned char>(styleByte & styleMask));
allSame = allSame &&
- (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
+ (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed)
allSame = allSame &&
- (ll->chars[numCharsInLine] == chDoc);
+ (ll->chars[numCharsInLine] == chDoc);
else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
+ (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
else // Style::caseUpper
allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
+ (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
numCharsInLine++;
}
allSame = allSame && (ll->styles[numCharsInLine] == styleByte); // For eolFilled
@@ -1790,31 +1850,40 @@
int ctrlCharWidth[32] = {0};
bool isControlNext = IsControlCharacter(ll->chars[0]);
+ int trailBytes = 0;
+ bool isBadUTFNext = IsUnicodeMode() && BadUTF(ll->chars, numCharsInLine, trailBytes);
for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) {
bool isControl = isControlNext;
isControlNext = IsControlCharacter(ll->chars[charInLine + 1]);
+ bool isBadUTF = isBadUTFNext;
+ isBadUTFNext = IsUnicodeMode() && BadUTF(ll->chars + charInLine + 1, numCharsInLine - charInLine - 1, trailBytes);
if ((ll->styles[charInLine] != ll->styles[charInLine + 1]) ||
- isControl || isControlNext) {
+ isControl || isControlNext || isBadUTF || isBadUTFNext) {
ll->positions[startseg] = 0;
if (vstyle.styles[ll->styles[charInLine]].visible) {
if (isControl) {
if (ll->chars[charInLine] == '\t') {
ll->positions[charInLine + 1] = ((((startsegx + 2) /
- tabWidth) + 1) * tabWidth) - startsegx;
+ tabWidth) + 1) * tabWidth) - startsegx;
} else if (controlCharSymbol < 32) {
if (ctrlCharWidth[ll->chars[charInLine]] == 0) {
const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]);
// +3 For a blank on front and rounded edge each side:
ctrlCharWidth[ll->chars[charInLine]] =
- surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3;
+ surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3;
}
ll->positions[charInLine + 1] = ctrlCharWidth[ll->chars[charInLine]];
} else {
char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
surface->MeasureWidths(ctrlCharsFont, cc, 1,
- ll->positions + startseg + 1);
+ ll->positions + startseg + 1);
}
lastSegItalics = false;
+ } else if (isBadUTF) {
+ char hexits[3];
+ sprintf(hexits, "%2X", ll->chars[charInLine] & 0xff);
+ ll->positions[charInLine + 1] =
+ surface->WidthText(ctrlCharsFont, hexits, istrlen(hexits)) + 3;
} else { // Regular character
int lenSeg = charInLine - startseg + 1;
if ((lenSeg == 1) && (' ' == ll->chars[startseg])) {
@@ -1824,7 +1893,7 @@
} else {
lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic;
posCache.MeasureWidths(surface, vstyle, ll->styles[charInLine], ll->chars + startseg,
- lenSeg, ll->positions + startseg + 1);
+ lenSeg, ll->positions + startseg + 1);
}
}
} else { // invisible
@@ -1873,12 +1942,12 @@
// Try moving to start of last character
if (p > 0) {
lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1)
- - posLineStart;
+ - posLineStart;
}
if (lastGoodBreak == lastLineStart) {
// Ensure at least one character on line.
lastGoodBreak = pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart + 1, 1)
- - posLineStart;
+ - posLineStart;
}
}
lastLineStart = lastGoodBreak;
@@ -1893,7 +1962,7 @@
if (p > 0) {
if (wrapState == eWrapChar) {
lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1)
- - posLineStart;
+ - posLineStart;
p = pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart;
continue;
} else if (ll->styles[p] != ll->styles[p - 1]) {
@@ -1915,7 +1984,7 @@
}
ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground,
- ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
+ ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
if (inSelection) {
if (vsDraw.selbackset && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
return SelectionBackground(vsDraw);
@@ -1937,11 +2006,11 @@
Point from(0, ((lineVisible & 1) && (lineHeight & 1)) ? 1 : 0);
PRectangle rcCopyArea(start + 1, rcSegment.top, start + 2, rcSegment.bottom);
surface->Copy(rcCopyArea, from,
- highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide);
+ highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide);
}
void Editor::DrawWrapMarker(Surface *surface, PRectangle rcPlace,
- bool isEndMarker, ColourAllocated wrapColour) {
+ bool isEndMarker, ColourAllocated wrapColour) {
surface->PenColour(wrapColour);
enum { xa = 1 }; // gap before start
@@ -1964,10 +2033,10 @@
int yBase;
int yDir;
void MoveTo(int xRelative, int yRelative) {
- surface->MoveTo(xBase + xDir * xRelative, yBase + yDir * yRelative);
+ surface->MoveTo(xBase + xDir * xRelative, yBase + yDir * yRelative);
}
void LineTo(int xRelative, int yRelative) {
- surface->LineTo(xBase + xDir * xRelative, yBase + yDir * yRelative);
+ surface->LineTo(xBase + xDir * xRelative, yBase + yDir * yRelative);
}
};
Relative rel = {surface, x0, xStraight ? 1 : -1, y0, yStraight ? 1 : -1};
@@ -1983,7 +2052,7 @@
rel.LineTo(xa + w, y);
rel.LineTo(xa + w, y - 2 * dy);
rel.LineTo(xa - 1, // on windows lineto is exclusive endpoint, perhaps GTK not...
- y - 2 * dy);
+ y - 2 * dy);
}
static void SimpleAlphaRectangle(Surface *surface, PRectangle rc, ColourAllocated fill, int alpha) {
@@ -1993,9 +2062,9 @@
}
void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
- int line, int lineEnd, int xStart, int subLine, int subLineStart,
- bool overrideBackground, ColourAllocated background,
- bool drawWrapMarkEnd, ColourAllocated wrapColour) {
+ int line, int lineEnd, int xStart, int subLine, int subLineStart,
+ bool overrideBackground, ColourAllocated background,
+ bool drawWrapMarkEnd, ColourAllocated wrapColour) {
int styleMask = pdoc->stylingBitsMask;
PRectangle rcSegment = rcLine;
@@ -2006,7 +2075,7 @@
rcSegment.right = xEol + vsDraw.aveCharWidth + xStart;
int posLineEnd = pdoc->LineStart(line + 1);
bool eolInSelection = (subLine == (ll->lines - 1)) &&
- (posLineEnd > ll->selStart) && (posLineEnd <= ll->selEnd) && (ll->selStart != ll->selEnd);
+ (posLineEnd > ll->selStart) && (posLineEnd <= ll->selEnd) && (ll->selStart != ll->selEnd);
if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
surface->FillRectangle(rcSegment, SelectionBackground(vsDraw));
@@ -2044,7 +2113,7 @@
if (vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha != SC_ALPHA_NOALPHA)) {
SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
}
- }
+ }
if (drawWrapMarkEnd) {
PRectangle rcPlace = rcSegment;
@@ -2062,7 +2131,7 @@
}
void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
- PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under) {
+ PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under) {
// Draw decorators
const int posLineStart = pdoc->LineStart(line);
const int lineStart = ll->LineStart(subLine);
@@ -2092,10 +2161,10 @@
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);
+ 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;
@@ -2106,9 +2175,9 @@
}
}
- for (Decoration *deco=pdoc->decorations.root; deco; deco = deco->next) {
+ for (Decoration *deco = pdoc->decorations.root; deco; deco = deco->next) {
if (under == vsDraw.indicators[deco->indicator].under) {
- int startPos = posLineStart + subLineStart;
+ int startPos = posLineStart + lineStart;
if (!deco->rs.ValueAt(startPos)) {
startPos = deco->rs.EndRun(startPos);
}
@@ -2117,10 +2186,10 @@
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);
+ 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);
}
@@ -2128,8 +2197,32 @@
}
}
+void DrawTextBlob(Surface *surface, ViewStyle &vsDraw, PRectangle rcSegment,
+ const char *s, ColourAllocated textBack, ColourAllocated textFore, bool twoPhaseDraw) {
+ if (!twoPhaseDraw) {
+ surface->FillRectangle(rcSegment, textBack);
+ }
+ Font &ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font;
+ 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, s, istrlen(s),
+ textBack, textFore);
+}
+
void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
- PRectangle rcLine, LineLayout *ll, int subLine) {
+ PRectangle rcLine, LineLayout *ll, int subLine) {
PRectangle rcSegment = rcLine;
@@ -2154,7 +2247,7 @@
int marks = pdoc->GetMark(line);
for (int markBit = 0; (markBit < 32) && marks; markBit++) {
if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_BACKGROUND) &&
- (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) {
+ (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) {
background = vsDraw.markers[markBit].back.allocated;
overrideBackground = true;
}
@@ -2167,7 +2260,7 @@
if (marksMasked) {
for (int markBit = 0; (markBit < 32) && marksMasked; markBit++) {
if ((marksMasked & 1) && (vsDraw.markers[markBit].markType != SC_MARK_EMPTY) &&
- (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) {
+ (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) {
overrideBackground = true;
background = vsDraw.markers[markBit].back.allocated;
}
@@ -2178,7 +2271,7 @@
}
bool drawWhitespaceBackground = (vsDraw.viewWhitespace != wsInvisible) &&
- (!overrideBackground) && (vsDraw.whitespaceBackgroundSet);
+ (!overrideBackground) && (vsDraw.whitespaceBackgroundSet);
bool inIndentation = subLine == 0; // Do not handle indentation except on first subline.
int indentWidth = pdoc->IndentSize() * vsDraw.spaceWidth;
@@ -2222,7 +2315,7 @@
// default bgnd here..
surface->FillRectangle(rcSegment, overrideBackground ? background :
- vsDraw.styles[STYLE_DEFAULT].back.allocated);
+ 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
@@ -2246,7 +2339,7 @@
// Does not take margin into account but not significant
int xStartVisible = subLineStart - xStart;
- BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, xStartVisible);
+ BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible);
int next = bfBack.First();
// Background drawing loop
@@ -2284,13 +2377,13 @@
// Normal text display
surface->FillRectangle(rcSegment, textBack);
if (vsDraw.viewWhitespace != wsInvisible ||
- (inIndentation && vsDraw.viewIndentationGuides)) {
+ (inIndentation && vsDraw.viewIndentationGuides == ivReal)) {
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);
+ ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom);
surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground.allocated);
}
} else {
@@ -2321,7 +2414,7 @@
inIndentation = subLine == 0; // Do not handle indentation except on first subline.
// Foreground drawing loop
- BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, xStartVisible);
+ BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible);
next = bfFore.First();
while (next < lineEnd) {
@@ -2359,23 +2452,24 @@
textBack = vsDraw.whitespaceBackground.allocated;
surface->FillRectangle(rcSegment, textBack);
}
- if ((vsDraw.viewWhitespace != wsInvisible) || ((inIndentation && vsDraw.viewIndentationGuides))) {
+ if ((vsDraw.viewWhitespace != wsInvisible) ||
+ (inIndentation && vsDraw.viewIndentationGuides != ivNone)) {
if (vsDraw.whitespaceForegroundSet)
textFore = vsDraw.whitespaceForeground.allocated;
surface->PenColour(textFore);
}
- if (inIndentation && vsDraw.viewIndentationGuides) {
+ if (inIndentation && vsDraw.viewIndentationGuides == ivReal) {
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));
+ (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);
+ rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent);
DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2);
}
}
@@ -2385,46 +2479,32 @@
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);
+ DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, textBack, textFore, twoPhaseDraw);
} else {
char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
surface->DrawTextNoClip(rcSegment, ctrlCharsFont,
- rcSegment.top + vsDraw.maxAscent,
- cc, 1, textBack, textFore);
+ rcSegment.top + vsDraw.maxAscent,
+ cc, 1, textBack, textFore);
}
+ } else if ((i == startseg) && (static_cast<unsigned char>(ll->chars[i]) >= 0x80) && IsUnicodeMode()) {
+ char hexits[3];
+ sprintf(hexits, "%2X", ll->chars[i] & 0xff);
+ DrawTextBlob(surface, vsDraw, rcSegment, hexits, textBack, textFore, twoPhaseDraw);
} 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);
+ 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);
+ rcSegment.top + vsDraw.maxAscent, ll->chars + startseg,
+ i - startseg + 1, textFore, textBack);
}
}
if (vsDraw.viewWhitespace != wsInvisible ||
- (inIndentation && vsDraw.viewIndentationGuides)) {
+ (inIndentation && vsDraw.viewIndentationGuides != ivNone)) {
for (int cpos = 0; cpos <= i - startseg; cpos++) {
if (ll->chars[cpos + startseg] == ' ') {
if (vsDraw.viewWhitespace != wsInvisible) {
@@ -2444,11 +2524,11 @@
surface->FillRectangle(rcDot, textFore);
}
}
- if (inIndentation && vsDraw.viewIndentationGuides) {
+ if (inIndentation && vsDraw.viewIndentationGuides == ivReal) {
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]));
+ (ll->xHighlightGuide == ll->positions[cpos + startseg]));
}
}
} else {
@@ -2475,7 +2555,50 @@
break;
}
}
+ if ((vsDraw.viewIndentationGuides == ivLookForward || vsDraw.viewIndentationGuides == ivLookBoth)
+ && (subLine == 0)) {
+ int indentSpace = pdoc->GetLineIndentation(line);
+ // Find the most recent line with some text
+ int lineLastWithText = line;
+ while (lineLastWithText > 0 && pdoc->IsWhiteLine(lineLastWithText)) {
+ lineLastWithText--;
+ }
+ if (lineLastWithText < line) {
+ // This line is empty, so use indentation of last line with text
+ int indentLastWithText = pdoc->GetLineIndentation(lineLastWithText);
+ int isFoldHeader = pdoc->GetLevel(lineLastWithText) & SC_FOLDLEVELHEADERFLAG;
+ if (isFoldHeader) {
+ // Level is one more level than parent
+ indentLastWithText += pdoc->IndentSize();
+ }
+ if (vsDraw.viewIndentationGuides == ivLookForward) {
+ // In viLookForward mode, previous line only used if it is a fold header
+ if (isFoldHeader) {
+ indentSpace = Platform::Maximum(indentSpace, indentLastWithText);
+ }
+ } else { // viLookBoth
+ indentSpace = Platform::Maximum(indentSpace, indentLastWithText);
+ }
+ }
+
+ int lineNextWithText = line;
+ while (lineNextWithText < pdoc->LinesTotal() && pdoc->IsWhiteLine(lineNextWithText)) {
+ lineNextWithText++;
+ }
+ if (lineNextWithText > line) {
+ // This line is empty, so use indentation of last line with text
+ indentSpace = Platform::Maximum(indentSpace,
+ pdoc->GetLineIndentation(lineNextWithText));
+ }
+
+ for (int indentPos = pdoc->IndentSize(); indentPos < indentSpace; indentPos += pdoc->IndentSize()) {
+ int xIndent = indentPos * vsDraw.spaceWidth;
+ DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment,
+ (ll->xHighlightGuide == xIndent));
+ }
+ }
+
DrawIndicators(surface, vsDraw, line, xStart, rcLine, ll, subLine, lineEnd, false);
// End of the drawing of the current line
@@ -2526,7 +2649,7 @@
int lineStart = ll->LineStart(subLine);
int posBefore = posCaret;
- int posAfter = MovePositionOutsideChar(posCaret+1, 1);
+ int posAfter = MovePositionOutsideChar(posCaret + 1, 1);
int numCharsToDraw = posAfter - posCaret;
// Work out where the starting and ending offsets are. We need to
@@ -2541,7 +2664,7 @@
}
// Char shares horizontal space, update the numChars to draw
// Update posBefore to point to the prev char
- posBefore = MovePositionOutsideChar(posBefore-1, -1);
+ posBefore = MovePositionOutsideChar(posBefore - 1, -1);
numCharsToDraw = posAfter - posBefore;
offsetFirstChar = offset - (posCaret - posBefore);
}
@@ -2554,7 +2677,7 @@
// the next character ends, and 2nd next begins. We'll need
// to compare these two
posBefore = posAfter;
- posAfter = MovePositionOutsideChar(posAfter+1, 1);
+ 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
@@ -2572,9 +2695,9 @@
// (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);
+ rcCaret.top + vsDraw.maxAscent, ll->chars + offsetFirstChar,
+ numCharsToDraw, vsDraw.styles[styleMain].back.allocated,
+ vsDraw.caretcolour.allocated);
}
void Editor::RefreshPixMaps(Surface *surfaceWindow) {
@@ -2636,9 +2759,9 @@
if (!pixmapLine->Initialised()) {
PRectangle rcClient = GetClientRectangle();
pixmapLine->InitPixMap(rcClient.Width(), vs.lineHeight,
- surfaceWindow, wMain.GetID());
+ surfaceWindow, wMain.GetID());
pixmapSelMargin->InitPixMap(vs.fixedColumnWidth,
- rcClient.Height(), surfaceWindow, wMain.GetID());
+ rcClient.Height(), surfaceWindow, wMain.GetID());
}
}
}
@@ -2799,7 +2922,7 @@
Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1));
// Highlight the current braces if any
ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
- highlightGuideColumn * vs.spaceWidth);
+ highlightGuideColumn * vs.spaceWidth);
// Draw the line
DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
@@ -2869,8 +2992,7 @@
// Draw the Caret
if (lineDoc == lineCaret) {
int offset = Platform::Minimum(posCaret - rangeLine.start, ll->maxLineLength);
- if ((offset >= ll->LineStart(subLine)) &&
- ((offset < ll->LineStart(subLine + 1)) || offset == ll->numCharsInLine)) {
+ if (ll->InLine(offset, subLine)) {
int xposCaret = ll->positions[offset] - ll->positions[ll->LineStart(subLine)] + xStart;
if (actualWrapVisualStartIndent != 0) {
@@ -2879,7 +3001,7 @@
xposCaret += actualWrapVisualStartIndent * vs.aveCharWidth;
}
if ((xposCaret >= 0) && (vs.caretWidth > 0) && (vs.caretStyle != CARETSTYLE_INVISIBLE) &&
- ((posDrag >= 0) || (caret.active && caret.on))) {
+ ((posDrag >= 0) || (caret.active && caret.on))) {
bool caretAtEOF = false;
bool caretAtEOL = false;
bool drawBlockCaret = false;
@@ -2899,7 +3021,7 @@
if (widthOverstrikeCaret < 3) // Make sure its visible
widthOverstrikeCaret = 3;
- if (offset > 0)
+ if (offset > ll->LineStart(subLine))
caretWidthOffset = 1; // Move back so overlaps both character cells.
if (posDrag >= 0) {
/* Dragging text, use a line caret */
@@ -2936,7 +3058,7 @@
if (bufferedDraw) {
Point from(vs.fixedColumnWidth, 0);
PRectangle rcCopyArea(vs.fixedColumnWidth, yposScreen,
- rcClient.right, yposScreen + vs.lineHeight);
+ rcClient.right, yposScreen + vs.lineHeight);
surfaceWindow->Copy(rcCopyArea, from, *pixmapLine);
}
//durCopy += et.Duration(true);
@@ -2948,6 +3070,9 @@
yposScreen += vs.lineHeight;
visibleLine++;
+
+ lineWidthMaxSeen = Platform::Maximum(
+ lineWidthMaxSeen, ll->positions[ll->numCharsInLine]);
//gdk_flush();
}
ll.Set(0);
@@ -3025,7 +3150,7 @@
vsPrint.showMarkedLines = false;
vsPrint.fixedColumnWidth = 0;
vsPrint.zoomLevel = printMagnification;
- vsPrint.viewIndentationGuides = false;
+ vsPrint.viewIndentationGuides = ivNone;
// Don't show the selection when printing
vsPrint.selbackset = false;
vsPrint.selforeset = false;
@@ -3035,7 +3160,7 @@
vsPrint.showCaretLineBackground = false;
// Set colours for printing according to users settings
- for (int sty = 0;sty <= STYLE_MAX;sty++) {
+ for (size_t sty = 0;sty < vsPrint.stylesSize;sty++) {
if (printColourMode == SC_PRINT_INVERTLIGHT) {
vsPrint.styles[sty].fore.desired = InvertedLight(vsPrint.styles[sty].fore.desired);
vsPrint.styles[sty].back.desired = InvertedLight(vsPrint.styles[sty].back.desired);
@@ -3058,7 +3183,7 @@
int lineNumberWidth = 0;
if (lineNumberIndex >= 0) {
lineNumberWidth = surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font,
- "99999" lineNumberPrintSpace, 5 + istrlen(lineNumberPrintSpace));
+ "99999" lineNumberPrintSpace, 5 + istrlen(lineNumberPrintSpace));
vsPrint.ms[lineNumberIndex].width = lineNumberWidth;
vsPrint.Refresh(*surfaceMeasure); // Recalculate fixedColumnWidth
}
@@ -3142,12 +3267,12 @@
rcNumber.right = rcNumber.left + lineNumberWidth;
// Right justify
rcNumber.left = rcNumber.right - surfaceMeasure->WidthText(
- vsPrint.styles[STYLE_LINENUMBER].font, number, istrlen(number));
+ vsPrint.styles[STYLE_LINENUMBER].font, number, istrlen(number));
surface->FlushCachedState();
surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font,
- ypos + vsPrint.maxAscent, number, istrlen(number),
- vsPrint.styles[STYLE_LINENUMBER].fore.allocated,
- vsPrint.styles[STYLE_LINENUMBER].back.allocated);
+ ypos + vsPrint.maxAscent, number, istrlen(number),
+ vsPrint.styles[STYLE_LINENUMBER].fore.allocated,
+ vsPrint.styles[STYLE_LINENUMBER].back.allocated);
}
// Draw the line
@@ -3238,6 +3363,7 @@
AddCharUTF(s, 1);
}
+// AddCharUTF inserts an array of bytes which may or may not be in UTF-8.
void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
bool wasSelection = currentPos != anchor;
ClearSelection();
@@ -3257,6 +3383,14 @@
if (charReplaceAction) {
pdoc->EndUndoAction();
}
+ // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
+ if (wrapState != eWrapNone) {
+ AutoSurface surface(this);
+ if (surface) {
+ WrapOneLine(surface, pdoc->LineFromPosition(currentPos));
+ }
+ SetScrollBars();
+ }
EnsureCaretVisible();
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
@@ -3266,7 +3400,7 @@
if (treatAsDBCS) {
NotifyChar((static_cast<unsigned char>(s[0]) << 8) |
- static_cast<unsigned char>(s[1]));
+ static_cast<unsigned char>(s[1]));
} else {
int byte = static_cast<unsigned char>(s[0]);
if ((byte < 0xC0) || (1 == len)) {
@@ -3353,6 +3487,7 @@
}
void Editor::Cut() {
+ pdoc->CheckReadOnly();
if (!pdoc->IsReadOnly() && !SelectionContainsProtected()) {
Copy();
ClearSelection();
@@ -3522,7 +3657,7 @@
scn.line = LineFromLocation(pt);
scn.position = PositionFromLocationClose(pt);
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
- (alt ? SCI_ALT : 0);
+ (alt ? SCI_ALT : 0);
NotifyParent(scn);
}
@@ -3531,7 +3666,7 @@
scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK;
scn.position = position;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
- (alt ? SCI_ALT : 0);
+ (alt ? SCI_ALT : 0);
NotifyParent(scn);
}
@@ -3540,7 +3675,7 @@
scn.nmhdr.code = SCN_HOTSPOTCLICK;
scn.position = position;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
- (alt ? SCI_ALT : 0);
+ (alt ? SCI_ALT : 0);
NotifyParent(scn);
}
@@ -3580,7 +3715,7 @@
SCNotification scn = {0};
scn.nmhdr.code = SCN_MARGINCLICK;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
- (alt ? SCI_ALT : 0);
+ (alt ? SCI_ALT : 0);
scn.position = pdoc->LineStart(LineFromLocation(pt));
scn.margin = marginClicked;
NotifyParent(scn);
@@ -3632,7 +3767,7 @@
}
void Editor::CheckModificationForWrap(DocModification mh) {
- if (mh.modificationType & (SC_MOD_INSERTTEXT|SC_MOD_DELETETEXT)) {
+ if (mh.modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) {
llc.Invalidate(LineLayout::llCheckTextAndStyle);
if (wrapState != eWrapNone) {
int lineDoc = pdoc->LineFromPosition(mh.position);
@@ -3670,7 +3805,16 @@
if (paintState == painting) {
CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length));
}
- if (mh.modificationType & (SC_MOD_CHANGESTYLE|SC_MOD_CHANGEINDICATOR)) {
+ if (mh.modificationType & SC_MOD_CHANGELINESTATE) {
+ if (paintState == painting) {
+ CheckForChangeOutsidePaint(
+ Range(pdoc->LineStart(mh.line), pdoc->LineStart(mh.line + 1)));
+ } else {
+ // Could check that change is before last visible line.
+ Redraw();
+ }
+ }
+ if (mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) {
if (mh.modificationType & SC_MOD_CHANGESTYLE) {
pdoc->IncrementStyleClock();
}
@@ -3692,13 +3836,11 @@
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.
@@ -3768,7 +3910,7 @@
// If client wants to see this modification
if (mh.modificationType & modEventMask) {
- if ((mh.modificationType & (SC_MOD_CHANGESTYLE|SC_MOD_CHANGEINDICATOR)) == 0) {
+ if ((mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) == 0) {
// Real modification made to text of document.
NotifyChange(); // Send EN_CHANGE
}
@@ -3896,8 +4038,8 @@
case SCI_SELECTIONDUPLICATE:
break;
- // Filter out all others like display changes. Also, newlines are redundant
- // with char insert messages.
+ // Filter out all others like display changes. Also, newlines are redundant
+ // with char insert messages.
case SCI_NEWLINE:
default:
// printf("Filtered out %ld of macro recording\n", iMessage);
@@ -3926,9 +4068,9 @@
int currentLine = pdoc->LineFromPosition(currentPos);
int topStutterLine = topLine + caretYSlop;
int bottomStutterLine =
- pdoc->LineFromPosition(PositionFromLocation(
- Point(lastXChosen, direction * vs.lineHeight * LinesToScroll())))
- - caretYSlop - 1;
+ pdoc->LineFromPosition(PositionFromLocation(
+ Point(lastXChosen, direction * vs.lineHeight * LinesToScroll())))
+ - caretYSlop - 1;
if (stuttered && (direction < 0 && currentLine > topStutterLine)) {
topLineNew = topLine;
@@ -3942,9 +4084,9 @@
Point pt = LocationFromPosition(currentPos);
topLineNew = Platform::Clamp(
- topLine + direction * LinesToScroll(), 0, MaxScrollPos());
+ topLine + direction * LinesToScroll(), 0, MaxScrollPos());
newPos = PositionFromLocation(
- Point(lastXChosen, pt.y + direction * (vs.lineHeight * LinesToScroll())));
+ Point(lastXChosen, pt.y + direction * (vs.lineHeight * LinesToScroll())));
}
if (topLineNew != topLine) {
@@ -3963,7 +4105,7 @@
int startAnchor = anchor;
if (selType == selStream) {
pdoc->ChangeCase(Range(SelectionStart(), SelectionEnd()),
- makeUpperCase);
+ makeUpperCase);
SetSelection(startCurrent, startAnchor);
} else {
SelectionLineIterator lineIterator(this, false);
@@ -4043,6 +4185,7 @@
}
}
SetLastXChosen();
+ SetScrollBars();
EnsureCaretVisible();
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
@@ -4051,7 +4194,7 @@
void Editor::CursorUpOrDown(int direction, selTypes sel) {
Point pt = LocationFromPosition(currentPos);
int posNew = PositionFromLocation(
- Point(lastXChosen, pt.y + direction * vs.lineHeight));
+ Point(lastXChosen, pt.y + direction * vs.lineHeight));
if (direction < 0) {
// Line wrapping may lead to a location on the same line, so
// seek back if that is the case.
@@ -4264,7 +4407,7 @@
int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
int realEndPos = pdoc->LineEndPosition(currentPos);
if (endPos > realEndPos // if moved past visible EOLs
- || currentPos >= endPos) // if at end of display line already
+ || currentPos >= endPos) // if at end of display line already
endPos = realEndPos;
MovePositionTo(endPos);
SetLastXChosen();
@@ -4274,7 +4417,7 @@
int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
int realEndPos = pdoc->LineEndPosition(currentPos);
if (endPos > realEndPos // if moved past visible EOLs
- || currentPos >= endPos) // if at end of display line already
+ || currentPos >= endPos) // if at end of display line already
endPos = realEndPos;
MovePositionTo(endPos, selStream);
SetLastXChosen();
@@ -4449,7 +4592,7 @@
int lineStart = pdoc->LineFromPosition(SelectionStart());
int lineEnd = pdoc->LineFromPosition(SelectionEnd());
CopyRangeToClipboard(pdoc->LineStart(lineStart),
- pdoc->LineStart(lineEnd + 1));
+ pdoc->LineStart(lineEnd + 1));
}
break;
case SCI_LINECUT: {
@@ -4502,22 +4645,22 @@
break;
case SCI_HOMEDISPLAY:
MovePositionTo(MovePositionSoVisible(
- StartEndDisplayLine(currentPos, true), -1));
+ StartEndDisplayLine(currentPos, true), -1));
SetLastXChosen();
break;
case SCI_HOMEDISPLAYEXTEND:
MovePositionTo(MovePositionSoVisible(
- StartEndDisplayLine(currentPos, true), -1), selStream);
+ StartEndDisplayLine(currentPos, true), -1), selStream);
SetLastXChosen();
break;
case SCI_LINEENDDISPLAY:
MovePositionTo(MovePositionSoVisible(
- StartEndDisplayLine(currentPos, false), 1));
+ StartEndDisplayLine(currentPos, false), 1));
SetLastXChosen();
break;
case SCI_LINEENDDISPLAYEXTEND:
MovePositionTo(MovePositionSoVisible(
- StartEndDisplayLine(currentPos, false), 1), selStream);
+ StartEndDisplayLine(currentPos, false), 1), selStream);
SetLastXChosen();
break;
}
@@ -4531,7 +4674,7 @@
int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) {
DwellEnd(false);
int modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
- (alt ? SCI_ALT : 0);
+ (alt ? SCI_ALT : 0);
int msg = kmap.Find(key, modifiers);
if (msg) {
if (consumed)
@@ -4572,7 +4715,7 @@
SetEmptySelection(currentPos + 1);
} else {
int numSpaces = (pdoc->tabInChars) -
- (pdoc->GetColumn(currentPos) % (pdoc->tabInChars));
+ (pdoc->GetColumn(currentPos) % (pdoc->tabInChars));
if (numSpaces < 1)
numSpaces = pdoc->tabInChars;
for (int i = 0; i < numSpaces; i++) {
@@ -4593,7 +4736,7 @@
pdoc->EndUndoAction();
} else {
int newColumn = ((pdoc->GetColumn(currentPos) - 1) / pdoc->tabInChars) *
- pdoc->tabInChars;
+ pdoc->tabInChars;
if (newColumn < 0)
newColumn = 0;
int newPos = currentPos;
@@ -4632,19 +4775,19 @@
* @return The position of the found text, -1 if not found.
*/
long Editor::FindText(
- uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
- ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX.
- sptr_t lParam) { ///< @c TextToFind structure: The text to search for in the given range.
+ uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
+ ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX.
+ sptr_t lParam) { ///< @c TextToFind structure: The text to search for in the given range.
TextToFind *ft = reinterpret_cast<TextToFind *>(lParam);
int lengthFound = istrlen(ft->lpstrText);
int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText,
- (wParam & SCFIND_MATCHCASE) != 0,
- (wParam & SCFIND_WHOLEWORD) != 0,
- (wParam & SCFIND_WORDSTART) != 0,
- (wParam & SCFIND_REGEXP) != 0,
- (wParam & SCFIND_POSIX) != 0,
- &lengthFound);
+ (wParam & SCFIND_MATCHCASE) != 0,
+ (wParam & SCFIND_WHOLEWORD) != 0,
+ (wParam & SCFIND_WORDSTART) != 0,
+ (wParam & SCFIND_REGEXP) != 0,
+ (wParam & SCFIND_POSIX) != 0,
+ &lengthFound);
if (pos != -1) {
ft->chrgText.cpMin = pos;
ft->chrgText.cpMax = pos + lengthFound;
@@ -4675,7 +4818,7 @@
long Editor::SearchText(
unsigned int iMessage, ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV.
uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
- ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX.
+ ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX.
sptr_t lParam) { ///< The text to search for.
const char *txt = reinterpret_cast<char *>(lParam);
@@ -4683,20 +4826,20 @@
int lengthFound = istrlen(txt);
if (iMessage == SCI_SEARCHNEXT) {
pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt,
- (wParam & SCFIND_MATCHCASE) != 0,
- (wParam & SCFIND_WHOLEWORD) != 0,
- (wParam & SCFIND_WORDSTART) != 0,
- (wParam & SCFIND_REGEXP) != 0,
- (wParam & SCFIND_POSIX) != 0,
- &lengthFound);
+ (wParam & SCFIND_MATCHCASE) != 0,
+ (wParam & SCFIND_WHOLEWORD) != 0,
+ (wParam & SCFIND_WORDSTART) != 0,
+ (wParam & SCFIND_REGEXP) != 0,
+ (wParam & SCFIND_POSIX) != 0,
+ &lengthFound);
} else {
pos = pdoc->FindText(searchAnchor, 0, txt,
- (wParam & SCFIND_MATCHCASE) != 0,
- (wParam & SCFIND_WHOLEWORD) != 0,
- (wParam & SCFIND_WORDSTART) != 0,
- (wParam & SCFIND_REGEXP) != 0,
- (wParam & SCFIND_POSIX) != 0,
- &lengthFound);
+ (wParam & SCFIND_MATCHCASE) != 0,
+ (wParam & SCFIND_WHOLEWORD) != 0,
+ (wParam & SCFIND_WORDSTART) != 0,
+ (wParam & SCFIND_REGEXP) != 0,
+ (wParam & SCFIND_POSIX) != 0,
+ &lengthFound);
}
if (pos != -1) {
@@ -4713,12 +4856,12 @@
long Editor::SearchInTarget(const char *text, int length) {
int lengthFound = length;
int pos = pdoc->FindText(targetStart, targetEnd, text,
- (searchFlags & SCFIND_MATCHCASE) != 0,
- (searchFlags & SCFIND_WHOLEWORD) != 0,
- (searchFlags & SCFIND_WORDSTART) != 0,
- (searchFlags & SCFIND_REGEXP) != 0,
- (searchFlags & SCFIND_POSIX) != 0,
- &lengthFound);
+ (searchFlags & SCFIND_MATCHCASE) != 0,
+ (searchFlags & SCFIND_WHOLEWORD) != 0,
+ (searchFlags & SCFIND_WORDSTART) != 0,
+ (searchFlags & SCFIND_REGEXP) != 0,
+ (searchFlags & SCFIND_POSIX) != 0,
+ &lengthFound);
if (pos != -1) {
targetStart = pos;
targetEnd = pos + lengthFound;
@@ -4761,7 +4904,7 @@
void Editor::CopySelectionFromRange(SelectionText *ss, int start, int end) {
ss->Set(CopyRange(start, end), end - start + 1,
- pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
+ pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
}
void Editor::CopySelectionRange(SelectionText *ss) {
@@ -4787,8 +4930,8 @@
lineIterator.Reset();
while (lineIterator.Iterate()) {
for (int i = lineIterator.startPos;
- i < lineIterator.endPos;
- i++) {
+ i < lineIterator.endPos;
+ i++) {
text[j++] = pdoc->CharAt(i);
}
if (selType != selLines) {
@@ -4804,7 +4947,7 @@
}
}
ss->Set(text, size + 1, pdoc->dbcsCodePage,
- vs.styles[STYLE_DEFAULT].characterSet, selType == selRectangle);
+ vs.styles[STYLE_DEFAULT].characterSet, selType == selRectangle);
}
}
@@ -4813,14 +4956,14 @@
end = pdoc->ClampPositionIntoDocument(end);
SelectionText selectedText;
selectedText.Set(CopyRange(start, end), end - start + 1,
- pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
+ pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
CopyToClipboard(selectedText);
}
void Editor::CopyText(int length, const char *text) {
SelectionText selectedText;
selectedText.Copy(text, length + 1,
- pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
+ pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
CopyToClipboard(selectedText);
}
@@ -4991,13 +5134,13 @@
void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
if (lineAnchor_ < lineCurrent_) {
SetSelection(pdoc->LineStart(lineCurrent_ + 1),
- pdoc->LineStart(lineAnchor_));
+ pdoc->LineStart(lineAnchor_));
} else if (lineAnchor_ > lineCurrent_) {
SetSelection(pdoc->LineStart(lineCurrent_),
- pdoc->LineStart(lineAnchor_ + 1));
+ pdoc->LineStart(lineAnchor_ + 1));
} else { // Same line, select it
SetSelection(pdoc->LineStart(lineAnchor_ + 1),
- pdoc->LineStart(lineAnchor_));
+ pdoc->LineStart(lineAnchor_));
}
}
@@ -5051,10 +5194,10 @@
if (selectionType == selWord) {
if (currentPos >= originalAnchorPos) { // Moved forward
SetSelection(pdoc->ExtendWordSelect(currentPos, 1),
- pdoc->ExtendWordSelect(originalAnchorPos, -1));
+ pdoc->ExtendWordSelect(originalAnchorPos, -1));
} else { // Moved backward
SetSelection(pdoc->ExtendWordSelect(currentPos, -1),
- pdoc->ExtendWordSelect(originalAnchorPos, 1));
+ pdoc->ExtendWordSelect(originalAnchorPos, 1));
}
} else if (selectionType == selLine) {
lineAnchor = LineFromLocation(pt);
@@ -5082,7 +5225,7 @@
// Single click in margin: select whole line
LineSelection(lineAnchor, lineAnchor);
SetSelection(pdoc->LineStart(lineAnchor + 1),
- pdoc->LineStart(lineAnchor));
+ pdoc->LineStart(lineAnchor));
} else {
// Single shift+click in margin: select from line anchor to clicked line
if (anchor > currentPos)
@@ -5107,14 +5250,6 @@
else
inDragDrop = ddNone;
}
-#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);
@@ -5230,10 +5365,10 @@
// being unmade.
} else if (movePos > originalAnchorPos) { // Moved forward
SetSelection(pdoc->ExtendWordSelect(movePos, 1),
- pdoc->ExtendWordSelect(originalAnchorPos, -1));
+ pdoc->ExtendWordSelect(originalAnchorPos, -1));
} else { // Moved backward
SetSelection(pdoc->ExtendWordSelect(movePos, -1),
- pdoc->ExtendWordSelect(originalAnchorPos, 1));
+ pdoc->ExtendWordSelect(originalAnchorPos, 1));
}
} else {
// Continue selecting by line
@@ -5366,6 +5501,10 @@
}
}
}
+ if (horizontalScrollBarVisible && trackLineWidth && (lineWidthMaxSeen > scrollWidth)) {
+ scrollWidth = lineWidthMaxSeen;
+ SetScrollBars();
+ }
if ((dwellDelay < SC_TIME_FOREVER) &&
(ticksToDwell > 0) &&
(!HaveMouseCapture())) {
@@ -5413,7 +5552,11 @@
}
bool Editor::PaintContains(PRectangle rc) {
- return rcPaint.Contains(rc);
+ if (rc.Empty()) {
+ return true;
+ } else {
+ return rcPaint.Contains(rc);
+ }
}
bool Editor::PaintContainsMargin() {
@@ -5583,7 +5726,7 @@
SetVerticalScrollPos();
Redraw();
} else if ((lineDisplay > topLine + LinesOnScreen() - 1) ||
- ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) {
+ ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) {
SetTopLine(Platform::Clamp(lineDisplay - LinesOnScreen() + 1 + visibleSlop, 0, MaxScrollPos()));
SetVerticalScrollPos();
Redraw();
@@ -5604,8 +5747,10 @@
length = istrlen(text);
if (replacePatterns) {
text = pdoc->SubstituteByPosition(text, &length);
- if (!text)
+ if (!text) {
+ pdoc->EndUndoAction();
return 0;
+ }
}
if (targetStart != targetEnd)
pdoc->DeleteChars(targetStart, targetEnd - targetStart);
@@ -5645,11 +5790,11 @@
char *text = new char[textLength];
if (text) {
size_t i;
- for (i=0;i<textLength;i++) {
+ for (i = 0;i < textLength;i++) {
text[i] = buffer[i*2];
}
pdoc->InsertString(CurrentPosition(), text, textLength);
- for (i=0;i<textLength;i++) {
+ for (i = 0;i < textLength;i++) {
text[i] = buffer[i*2+1];
}
pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff));
@@ -5667,6 +5812,89 @@
return reinterpret_cast<char *>(lParam);
}
+void Editor::StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
+ vs.EnsureStyle(wParam);
+ switch (iMessage) {
+ case SCI_STYLESETFORE:
+ vs.styles[wParam].fore.desired = ColourDesired(lParam);
+ break;
+ case SCI_STYLESETBACK:
+ vs.styles[wParam].back.desired = ColourDesired(lParam);
+ break;
+ case SCI_STYLESETBOLD:
+ vs.styles[wParam].bold = lParam != 0;
+ break;
+ case SCI_STYLESETITALIC:
+ vs.styles[wParam].italic = lParam != 0;
+ break;
+ case SCI_STYLESETEOLFILLED:
+ vs.styles[wParam].eolFilled = lParam != 0;
+ break;
+ case SCI_STYLESETSIZE:
+ vs.styles[wParam].size = lParam;
+ break;
+ case SCI_STYLESETFONT:
+ if (lParam != 0) {
+ vs.SetStyleFontName(wParam, CharPtrFromSPtr(lParam));
+ }
+ break;
+ case SCI_STYLESETUNDERLINE:
+ vs.styles[wParam].underline = lParam != 0;
+ break;
+ case SCI_STYLESETCASE:
+ vs.styles[wParam].caseForce = static_cast<Style::ecaseForced>(lParam);
+ break;
+ case SCI_STYLESETCHARACTERSET:
+ vs.styles[wParam].characterSet = lParam;
+ break;
+ case SCI_STYLESETVISIBLE:
+ vs.styles[wParam].visible = lParam != 0;
+ break;
+ case SCI_STYLESETCHANGEABLE:
+ vs.styles[wParam].changeable = lParam != 0;
+ break;
+ case SCI_STYLESETHOTSPOT:
+ vs.styles[wParam].hotspot = lParam != 0;
+ break;
+ }
+ InvalidateStyleRedraw();
+}
+
+sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
+ vs.EnsureStyle(wParam);
+ switch (iMessage) {
+ case SCI_STYLEGETFORE:
+ return vs.styles[wParam].fore.desired.AsLong();
+ case SCI_STYLEGETBACK:
+ return vs.styles[wParam].back.desired.AsLong();
+ case SCI_STYLEGETBOLD:
+ return vs.styles[wParam].bold ? 1 : 0;
+ case SCI_STYLEGETITALIC:
+ return vs.styles[wParam].italic ? 1 : 0;
+ case SCI_STYLEGETEOLFILLED:
+ return vs.styles[wParam].eolFilled ? 1 : 0;
+ case SCI_STYLEGETSIZE:
+ return vs.styles[wParam].size;
+ case SCI_STYLEGETFONT:
+ if (lParam != 0)
+ strcpy(CharPtrFromSPtr(lParam), vs.styles[wParam].fontName);
+ return strlen(vs.styles[wParam].fontName);
+ case SCI_STYLEGETUNDERLINE:
+ return vs.styles[wParam].underline ? 1 : 0;
+ case SCI_STYLEGETCASE:
+ return static_cast<int>(vs.styles[wParam].caseForce);
+ case SCI_STYLEGETCHARACTERSET:
+ return vs.styles[wParam].characterSet;
+ case SCI_STYLEGETVISIBLE:
+ return vs.styles[wParam].visible ? 1 : 0;
+ case SCI_STYLEGETCHANGEABLE:
+ return vs.styles[wParam].changeable ? 1 : 0;
+ case SCI_STYLEGETHOTSPOT:
+ return vs.styles[wParam].hotspot ? 1 : 0;
+ }
+ return 0;
+}
+
sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
//Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam);
@@ -5896,10 +6124,10 @@
return searchFlags;
case SCI_POSITIONBEFORE:
- return pdoc->MovePositionOutsideChar(wParam-1, -1, true);
+ return pdoc->MovePositionOutsideChar(wParam - 1, -1, true);
case SCI_POSITIONAFTER:
- return pdoc->MovePositionOutsideChar(wParam+1, 1, true);
+ return pdoc->MovePositionOutsideChar(wParam + 1, 1, true);
case SCI_LINESCROLL:
ScrollTo(topLine + lParam);
@@ -6394,6 +6622,7 @@
case SCI_SETSCROLLWIDTH:
PLATFORM_ASSERT(wParam > 0);
if ((wParam > 0) && (wParam != static_cast<unsigned int >(scrollWidth))) {
+ lineWidthMaxSeen = 0;
scrollWidth = wParam;
SetScrollBars();
}
@@ -6402,6 +6631,13 @@
case SCI_GETSCROLLWIDTH:
return scrollWidth;
+ case SCI_SETSCROLLWIDTHTRACKING:
+ trackLineWidth = wParam != 0;
+ break;
+
+ case SCI_GETSCROLLWIDTHTRACKING:
+ return trackLineWidth;
+
case SCI_LINESJOIN:
LinesJoin();
break;
@@ -6411,7 +6647,7 @@
break;
case SCI_TEXTWIDTH:
- PLATFORM_ASSERT(wParam <= STYLE_MAX);
+ PLATFORM_ASSERT(wParam < vs.stylesSize);
PLATFORM_ASSERT(lParam);
return TextWidth(wParam, CharPtrFromSPtr(lParam));
@@ -6472,7 +6708,7 @@
return verticalScrollBarVisible;
case SCI_SETINDENTATIONGUIDES:
- vs.viewIndentationGuides = wParam != 0;
+ vs.viewIndentationGuides = IndentView(wParam);
Redraw();
break;
@@ -6640,157 +6876,42 @@
break;
case SCI_STYLESETFORE:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].fore.desired = ColourDesired(lParam);
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETBACK:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].back.desired = ColourDesired(lParam);
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETBOLD:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].bold = lParam != 0;
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETITALIC:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].italic = lParam != 0;
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETEOLFILLED:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].eolFilled = lParam != 0;
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETSIZE:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].size = lParam;
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETFONT:
- if (lParam == 0)
- return 0;
- if (wParam <= STYLE_MAX) {
- vs.SetStyleFontName(wParam, CharPtrFromSPtr(lParam));
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETUNDERLINE:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].underline = lParam != 0;
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETCASE:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].caseForce = static_cast<Style::ecaseForced>(lParam);
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETCHARACTERSET:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].characterSet = lParam;
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETVISIBLE:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].visible = lParam != 0;
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETCHANGEABLE:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].changeable = lParam != 0;
- InvalidateStyleRedraw();
- }
- break;
case SCI_STYLESETHOTSPOT:
- if (wParam <= STYLE_MAX) {
- vs.styles[wParam].hotspot = lParam != 0;
- InvalidateStyleRedraw();
- }
+ StyleSetMessage(iMessage, wParam, lParam);
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;
+ return StyleGetMessage(iMessage, wParam, lParam);
+
case SCI_STYLERESETDEFAULT:
vs.ResetDefaultStyle();
InvalidateStyleRedraw();
break;
case SCI_SETSTYLEBITS:
+ vs.EnsureStyle((1 << wParam) - 1);
pdoc->SetStylingBits(wParam);
break;
@@ -7001,12 +7122,12 @@
case SCI_ASSIGNCMDKEY:
kmap.AssignCmdKey(Platform::LowShortFromLong(wParam),
- Platform::HighShortFromLong(wParam), lParam);
+ Platform::HighShortFromLong(wParam), lParam);
break;
case SCI_CLEARCMDKEY:
kmap.AssignCmdKey(Platform::LowShortFromLong(wParam),
- Platform::HighShortFromLong(wParam), SCI_NULL);
+ Platform::HighShortFromLong(wParam), SCI_NULL);
break;
case SCI_CLEARALLCMDKEYS:
Modified: trunk/scintilla/Editor.h
===================================================================
--- trunk/scintilla/Editor.h 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/Editor.h 2007-12-02 11:58:17 UTC (rev 2086)
@@ -136,6 +136,8 @@
int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret
bool horizontalScrollBarVisible;
int scrollWidth;
+ bool trackLineWidth;
+ int lineWidthMaxSeen;
bool verticalScrollBarVisible;
bool endAtLastLine;
bool caretSticky;
@@ -297,6 +299,7 @@
virtual void UpdateSystemCaret();
void NeedWrapping(int docLineStart = 0, int docLineEnd = wrapLineLarge);
+ bool WrapOneLine(Surface *surface, int lineToWrap);
bool WrapLines(bool fullWrap, int priorityWrapLineStart);
void LinesJoin();
void LinesSplit(int pixelWidth);
@@ -454,6 +457,8 @@
void AddStyledText(char *buffer, int appendLength);
virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
+ void StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+ sptr_t StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
public:
// Public so the COM thunks can access it.
Modified: trunk/scintilla/LexBash.cxx
===================================================================
--- trunk/scintilla/LexBash.cxx 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/LexBash.cxx 2007-12-02 11:58:17 UTC (rev 2086)
@@ -2,7 +2,7 @@
/** @file LexBash.cxx
** Lexer for Bash.
**/
-// Copyright 2004-2005 by Neil Hodgson <neilh at scintilla.org>
+// Copyright 2004-2007 by Neil Hodgson <neilh at scintilla.org>
// Adapted from LexPerl by Kein-Hong Man <mkh at pl.jaring.my> 2004
// The License.txt file describes the conditions under which this software may be distributed.
@@ -20,11 +20,17 @@
#include "Scintilla.h"
#include "SciLexer.h"
+// define this if you want 'invalid octals' to be marked as errors
+// usually, this is not a good idea, permissive lexing is better
+#undef PEDANTIC_OCTAL
+
#define BASH_BASE_ERROR 65
#define BASH_BASE_DECIMAL 66
#define BASH_BASE_HEX 67
+#ifdef PEDANTIC_OCTAL
#define BASH_BASE_OCTAL 68
#define BASH_BASE_OCTAL_ERROR 69
+#endif
#define HERE_DELIM_MAX 256
@@ -277,7 +283,11 @@
ch = chNext;
chNext = chNext2;
} else if (isdigit(chNext)) {
+#ifdef PEDANTIC_OCTAL
numBase = BASH_BASE_OCTAL;
+#else
+ numBase = BASH_BASE_HEX;
+#endif
}
}
} else if (iswordstart(ch)) {
@@ -369,14 +379,16 @@
// hex digit 0-9a-fA-F
} else
goto numAtEnd;
+#ifdef PEDANTIC_OCTAL
} else if (numBase == BASH_BASE_OCTAL ||
numBase == BASH_BASE_OCTAL_ERROR) {
if (digit > 7) {
if (digit <= 9) {
- numBase = BASH_BASE_OCTAL_ERROR;
+ numBase = BASH_BASE_OCTAL_ERROR;
} else
goto numAtEnd;
}
+#endif
} else if (numBase == BASH_BASE_ERROR) {
if (digit > 9)
goto numAtEnd;
@@ -394,8 +406,11 @@
}
} else {
numAtEnd:
- if (numBase == BASH_BASE_ERROR ||
- numBase == BASH_BASE_OCTAL_ERROR)
+ if (numBase == BASH_BASE_ERROR
+#ifdef PEDANTIC_OCTAL
+ || numBase == BASH_BASE_OCTAL_ERROR
+#endif
+ )
state = SCE_SH_ERROR;
styler.ColourTo(i - 1, state);
state = SCE_SH_DEFAULT;
Modified: trunk/scintilla/LexCPP.cxx
===================================================================
--- trunk/scintilla/LexCPP.cxx 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/LexCPP.cxx 2007-12-02 11:58:17 UTC (rev 2086)
@@ -32,6 +32,24 @@
(state == SCE_C_COMMENTDOCKEYWORDERROR);
}
+// Preconditions: sc.currentPos points to a character after '+' or '-'.
+// The test for pos reaching 0 should be redundant,
+// and is in only for safety measures.
+// Limitation: this code will give the incorrect answer for code like
+// a = b+++/ptn/...
+// Putting a space between the '++' post-inc operator and the '+' binary op
+// fixes this, and is highly recommended for readability anyway.
+static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
+ int pos = (int) sc.currentPos;
+ while (--pos > 0) {
+ char ch = styler[pos];
+ if (ch == '+' || ch == '-') {
+ return styler[pos - 1] == ch;
+ }
+ }
+ return false;
+}
+
static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler, bool caseSensitive) {
@@ -42,7 +60,8 @@
bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
- CharacterSet setOKBeforeRE(CharacterSet::setNone, "(=,");
+ CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
+ CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
CharacterSet setDoxygen(CharacterSet::setLower, "$@\\&<>#{}[]");
@@ -297,7 +316,8 @@
sc.SetState(SCE_C_COMMENTLINEDOC);
else
sc.SetState(SCE_C_COMMENTLINE);
- } else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite)) {
+ } else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite) &&
+ (!setCouldBePostOp.Contains(chPrevNonWhite) || !FollowsPostfixOperator(sc, styler))) {
sc.SetState(SCE_C_REGEX); // JavaScript's RegEx
} else if (sc.ch == '\"') {
sc.SetState(SCE_C_STRING);
@@ -337,7 +357,7 @@
// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
-static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
+static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
Modified: trunk/scintilla/LexHTML.cxx
===================================================================
--- trunk/scintilla/LexHTML.cxx 2007-12-02 10:52:19 UTC (rev 2085)
+++ trunk/scintilla/LexHTML.cxx 2007-12-02 11:58:17 UTC (rev 2086)
@@ -565,7 +565,7 @@
break;
}
if (style == SCE_HJ_SYMBOLS) {
- chPrevNonWhite = styler.SafeGetCharAt(back);
+ chPrevNonWhite = static_cast<unsigned char>(styler.SafeGetCharAt(back));
}
}
@@ -676,10 +676,13 @@
case SCE_HJ_COMMENTDOC:
//case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
// the end of script marker from some JS interpreters.
+ case SCE_HB_COMMENTLINE:
+ case SCE_HBA_COMMENTLINE:
case SCE_HJ_DOUBLESTRING:
case SCE_HJ_SINGLESTRING:
case SCE_HJ_REGEX:
case SCE_HB_STRING:
+ case SCE_HBA_STRING:
case SCE_HP_STRING:
case SCE_HP_TRIPLE:
case SCE_HP_TRIPLEDOUBLE:
@@ -688,9 +691,8 @@
// check if the closing tag is a script tag
if (state == SCE_HJ_COMMENTLINE || isXml) {
char tag[7]; // room for the <script> tag
- char chr; // current char
- int j=0;
- chr = styler.SafeGetCharAt(i+2);
+ int j = 0;
+ char chr = styler.SafeGetCharAt(i+2);
while (j < 6 && !IsASpace(chr)) {
tag[j++] = static_cast<char>(MakeLowerCase(chr));
chr = styler.SafeGetCharAt(i+2+j);
@@ -740,7 +742,7 @@
levelCurrent++;
}
// should be better
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list