Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@623 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
6 changed files with 237 additions and 102 deletions
@ -0,0 +1,162 @@
@@ -0,0 +1,162 @@
|
||||
/* |
||||
* Created by SharpDevelop. |
||||
* User: Daniel Grunwald |
||||
* Date: 25.10.2005 |
||||
* Time: 16:55 |
||||
*/ |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Drawing; |
||||
using ICSharpCode.TextEditor.Document; |
||||
|
||||
namespace ICSharpCode.TextEditor |
||||
{ |
||||
/// <summary>
|
||||
/// A class that is able to draw a line on any control (outside the text editor)
|
||||
/// </summary>
|
||||
public class DrawableLine |
||||
{ |
||||
static StringFormat sf = (StringFormat)System.Drawing.StringFormat.GenericTypographic.Clone(); |
||||
|
||||
List<SimpleTextWord> words = new List<SimpleTextWord>(); |
||||
SizeF spaceSize; |
||||
Font monospacedFont; |
||||
Font boldMonospacedFont; |
||||
|
||||
private class SimpleTextWord { |
||||
internal TextWordType Type; |
||||
internal string Word; |
||||
internal bool Bold; |
||||
internal Color Color; |
||||
|
||||
public SimpleTextWord(TextWordType Type, string Word, bool Bold, Color Color) |
||||
{ |
||||
this.Type = Type; |
||||
this.Word = Word; |
||||
this.Bold = Bold; |
||||
this.Color = Color; |
||||
} |
||||
|
||||
internal readonly static SimpleTextWord Space = new SimpleTextWord(TextWordType.Space, " ", false, Color.Black); |
||||
internal readonly static SimpleTextWord Tab = new SimpleTextWord(TextWordType.Tab, "\t", false, Color.Black); |
||||
} |
||||
|
||||
public DrawableLine(IDocument document, LineSegment line, Font monospacedFont, Font boldMonospacedFont) |
||||
{ |
||||
this.monospacedFont = monospacedFont; |
||||
this.boldMonospacedFont = boldMonospacedFont; |
||||
if (line.Words != null) { |
||||
foreach (TextWord word in line.Words) { |
||||
if (word.Type == TextWordType.Space) { |
||||
words.Add(SimpleTextWord.Space); |
||||
} else if (word.Type == TextWordType.Tab) { |
||||
words.Add(SimpleTextWord.Tab); |
||||
} else { |
||||
words.Add(new SimpleTextWord(TextWordType.Word, word.Word, word.Font.Bold, word.Color)); |
||||
} |
||||
} |
||||
} else { |
||||
words.Add(new SimpleTextWord(TextWordType.Word, document.GetText(line), false, Color.Black)); |
||||
} |
||||
} |
||||
|
||||
public int LineLength { |
||||
get { |
||||
int length = 0; |
||||
foreach (SimpleTextWord word in words) { |
||||
length += word.Word.Length; |
||||
} |
||||
return length; |
||||
} |
||||
} |
||||
|
||||
public void SetBold(int startIndex, int endIndex, bool bold) |
||||
{ |
||||
if (startIndex < 0) |
||||
throw new ArgumentException("startIndex must be >= 0"); |
||||
if (startIndex > endIndex) |
||||
throw new ArgumentException("startIndex must be <= endIndex"); |
||||
if (startIndex == endIndex) return; |
||||
int pos = 0; |
||||
for (int i = 0; i < words.Count; i++) { |
||||
SimpleTextWord word = words[i]; |
||||
if (pos >= endIndex) |
||||
break; |
||||
int wordEnd = pos + word.Word.Length; |
||||
// 3 possibilities:
|
||||
if (startIndex <= pos && endIndex >= wordEnd) { |
||||
// word is fully in region:
|
||||
word.Bold = bold; |
||||
} else if (startIndex <= pos) { |
||||
// beginning of word is in region
|
||||
int inRegionLength = endIndex - pos; |
||||
SimpleTextWord newWord = new SimpleTextWord(word.Type, word.Word.Substring(inRegionLength), word.Bold, word.Color); |
||||
words.Insert(i + 1, newWord); |
||||
|
||||
word.Bold = bold; |
||||
word.Word = word.Word.Substring(0, inRegionLength); |
||||
} else if (startIndex < wordEnd) { |
||||
// end of word is in region (or middle of word is in region)
|
||||
int notInRegionLength = startIndex - pos; |
||||
|
||||
SimpleTextWord newWord = new SimpleTextWord(word.Type, word.Word.Substring(notInRegionLength), word.Bold, word.Color); |
||||
// newWord.Bold will be set in the next iteration
|
||||
words.Insert(i + 1, newWord); |
||||
|
||||
word.Word = word.Word.Substring(0, notInRegionLength); |
||||
} |
||||
pos = wordEnd; |
||||
} |
||||
} |
||||
|
||||
public static float DrawDocumentWord(Graphics g, string word, PointF position, Font font, Color foreColor) |
||||
{ |
||||
if (word == null || word.Length == 0) { |
||||
return 0f; |
||||
} |
||||
SizeF wordSize = g.MeasureString(word, font, 32768, sf); |
||||
|
||||
g.DrawString(word, |
||||
font, |
||||
BrushRegistry.GetBrush(foreColor), |
||||
position, |
||||
sf); |
||||
return wordSize.Width; |
||||
} |
||||
|
||||
public SizeF GetSpaceSize(Graphics g) |
||||
{ |
||||
if (spaceSize.IsEmpty) { |
||||
spaceSize = g.MeasureString("-", boldMonospacedFont, new PointF(0, 0), sf); |
||||
} |
||||
return spaceSize; |
||||
} |
||||
|
||||
public void DrawLine(Graphics g, ref float xPos, float yPos) |
||||
{ |
||||
SizeF spaceSize = GetSpaceSize(g); |
||||
foreach (SimpleTextWord word in words) { |
||||
switch (word.Type) { |
||||
case TextWordType.Space: |
||||
xPos += spaceSize.Width; |
||||
break; |
||||
case TextWordType.Tab: |
||||
float tabWidth = spaceSize.Width * 4; |
||||
xPos += tabWidth; |
||||
xPos = (int)((xPos + 2) / tabWidth) * tabWidth; |
||||
break; |
||||
case TextWordType.Word: |
||||
xPos += DrawDocumentWord(g, |
||||
word.Word, |
||||
new PointF(xPos, yPos), |
||||
word.Bold ? boldMonospacedFont : monospacedFont, |
||||
word.Color |
||||
); |
||||
|
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue