public TextWord(IDocument document, LineSegment word, int offset, int length, HighlightColor color, bool hasDefaultColor) { Debug.Assert(document != null); Debug.Assert(word != null); Debug.Assert(color != null); this.document = document; this.word = word; this.offset = offset; this.length = length; this.color = color; this.hasDefaultColor = hasDefaultColor; this.type = TextWordType.Word; }
/// <summary> /// Get the object, which was inserted under the keyword (line, at offset, with length length), /// returns null, if no such keyword was inserted. /// </summary> public object this[IDocument document, LineSegment line, int offset, int length] { get { if(length == 0) { return null; } Node next = root; int wordOffset = line.Offset + offset; if (casesensitive) { for (int i = 0; i < length; ++i) { int index = ((int)document.GetCharAt(wordOffset + i)) % 256; next = next.leaf[index]; if (next == null) { return null; } if (next.color != null && TextUtility.RegionMatches(document, wordOffset, length, next.word)) { return next.color; } } } else { for (int i = 0; i < length; ++i) { int index = ((int)Char.ToUpper(document.GetCharAt(wordOffset + i))) % 256; next = next.leaf[index]; if (next == null) { return null; } if (next.color != null && TextUtility.RegionMatches(document, casesensitive, wordOffset, length, next.word)) { return next.color; } } } return null; } }
/// <remarks> /// Returns true, if the line lineNumber is empty or filled with whitespaces. /// </remarks> public static bool IsEmptyLine(IDocument document, LineSegment line) { for (int i = line.Offset; i < line.Offset + line.Length; ++i) { char ch = document.GetCharAt(i); if (!Char.IsWhiteSpace(ch)) { return false; } } return true; }
// OLD 'SAFE & TESTED' CreateLines // int CreateLines(string text, int insertPosition, int offset) // { // int count = 0; // int start = 0; // ISegment nextDelimiter = NextDelimiter(text, 0); // while (nextDelimiter != null && nextDelimiter.Offset >= 0) { // int index = nextDelimiter.Offset + (nextDelimiter.Length - 1); // // LineSegment newLine = new LineSegment(offset + start, offset + index, nextDelimiter.Length); // // markLines.Add(newLine); // // if (insertPosition + count >= lineCollection.Count) { // lineCollection.Add(newLine); // } else { // lineCollection.Insert(insertPosition + count, newLine); // } // // ++count; // start = index + 1; // nextDelimiter = NextDelimiter(text, start); // } // // if (start < text.Length) { // if (insertPosition + count < lineCollection.Count) { // LineSegment l = (LineSegment)lineCollection[insertPosition + count]; // // int delta = text.Length - start; // // l.Offset -= delta; // l.TotalLength += delta; // } else { // LineSegment newLine = new LineSegment(offset + start, text.Length - start); // // markLines.Add(newLine); // lineCollection.Add(newLine); // ++count; // } // } // OnLineCountChanged(new LineManagerEventArgs(document, insertPosition, count)); // return count; // } int CreateLines(string text, int insertPosition, int offset) { int start = 0; ISegment nextDelimiter = NextDelimiter(text, 0); ArrayList newLines = new ArrayList(); while (nextDelimiter != null && nextDelimiter.Offset >= 0) { int index = nextDelimiter.Offset + (nextDelimiter.Length - 1); LineSegment newLine = new LineSegment(offset + start, offset + index, nextDelimiter.Length); newLines.Add(newLine); start = index + 1; nextDelimiter = NextDelimiter(text, start); } if (start < text.Length) { if (insertPosition + newLines.Count < lineCollection.Count) { LineSegment l = (LineSegment)lineCollection[insertPosition]; int delta = text.Length - start; l.Offset -= delta; l.TotalLength += delta; } else { LineSegment newLine = new LineSegment(offset + start, text.Length - start); newLines.Add(newLine); } } if (insertPosition >= lineCollection.Count) { lineCollection.AddRange(newLines); } else { lineCollection.InsertRange(insertPosition, newLines); } markLines.AddRange(newLines); OnLineCountChanged(new LineManagerEventArgs(document, insertPosition, newLines.Count)); return newLines.Count; }
int Insert(int lineNumber, int offset, string text) { if (text == null || text.Length == 0) { return 0; } textLength += text.Length; if (lineCollection.Count == 0 || lineNumber >= lineCollection.Count) { return CreateLines(text, lineCollection.Count, offset); } LineSegment line = (LineSegment)lineCollection[lineNumber]; ISegment nextDelimiter = NextDelimiter(text, 0); if (nextDelimiter == null || nextDelimiter.Offset < 0) { line.TotalLength += text.Length; markLines.Add(line); return 0; } int restLength = line.Offset + line.TotalLength - offset; if (restLength > 0) { LineSegment lineRest = new LineSegment(offset, restLength); lineRest.DelimiterLength = line.DelimiterLength; lineRest.Offset += text.Length; markLines.Add(lineRest); if (restLength - line.DelimiterLength < 0) { throw new ApplicationException("tried to insert inside delimiter string " + lineRest.ToString() + "!!!"); } lineCollection.Insert(lineNumber + 1, lineRest); OnLineCountChanged(new LineManagerEventArgs(document, lineNumber - 1, 1)); } line.DelimiterLength = nextDelimiter.Length; int nextStart = offset + nextDelimiter.Offset + nextDelimiter.Length; line.TotalLength = nextStart - line.Offset; markLines.Add(line); text = text.Substring(nextDelimiter.Offset + nextDelimiter.Length); return CreateLines(text, lineNumber + 1, nextStart) + 1; }
HighlightColor GetColor(HighlightRuleSet ruleSet, IDocument document, LineSegment currentSegment, int currentOffset, int currentLength) { if (ruleSet != null) { if (ruleSet.Reference != null) { return ruleSet.Highlighter.GetColor(document, currentSegment, currentOffset, currentLength); } else { return (HighlightColor)ruleSet.KeyWords[document, currentSegment, currentOffset, currentLength]; } } return null; }
bool MarkTokensInLine(IDocument document, int lineNumber, ref bool spanChanged) { bool processNextLine = false; LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null); currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? ((Stack)(previousLine.HighlightSpanStack.Clone())) : null); if(currentSpanStack != null) { while (currentSpanStack.Count > 0 && ((Span)currentSpanStack.Peek()).StopEOL) { currentSpanStack.Pop(); } if (currentSpanStack.Count == 0) { currentSpanStack = null; } } currentLine = (LineSegment)document.LineSegmentCollection[lineNumber]; if (currentLine.Length == -1) { // happens when buffer is empty ! return false; } ArrayList words = ParseLine(document); if (currentSpanStack != null && currentSpanStack.Count == 0) { currentSpanStack = null; } // Check if the span state has changed, if so we must re-render the next line // This check may seem utterly complicated but I didn't want to introduce any function calls // or alllocations here for perf reasons. if(currentLine.HighlightSpanStack != currentSpanStack) { if (currentLine.HighlightSpanStack == null) { processNextLine = false; foreach (Span sp in currentSpanStack) { if (!sp.StopEOL) { spanChanged = true; processNextLine = true; break; } } } else if (currentSpanStack == null) { processNextLine = false; foreach (Span sp in currentLine.HighlightSpanStack) { if (!sp.StopEOL) { spanChanged = true; processNextLine = true; break; } } } else { IEnumerator e1 = currentSpanStack.GetEnumerator(); IEnumerator e2 = currentLine.HighlightSpanStack.GetEnumerator(); bool done = false; while (!done) { bool blockSpanIn1 = false; while (e1.MoveNext()) { if (!((Span)e1.Current).StopEOL) { blockSpanIn1 = true; break; } } bool blockSpanIn2 = false; while (e2.MoveNext()) { if (!((Span)e2.Current).StopEOL) { blockSpanIn2 = true; break; } } if (blockSpanIn1 || blockSpanIn2) { if (blockSpanIn1 && blockSpanIn2) { if (e1.Current != e2.Current) { done = true; processNextLine = true; spanChanged = true; } } else { spanChanged = true; done = true; processNextLine = true; } } else { done = true; processNextLine = false; } } } } else { processNextLine = false; } currentLine.Words = words; currentLine.HighlightSpanStack = (currentSpanStack != null && currentSpanStack.Count > 0) ? currentSpanStack : null; return processNextLine; }
public void MarkTokens(IDocument document) { if (Rules.Count == 0) { return; } int lineNumber = 0; while (lineNumber < document.TotalNumberOfLines) { LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null); if (lineNumber >= document.LineSegmentCollection.Count) { // may be, if the last line ends with a delimiter break; // then the last line is not in the collection :) } currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? ((Stack)(previousLine.HighlightSpanStack.Clone())) : null); if (currentSpanStack != null) { while (currentSpanStack.Count > 0 && ((Span)currentSpanStack.Peek()).StopEOL) { currentSpanStack.Pop(); } if (currentSpanStack.Count == 0) currentSpanStack = null; } currentLine = (LineSegment)document.LineSegmentCollection[lineNumber]; if (currentLine.Length == -1) { // happens when buffer is empty ! return; } ArrayList words = ParseLine(document); currentLine.Words = words; currentLine.HighlightSpanStack = (currentSpanStack==null || currentSpanStack.Count==0) ? null : currentSpanStack; ++lineNumber; } document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea)); document.CommitUpdate(); }
public HighlightColor GetColor(IDocument document, LineSegment currentSegment, int currentOffset, int currentLength) { return GetColor(defaultRuleSet, document, currentSegment, currentOffset, currentLength); }
int GetLogicalColumn(LineSegment line, int xPos) { int currentColumn = 0; int realColumn = 0; float spaceWidth = GetWidth(' '); float physicalXPos = 0; int tabIndent = Document.TextEditorProperties.TabIndent; LineSegment currentLine = line; if (currentLine == null || currentLine.Words == null) { return 0; } for (int i = 0; i < currentLine.Words.Count && xPos + spaceWidth/2 > physicalXPos; ++i) { TextWord currentWord = ((TextWord)currentLine.Words[i]); switch (currentWord.Type) { case TextWordType.Space: physicalXPos += spaceWidth; currentColumn++; realColumn++; break; case TextWordType.Tab: int ind = realColumn % tabIndent; int hop = tabIndent - ind; physicalXPos += hop * spaceWidth; currentColumn++; realColumn += hop; break; case TextWordType.Word: string word = currentWord.Word; if (physicalXPos + MeasureString(FontContainer.DefaultFont, word) > xPos + spaceWidth/2) { do { word = word.Substring(0, word.Length - 1); } while (physicalXPos + MeasureString(FontContainer.DefaultFont, word) > xPos + spaceWidth/2); return currentColumn + word.Length; } physicalXPos += MeasureString(FontContainer.DefaultFont, word); currentColumn += word.Length; realColumn += word.Length; break; } } return currentColumn; // FIXME!!! // return (int)(physicalXPos - textArea.VirtualTop.X * spaceWidth); }
public int GetVisualColumn(LineSegment line, int logicalColumn) { int tabIndent = Document.TextEditorProperties.TabIndent; int column = 0; for (int i = 0; i < logicalColumn; ++i) { char ch; if (i >= line.Length) { ch = ' '; } else { ch = Document.GetCharAt(line.Offset + i); } switch (ch) { case '\t': int oldColumn = column; column += tabIndent; column = (column / tabIndent) * tabIndent; break; default: ++column; break; } } return column; }
public int GetDrawingXPos(LineSegment line, int logicalColumn) { int currentColumn = 0; int realColumn = 0; float physicalXPos = 0; float spaceWidth = GetWidth(' '); int tabIndent = Document.TextEditorProperties.TabIndent; LineSegment currentLine = line; if (currentLine.Words == null) { return (int)(physicalXPos - textArea.VirtualTop.X * spaceWidth); } for (int i = 0; i < currentLine.Words.Count && currentColumn < logicalColumn; ++i) { TextWord currentWord = ((TextWord)currentLine.Words[i]); switch (currentWord.Type) { case TextWordType.Space: physicalXPos += spaceWidth; currentColumn++; realColumn++; break; case TextWordType.Tab: int ind = realColumn % tabIndent; int hop = tabIndent - ind; physicalXPos += hop * spaceWidth; currentColumn++; realColumn += hop; break; case TextWordType.Word: string word = currentWord.Word; if (currentColumn + word.Length > logicalColumn) { word = word.Substring(0, logicalColumn - currentColumn); } float lastPos = physicalXPos; physicalXPos += MeasureString(FontContainer.DefaultFont, word); currentColumn += word.Length; realColumn += word.Length; break; } } return (int)(physicalXPos /*- textArea.VirtualTop.X * spaceWidth*/); }