Esempio n. 1
0
            /// <summary>
            /// format text line using LS
            /// </summary>
            /// <param name="fullText">state of the full text backing store</param>
            /// <param name="cpFirst">first cp to format</param>
            /// <param name="lineLength">character length of the line</param>
            /// <param name="formatWidth">width used to format</param>
            /// <param name="finiteFormatWidth">width used to detect overflowing of format result</param>
            /// <param name="paragraphWidth">paragraph width</param>
            /// <param name="lineFlags">line formatting control flags</param>
            /// <param name="collapsingSymbol">line end collapsing symbol</param>
            private void FormatLine(
                FullTextState fullText,
                int cpFirst,
                int lineLength,
                int formatWidth,
                int finiteFormatWidth,
                int paragraphWidth,
                LineFlags lineFlags,
                FormattedTextSymbols collapsingSymbol
                )
            {
                _fullText       = fullText;
                _paragraphWidth = paragraphWidth;

                TextStore      store    = fullText.TextStore;
                FormatSettings settings = store.Settings;
                ParaProp       pap      = settings.Pap;

                _paragraphTextDecorations = pap.TextDecorations;
                if (_paragraphTextDecorations != null)
                {
                    if (_paragraphTextDecorations.Count != 0)
                    {
                        _defaultTextDecorationsBrush = pap.DefaultTextDecorationsBrush;
                    }
                    else
                    {
                        _paragraphTextDecorations = null;
                    }
                }

                _metrics = GetLineMetrics(fullText, cpFirst, lineLength, formatWidth, finiteFormatWidth, paragraphWidth, lineFlags, collapsingSymbol);

                lineLength = _metrics._cchLength;
                if (lineLength > _metrics._cchNewline)
                {
                    var lineBreakpoints = store.FindLineBreakpoints(cpFirst, lineLength);

                    // check for line wrap
                    if (pap.Wrap && _metrics._textStart + _metrics._textWidthAtTrailing > finiteFormatWidth)
                    {
                        for (int i = lineLength - 1; i > 0; i--)
                        {
                            if (lineBreakpoints.GetBreakConditionBefore(i + cpFirst) == DWriteBreakCondition.CanBreak)
                            {
                                var trailingWhitespace = lineBreakpoints.WhitespaceLengthBefore(i + cpFirst);
                                var trimmedMetrics     = GetLineMetrics(fullText, cpFirst, i - trailingWhitespace, formatWidth, finiteFormatWidth, paragraphWidth, lineFlags, collapsingSymbol);
                                if (trimmedMetrics._textStart + trimmedMetrics._textWidthAtTrailing <= finiteFormatWidth)
                                {
                                    _metrics = GetLineMetrics(fullText, cpFirst, i, formatWidth, finiteFormatWidth, paragraphWidth, lineFlags, collapsingSymbol);
                                    _metrics._cchTrailing         = trailingWhitespace;
                                    _metrics._textWidthAtTrailing = trimmedMetrics._textWidth;
                                    break;
                                }
                            }
                        }
                    }
                }

                if (collapsingSymbol == null)
                {
                    // overflow detection for potential collapsible line
                    if (_metrics._textStart + _metrics._textWidthAtTrailing > finiteFormatWidth)
                    {
                        bool hasOverflowed = true;
                        if (_textFormattingMode == TextFormattingMode.Display)
                        {
                            // apply display-mode rounding before checking for overflow
                            double realWidth       = Width;
                            double realFormatWidth = _metrics._formatter.IdealToReal(finiteFormatWidth, PixelsPerDip);
                            hasOverflowed = (TextFormatterImp.CompareReal(realWidth, realFormatWidth, PixelsPerDip, _textFormattingMode) > 0);
                        }

                        if (hasOverflowed)
                        {
                            // line has overflowed
                            _statusFlags |= StatusFlags.HasOverflowed;
                        }
                    }
                }
            }