Exemplo n.º 1
0
            internal FullTextLine(
                FormatSettings settings,
                int cpFirst,
                int lineLength,
                int paragraphWidth,
                LineFlags lineFlags
                )
                : this(settings.TextFormattingMode, settings.Pap.Justify, settings.TextSource.PixelsPerDip)
            {
                if ((lineFlags & LineFlags.KeepState) != 0 ||
                    settings.Pap.AlwaysCollapsible)
                {
                    _statusFlags |= StatusFlags.KeepState;
                }

                int finiteFormatWidth = settings.GetFiniteFormatWidth(paragraphWidth);

                FullTextState fullText = FullTextState.Create(settings, cpFirst, finiteFormatWidth);

                // formatting the line
                FormatLine(
                    fullText,
                    cpFirst,
                    lineLength,
                    fullText.FormatWidth,
                    finiteFormatWidth,
                    paragraphWidth,
                    lineFlags,
                    null    // collapsingSymbol
                    );
            }
Exemplo n.º 2
0
            private TextMetrics GetRunMetrics(FullTextState textState, TextRun textRun, CharacterBufferRange chars)
            {
                if (textRun is TextCharacters)
                {
                    var textChars    = (TextCharacters)textRun;
                    var result       = new TextMetrics();
                    var props        = textChars.Properties;
                    var typeface     = props.Typeface;
                    var ideal_emsize = TextFormatterImp.RealToIdeal(props.FontRenderingEmSize);

                    result._textAscent     = (int)Math.Round(typeface.Baseline(ideal_emsize, Constants.DefaultIdealToReal, props.PixelsPerDip, _textFormattingMode));
                    result._textHeight     = (int)Math.Round(typeface.LineSpacing(ideal_emsize, Constants.DefaultIdealToReal, props.PixelsPerDip, _textFormattingMode));
                    result._height         = result._textHeight;
                    result._baselineOffset = result._textAscent;

                    // width calculation
                    var formatted = GetFormattedTextSymbols(textChars, chars, 0);                     // isSideways
                    result._textWidth = formatted.UnscaledWidth;

                    return(result);
                }
                else if (textRun is TextHidden)
                {
                    var result = new TextMetrics();
                    // Default should be empty
                    return(result);
                }
                else
                {
                    throw new NotImplementedException(String.Format("Managed.TextFormatting.FullTextLine.GetRunMetrics for {0}", textRun.GetType().FullName));
                }
            }
Exemplo n.º 3
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;
                        }
                    }
                }
            }
Exemplo n.º 4
0
            // For a given line length, return TextMetrics for as manu characters fit in the width
            private TextMetrics GetLineMetrics(
                FullTextState fullText,
                int cpFirst,
                int lineLength,
                int formatWidth,
                int finiteFormatWidth,
                int paragraphWidth,
                LineFlags lineFlags,
                FormattedTextSymbols collapsingSymbol
                )
            {
                TextMetrics result = new TextMetrics();

                result._formatter = fullText.Formatter;
                Debug.Assert(result._formatter != null);

                TextStore      store        = fullText.TextStore;
                FormatSettings settings     = store.Settings;
                ParaProp       pap          = settings.Pap;
                var            pixelsPerDip = settings.TextSource.PixelsPerDip;

                int pos             = cpFirst;
                int content_ascent  = 0;
                int content_descent = 0;

                while (lineLength <= 0 || cpFirst + lineLength > pos)
                {
                    TextRun textRun;
                    int     runLength;
                    CharacterBufferRange chars = settings.FetchTextRun(pos, cpFirst, out textRun, out runLength);

                    if (lineLength > 0 && pos + runLength > cpFirst + lineLength)
                    {
                        runLength = cpFirst + lineLength - pos;
                        chars     = new CharacterBufferRange(chars, 0, runLength);
                    }

                    if (textRun is TextEndOfParagraph || textRun is TextEndOfLine)
                    {
                        pos += runLength;
                        result._cchNewline = runLength;
                        break;
                    }

                    TextMetrics runMetrics = GetRunMetrics(fullText, textRun, chars);

                    if (content_ascent < runMetrics._textAscent)
                    {
                        content_ascent = runMetrics._textAscent;
                    }

                    if (content_descent < runMetrics._textHeight - runMetrics._textAscent)
                    {
                        content_descent = runMetrics._textHeight - runMetrics._textAscent;
                    }

                    result._textWidth += runMetrics._textWidth;

                    pos += runLength;
                }

                result._pixelsPerDip        = pixelsPerDip;
                result._cchLength           = pos - cpFirst;
                result._textWidthAtTrailing = result._textWidth;                 // will be set later by FormatLine

                if (pap.LineHeight > 0)
                {
                    // Host specifies line height, honor it.
                    result._height         = pap.LineHeight;
                    result._baselineOffset = (int)Math.Round(
                        result._height
                        * pap.DefaultTypeface.Baseline(pap.EmSize, Constants.DefaultIdealToReal, pixelsPerDip, _textFormattingMode)
                        / pap.DefaultTypeface.LineSpacing(pap.EmSize, Constants.DefaultIdealToReal, pixelsPerDip, _textFormattingMode)
                        );
                }

                if (content_ascent > 0)
                {
                    result._textAscent = content_ascent;
                    result._textHeight = content_ascent + content_descent;

                    // TODO: VerticalAdjust
                }
                else
                {
                    // Line is empty so text height and text baseline are based on the default typeface;
                    // it doesn't make sense even for an emtpy line to have zero text height
                    result._textAscent = (int)Math.Round(pap.DefaultTypeface.Baseline(pap.EmSize, Constants.DefaultIdealToReal, pixelsPerDip, _textFormattingMode));
                    result._textHeight = (int)Math.Round(pap.DefaultTypeface.LineSpacing(pap.EmSize, Constants.DefaultIdealToReal, pixelsPerDip, _textFormattingMode));
                }

                if (result._height <= 0)
                {
                    result._height         = result._textHeight;
                    result._baselineOffset = result._textAscent;
                }

                return(result);
            }