public TextCharacters(ReadOnlySlice <char> text, int offsetToFirstCharacter, int length, TextRunProperties properties) { Text = text.Skip(offsetToFirstCharacter).Take(length); TextSourceLength = length; Properties = properties; }
public TextRun GetTextRun(int textSourceIndex) { if (textSourceIndex > _text.Length) { return(null); } var runText = _text.Skip(textSourceIndex); return(runText.IsEmpty ? null : new TextCharacters(runText, _defaultGenericPropertiesRunProperties)); }
public TextRun GetTextRun(int textSourceIndex) { var runText = _text.Skip(textSourceIndex); if (runText.IsEmpty) { return(new TextEndOfParagraph()); } return(new TextCharacters(runText, _defaultGenericPropertiesRunProperties)); }
public void Should_Skip() { var buffer = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var slice = new ReadOnlySlice <int>(buffer); var skipped = slice.Skip(2); var expected = buffer.Skip(2); Assert.Equal(expected, skipped); }
public TextRun GetTextRun(int textSourceIndex) { var runText = _text.Skip(textSourceIndex); if (runText.IsEmpty) { return(new TextEndOfLine()); } var textStyleRun = CreateTextStyleRunWithOverride(runText, _defaultStyle, _textStyleOverrides); return(new TextCharacters(runText.Take(textStyleRun.TextPointer.Length), textStyleRun.Style)); }
public TextRun GetTextRun(int textSourceIndex) { if (_textStyleRuns.IsEmpty) { return(new TextEndOfParagraph()); } var styleRun = _textStyleRuns[0]; _textStyleRuns = _textStyleRuns.Skip(1); return(new TextCharacters(_text.AsSlice(styleRun.TextPointer.Start, styleRun.TextPointer.Length), _defaultStyle)); }
public TextRun GetTextRun(int textSourceIndex) { if (_styleSpans.IsEmpty) { return(new TextEndOfParagraph()); } var currentSpan = _styleSpans[0]; _styleSpans = _styleSpans.Skip(1); return(new TextCharacters(_text.AsSlice(currentSpan.Start, currentSpan.Length), _defaultStyle)); }
/// <summary> /// Moves to the next <see cref="Codepoint"/>. /// </summary> /// <returns></returns> public bool MoveNext() { if (_text.IsEmpty) { Current = Codepoint.ReplacementCodepoint; return(false); } Current = Codepoint.ReadAt(_text, 0, out var count); _text = _text.Skip(count); return(true); }
public TextRun GetTextRun(int textSourceIndex) { if (textSourceIndex > _text.End) { return(new TextEndOfLine()); } var runText = _text.Skip(textSourceIndex); if (runText.IsEmpty) { return(new TextEndOfLine()); } var textStyleRun = CreateTextStyleRun(runText, _defaultProperties, _textModifier); return(new TextCharacters(runText.Take(textStyleRun.Length), textStyleRun.Value)); }
/// <summary> /// Gets a list of <see cref="ShapeableTextCharacters"/>. /// </summary> /// <returns>The shapeable text characters.</returns> internal IReadOnlyList <ShapeableTextCharacters> GetShapeableCharacters(ReadOnlySlice <char> runText, sbyte biDiLevel, ref TextRunProperties?previousProperties) { var shapeableCharacters = new List <ShapeableTextCharacters>(2); while (!runText.IsEmpty) { var shapeableRun = CreateShapeableRun(runText, Properties, biDiLevel, ref previousProperties); shapeableCharacters.Add(shapeableRun); runText = runText.Skip(shapeableRun.Text.Length); previousProperties = shapeableRun.Properties; } return(shapeableCharacters); }
/// <summary> /// Creates a shapeable text run with unique properties. /// </summary> /// <param name="text">The text to create text runs from.</param> /// <param name="defaultProperties">The default text run properties.</param> /// <param name="biDiLevel">The bidi level of the run.</param> /// <param name="previousProperties"></param> /// <returns>A list of shapeable text runs.</returns> private static ShapeableTextCharacters CreateShapeableRun(ReadOnlySlice <char> text, TextRunProperties defaultProperties, sbyte biDiLevel, ref TextRunProperties?previousProperties) { var defaultTypeface = defaultProperties.Typeface; var currentTypeface = defaultTypeface; var previousTypeface = previousProperties?.Typeface; if (TryGetShapeableLength(text, currentTypeface, null, out var count, out var script)) { if (script == Script.Common && previousTypeface is not null) { if (TryGetShapeableLength(text, previousTypeface.Value, defaultTypeface, out var fallbackCount, out _)) { return(new ShapeableTextCharacters(text.Take(fallbackCount), defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel)); } } return(new ShapeableTextCharacters(text.Take(count), defaultProperties.WithTypeface(currentTypeface), biDiLevel)); } if (previousTypeface is not null) { if (TryGetShapeableLength(text, previousTypeface.Value, defaultTypeface, out count, out _)) { return(new ShapeableTextCharacters(text.Take(count), defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel)); } } var codepoint = Codepoint.ReplacementCodepoint; var codepointEnumerator = new CodepointEnumerator(text.Skip(count)); while (codepointEnumerator.MoveNext()) { if (codepointEnumerator.Current.IsWhiteSpace) { continue; } codepoint = codepointEnumerator.Current; break; } //ToDo: Fix FontFamily fallback var matchFound = FontManager.Current.TryMatchCharacter(codepoint, defaultTypeface.Style, defaultTypeface.Weight, defaultTypeface.Stretch, defaultTypeface.FontFamily, defaultProperties.CultureInfo, out currentTypeface); if (matchFound && TryGetShapeableLength(text, currentTypeface, defaultTypeface, out count, out _)) { //Fallback found return(new ShapeableTextCharacters(text.Take(count), defaultProperties.WithTypeface(currentTypeface), biDiLevel)); } // no fallback found currentTypeface = defaultTypeface; var glyphTypeface = currentTypeface.GlyphTypeface; var enumerator = new GraphemeEnumerator(text); while (enumerator.MoveNext()) { var grapheme = enumerator.Current; if (!grapheme.FirstCodepoint.IsWhiteSpace && glyphTypeface.TryGetGlyph(grapheme.FirstCodepoint, out _)) { break; } count += grapheme.Text.Length; } return(new ShapeableTextCharacters(text.Take(count), defaultProperties, biDiLevel)); }