Пример #1
0
        private TextLineMetrics CreateLineMetrics()
        {
            var width = 0d;
            var widthIncludingWhitespace = 0d;
            var trailingWhitespaceLength = 0;
            var newLineLength            = 0;
            var ascent              = 0d;
            var descent             = 0d;
            var lineGap             = 0d;
            var fontRenderingEmSize = 0d;

            for (var index = 0; index < _textRuns.Count; index++)
            {
                var textRun = _textRuns[index];

                var fontMetrics =
                    new FontMetrics(textRun.Properties.Typeface, textRun.Properties.FontRenderingEmSize);

                if (fontRenderingEmSize < textRun.Properties.FontRenderingEmSize)
                {
                    fontRenderingEmSize = textRun.Properties.FontRenderingEmSize;

                    if (ascent > fontMetrics.Ascent)
                    {
                        ascent = fontMetrics.Ascent;
                    }

                    if (descent < fontMetrics.Descent)
                    {
                        descent = fontMetrics.Descent;
                    }

                    if (lineGap < fontMetrics.LineGap)
                    {
                        lineGap = fontMetrics.LineGap;
                    }
                }

                switch (_paragraphProperties.FlowDirection)
                {
                case FlowDirection.LeftToRight:
                {
                    if (index == _textRuns.Count - 1)
                    {
                        width = widthIncludingWhitespace + textRun.GlyphRun.Metrics.Width;
                        trailingWhitespaceLength = textRun.GlyphRun.Metrics.TrailingWhitespaceLength;
                        newLineLength            = textRun.GlyphRun.Metrics.NewlineLength;
                    }

                    break;
                }

                case FlowDirection.RightToLeft:
                {
                    if (index == _textRuns.Count - 1)
                    {
                        var firstRun = _textRuns[0];

                        var offset = firstRun.GlyphRun.Metrics.WidthIncludingTrailingWhitespace -
                                     firstRun.GlyphRun.Metrics.Width;

                        width = widthIncludingWhitespace +
                                textRun.GlyphRun.Metrics.WidthIncludingTrailingWhitespace - offset;

                        trailingWhitespaceLength = firstRun.GlyphRun.Metrics.TrailingWhitespaceLength;
                        newLineLength            = firstRun.GlyphRun.Metrics.NewlineLength;
                    }

                    break;
                }
                }

                widthIncludingWhitespace += textRun.GlyphRun.Metrics.WidthIncludingTrailingWhitespace;
            }

            var start = GetParagraphOffsetX(width, widthIncludingWhitespace, _paragraphWidth,
                                            _paragraphProperties.TextAlignment, _paragraphProperties.FlowDirection);

            var lineHeight = _paragraphProperties.LineHeight;

            var height = double.IsNaN(lineHeight) || MathUtilities.IsZero(lineHeight) ?
                         descent - ascent + lineGap :
                         lineHeight;

            return(new TextLineMetrics(widthIncludingWhitespace > _paragraphWidth, height, newLineLength, start,
                                       -ascent, trailingWhitespaceLength, width, widthIncludingWhitespace));
        }
