Browse Source

Fixed HighlightingColorizer crash in combination with folding.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5586 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Daniel Grunwald 16 years ago
parent
commit
ce47f3f815
  1. 46
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs
  2. 5
      src/Main/Base/Project/Src/Util/WorkerThread.cs

46
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColorizer.cs

@ -106,6 +106,26 @@ namespace ICSharpCode.AvalonEdit.Highlighting
} }
} }
DocumentLine lastColorizedLine;
/// <inheritdoc/>
protected override void Colorize(ITextRunConstructionContext context)
{
this.lastColorizedLine = null;
base.Colorize(context);
if (this.lastColorizedLine != context.VisualLine.LastDocumentLine) {
IHighlighter highlighter = context.TextView.Services.GetService(typeof(IHighlighter)) as IHighlighter;
if (highlighter != null) {
// In some cases, it is possible that we didn't highlight the last document line within the visual line
// (e.g. when the line ends with a fold marker).
// But even if we didn't highlight it, we'll have to update the highlighting state for it so that the
// proof inside TextViewDocumentHighlighter.OnHighlightStateChanged holds.
highlighter.GetSpanStack(context.VisualLine.LastDocumentLine.LineNumber);
}
}
this.lastColorizedLine = null;
}
/// <inheritdoc/> /// <inheritdoc/>
protected override void ColorizeLine(DocumentLine line) protected override void ColorizeLine(DocumentLine line)
{ {
@ -117,6 +137,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
visualLineElement => ApplyColorToElement(visualLineElement, section.Color)); visualLineElement => ApplyColorToElement(visualLineElement, section.Color));
} }
} }
this.lastColorizedLine = line;
} }
/// <summary> /// <summary>
@ -140,6 +161,14 @@ namespace ICSharpCode.AvalonEdit.Highlighting
} }
} }
/// <summary>
/// This class is responsible for telling the TextView to redraw lines when the highlighting state has changed.
/// </summary>
/// <remarks>
/// Creation of a VisualLine triggers the syntax highlighter (which works on-demand), so it says:
/// Hey, the user typed "/*". Don't just recreate that line, but also the next one
/// because my highlighting state (at end of line) changed!
/// </remarks>
sealed class TextViewDocumentHighlighter : DocumentHighlighter sealed class TextViewDocumentHighlighter : DocumentHighlighter
{ {
readonly TextView textView; readonly TextView textView;
@ -202,10 +231,23 @@ namespace ICSharpCode.AvalonEdit.Highlighting
// From this follows that the highlighting state at N is still up-to-date. // From this follows that the highlighting state at N is still up-to-date.
// The above proof holds even in the presence of folding: folding only ever hides text in the middle of a visual line. // The above proof holds even in the presence of folding: folding only ever hides text in the middle of a visual line.
// The HighlightingColorizer will always be asked to highlight the LastDocumentLine of a visual line, so it will always // Our Colorize-override ensures that the highlighting state is always updated for the LastDocumentLine,
// invalidate the next visual line when a folded line is constructed and the highlighting stack changed. // so it will always invalidate the next visual line when a folded line is constructed
// and the highlighting stack has changed.
textView.Redraw(line.NextLine, DispatcherPriority.Normal); textView.Redraw(line.NextLine, DispatcherPriority.Normal);
/*
* Meta-comment: "why does this have to be so complicated?"
*
* The problem is that I want to re-highlight only on-demand and incrementally;
* and at the same time only repaint changed lines.
* So the highlighter and the VisualLine construction both have to run in a single pass.
* The highlighter must take care that it never touches already constructed visual lines;
* if it detects that something must be redrawn because the highlighting state changed,
* it must do so early enough in the construction process.
* But doing it too early means it doesn't have the information necessary to re-highlight and redraw only the desired parts.
*/
} }
} }
} }

5
src/Main/Base/Project/Src/Util/WorkerThread.cs

@ -66,8 +66,13 @@ namespace ICSharpCode.SharpDevelop.Util
} }
readonly object lockObject = new object(); readonly object lockObject = new object();
// access needs lock using 'lockObject'
Queue<AsyncTask> taskQueue = new Queue<AsyncTask>(); Queue<AsyncTask> taskQueue = new Queue<AsyncTask>();
// access needs lock using 'lockObject'
bool workerRunning; bool workerRunning;
// not a shared variable: accessed only within worker thread
bool exitWorker; bool exitWorker;
/// <summary> /// <summary>

Loading…
Cancel
Save