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)); }
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)); }
public TextFormat(Typeface typeface, double fontRenderingEmSize) { Typeface = typeface; FontRenderingEmSize = fontRenderingEmSize; FontMetrics = new FontMetrics(typeface, fontRenderingEmSize); }