Пример #2
0
        private TextLineMetrics CreateLineMetrics()
        {
            var start  = 0d;
            var height = 0d;
            var width  = 0d;
            var widthIncludingWhitespace = 0d;
            var trailingWhitespaceLength = 0;
            var newLineLength            = 0;
            var ascent              = 0d;
            var descent             = 0d;
            var lineGap             = 0d;
            var fontRenderingEmSize = 0d;

            var lineHeight = _paragraphProperties.LineHeight;

            if (_textRuns.Count == 0)
            {
                var glyphTypeface = _paragraphProperties.DefaultTextRunProperties.Typeface.GlyphTypeface;
                fontRenderingEmSize = _paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize;
                var scale = fontRenderingEmSize / glyphTypeface.DesignEmHeight;
                ascent = glyphTypeface.Ascent * scale;
                height = double.IsNaN(lineHeight) || MathUtilities.IsZero(lineHeight) ?
                         descent - ascent + lineGap :
                         lineHeight;

                return(new TextLineMetrics(false, height, 0, start, -ascent, 0, 0, 0));
            }

            for (var index = 0; index < _textRuns.Count; index++)
            {
                switch (_textRuns[index])
                {
                case ShapedTextCharacters textRun:
                {
                    var fontMetrics =
                        new FontMetrics(textRun.Properties.Typeface, textRun.Properties.FontRenderingEmSize);

                    if (fontRenderingEmSize < textRun.Properties.FontRenderingEmSize)
                    {
                        fontRenderingEmSize = textRun.Properties.FontRenderingEmSize;

                        if (ascent > fontMetrics.Ascent)
                        {
                            ascent = fontMetrics.Ascent;
                        }

                        if (descent < fontMetrics.Descent)
                        {
                            descent = fontMetrics.Descent;
                        }

                        if (lineGap < fontMetrics.LineGap)
                        {
                            lineGap = fontMetrics.LineGap;
                        }

                        if (descent - ascent + lineGap > height)
                        {
                            height = descent - ascent + lineGap;
                        }
                    }

                    switch (_paragraphProperties.FlowDirection)
                    {
                    case FlowDirection.LeftToRight:
                    {
                        if (index == _textRuns.Count - 1)
                        {
                            width = widthIncludingWhitespace + textRun.GlyphRun.Metrics.Width;
                            trailingWhitespaceLength = textRun.GlyphRun.Metrics.TrailingWhitespaceLength;
                            newLineLength            = textRun.GlyphRun.Metrics.NewlineLength;
                        }

                        break;
                    }

                    case FlowDirection.RightToLeft:
                    {
                        if (index == _textRuns.Count - 1)
                        {
                            var firstRun = _textRuns[0];

                            if (firstRun is ShapedTextCharacters shapedTextCharacters)
                            {
                                var offset = shapedTextCharacters.GlyphRun.Metrics.WidthIncludingTrailingWhitespace -
                                             shapedTextCharacters.GlyphRun.Metrics.Width;

                                width = widthIncludingWhitespace +
                                        textRun.GlyphRun.Metrics.WidthIncludingTrailingWhitespace - offset;

                                trailingWhitespaceLength = shapedTextCharacters.GlyphRun.Metrics.TrailingWhitespaceLength;
                                newLineLength            = shapedTextCharacters.GlyphRun.Metrics.NewlineLength;
                            }
                        }

                        break;
                    }
                    }

                    widthIncludingWhitespace += textRun.GlyphRun.Metrics.WidthIncludingTrailingWhitespace;

                    break;
                }

                case { } drawableTextRun:
                {
                    widthIncludingWhitespace += drawableTextRun.Size.Width;

                    switch (_paragraphProperties.FlowDirection)
                    {
                    case FlowDirection.LeftToRight:
                    {
                        if (index == _textRuns.Count - 1)
                        {
                            width = widthIncludingWhitespace;
                            trailingWhitespaceLength = 0;
                            newLineLength            = 0;
                        }

                        break;
                    }

                    case FlowDirection.RightToLeft:
                    {
                        if (index == _textRuns.Count - 1)
                        {
                            width = widthIncludingWhitespace;
                            trailingWhitespaceLength = 0;
                            newLineLength            = 0;
                        }

                        break;
                    }
                    }

                    if (drawableTextRun.Size.Height > height)
                    {
                        height = drawableTextRun.Size.Height;
                    }

                    if (ascent > -drawableTextRun.Baseline)
                    {
                        ascent = -drawableTextRun.Baseline;
                    }

                    break;
                }
                }
            }

            start = GetParagraphOffsetX(width, widthIncludingWhitespace, _paragraphWidth,
                                        _paragraphProperties.TextAlignment, _paragraphProperties.FlowDirection);

            if (!double.IsNaN(lineHeight) && !MathUtilities.IsZero(lineHeight))
            {
                height = lineHeight;
            }

            return(new TextLineMetrics(widthIncludingWhitespace > _paragraphWidth, height, newLineLength, start,
                                       -ascent, trailingWhitespaceLength, width, widthIncludingWhitespace));
        }
Пример #3
0
 public TextFormat(Typeface typeface, double fontRenderingEmSize)
 {
     Typeface            = typeface;
     FontRenderingEmSize = fontRenderingEmSize;
     FontMetrics         = new FontMetrics(typeface, fontRenderingEmSize);
 }