private void paintText( Graphics graphics, HighlightOptions highlightOptions, RectangularSelection selection, SelectionOptions selectionOptions, Rectangle contentArea, bool isTextSelecting) { _paintInProgress = true; if (selection.Selecting) { TextSelection.Clear(); } var context = new RichTextRenderContext { Text = DataText, TextSelection = TextSelection.Clone(), HighlightRanges = HighlightRanges, Graphics = graphics, Rect = contentArea, HorizAlignment = HorizontalAlignment, Font = Font, ForeColor = ForeColor, HighlightContextColor = highlightOptions.HighlightContextColor, HighlightColor = highlightOptions.HighlightColor, HighlightBorderColor = highlightOptions.HighlightBorderColor, HighlightBorderWidth = 1f }; if (isTextSelecting) { context.Selecting = true; context.SelectionStart = selection.Start; context.SelectionEnd = selection.End; } context.SelectionBackColor = selectionOptions.BackColor; context.SelectionForeColor = selectionOptions.ForeColor; context.SelectionAlpha = selectionOptions.Alpha; RichTextRenderer.Render(context, _iconRecognizer); if (selection.Selecting) { TextSelection.SetSelection(context.TextSelection); } _paintInProgress = false; }
private static IEnumerable <RichTextToken> getSubtokens( RichTextToken originalToken, RichTextRenderContext renderContext, IconRecognizer iconRecognizer) { IEnumerable <RichTextToken> tokens; if (iconRecognizer == null) { tokens = Sequence.From(originalToken); } else { tokens = iconRecognizer.Recognize(originalToken, renderContext.Text); } foreach (var token in tokens) { if (token.IconName != null || token.Length == 1) { yield return(token); } else { var splitPositions = Enumerable.Range(token.Index + 1, token.Length) .Where(i => i == token.Index + token.Length || !char.IsLetterOrDigit(renderContext.Text[i]) || !char.IsLetterOrDigit(renderContext.Text[i - 1])); int position = token.Index; foreach (int i in splitPositions) { var subtoken = new RichTextToken(token, position, i - position); yield return(subtoken); position = i; } } } }
public RichTextLayout(RichTextRenderContext renderContext, IconRecognizer iconRecognizer) { _renderContext = renderContext; _iconRecognizer = iconRecognizer; _highlightBrush = new SolidBrush(renderContext.HighlightColor); _highlightContextBrush = new SolidBrush(renderContext.HighlightContextColor); _selectionBrush = new SolidBrush(Color.FromArgb(_renderContext.SelectionAlpha, _renderContext.SelectionBackColor)); _pen = new Pen(renderContext.HighlightBorderColor, renderContext.HighlightBorderWidth); _x = _renderContext.Rect.Left; _y = _renderContext.Rect.Top; var lineSize = getLineSize(@" "); _lineHeight = lineSize.Height; _spaceWidth = lineSize.Width; _iconShadowOffset = new SizeF(-0.7f, 1f).ByDpi().ToPointF(); }
public static void Render(RichTextRenderContext renderContext, IconRecognizer iconRecognizer) { var textTokenPrinter = new RichTextLayout(renderContext, iconRecognizer); var readingContext = new RichTextTokenReader(renderContext.Text, renderContext.HighlightRanges); var currentWord = new List <RichTextToken>(); bool aborted = false; while (readingContext.ReadToken()) { var token = readingContext.Current; bool isCj = renderContext.Text[token.Index + token.Length - 1].IsCj(); if (token.Type == RichTextTokenType.Word) { var subtokens = getSubtokens(token, renderContext, iconRecognizer); currentWord.AddRange(subtokens); if (isCj) { bool canContinue = textTokenPrinter.PrintWord(currentWord); if (currentWord.Count > 0 && !canContinue) { aborted = true; break; } currentWord.Clear(); } } else if (token.Type == RichTextTokenType.Space) { bool canContinue = textTokenPrinter.PrintWord(currentWord); if (currentWord.Count > 0 && !canContinue) { aborted = true; break; } currentWord.Clear(); canContinue = textTokenPrinter.PrintSpace(token); if (!canContinue) { aborted = true; break; } } else if (token.Type == RichTextTokenType.NewLine) { bool canContinue = textTokenPrinter.PrintWord(currentWord); if (currentWord.Count > 0 && !canContinue) { aborted = true; break; } currentWord.Clear(); canContinue = textTokenPrinter.NewParagraph(); if (!canContinue) { aborted = true; break; } } } if (!aborted && currentWord.Count > 0) { textTokenPrinter.PrintWord(currentWord); } textTokenPrinter.Flush(); }