public ShapeableTextCharacters(ReadOnlySlice <char> text, TextRunProperties properties, sbyte biDiLevel) { TextSourceLength = text.Length; Text = text; Properties = properties; BidiLevel = biDiLevel; }
public FormattedTextSource(ReadOnlySlice <char> text, TextRunProperties defaultProperties, IReadOnlyList <ValueSpan <TextRunProperties> > textModifier) { _text = text; _defaultProperties = defaultProperties; _textModifier = textModifier; }
public TextCharacters(ReadOnlySlice <char> text, int offsetToFirstCharacter, int length, TextRunProperties properties) { Text = text.Skip(offsetToFirstCharacter).Take(length); TextSourceLength = length; Properties = properties; }
public ShapedTextCharacters(ShapedBuffer shapedBuffer, TextRunProperties properties) { ShapedBuffer = shapedBuffer; Text = shapedBuffer.Text; Properties = properties; TextSourceLength = Text.Length; FontMetrics = new FontMetrics(properties.Typeface, properties.FontRenderingEmSize); }
public ShapedTextCharacters(GlyphRun glyphRun, TextRunProperties properties) { Text = glyphRun.Characters; Properties = properties; TextSourceLength = Text.Length; FontMetrics = new FontMetrics(Properties.Typeface, Properties.FontRenderingEmSize); GlyphRun = glyphRun; }
/// <summary> /// Construct a text trailing word ellipsis collapsing properties /// </summary> /// <param name="width">width in which collapsing is constrained to</param> /// <param name="textRunProperties">text run properties of ellispis symbol</param> public TextTrailingWordEllipsis( double width, TextRunProperties textRunProperties ) { Width = width; Symbol = new TextCharacters(s_ellipsis, textRunProperties); }
/// <summary> /// Creates an ellipsis. /// </summary> /// <param name="properties">The text run properties.</param> /// <returns></returns> private static ShapedTextCharacters CreateEllipsisRun(TextRunProperties properties) { var formatterImpl = AvaloniaLocator.Current.GetService <ITextShaperImpl>(); var glyphRun = formatterImpl.ShapeText(s_ellipsis, properties.Typeface, properties.FontRenderingEmSize, properties.CultureInfo); return(new ShapedTextCharacters(glyphRun, properties)); }
/// <summary> /// Construct a text trailing word ellipsis collapsing properties. /// </summary> /// <param name="ellipsis">Text used as collapsing symbol.</param> /// <param name="width">width in which collapsing is constrained to.</param> /// <param name="textRunProperties">text run properties of ellipsis symbol.</param> public TextTrailingWordEllipsis( ReadOnlySlice <char> ellipsis, double width, TextRunProperties textRunProperties ) { Width = width; Symbol = new TextCharacters(ellipsis, textRunProperties); }
/// <summary> /// Construct a text trailing word ellipsis collapsing properties. /// </summary> /// <param name="ellipsis">Text used as collapsing symbol.</param> /// <param name="prefixLength">Length of leading prefix.</param> /// <param name="width">width in which collapsing is constrained to</param> /// <param name="textRunProperties">text run properties of ellispis symbol</param> public TextLeadingPrefixCharacterEllipsis( ReadOnlySlice <char> ellipsis, int prefixLength, double width, TextRunProperties textRunProperties) { if (_prefixLength < 0) { throw new ArgumentOutOfRangeException(nameof(prefixLength)); } _prefixLength = prefixLength; Width = width; Symbol = new TextCharacters(ellipsis, textRunProperties); }
/// <summary> /// Creates a span of text run properties that has modifier applied. /// </summary> /// <param name="text">The text to create the properties for.</param> /// <param name="defaultProperties">The default text properties.</param> /// <param name="textModifier">The text properties modifier.</param> /// <returns> /// The created text style run. /// </returns> private static ValueSpan <TextRunProperties> CreateTextStyleRun(ReadOnlySlice <char> text, TextRunProperties defaultProperties, IReadOnlyList <ValueSpan <TextRunProperties> > textModifier) { if (textModifier == null || textModifier.Count == 0) { return(new ValueSpan <TextRunProperties>(text.Start, text.Length, defaultProperties)); } var currentProperties = defaultProperties; var hasOverride = false; var i = 0; var length = 0; for (; i < textModifier.Count; i++) { var propertiesOverride = textModifier[i]; var textRange = new TextRange(propertiesOverride.Start, propertiesOverride.Length); if (textRange.End < text.Start) { continue; } if (textRange.Start > text.End) { length = text.Length; break; } if (textRange.Start > text.Start) { if (propertiesOverride.Value != currentProperties) { length = Math.Min(Math.Abs(textRange.Start - text.Start), text.Length); break; } } length += Math.Min(text.Length - length, textRange.Length); if (hasOverride) { continue; } hasOverride = true; currentProperties = propertiesOverride.Value; } if (length < text.Length && i == textModifier.Count) { if (currentProperties == defaultProperties) { length = text.Length; } } if (length != text.Length) { text = text.Take(length); } return(new ValueSpan <TextRunProperties>(text.Start, length, currentProperties)); }
/// <summary> /// Creates a span of text run properties that has modifier applied. /// </summary> /// <param name="text">The text to create the properties for.</param> /// <param name="firstTextSourceIndex">The first text source index.</param> /// <param name="defaultProperties">The default text properties.</param> /// <param name="textModifier">The text properties modifier.</param> /// <returns> /// The created text style run. /// </returns> private static ValueSpan <TextRunProperties> CreateTextStyleRun(ReadOnlySlice <char> text, int firstTextSourceIndex, TextRunProperties defaultProperties, IReadOnlyList <ValueSpan <TextRunProperties> >?textModifier) { if (textModifier == null || textModifier.Count == 0) { return(new ValueSpan <TextRunProperties>(firstTextSourceIndex, text.Length, defaultProperties)); } var currentProperties = defaultProperties; var hasOverride = false; var i = 0; var length = 0; for (; i < textModifier.Count; i++) { var propertiesOverride = textModifier[i]; var textRange = new TextRange(propertiesOverride.Start, propertiesOverride.Length); if (textRange.Start + textRange.Length <= firstTextSourceIndex) { continue; } if (textRange.Start > firstTextSourceIndex + text.Length) { length = text.Length; break; } if (textRange.Start > firstTextSourceIndex) { if (propertiesOverride.Value != currentProperties) { length = Math.Min(Math.Abs(textRange.Start - firstTextSourceIndex), text.Length); break; } } length = Math.Max(0, textRange.Start + textRange.Length - firstTextSourceIndex); if (hasOverride) { continue; } hasOverride = true; currentProperties = propertiesOverride.Value; } if (length < text.Length && i == textModifier.Count) { if (currentProperties == defaultProperties) { length = text.Length; } } if (length == 0 && currentProperties != defaultProperties) { currentProperties = defaultProperties; length = text.Length; } length = CoerceLength(text, length); return(new ValueSpan <TextRunProperties>(firstTextSourceIndex, length, currentProperties)); }
/// <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> /// <returns>A list of shapeable text runs.</returns> private ShapeableTextCharacters CreateShapeableRun(ReadOnlySlice <char> text, TextRunProperties defaultProperties) { var defaultTypeface = defaultProperties.Typeface; var currentTypeface = defaultTypeface; if (TryGetRunProperties(text, currentTypeface, defaultTypeface, out var count)) { return(new ShapeableTextCharacters(text.Take(count), new GenericTextRunProperties(currentTypeface, defaultProperties.FontRenderingEmSize, defaultProperties.TextDecorations, defaultProperties.ForegroundBrush))); } var codepoint = Codepoint.ReadAt(text, count, out _); //ToDo: Fix FontFamily fallback var matchFound = FontManager.Current.TryMatchCharacter(codepoint, defaultTypeface.Style, defaultTypeface.Weight, defaultTypeface.FontFamily, defaultProperties.CultureInfo, out currentTypeface); if (matchFound && TryGetRunProperties(text, currentTypeface, defaultTypeface, out count)) { //Fallback found return(new ShapeableTextCharacters(text.Take(count), new GenericTextRunProperties(currentTypeface, defaultProperties.FontRenderingEmSize, defaultProperties.TextDecorations, defaultProperties.ForegroundBrush))); } // 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), new GenericTextRunProperties(currentTypeface, defaultProperties.FontRenderingEmSize, defaultProperties.TextDecorations, defaultProperties.ForegroundBrush))); }
public TextCharacters(ReadOnlySlice <char> text, TextRunProperties properties) { TextSourceLength = text.Length; Text = text; Properties = properties; }
/// <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)); }