Esempio n. 1
0
		/// <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;
			}
		}
		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 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;
//				Console.WriteLine("1:Line length of line {0} set to {1}", lineNumber, line.TotalLength - line.DelimiterLength);
				markLines.Add(line);
				OnLineLengthChanged(new LineLengthEventArgs(document, lineNumber, offset -line.Offset, text.Length));
				return 0;
			}
			
			int restLength = line.Offset + line.TotalLength - offset;
			
			if (restLength > 0) {
//				Console.WriteLine("Insert: Set restline in line {0} to length {1}", lineNumber, restLength);
				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;
//			Console.WriteLine("2:Line length of line {0} set to {1}", lineNumber, line.TotalLength - line.DelimiterLength);
			
			markLines.Add(line);
			text = text.Substring(nextDelimiter.Offset + nextDelimiter.Length);
			
			return CreateLines(text, lineNumber + 1, nextStart) + 1;
		}
Esempio n. 4
0
		/// <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;
		}
		void DrawLine(Graphics g, LineSegment line, float yPos, RectangleF margin)
		{
			float xPos = 0;
			float fontHeight = Font.GetHeight(g);
//			bool  gotNonWhitespace = false;
			curTabIndent = 0 ;
			
			foreach (TextWord word in line.Words) {
				switch (word.Type) {
					case TextWordType.Space:
						Advance(ref xPos, ref yPos, margin.Width, textAreaControl.TextArea.TextViewMargin.GetWidth(' '), fontHeight);
//						if (!gotNonWhitespace) {
//							curTabIndent = xPos;
//						}
						break;
					case TextWordType.Tab:
						Advance(ref xPos, ref yPos, margin.Width, TabIndent * textAreaControl.TextArea.TextViewMargin.GetWidth(' '), fontHeight);
//						if (!gotNonWhitespace) {
//							curTabIndent = xPos;
//						}
						break;
					case TextWordType.Word:
//						if (!gotNonWhitespace) {
//							gotNonWhitespace = true;
//							curTabIndent    += TabIndent * textAreaControl.TextArea.TextView.GetWidth(' ');
//						}
						g.DrawString(word.Word, word.Font, BrushRegistry.GetBrush(word.Color), xPos + margin.X, yPos);
						SizeF drawingSize = g.MeasureString(word.Word, word.Font, new SizeF(margin.Width, fontHeight * 100), printingStringFormat);
						Advance(ref xPos, ref yPos, margin.Width, drawingSize.Width, fontHeight);
						break;
				}
			}
		}
		// Mark document文档中的一行.
		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;
			}
			
//// Alex: remove old words
			if (currentLine.Words!=null) currentLine.Words.Clear();
			currentLine.Words = words;
			currentLine.HighlightSpanStack = (currentSpanStack != null && currentSpanStack.Count > 0) ? currentSpanStack : null;
			
			return processNextLine;
		}
		float MeasurePrintingHeight(Graphics g, LineSegment line, float maxWidth)
		{
			float xPos = 0;
			float yPos = 0;
			float fontHeight = Font.GetHeight(g);
//			bool  gotNonWhitespace = false;
			curTabIndent = 0;
			foreach (TextWord word in line.Words) {
				switch (word.Type) {
					case TextWordType.Space:
						Advance(ref xPos, ref yPos, maxWidth, textAreaControl.TextArea.TextViewMargin.GetWidth(' '), fontHeight);
//						if (!gotNonWhitespace) {
//							curTabIndent = xPos;
//						}
						break;
					case TextWordType.Tab:
						Advance(ref xPos, ref yPos, maxWidth, TabIndent * textAreaControl.TextArea.TextViewMargin.GetWidth(' '), fontHeight);
//						if (!gotNonWhitespace) {
//							curTabIndent = xPos;
//						}
						break;
					case TextWordType.Word:
//						if (!gotNonWhitespace) {
//							gotNonWhitespace = true;
//							curTabIndent    += TabIndent * textAreaControl.TextArea.TextView.GetWidth(' ');
//						}
						SizeF drawingSize = g.MeasureString(word.Word, word.Font, new SizeF(maxWidth, fontHeight * 100), printingStringFormat);
						Advance(ref xPos, ref yPos, maxWidth, drawingSize.Width, fontHeight);
						break;
				}
			}
			return yPos + fontHeight;
		}
		// Mark整个文档.
		public void MarkTokens(IDocument document)
		{
			if (RuleSets.Count == 0) {//如果没有Rule Set则退出,即不给当前文档mark token
				return;
			}
			
			int lineNumber = 0;//从第一行开始mark token
			
			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 LineSegmentCollection :)
				}
				
				//当前行中的SpanStack总是获取前面一行中的SpanStack
				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);

				if (currentLine.Words!=null) currentLine.Words.Clear();
				currentLine.Words = words;
				currentLine.HighlightSpanStack = (currentSpanStack==null || currentSpanStack.Count==0) ? null : currentSpanStack;
				
				++lineNumber;
			}
			document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
			document.OnUpdateCommited();
		}
		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;
		}
		public HighlightColor GetColor(IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
		{
			//如果不指定RuleSet,则用defaultRuleSet来作为规则集.
			return GetColor(defaultRuleSet, document, currentSegment, currentOffset, currentLength);
		}
Esempio n. 11
0
		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;
		}
Esempio n. 12
0
		public TextWord(IDocument document, LineSegment line, int offset, int length, HighlightColor highlightColor, bool hasDefaultColor)
		{
			Debug.Assert(document != null);
			Debug.Assert(line != null);
			Debug.Assert(highlightColor != null);
			
			this.document = document;
			this.line  = line;
			this.offset = offset;
			this.length = length;
			this.highlightColor = highlightColor;
			this.hasDefaultColor = hasDefaultColor;
		}