Example #1
0
        public static string ProcessTrimming(Control control, string text, double availableWidth)
        {
            TextTrimming   trimming       = GetTextTrimming(control);
            TrimmingSource source         = GetTrimmingSource(control);
            string         wordSeparators = GetWordSeparators(control);

            return(ProcessTrimming(control, text, availableWidth, trimming, source, wordSeparators));
        }
Example #2
0
 /// <summary>
 /// Sets the value of the <see cref="TrimmingSource"/> dependency property attached to the given <see cref="DependencyObject"/>.
 /// </summary>
 /// <param name="target">The target <see cref="DependencyObject"/>.</param>
 /// <param name="value">The value to set.</param>
 public static void SetTrimmingSource([NotNull] DependencyObject target, TrimmingSource value)
 {
     target.SetValue(TrimmingSourceProperty, value);
 }
Example #3
0
        private static string ProcessTrimming(string text, [NotNull] Typeface typeface, double fontSize, TextTrimming trimming, TrimmingSource source, string wordSeparators, double availableWidth)
        {
            if (trimming == TextTrimming.None)
            {
                return(text);
            }

            var textWidth = GetTextWidth(text, trimming, typeface, fontSize, wordSeparators, out double[] sizes);

            if (availableWidth >= textWidth)
            {
                return(text);
            }
            if (sizes.Length == 0)
            {
                return(text);
            }

            List <string> words;

            switch (trimming)
            {
            case TextTrimming.CharacterEllipsis:
                words = text.ToCharArray().Select(c => c.ToString(CultureInfo.InvariantCulture)).ToList();
                break;

            case TextTrimming.WordEllipsis:
                words = SplitWords(text, wordSeparators);
                break;

            default:
                throw new ArgumentException("Invalid 'TextTrimming' argument.");
            }

            var firstWord = true;

            switch (source)
            {
            case TrimmingSource.Begin:
            {
                var currentWidth = GetTextWidth(Ellipsis, trimming, typeface, fontSize, wordSeparators, out _);

                var ending = new StringBuilder();
                for (var i = words.Count - 1; i >= 0; --i)
                {
                    var test = currentWidth + sizes[i];

                    if (test > availableWidth)
                    {
                        // If there's not enough room for a single word, fall back on character trimming from the beginning
                        if (trimming == TextTrimming.WordEllipsis && firstWord)
                        {
                            return(ProcessTrimming(words[i], typeface, fontSize, TextTrimming.CharacterEllipsis, TrimmingSource.Begin, wordSeparators, availableWidth));
                        }
                        break;
                    }
                    ending.Insert(0, words[i]);
                    currentWidth = test;
                    firstWord    = false;
                }

                return($"{Ellipsis}{ending}");
            }

            case TrimmingSource.Middle:
            {
                var currentWidth = GetTextWidth(Ellipsis, trimming, typeface, fontSize, wordSeparators, out _);

                var begin  = new StringBuilder();
                var ending = new StringBuilder();
                for (int i = 0, j = words.Count - 1; i <= j; ++i, --j)
                {
                    var test = currentWidth + sizes[i] + (i != j ? sizes[j] : 0);

                    if (test > availableWidth)
                    {
                        // If there's not enough room for a single word, fall back on character trimming from the end
                        if (trimming == TextTrimming.WordEllipsis && firstWord)
                        {
                            return(ProcessTrimming(words[j], typeface, fontSize, TextTrimming.CharacterEllipsis, TrimmingSource.End, wordSeparators, availableWidth));
                        }
                        break;
                    }
                    begin.Append(words[i]);
                    if (i != j)
                    {
                        ending.Insert(0, words[j]);
                    }

                    currentWidth = test;
                    firstWord    = false;
                }

                return(string.Format("{0}{2}{1}", begin, ending, Ellipsis));
            }

            case TrimmingSource.End:
            {
                var currentWidth = GetTextWidth(Ellipsis, trimming, typeface, fontSize, wordSeparators, out _);

                var begin = new StringBuilder();
                for (var i = 0; i < words.Count; ++i)
                {
                    var test = currentWidth + sizes[i];

                    if (test > availableWidth)
                    {
                        // If there's not enough room for a single word, fall back on character trimming from the end
                        if (trimming == TextTrimming.WordEllipsis && firstWord)
                        {
                            return(ProcessTrimming(words[i], typeface, fontSize, TextTrimming.CharacterEllipsis, TrimmingSource.Begin, wordSeparators, availableWidth));
                        }
                        break;
                    }

                    begin.Append(words[i]);
                    currentWidth = test;
                    firstWord    = false;
                }

                return($"{begin}{Ellipsis}");
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Example #4
0
        public static string ProcessTrimming([NotNull] TextBlock textBlock, string text, TextTrimming trimming, TrimmingSource source, string wordSeparators, double availableWidth)
        {
            var typeface = new Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch);

            return(ProcessTrimming(text, typeface, textBlock.FontSize, trimming, source, wordSeparators, availableWidth));
        }
Example #5
0
 /// <summary>
 /// Sets the value of the <see cref="TrimmingSource"/> dependency property attached to the given <see cref="DependencyObject"/>.
 /// </summary>
 /// <param name="target">The target <see cref="DependencyObject"/>.</param>
 /// <param name="value">The value to set.</param>
 public static void SetTrimmingSource(DependencyObject target, TrimmingSource value)
 {
     target.SetValue(TrimmingSourceProperty, value);
 }
Example #6
0
        private static string ProcessTrimming(Control control, string text, double availableWidth, TextTrimming trimming, TrimmingSource source, string wordSeparators)
        {
            if (trimming == TextTrimming.None)
            {
                return text;
            }

            double[] sizes;
            var textWidth = GetTextWidth(control, text, trimming, out sizes);
            if (availableWidth >= textWidth)
            {
                return text;
            }
            if (sizes.Length == 0)
            {
                return text;
            }

            List<string> words;

            switch (trimming)
            {
                case TextTrimming.CharacterEllipsis:
                    words = text.ToCharArray().Select(c => c.ToString(CultureInfo.InvariantCulture)).ToList();
                    break;
                case TextTrimming.WordEllipsis:
                    words = SplitWords(text, wordSeparators);
                    break;
                default:
                    throw new ArgumentException("Invalid 'TextTrimming' argument.");
            }

            bool firstWord = true;
            
            switch (source)
            {
                case TrimmingSource.Begin:
                {
                    var currentWidth = GetTextWidth(control, Ellipsis, trimming);

                    var ending = new StringBuilder();
                    for (int i = words.Count - 1; i >= 0; --i)
                    {
                        var test = currentWidth + sizes[i];

                        if (test > availableWidth)
                        {
                            // If there's not enough room for a single word, fall back on character trimming from the beginning
                            if (trimming == TextTrimming.WordEllipsis && firstWord)
                            {
                                return ProcessTrimming(control, words[i], availableWidth, TextTrimming.CharacterEllipsis, TrimmingSource.Begin, wordSeparators);
                            }
                            break;
                        }
                        ending.Insert(0, words[i]);
                        currentWidth = test;
                        firstWord = false;
                    }

                    return string.Format("{0}{1}", Ellipsis, ending);
                }
                case TrimmingSource.Middle:
                {
                    var currentWidth = GetTextWidth(control, Ellipsis, trimming);

                    var begin = new StringBuilder();
                    var ending = new StringBuilder();
                    for (int i = 0, j = words.Count - 1; i <= j; ++i, --j)
                    {
                        var test = currentWidth + sizes[i] + (i != j ? sizes[j] : 0);

                        if (test > availableWidth)
                        {
                            // If there's not enough room for a single word, fall back on character trimming from the end
                            if (trimming == TextTrimming.WordEllipsis && firstWord)
                            {
                                return ProcessTrimming(control, words[j], availableWidth, TextTrimming.CharacterEllipsis, TrimmingSource.End, wordSeparators);
                            }
                            break;
                        }
                        begin.Append(words[i]);
                        if (i != j)
                            ending.Insert(0, words[j]);

                        currentWidth = test;
                        firstWord = false;
                    }

                    return string.Format("{0}{2}{1}", begin, ending, Ellipsis);
                }
                case TrimmingSource.End:
                {
                    var currentWidth = GetTextWidth(control, Ellipsis, trimming);

                    var begin = new StringBuilder();
                    for (int i = 0; i < words.Count; ++i)
                    {
                        var test = currentWidth + sizes[i];

                        if (test > availableWidth)
                        {
                            // If there's not enough room for a single word, fall back on character trimming from the end
                            if (trimming == TextTrimming.WordEllipsis && firstWord)
                            {
                                return ProcessTrimming(control, words[i], availableWidth, TextTrimming.CharacterEllipsis, TrimmingSource.Begin, wordSeparators);
                            }
                            break;
                        }

                        begin.Append(words[i]);
                        currentWidth = test;
                        firstWord = false;
                    }

                    return string.Format("{0}{1}", begin, Ellipsis);
                }
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }