Repository: AvaloniaUI/Avalonia

Issue:
Text alignment mismatch when using icon fonts
## Describe the bug

Text alignment mismatch when using icon fonts such as SegoeFluentIcons.

## To Reproduce

Check out `icon-font-err` branch for both repo:

[Avalonia Test](https://github.com/laolarou726/TypesettingErrorDemo)
[WPF Test](https://github.com/laolarou726/TypesettingErrorDemoWPF)

## Screenshots

In Avalonia:
<img width="225" alt="image" src="https://github.com/AvaloniaUI/Avalonia/assets/25716486/cbcc067e-c8d8-4d5c-aa9d-6caff4924f8c">

In WPF:
<img width="186" alt="image" src="https://github.com/AvaloniaUI/Avalonia/assets/25716486/2c85bcb6-a93f-4cf1-a7f9-fa337d3d7325">

## Environment

- OS: Windows 11 22H2
- Avalonia-Version: 11.1.999-cibuild0040792-beta



Hints:
Two notes here:

 1. This may be a Skia issue
 2. I recall UWP/WinUI has a similar problem that remains unfixed: https://github.com/microsoft/microsoft-ui-xaml/issues/3077. This was not for fonts though, just paths.

I saw this issue as well with a piece of art I made myself. It almost seemed like it was using relative pathing even when the absolute path symbols were used (capital letters instead of lower case).  In my case I was able to move an arc that was being drawn incorrectly to the front of the path and it corrected itself.  It really was quite bizarre.
@Alshain01 Do you happen to have the path data you can share? That is probably easier to debug than a font.
> @Alshain01 Do you happen to have the path data you can share? That is probably easier to debug than a font.

I would love to help but while I made it, I did so on the job, so it's proprietary and doesn't belong to me.
I have a similar situation, but I don’t know if it is the same problem as you. My icon will have one or two extra paddngs on the left. I always thought it was a problem with the default Text HorizontalAlignment, but I found that the normal text is Normal, only IconFont has this problem (normal on WPF)
Avalonia:
![image](https://github.com/AvaloniaUI/Avalonia/assets/45205313/5b204152-a742-4d01-aaaa-29966d0ebfb0)
WPF:
![(Q5)7@FL0LDI CE8JM 9GCG](https://github.com/AvaloniaUI/Avalonia/assets/45205313/7ae0a7c7-4fa4-45e0-af88-25da814e8e49)


@SmRiley do you have a sample xaml and font file for us ?
> @SmRiley do you have a sample xaml and font file for us ?

[AvaloniaIconFontErrorDemo.zip](https://github.com/AvaloniaUI/Avalonia/files/13191450/AvaloniaIconFontErrorDemo.zip)
Sure, and this is the demo running result
![image](https://github.com/AvaloniaUI/Avalonia/assets/45205313/53855632-ea0b-4042-a871-804b68b83407)
@timunie 
thx ❤️ 
Any update on this?

Patch:
diff --git a/src/Avalonia.Base/Media/PathMarkupParser.cs b/src/Avalonia.Base/Media/PathMarkupParser.cs
index 7b9fdf9330d..fa790c17c00 100644
--- a/src/Avalonia.Base/Media/PathMarkupParser.cs
+++ b/src/Avalonia.Base/Media/PathMarkupParser.cs
@@ -259,7 +259,7 @@ private void AddLine(ref ReadOnlySpan<char> span, bool relative)
         {
             ThrowIfDisposed();
 
-            _currentPoint = relative
+            var next = relative
                                 ? ReadRelativePoint(ref span, _currentPoint)
                                 : ReadPoint(ref span);
 
@@ -268,14 +268,15 @@ private void AddLine(ref ReadOnlySpan<char> span, bool relative)
                 CreateFigure();
             }
 
-            _geometryContext.LineTo(_currentPoint);
+            _geometryContext.LineTo(next);
+            _currentPoint = next;
         }
 
         private void AddHorizontalLine(ref ReadOnlySpan<char> span, bool relative)
         {
             ThrowIfDisposed();
 
-            _currentPoint = relative
+            var next = relative
                                 ? new Point(_currentPoint.X + ReadDouble(ref span), _currentPoint.Y)
                                 : _currentPoint.WithX(ReadDouble(ref span));
 
@@ -284,14 +285,15 @@ private void AddHorizontalLine(ref ReadOnlySpan<char> span, bool relative)
                 CreateFigure();
             }
 
-            _geometryContext.LineTo(_currentPoint);
+            _geometryContext.LineTo(next);
+            _currentPoint = next;
         }
 
         private void AddVerticalLine(ref ReadOnlySpan<char> span, bool relative)
         {
             ThrowIfDisposed();
 
-            _currentPoint = relative
+            var next = relative
                                 ? new Point(_currentPoint.X, _currentPoint.Y + ReadDouble(ref span))
                                 : _currentPoint.WithY(ReadDouble(ref span));
 
@@ -300,7 +302,8 @@ private void AddVerticalLine(ref ReadOnlySpan<char> span, bool relative)
                 CreateFigure();
             }
 
-            _geometryContext.LineTo(_currentPoint);
+            _geometryContext.LineTo(next);
+            _currentPoint = next;
         }
 
         private void AddCubicBezierCurve(ref ReadOnlySpan<char> span, bool relative)


Test patch:
diff --git a/tests/Avalonia.Base.UnitTests/Media/PathMarkupParserTests.cs b/tests/Avalonia.Base.UnitTests/Media/PathMarkupParserTests.cs
index c829690eb4a..755ab7ff25a 100644
--- a/tests/Avalonia.Base.UnitTests/Media/PathMarkupParserTests.cs
+++ b/tests/Avalonia.Base.UnitTests/Media/PathMarkupParserTests.cs
@@ -319,5 +319,24 @@ public void Should_Parse_Flags_Without_Separator()
                 Assert.IsType<ArcSegment>(arcSegment);
             }
         }
+
+        [Fact]
+        public void Should_Handle_StartPoint_After_Empty_Figure()
+        {
+            var pathGeometry = new PathGeometry();
+            using var context = new PathGeometryContext(pathGeometry);
+            using var parser = new PathMarkupParser(context);
+            parser.Parse("M50,50z l -5,-5");
+
+            Assert.Equal(2, pathGeometry.Figures.Count);
+
+            var firstFigure = pathGeometry.Figures[0];
+
+            Assert.Equal(new Point(50, 50), firstFigure.StartPoint);
+
+            var secondFigure = pathGeometry.Figures[1];
+
+            Assert.Equal(new Point(50, 50), secondFigure.StartPoint);
+        }
     }
 }