void PushColor(HighlightingColor color) { if (highlightedLine == null) { return; } if (color == null) { highlightedSectionStack.Push(null); } else if (lastPoppedSection != null && lastPoppedSection.Color == color && lastPoppedSection.Offset + lastPoppedSection.Length == position + lineStartOffset) { highlightedSectionStack.Push(lastPoppedSection); lastPoppedSection = null; } else { HighlightedSection hs = new HighlightedSection { Offset = position + lineStartOffset, Color = color }; highlightedLine.Sections.Add(hs); highlightedSectionStack.Push(hs); lastPoppedSection = null; } }
void BeginColorSpan() { WriteIndentationIfNecessary(); colorStack.Push(currentColor); currentColor = currentColor.Clone(); currentColorBegin = documentTextWriter.InsertionOffset; }
public HtmlElement(int offset, int nesting, bool isEnd, HighlightingColor color) { this.Offset = offset; this.Nesting = nesting; this.IsEnd = isEnd; this.Color = color; }
/// <summary> /// Gets whether the color needs to be written out to HTML. /// </summary> public virtual bool ColorNeedsSpanForStyling(HighlightingColor color) { if (color == null) { throw new ArgumentNullException("color"); } return(!string.IsNullOrEmpty(color.ToCss())); }
/// <summary> /// Gets whether the color is empty (has no effect on a VisualLineTextElement). /// For example, the C# "Punctuation" is an empty color. /// </summary> internal static bool IsEmptyColor(HighlightingColor color) { if (color == null) { return(true); } return(color.Background == null && color.Foreground == null && color.FontStyle == null && color.FontWeight == null && color.Underline == null && color.Strikethrough == null); }
/// <summary> /// Creates a new RichTextModelWriter that inserts into document, starting at insertionOffset. /// </summary> public RichTextModelWriter(RichTextModel richTextModel, IDocument document, int insertionOffset) : base(new DocumentTextWriter(document, insertionOffset)) { if (richTextModel == null) { throw new ArgumentNullException("richTextModel"); } this.richTextModel = richTextModel; this.documentTextWriter = (DocumentTextWriter)base.textWriter; currentColor = richTextModel.GetHighlightingAt(Math.Max(0, insertionOffset - 1)); }
/// <summary> /// Writes the HTML attribute for the style to the text writer. /// </summary> public virtual void WriteStyleAttributeForColor(TextWriter writer, HighlightingColor color) { if (writer == null) { throw new ArgumentNullException("writer"); } if (color == null) { throw new ArgumentNullException("color"); } writer.Write(" style=\""); WebUtility.HtmlEncode(color.ToCss(), writer); writer.Write('"'); }
/// <summary> /// Sets the HighlightingColor for the specified range of text, /// completely replacing the existing highlighting in that area. /// </summary> public void SetHighlighting(int offset, int length, HighlightingColor color) { if (length <= 0) { return; } int startIndex = GetIndexForOffset(offset); int endIndex = GetIndexForOffset(offset + length); stateChanges[startIndex] = color != null?color.Clone() : new HighlightingColor(); stateChanges.RemoveRange(startIndex + 1, endIndex - (startIndex + 1)); stateChangeOffsets.RemoveRange(startIndex + 1, endIndex - (startIndex + 1)); }
/// <summary> /// Creates WPF Run instances that can be used for TextBlock.Inlines. /// </summary> /// <param name="textSource">The text source that holds the text for this RichTextModel.</param> public Run[] CreateRuns(ITextSource textSource) { Run[] runs = new Run[stateChanges.Count]; for (int i = 0; i < runs.Length; i++) { int startOffset = stateChangeOffsets[i]; int endOffset = i + 1 < stateChangeOffsets.Count ? stateChangeOffsets[i + 1] : textSource.TextLength; Run r = new Run(textSource.GetText(startOffset, endOffset - startOffset)); HighlightingColor state = stateChanges[i]; RichText.ApplyColorToTextElement(r, state); runs[i] = r; } return(runs); }
/// <summary> /// Creates WPF Run instances that can be used for TextBlock.Inlines. /// </summary> public Run[] CreateRuns() { Run[] runs = new Run[stateChanges.Length]; for (int i = 0; i < runs.Length; i++) { int startOffset = stateChangeOffsets[i]; int endOffset = i + 1 < stateChangeOffsets.Length ? stateChangeOffsets[i + 1] : text.Length; Run r = new Run(text.Substring(startOffset, endOffset - startOffset)); HighlightingColor state = stateChanges[i]; ApplyColorToTextElement(r, state); runs[i] = r; } return(runs); }
/// <inheritdoc/> public override void BeginSpan(HighlightingColor highlightingColor) { WriteIndentationAndSpace(); if (options.ColorNeedsSpanForStyling(highlightingColor)) { htmlWriter.Write("<span"); options.WriteStyleAttributeForColor(htmlWriter, highlightingColor); htmlWriter.Write('>'); endTagStack.Push("</span>"); } else { endTagStack.Push(null); } }
/// <summary> /// Applies the HighlightingColor to the specified range of text. /// If the color specifies <c>null</c> for some properties, existing highlighting is preserved. /// </summary> public void ApplyHighlighting(int offset, int length, HighlightingColor color) { if (color == null || color.IsEmptyForMerge) { // Optimization: don't split the HighlightingState when we're not changing // any property. For example, the "Punctuation" color in C# is // empty by default. return; } int startIndex = GetIndexForOffset(offset); int endIndex = GetIndexForOffset(offset + length); for (int i = startIndex; i < endIndex; i++) { stateChanges[i].MergeWith(color); } }
internal static void ApplyColorToTextElement(TextElement r, HighlightingColor state) { if (state.Foreground != null) { r.Foreground = state.Foreground.GetBrush(null); } if (state.Background != null) { r.Background = state.Background.GetBrush(null); } if (state.FontWeight != null) { r.FontWeight = state.FontWeight.Value; } if (state.FontStyle != null) { r.FontStyle = state.FontStyle.Value; } }
internal static void ApplyColorToElement(VisualLineElement element, HighlightingColor color, ITextRunConstructionContext context) { if (color.Foreground != null) { Brush b = color.Foreground.GetBrush(context); if (b != null) { element.TextRunProperties.SetForegroundBrush(b); } } if (color.Background != null) { Brush b = color.Background.GetBrush(context); if (b != null) { element.BackgroundBrush = b; } } if (color.FontStyle != null || color.FontWeight != null || color.FontFamily != null) { Typeface tf = element.TextRunProperties.Typeface; element.TextRunProperties.SetTypeface(new Typeface( color.FontFamily ?? tf.FontFamily, color.FontStyle ?? tf.Style, color.FontWeight ?? tf.Weight, tf.Stretch )); } if (color.Underline ?? false) { element.TextRunProperties.SetTextDecorations(TextDecorations.Underline); } if (color.Strikethrough ?? false) { element.TextRunProperties.SetTextDecorations(TextDecorations.Strikethrough); } if (color.FontSize.HasValue) { element.TextRunProperties.SetFontRenderingEmSize(color.FontSize.Value); } }
/// <summary> /// Applies the properties from the HighlightingColor to the specified text segment. /// </summary> public void SetHighlighting(int offset, int length, HighlightingColor color) { if (color == null) { throw new ArgumentNullException("color"); } if (color.Foreground == null && color.Background == null && color.FontStyle == null && color.FontWeight == null && color.Underline == null) { // Optimization: don't split the HighlightingState when we're not changing // any property. For example, the "Punctuation" color in C# is // empty by default. return; } int startIndex = GetIndexForOffset(offset); int endIndex = GetIndexForOffset(offset + length); for (int i = startIndex; i < endIndex; i++) { stateChanges[i].MergeWith(color); } }
void Insert(ref int pos, ref int newSectionStart, int insertionEndPos, HighlightingColor color, Stack <int> insertionStack) { if (newSectionStart >= insertionEndPos) { // nothing to insert here return; } while (insertionStack.Peek() <= newSectionStart) { insertionStack.Pop(); } while (insertionStack.Peek() < insertionEndPos) { int end = insertionStack.Pop(); // insert the portion from newSectionStart to end if (end > newSectionStart) { this.Sections.Insert(pos++, new HighlightedSection { Offset = newSectionStart, Length = end - newSectionStart, Color = color }); newSectionStart = end; } } if (insertionEndPos > newSectionStart) { this.Sections.Insert(pos++, new HighlightedSection { Offset = newSectionStart, Length = insertionEndPos - newSectionStart, Color = color }); newSectionStart = insertionEndPos; } }
/// <inheritdoc/> public override void EndSpan() { currentColor = colorStack.Pop(); currentColorBegin = documentTextWriter.InsertionOffset; }
/// <inheritdoc/> public override void BeginSpan(HighlightingColor highlightingColor) { BeginColorSpan(); currentColor.MergeWith(highlightingColor); currentColor.Freeze(); }
/// <summary> /// Applies a highlighting color to a visual line element. /// </summary> protected virtual void ApplyColorToElement(VisualLineElement element, HighlightingColor color) { ApplyColorToElement(element, color, CurrentContext); }