private void printCaret(RectangleF rect, RichTextToken token) { if (_renderContext.Selecting) { return; } if (!_renderContext.TextSelection.IsCaretVisible) { return; } var roundedRect = rect.Round(); int x; if (token.Right == _renderContext.TextSelection.End) { x = roundedRect.Right - 1; } else if (token.Index == _renderContext.TextSelection.End) { x = roundedRect.Left - 1; } else { return; } float top = roundedRect.Top; var bottom = roundedRect.Bottom - 1f; _renderContext.Graphics.DrawLine(_caretPen, x, top, x, bottom); }
public IList <RichTextToken> Recognize(RichTextToken originalToken, string text) { var result = new List <RichTextToken>(); int iconStart = -1; int iconEnd = originalToken.Index - 1; for (int i = originalToken.Index; i <= originalToken.Index + originalToken.Length; i++) { bool tokenEnded = i == originalToken.Index + originalToken.Length; char c; if (tokenEnded) { c = default(char); } else { c = text[i]; } if (iconStart < 0 && c == '{' || tokenEnded) { iconStart = i; int index = iconEnd + 1; int length = i - index; if (length > 0) { result.Add( new RichTextToken(originalToken, index, length) { IconName = null }); iconEnd = index + length - 1; } } else if (iconStart >= 0 && c == '}') { iconEnd = i; int length = i + 1 - iconStart; var token = new RichTextToken(originalToken, iconStart, length); string symbol = text.Substring(iconStart + 1, length - 2); if (_imageByText.TryGetValue(symbol, out var icon)) { token.IconName = symbol; token.IconNeedsShadow = icon.Width == icon.Height && !_nonShadowedIcons.Contains(symbol); } result.Add(token); iconStart = -1; } } return(result); }
public bool PrintSpace(RichTextToken space) { if (_y + _lineHeight * HeightPart < _renderContext.Rect.Bottom) { if (_x + _spaceWidth >= _renderContext.Rect.Right) { return(newLine()); } var targetRect = new RectangleF(_x, _y, _spaceWidth, _lineHeight); var printBatch = new RenderBatch(space.IsHighlighted); if (space.IsHighlighted) { printHighlight(targetRect, printBatch, space.IsContext); } printBatch.Add(targetRect, (rect, hb, he) => { _renderContext.TextSelection.PrintedTokens.Add((space, rect)); printSelection(rect, space); printCaret(rect, space); }); _lineQueue.Add(printBatch); _x += _spaceWidth; return(true); } return(false); }
private bool printSelection(RectangleF tokenRect, RichTextToken token) { var textSelection = _renderContext.TextSelection; if (!_renderContext.Selecting && textSelection.IsEmpty) { return(false); } int tokenRight = token.Index + token.Length; bool isSelected = textSelection.Start <tokenRight && textSelection.Start + textSelection.Length> token.Index; if (textSelection.IsEmpty) { var(isStart, isRightToLeft) = isRectSelectionStart(tokenRect); if (!isStart) { return(false); } if (isRightToLeft) { textSelection.Begin = tokenRight; textSelection.End = token.Index; } else { textSelection.Begin = token.Index; textSelection.End = tokenRight; } } else if (!isSelected) { if (!isRectSelectionContinuation(tokenRect)) { return(false); } if (textSelection.IsRightToLeft) { textSelection.Begin = tokenRight; } else { textSelection.End = tokenRight; } } RectangleF selectionRect = tokenRect.Round(); selectionRect.Offset(-0.5f, -0.5f); _renderContext.Graphics.FillRectangle(_selectionBrush, selectionRect); return(true); }
private void readWord() { int start = _i; bool matchStartedOriginal = _matchStarted; bool matchIsContextOriginal = _matchIsContext; while (true) { _i++; updateMatchState(); if (_i == _len || _text[_i] == ' ' || _text[_i] == '\r' || _text[_i] == '\n' || _matchStarted != matchStartedOriginal || _matchIsContext != matchIsContextOriginal || _text[_i - 1].IsCjk()) { Current = new RichTextToken { Index = start, Length = _i - start, Type = RichTextTokenType.Word, IsHighlighted = matchStartedOriginal, IsContext = matchIsContextOriginal }; break; } } }
private void readSpace() { Current = new RichTextToken { Index = _i, Length = 1, Type = RichTextTokenType.Space, IsHighlighted = _matchStarted, IsContext = _matchIsContext }; _i++; updateMatchState(); }
private float getTokenWidth(string text, RichTextToken richTextToken) { float delta; if (richTextToken.IconName == null) { delta = getLineSize(text.Substring(richTextToken.Index, richTextToken.Length)).Width; } else { delta = _iconRecognizer.GetIcon(richTextToken.IconName, (int)Math.Round(_lineHeight)).Width; } return(delta); }
private void readNewLine() { if (_text[_i] == '\r') { if (_i + 1 >= _len || _text[_i + 1] != '\n') { throw new Exception(@"invalid line end"); } Current = new RichTextToken { Index = _i, Length = 2, Type = RichTextTokenType.NewLine, IsHighlighted = _matchStarted, IsContext = _matchIsContext }; _i++; updateMatchState(); _i++; updateMatchState(); } else if (_text[_i] == '\n') { Current = new RichTextToken { Index = _i, Length = 1, Type = RichTextTokenType.NewLine, IsHighlighted = _matchStarted, IsContext = _matchIsContext }; _i++; updateMatchState(); } else { throw new Exception(@"invalid line end"); } }
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; } } } }