Esempio n. 1
0
        public IEnumerable <TextLine> DivideTextItemsIntoLines(float availableWidth, float availableHeight)
        {
            var queue            = new Queue <ITextBlockItem>(RenderingQueue);
            var currentItemIndex = CurrentElementIndex;
            var currentHeight    = 0f;

            while (queue.Any())
            {
                var line = GetNextLine();

                if (!line.Elements.Any())
                {
                    yield break;
                }

                if (currentHeight + line.LineHeight > availableHeight + Size.Epsilon)
                {
                    yield break;
                }

                currentHeight += line.LineHeight;
                yield return(line);
            }

            TextLine GetNextLine()
            {
                var currentWidth = 0f;

                var currentLineElements = new List <TextLineElement>();

                while (true)
                {
                    if (!queue.Any())
                    {
                        break;
                    }

                    var currentElement = queue.Peek();

                    var measurementRequest = new TextMeasurementRequest
                    {
                        Canvas      = Canvas,
                        PageContext = PageContext,

                        StartIndex     = currentItemIndex,
                        AvailableWidth = availableWidth - currentWidth,

                        IsFirstElementInBlock = currentElement == Items.First(),
                        IsFirstElementInLine  = !currentLineElements.Any()
                    };

                    var measurementResponse = currentElement.Measure(measurementRequest);

                    if (measurementResponse == null)
                    {
                        break;
                    }

                    currentLineElements.Add(new TextLineElement
                    {
                        Item        = currentElement,
                        Measurement = measurementResponse
                    });

                    currentWidth    += measurementResponse.Width;
                    currentItemIndex = measurementResponse.NextIndex;

                    if (!measurementResponse.IsLast)
                    {
                        break;
                    }

                    currentItemIndex = 0;
                    queue.Dequeue();
                }

                return(TextLine.From(currentLineElements));
            }
        }