Exemplo n.º 1
0
        public static List <ShapedTextCharacters>?Collapse(TextLine textLine, TextCollapsingProperties properties, bool isWordEllipsis)
        {
            var shapedTextRuns = textLine.TextRuns as List <ShapedTextCharacters>;

            if (shapedTextRuns is null)
            {
                return(null);
            }

            var runIndex        = 0;
            var currentWidth    = 0.0;
            var collapsedLength = 0;
            var textRange       = textLine.TextRange;
            var shapedSymbol    = TextFormatterImpl.CreateSymbol(properties.Symbol, FlowDirection.LeftToRight);

            if (properties.Width < shapedSymbol.GlyphRun.Size.Width)
            {
                return(new List <ShapedTextCharacters>(0));
            }

            var availableWidth = properties.Width - shapedSymbol.Size.Width;

            while (runIndex < shapedTextRuns.Count)
            {
                var currentRun = shapedTextRuns[runIndex];

                currentWidth += currentRun.Size.Width;

                if (currentWidth > availableWidth)
                {
                    if (currentRun.TryMeasureCharacters(availableWidth, out var measuredLength))
                    {
                        if (isWordEllipsis && measuredLength < textRange.End)
                        {
                            var currentBreakPosition = 0;

                            var lineBreaker = new LineBreakEnumerator(currentRun.Text);

                            while (currentBreakPosition < measuredLength && lineBreaker.MoveNext())
                            {
                                var nextBreakPosition = lineBreaker.Current.PositionMeasure;

                                if (nextBreakPosition == 0)
                                {
                                    break;
                                }

                                if (nextBreakPosition >= measuredLength)
                                {
                                    break;
                                }

                                currentBreakPosition = nextBreakPosition;
                            }

                            measuredLength = currentBreakPosition;
                        }
                    }

                    collapsedLength += measuredLength;

                    var shapedTextCharacters = new List <ShapedTextCharacters>(shapedTextRuns.Count);

                    if (collapsedLength > 0)
                    {
                        var splitResult = TextFormatterImpl.SplitShapedRuns(shapedTextRuns, collapsedLength);

                        shapedTextCharacters.AddRange(splitResult.First);

                        TextLineImpl.SortRuns(shapedTextCharacters);
                    }

                    shapedTextCharacters.Add(shapedSymbol);

                    return(shapedTextCharacters);
                }

                availableWidth -= currentRun.Size.Width;

                collapsedLength += currentRun.GlyphRun.Characters.Length;

                runIndex++;
            }

            return(null);
        }
Exemplo n.º 2
0
        public static List <DrawableTextRun>?Collapse(TextLine textLine, TextCollapsingProperties properties, bool isWordEllipsis)
        {
            if (textLine.TextRuns is not List <DrawableTextRun> textRuns || textRuns.Count == 0)
            {
                return(null);
            }

            var runIndex        = 0;
            var currentWidth    = 0.0;
            var collapsedLength = 0;
            var shapedSymbol    = TextFormatterImpl.CreateSymbol(properties.Symbol, FlowDirection.LeftToRight);

            if (properties.Width < shapedSymbol.GlyphRun.Size.Width)
            {
                //Not enough space to fit in the symbol
                return(new List <DrawableTextRun>(0));
            }

            var availableWidth = properties.Width - shapedSymbol.Size.Width;

            while (runIndex < textRuns.Count)
            {
                var currentRun = textRuns[runIndex];

                switch (currentRun)
                {
                case ShapedTextCharacters shapedRun:
                {
                    currentWidth += shapedRun.Size.Width;

                    if (currentWidth > availableWidth)
                    {
                        if (shapedRun.TryMeasureCharacters(availableWidth, out var measuredLength))
                        {
                            if (isWordEllipsis && measuredLength < textLine.Length)
                            {
                                var currentBreakPosition = 0;

                                var lineBreaker = new LineBreakEnumerator(currentRun.Text);

                                while (currentBreakPosition < measuredLength && lineBreaker.MoveNext())
                                {
                                    var nextBreakPosition = lineBreaker.Current.PositionMeasure;

                                    if (nextBreakPosition == 0)
                                    {
                                        break;
                                    }

                                    if (nextBreakPosition >= measuredLength)
                                    {
                                        break;
                                    }

                                    currentBreakPosition = nextBreakPosition;
                                }

                                measuredLength = currentBreakPosition;
                            }
                        }

                        collapsedLength += measuredLength;

                        var collapsedRuns = new List <DrawableTextRun>(textRuns.Count);

                        if (collapsedLength > 0)
                        {
                            var splitResult = TextFormatterImpl.SplitDrawableRuns(textRuns, collapsedLength);

                            collapsedRuns.AddRange(splitResult.First);
                        }

                        collapsedRuns.Add(shapedSymbol);

                        return(collapsedRuns);
                    }

                    availableWidth -= currentRun.Size.Width;


                    break;
                }

                case { } drawableRun:
                {
                    //The whole run needs to fit into available space
                    if (currentWidth + drawableRun.Size.Width > availableWidth)
                    {
                        var collapsedRuns = new List <DrawableTextRun>(textRuns.Count);

                        if (collapsedLength > 0)
                        {
                            var splitResult = TextFormatterImpl.SplitDrawableRuns(textRuns, collapsedLength);

                            collapsedRuns.AddRange(splitResult.First);
                        }

                        collapsedRuns.Add(shapedSymbol);

                        return(collapsedRuns);
                    }

                    break;
                }
                }

                collapsedLength += currentRun.TextSourceLength;

                runIndex++;
            }

            return(null);
        }