diff --git a/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
index 7f15845596..ddee880288 100644
--- a/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
+++ b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
@@ -61,7 +61,6 @@ namespace RenderDemo.Pages
{
Foreground = Brushes.Black,
GlyphRun = new GlyphRun(_glyphTypeface, _fontSize, _glyphIndices),
- BaselineOrigin = new Point(0, -_glyphTypeface.Ascent * scale)
};
drawingGroup.Children.Add(glyphRunDrawing);
@@ -69,7 +68,7 @@ namespace RenderDemo.Pages
var geometryDrawing = new GeometryDrawing
{
Pen = new Pen(Brushes.Black),
- Geometry = new RectangleGeometry { Rect = glyphRunDrawing.GlyphRun.Bounds }
+ Geometry = new RectangleGeometry { Rect = new Rect(glyphRunDrawing.GlyphRun.Size) }
};
drawingGroup.Children.Add(geometryDrawing);
diff --git a/src/Avalonia.Controls/Primitives/AccessText.cs b/src/Avalonia.Controls/Primitives/AccessText.cs
index 89f672deaa..7a5e6ce426 100644
--- a/src/Avalonia.Controls/Primitives/AccessText.cs
+++ b/src/Avalonia.Controls/Primitives/AccessText.cs
@@ -126,7 +126,7 @@ namespace Avalonia.Controls.Primitives
if (shapedTextCharacters.GlyphRun.Characters.End < textPosition)
{
- currentX += shapedTextCharacters.GlyphRun.Bounds.Width;
+ currentX += shapedTextCharacters.Size.Width;
continue;
}
@@ -143,7 +143,7 @@ namespace Avalonia.Controls.Primitives
width = 0.0;
}
- return new Rect(currentX, currentY, width, shapedTextCharacters.GlyphRun.Bounds.Height);
+ return new Rect(currentX, currentY, width, shapedTextCharacters.Size.Height);
}
}
diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs
index d8477840af..d61519e697 100644
--- a/src/Avalonia.Controls/TextBlock.cs
+++ b/src/Avalonia.Controls/TextBlock.cs
@@ -434,7 +434,10 @@ namespace Avalonia.Controls
var padding = Padding;
- TextLayout.Draw(context, new Point(padding.Left + offsetX, padding.Top));
+ using (context.PushPostTransform(Matrix.CreateTranslation(padding.Left + offsetX, padding.Top)))
+ {
+ TextLayout.Draw(context);
+ }
}
///
diff --git a/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs b/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
index 3ae6c8c30e..4f6af0a41b 100644
--- a/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
+++ b/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
@@ -385,7 +385,7 @@ namespace Avalonia.Headless
}
- public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun, Point baselineOrigin)
+ public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
{
}
diff --git a/src/Avalonia.Visuals/ApiCompatBaseline.txt b/src/Avalonia.Visuals/ApiCompatBaseline.txt
index 5aa497861d..148916932f 100644
--- a/src/Avalonia.Visuals/ApiCompatBaseline.txt
+++ b/src/Avalonia.Visuals/ApiCompatBaseline.txt
@@ -1,15 +1,33 @@
Compat issues with assembly Avalonia.Visuals:
+MembersMustExist : Member 'public void Avalonia.Media.DrawingContext.DrawGlyphRun(Avalonia.Media.IBrush, Avalonia.Media.GlyphRun, Avalonia.Point)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.Media.Typeface Avalonia.Media.FontManager.GetOrAddTypeface(Avalonia.Media.FontFamily, Avalonia.Media.FontStyle, Avalonia.Media.FontWeight)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.Media.Typeface Avalonia.Media.FontManager.MatchCharacter(System.Int32, Avalonia.Media.FontStyle, Avalonia.Media.FontWeight, Avalonia.Media.FontFamily, System.Globalization.CultureInfo)' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public Avalonia.Rect Avalonia.Media.GlyphRun.Bounds.get()' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public Avalonia.StyledProperty Avalonia.StyledProperty Avalonia.Media.GlyphRunDrawing.BaselineOriginProperty' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public Avalonia.Point Avalonia.Media.GlyphRunDrawing.BaselineOrigin.get()' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public void Avalonia.Media.GlyphRunDrawing.BaselineOrigin.set(Avalonia.Point)' does not exist in the implementation but it does exist in the contract.
CannotSealType : Type 'Avalonia.Media.Typeface' is actually (has the sealed modifier) sealed in the implementation but not sealed in the contract.
TypeCannotChangeClassification : Type 'Avalonia.Media.Typeface' is a 'struct' in the implementation but is a 'class' in the contract.
CannotMakeMemberNonVirtual : Member 'public System.Boolean Avalonia.Media.Typeface.Equals(System.Object)' is non-virtual in the implementation but is virtual in the contract.
CannotMakeMemberNonVirtual : Member 'public System.Int32 Avalonia.Media.Typeface.GetHashCode()' is non-virtual in the implementation but is virtual in the contract.
TypesMustExist : Type 'Avalonia.Media.Fonts.FontKey' does not exist in the implementation but it does exist in the contract.
+CannotAddAbstractMembers : Member 'public Avalonia.Size Avalonia.Media.TextFormatting.DrawableTextRun.Size' is abstract in the implementation but is missing in the contract.
+MembersMustExist : Member 'public Avalonia.Rect Avalonia.Media.TextFormatting.DrawableTextRun.Bounds.get()' does not exist in the implementation but it does exist in the contract.
+CannotAddAbstractMembers : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext)' is abstract in the implementation but is missing in the contract.
+MembersMustExist : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext, Avalonia.Point)' does not exist in the implementation but it does exist in the contract.
+CannotAddAbstractMembers : Member 'public Avalonia.Size Avalonia.Media.TextFormatting.DrawableTextRun.Size.get()' is abstract in the implementation but is missing in the contract.
+MembersMustExist : Member 'public Avalonia.Rect Avalonia.Media.TextFormatting.ShapedTextCharacters.Bounds.get()' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public void Avalonia.Media.TextFormatting.ShapedTextCharacters.Draw(Avalonia.Media.DrawingContext, Avalonia.Point)' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public void Avalonia.Media.TextFormatting.TextLayout.Draw(Avalonia.Media.DrawingContext, Avalonia.Point)' does not exist in the implementation but it does exist in the contract.
CannotAddAbstractMembers : Member 'public Avalonia.Media.TextFormatting.TextLineBreak Avalonia.Media.TextFormatting.TextLine.TextLineBreak' is abstract in the implementation but is missing in the contract.
+CannotAddAbstractMembers : Member 'public void Avalonia.Media.TextFormatting.TextLine.Draw(Avalonia.Media.DrawingContext)' is abstract in the implementation but is missing in the contract.
+MembersMustExist : Member 'public void Avalonia.Media.TextFormatting.TextLine.Draw(Avalonia.Media.DrawingContext, Avalonia.Point)' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public Avalonia.Media.TextFormatting.TextLineBreak Avalonia.Media.TextFormatting.TextLine.LineBreak.get()' does not exist in the implementation but it does exist in the contract.
CannotAddAbstractMembers : Member 'public Avalonia.Media.TextFormatting.TextLineBreak Avalonia.Media.TextFormatting.TextLine.TextLineBreak.get()' is abstract in the implementation but is missing in the contract.
+InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.IDrawingContextImpl.DrawGlyphRun(Avalonia.Media.IBrush, Avalonia.Media.GlyphRun)' is present in the implementation but not in the contract.
+InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.IDrawingContextImpl.DrawGlyphRun(Avalonia.Media.IBrush, Avalonia.Media.GlyphRun, Avalonia.Point)' is present in the contract but not in the implementation.
+MembersMustExist : Member 'public void Avalonia.Platform.IDrawingContextImpl.DrawGlyphRun(Avalonia.Media.IBrush, Avalonia.Media.GlyphRun, Avalonia.Point)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Boolean Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32, Avalonia.Media.FontStyle, Avalonia.Media.FontWeight, Avalonia.Media.FontFamily, System.Globalization.CultureInfo, Avalonia.Media.Fonts.FontKey)' is present in the contract but not in the implementation.
MembersMustExist : Member 'public System.Boolean Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32, Avalonia.Media.FontStyle, Avalonia.Media.FontWeight, Avalonia.Media.FontFamily, System.Globalization.CultureInfo, Avalonia.Media.Fonts.FontKey)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Boolean Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32, Avalonia.Media.FontStyle, Avalonia.Media.FontWeight, Avalonia.Media.FontFamily, System.Globalization.CultureInfo, Avalonia.Media.Typeface)' is present in the implementation but not in the contract.
-Total Issues: 13
+Total Issues: 31
diff --git a/src/Avalonia.Visuals/Media/DrawingContext.cs b/src/Avalonia.Visuals/Media/DrawingContext.cs
index ba7191d7a6..ae4c927ae2 100644
--- a/src/Avalonia.Visuals/Media/DrawingContext.cs
+++ b/src/Avalonia.Visuals/Media/DrawingContext.cs
@@ -206,14 +206,13 @@ namespace Avalonia.Media
///
/// The foreground brush.
/// The glyph run.
- /// The baseline origin of the glyph run.
- public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun, Point baselineOrigin)
+ public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
{
Contract.Requires(glyphRun != null);
if (foreground != null)
{
- PlatformImpl.DrawGlyphRun(foreground, glyphRun, baselineOrigin);
+ PlatformImpl.DrawGlyphRun(foreground, glyphRun);
}
}
diff --git a/src/Avalonia.Visuals/Media/GlyphRun.cs b/src/Avalonia.Visuals/Media/GlyphRun.cs
index da3a1f721c..14ab083b4f 100644
--- a/src/Avalonia.Visuals/Media/GlyphRun.cs
+++ b/src/Avalonia.Visuals/Media/GlyphRun.cs
@@ -16,8 +16,9 @@ namespace Avalonia.Media
private IGlyphRunImpl _glyphRunImpl;
private GlyphTypeface _glyphTypeface;
private double _fontRenderingEmSize;
- private Rect? _bounds;
+ private Size? _size;
private int _biDiLevel;
+ private Point? _baselineOrigin;
private ReadOnlySlice _glyphIndices;
private ReadOnlySlice _glyphAdvances;
@@ -89,6 +90,20 @@ namespace Avalonia.Media
set => Set(ref _fontRenderingEmSize, value);
}
+ ///
+ /// Gets or sets the baseline origin of the.
+ ///
+ public Point BaselineOrigin
+ {
+ get
+ {
+ _baselineOrigin ??= CalculateBaselineOrigin();
+
+ return _baselineOrigin.Value;
+ }
+ set => Set(ref _baselineOrigin, value);
+ }
+
///
/// Gets or sets an array of values that represent the glyph indices in the rendering physical font.
///
@@ -156,16 +171,13 @@ namespace Avalonia.Media
///
/// Gets or sets the conservative bounding box of the .
///
- public Rect Bounds
+ public Size Size
{
get
{
- if (_bounds == null)
- {
- _bounds = CalculateBounds();
- }
+ _size ??= CalculateSize();
- return _bounds.Value;
+ return _size.Value;
}
}
@@ -200,7 +212,7 @@ namespace Avalonia.Media
if (characterHit.FirstCharacterIndex + characterHit.TrailingLength > Characters.End)
{
- return Bounds.Width;
+ return Size.Width;
}
var glyphIndex = FindGlyphIndex(characterHit.FirstCharacterIndex);
@@ -257,7 +269,7 @@ namespace Avalonia.Media
}
//After
- if (distance > Bounds.Size.Width)
+ if (distance > Size.Width)
{
isInside = false;
@@ -529,12 +541,21 @@ namespace Avalonia.Media
}
///
- /// Calculates the bounds of the .
+ /// Calculates the default baseline origin of the .
+ ///
+ /// The baseline origin.
+ private Point CalculateBaselineOrigin()
+ {
+ return new Point(0, -GlyphTypeface.Ascent * Scale);
+ }
+
+ ///
+ /// Calculates the size of the .
///
///
/// The calculated bounds.
///
- private Rect CalculateBounds()
+ private Size CalculateSize()
{
var height = (GlyphTypeface.Descent - GlyphTypeface.Ascent + GlyphTypeface.LineGap) * Scale;
@@ -555,7 +576,7 @@ namespace Avalonia.Media
}
}
- return new Rect(0, GlyphTypeface.Ascent * Scale, width, height);
+ return new Size(width, height);
}
private void Set(ref T field, T value)
@@ -590,11 +611,15 @@ namespace Avalonia.Media
throw new InvalidOperationException();
}
+ _baselineOrigin = new Point(0, -GlyphTypeface.Ascent * Scale);
+
var platformRenderInterface = AvaloniaLocator.Current.GetService();
_glyphRunImpl = platformRenderInterface.CreateGlyphRun(this, out var width);
var height = (GlyphTypeface.Descent - GlyphTypeface.Ascent + GlyphTypeface.LineGap) * Scale;
+
+ _size = new Size(width, height);
}
void IDisposable.Dispose()
diff --git a/src/Avalonia.Visuals/Media/GlyphRunDrawing.cs b/src/Avalonia.Visuals/Media/GlyphRunDrawing.cs
index d0ea113a6f..7e0d5c3c81 100644
--- a/src/Avalonia.Visuals/Media/GlyphRunDrawing.cs
+++ b/src/Avalonia.Visuals/Media/GlyphRunDrawing.cs
@@ -8,9 +8,6 @@
public static readonly StyledProperty GlyphRunProperty =
AvaloniaProperty.Register(nameof(GlyphRun));
- public static readonly StyledProperty BaselineOriginProperty =
- AvaloniaProperty.Register(nameof(BaselineOrigin));
-
public IBrush Foreground
{
get => GetValue(ForegroundProperty);
@@ -23,12 +20,6 @@
set => SetValue(GlyphRunProperty, value);
}
- public Point BaselineOrigin
- {
- get => GetValue(BaselineOriginProperty);
- set => SetValue(BaselineOriginProperty, value);
- }
-
public override void Draw(DrawingContext context)
{
if (GlyphRun == null)
@@ -36,12 +27,12 @@
return;
}
- context.DrawGlyphRun(Foreground, GlyphRun, BaselineOrigin);
+ context.DrawGlyphRun(Foreground, GlyphRun);
}
public override Rect GetBounds()
{
- return GlyphRun?.Bounds ?? default;
+ return GlyphRun != null ? new Rect(GlyphRun.Size) : Rect.Empty;
}
}
}
diff --git a/src/Avalonia.Visuals/Media/TextDecoration.cs b/src/Avalonia.Visuals/Media/TextDecoration.cs
index 681fc5d499..d9b3f664ce 100644
--- a/src/Avalonia.Visuals/Media/TextDecoration.cs
+++ b/src/Avalonia.Visuals/Media/TextDecoration.cs
@@ -155,8 +155,7 @@ namespace Avalonia.Media
///
/// The drawing context.
/// The shaped characters that are decorated.
- /// The origin.
- internal void Draw(DrawingContext drawingContext, ShapedTextCharacters shapedTextCharacters, Point origin)
+ internal void Draw(DrawingContext drawingContext, ShapedTextCharacters shapedTextCharacters)
{
var fontRenderingEmSize = shapedTextCharacters.Properties.FontRenderingEmSize;
var fontMetrics = shapedTextCharacters.FontMetrics;
@@ -181,16 +180,20 @@ namespace Avalonia.Media
break;
}
+ var origin = new Point();
+
switch (Location)
{
- case TextDecorationLocation.Overline:
- origin += new Point(0, fontMetrics.Ascent);
+ case TextDecorationLocation.Baseline:
+ origin += shapedTextCharacters.GlyphRun.BaselineOrigin;
break;
case TextDecorationLocation.Strikethrough:
- origin += new Point(0, -fontMetrics.StrikethroughPosition);
+ origin += new Point(shapedTextCharacters.GlyphRun.BaselineOrigin.X,
+ shapedTextCharacters.GlyphRun.BaselineOrigin.Y - fontMetrics.StrikethroughPosition);
break;
case TextDecorationLocation.Underline:
- origin += new Point(0, -fontMetrics.UnderlinePosition);
+ origin += new Point(shapedTextCharacters.GlyphRun.BaselineOrigin.X,
+ shapedTextCharacters.GlyphRun.BaselineOrigin.Y - fontMetrics.UnderlinePosition);
break;
}
@@ -207,7 +210,7 @@ namespace Avalonia.Media
var pen = new Pen(Stroke ?? shapedTextCharacters.Properties.ForegroundBrush, thickness,
new DashStyle(StrokeDashArray, StrokeDashOffset), StrokeLineCap);
- drawingContext.DrawLine(pen, origin, origin + new Point(shapedTextCharacters.Bounds.Width, 0));
+ drawingContext.DrawLine(pen, origin, origin + new Point(shapedTextCharacters.Size.Width, 0));
}
}
}
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/DrawableTextRun.cs b/src/Avalonia.Visuals/Media/TextFormatting/DrawableTextRun.cs
index 56790cc0db..338c92f6b1 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/DrawableTextRun.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/DrawableTextRun.cs
@@ -6,15 +6,14 @@
public abstract class DrawableTextRun : TextRun
{
///
- /// Gets the bounds.
+ /// Gets the size.
///
- public abstract Rect Bounds { get; }
+ public abstract Size Size { get; }
///
/// Draws the at the given origin.
///
/// The drawing context.
- /// The origin.
- public abstract void Draw(DrawingContext drawingContext, Point origin);
+ public abstract void Draw(DrawingContext drawingContext);
}
}
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/ShapedTextCharacters.cs b/src/Avalonia.Visuals/Media/TextFormatting/ShapedTextCharacters.cs
index 9e67a03f45..09ecc0a026 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/ShapedTextCharacters.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/ShapedTextCharacters.cs
@@ -26,7 +26,7 @@ namespace Avalonia.Media.TextFormatting
public override int TextSourceLength { get; }
///
- public override Rect Bounds => GlyphRun.Bounds;
+ public override Size Size => GlyphRun.Size;
///
/// Gets the font metrics.
@@ -45,7 +45,7 @@ namespace Avalonia.Media.TextFormatting
public GlyphRun GlyphRun { get; }
///
- public override void Draw(DrawingContext drawingContext, Point origin)
+ public override void Draw(DrawingContext drawingContext)
{
if (GlyphRun.GlyphIndices.Length == 0)
{
@@ -64,11 +64,10 @@ namespace Avalonia.Media.TextFormatting
if (Properties.BackgroundBrush != null)
{
- drawingContext.DrawRectangle(Properties.BackgroundBrush, null,
- new Rect(origin.X, origin.Y + FontMetrics.Ascent, Bounds.Width, Bounds.Height));
+ drawingContext.DrawRectangle(Properties.BackgroundBrush, null, new Rect(Size));
}
- drawingContext.DrawGlyphRun(Properties.ForegroundBrush, GlyphRun, origin);
+ drawingContext.DrawGlyphRun(Properties.ForegroundBrush, GlyphRun);
if (Properties.TextDecorations == null)
{
@@ -77,7 +76,7 @@ namespace Avalonia.Media.TextFormatting
foreach (var textDecoration in Properties.TextDecorations)
{
- textDecoration.Draw(drawingContext, this, origin);
+ textDecoration.Draw(drawingContext, this);
}
}
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs
index b116249fd4..3e85f0f6f0 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs
@@ -52,7 +52,7 @@ namespace Avalonia.Media.TextFormatting
{
var glyphRun = textCharacters.GlyphRun;
- if (glyphRun.Bounds.Width < availableWidth)
+ if (glyphRun.Size.Width < availableWidth)
{
return glyphRun.Characters.Length;
}
@@ -348,7 +348,7 @@ namespace Avalonia.Media.TextFormatting
{
var currentRun = textRuns[runIndex];
- if (currentWidth + currentRun.GlyphRun.Bounds.Width > availableWidth)
+ if (currentWidth + currentRun.Size.Width > availableWidth)
{
var measuredLength = MeasureCharacters(currentRun, paragraphWidth - currentWidth);
@@ -421,7 +421,7 @@ namespace Avalonia.Media.TextFormatting
return new TextLineImpl(splitResult.First, textLineMetrics, lineBreak);
}
- currentWidth += currentRun.GlyphRun.Bounds.Width;
+ currentWidth += currentRun.Size.Width;
currentLength += currentRun.GlyphRun.Characters.Length;
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
index df1ecb4067..daa8807bf6 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
@@ -115,22 +115,24 @@ namespace Avalonia.Media.TextFormatting
/// Draws the text layout.
///
/// The drawing context.
- /// The origin.
- public void Draw(DrawingContext context, Point origin)
+ public void Draw(DrawingContext context)
{
if (!TextLines.Any())
{
return;
}
- var currentY = origin.Y;
+ var currentY = 0.0;
foreach (var textLine in TextLines)
{
var offsetX = TextLine.GetParagraphOffsetX(textLine.LineMetrics.Size.Width, Size.Width,
_paragraphProperties.TextAlignment);
- textLine.Draw(context, new Point(origin.X + offsetX, currentY));
+ using (context.PushPostTransform(Matrix.CreateTranslation(offsetX, currentY)))
+ {
+ textLine.Draw(context);
+ }
currentY += textLine.LineMetrics.Size.Height;
}
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLine.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLine.cs
index c052fb8948..8a1efa0611 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/TextLine.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLine.cs
@@ -51,8 +51,7 @@ namespace Avalonia.Media.TextFormatting
/// Draws the at the given origin.
///
/// The drawing context.
- /// The origin.
- public abstract void Draw(DrawingContext drawingContext, Point origin);
+ public abstract void Draw(DrawingContext drawingContext);
///
/// Create a collapsed line based on collapsed text properties.
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
index 51092cddda..f5e87d097b 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
@@ -33,17 +33,18 @@ namespace Avalonia.Media.TextFormatting
public override bool HasCollapsed { get; }
///
- public override void Draw(DrawingContext drawingContext, Point origin)
+ public override void Draw(DrawingContext drawingContext)
{
- var currentX = origin.X;
+ var currentX = 0.0;
foreach (var textRun in _textRuns)
{
- var baselineOrigin = new Point(currentX, origin.Y + LineMetrics.TextBaseline);
-
- textRun.Draw(drawingContext, baselineOrigin);
+ using (drawingContext.PushPostTransform(Matrix.CreateTranslation(currentX, 0)))
+ {
+ textRun.Draw(drawingContext);
+ }
- currentX += textRun.Bounds.Width;
+ currentX += textRun.Size.Width;
}
}
@@ -64,13 +65,13 @@ namespace Avalonia.Media.TextFormatting
var shapedSymbol = CreateShapedSymbol(collapsingProperties.Symbol);
- var availableWidth = collapsingProperties.Width - shapedSymbol.Bounds.Width;
+ var availableWidth = collapsingProperties.Width - shapedSymbol.Size.Width;
while (runIndex < _textRuns.Count)
{
var currentRun = _textRuns[runIndex];
- currentWidth += currentRun.GlyphRun.Bounds.Width;
+ currentWidth += currentRun.Size.Width;
if (currentWidth > availableWidth)
{
@@ -125,7 +126,7 @@ namespace Avalonia.Media.TextFormatting
return new TextLineImpl(shapedTextCharacters, textLineMetrics, TextLineBreak, true);
}
- availableWidth -= currentRun.GlyphRun.Bounds.Width;
+ availableWidth -= currentRun.Size.Width;
collapsedLength += currentRun.GlyphRun.Characters.Length;
@@ -133,7 +134,7 @@ namespace Avalonia.Media.TextFormatting
}
textLineMetrics =
- new TextLineMetrics(LineMetrics.Size.WithWidth(LineMetrics.Size.Width + shapedSymbol.Bounds.Width),
+ new TextLineMetrics(LineMetrics.Size.WithWidth(LineMetrics.Size.Width + shapedSymbol.Size.Width),
LineMetrics.TextBaseline, TextRange, LineMetrics.HasOverflowed);
return new TextLineImpl(new List(_textRuns) { shapedSymbol }, textLineMetrics, null,
@@ -156,12 +157,12 @@ namespace Avalonia.Media.TextFormatting
{
characterHit = run.GlyphRun.GetCharacterHitFromDistance(distance, out _);
- if (distance <= run.Bounds.Width)
+ if (distance <= run.Size.Width)
{
break;
}
- distance -= run.Bounds.Width;
+ distance -= run.Size.Width;
}
return characterHit;
@@ -229,7 +230,7 @@ namespace Avalonia.Media.TextFormatting
{
if (codepointIndex > textRun.Text.End)
{
- currentDistance += textRun.Bounds.Width;
+ currentDistance += textRun.Size.Width;
continue;
}
@@ -405,7 +406,7 @@ namespace Avalonia.Media.TextFormatting
for (var i = 0; i < shapedTextCharacters.Count; i++)
{
- shapedWidth += shapedTextCharacters[i].Bounds.Width;
+ shapedWidth += shapedTextCharacters[i].Size.Width;
}
return shapedWidth;
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLineMetrics.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLineMetrics.cs
index 6875cc1c04..c4d7527659 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/TextLineMetrics.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLineMetrics.cs
@@ -67,7 +67,7 @@ namespace Avalonia.Media.TextFormatting
var fontMetrics =
new FontMetrics(shapedRun.Properties.Typeface, shapedRun.Properties.FontRenderingEmSize);
- lineWidth += shapedRun.Bounds.Width;
+ lineWidth += shapedRun.Size.Width;
if (ascent > fontMetrics.Ascent)
{
diff --git a/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs b/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs
index c87946b3ea..019614ae80 100644
--- a/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs
+++ b/src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs
@@ -84,8 +84,7 @@ namespace Avalonia.Platform
///
/// The foreground.
/// The glyph run.
- /// The baseline origin of the glyph run.
- void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun, Point baselineOrigin);
+ void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun);
///
/// Creates a new that can be used as a render layer
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs
index 4a364998fd..cb6b1f59d4 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs
@@ -204,13 +204,13 @@ namespace Avalonia.Rendering.SceneGraph
}
///
- public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun, Point baselineOrigin)
+ public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
{
var next = NextDrawAs();
if (next == null || !next.Item.Equals(Transform, foreground, glyphRun))
{
- Add(new GlyphRunNode(Transform, foreground, glyphRun, baselineOrigin, CreateChildScene(foreground)));
+ Add(new GlyphRunNode(Transform, foreground, glyphRun, CreateChildScene(foreground)));
}
else
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs
index bdf05c4f86..a6dba1bd32 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using Avalonia.Media;
+using Avalonia.Media.Immutable;
using Avalonia.Platform;
using Avalonia.VisualTree;
@@ -17,20 +18,17 @@ namespace Avalonia.Rendering.SceneGraph
/// The transform.
/// The foreground brush.
/// The glyph run to draw.
- /// The baseline origin of the glyph run.
/// Child scenes for drawing visual brushes.
public GlyphRunNode(
Matrix transform,
IBrush foreground,
GlyphRun glyphRun,
- Point baselineOrigin,
IDictionary childScenes = null)
- : base(glyphRun.Bounds.Translate(baselineOrigin), transform)
+ : base(new Rect(glyphRun.Size), transform)
{
Transform = transform;
Foreground = foreground?.ToImmutable();
GlyphRun = glyphRun;
- BaselineOrigin = baselineOrigin;
ChildScenes = childScenes;
}
@@ -49,11 +47,6 @@ namespace Avalonia.Rendering.SceneGraph
///
public GlyphRun GlyphRun { get; }
- ///
- /// Gets the baseline origin.
- ///
- public Point BaselineOrigin { get; set; }
-
///
public override IDictionary ChildScenes { get; }
@@ -61,7 +54,7 @@ namespace Avalonia.Rendering.SceneGraph
public override void Render(IDrawingContextImpl context)
{
context.Transform = Transform;
- context.DrawGlyphRun(Foreground, GlyphRun, BaselineOrigin);
+ context.DrawGlyphRun(Foreground, GlyphRun);
}
///
diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index a155fd863b..98528a128a 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -401,16 +401,16 @@ namespace Avalonia.Skia
}
///
- public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun, Point baselineOrigin)
+ public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
{
- using (var paintWrapper = CreatePaint(_fillPaint, foreground, glyphRun.Bounds.Size))
+ using (var paintWrapper = CreatePaint(_fillPaint, foreground, glyphRun.Size))
{
var glyphRunImpl = (GlyphRunImpl)glyphRun.GlyphRunImpl;
ConfigureTextRendering(paintWrapper);
- Canvas.DrawText(glyphRunImpl.TextBlob, (float)baselineOrigin.X,
- (float)baselineOrigin.Y, paintWrapper.Paint);
+ Canvas.DrawText(glyphRunImpl.TextBlob, (float)glyphRun.BaselineOrigin.X,
+ (float)glyphRun.BaselineOrigin.Y, paintWrapper.Paint);
}
}
diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
index e0de40525f..258a51db5a 100644
--- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
+++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
@@ -324,13 +324,14 @@ namespace Avalonia.Direct2D1.Media
/// The foreground.
/// The glyph run.
///
- public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun, Point baselineOrigin)
+ public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
{
- using (var brush = CreateBrush(foreground, glyphRun.Bounds.Size))
+ using (var brush = CreateBrush(foreground, glyphRun.Size))
{
var glyphRunImpl = (GlyphRunImpl)glyphRun.GlyphRunImpl;
- _renderTarget.DrawGlyphRun(baselineOrigin.ToSharpDX(), glyphRunImpl.GlyphRun, brush.PlatformBrush, MeasuringMode.Natural);
+ _renderTarget.DrawGlyphRun(glyphRun.BaselineOrigin.ToSharpDX(), glyphRunImpl.GlyphRun,
+ brush.PlatformBrush, MeasuringMode.Natural);
}
}
diff --git a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs
index bf41381b52..f3e1c37705 100644
--- a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs
+++ b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs
@@ -369,7 +369,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
var glyphRun = shapedRun.GlyphRun;
- var width = glyphRun.Bounds.Width;
+ var width = glyphRun.Size.Width;
var characterHit = glyphRun.GetCharacterHitFromDistance(width, out _);