@@ -41,29 +41,37 @@ public PathGlyphBuilder(IPath path, LayoutMode layoutMode)
4141 /// <inheritdoc/>
4242 protected override void BeginText ( FontRectangle rect )
4343 {
44+ // TODO: This uses the baseline of the text, should it be the bottom?
4445 this . yOffset = rect . Height ;
4546 this . xOffset = rect . Left ;
4647 }
4748
4849 /// <inheritdoc/>
4950 protected override void BeginGlyph ( FontRectangle rect )
5051 {
51- if ( ! this . isVerticalLayout )
52+ // https://svgwg.org/svg2-draft/text.html#TextpathLayoutRules
53+ if ( this . isVerticalLayout )
5254 {
53- this . TransformGlyphHorizontal ( rect ) ;
55+ this . TransformGlyphVertical ( rect ) ;
5456 }
5557 else
5658 {
57- this . TransformGlyphVertical ( rect ) ;
59+ this . TransformGlyphHorizontal ( rect ) ;
5860 }
5961 }
6062
6163 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
6264 private void TransformGlyphHorizontal ( FontRectangle rect )
6365 {
66+ // Find the intersection point. Bottom-centre for horizontal text.
6467 float halfWidth = rect . Width * .5F ;
65- SegmentInfo point = this . path . PointAlongPath ( rect . Left + halfWidth - this . xOffset ) ;
66- Vector2 targetPoint = point . Point + new PointF ( - halfWidth , rect . Top - this . yOffset ) ;
68+ Vector2 intersectionPoint = new ( rect . Left + halfWidth , rect . Bottom ) ;
69+
70+ // Find the point of this intersection along the given path. This ensures the correct rotation.
71+ SegmentInfo point = this . path . PointAlongPath ( intersectionPoint . X - this . xOffset ) ;
72+
73+ // Now offset our target point since we're aligning top-left.
74+ Vector2 targetPoint = point . Point + new PointF ( - halfWidth , intersectionPoint . Y - rect . Height - this . yOffset ) ;
6775
6876 // Due to how matrix combining works you have to combine this in the reverse order of operation
6977 // this one rotates the glype then moves it.
@@ -74,12 +82,19 @@ private void TransformGlyphHorizontal(FontRectangle rect)
7482 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
7583 private void TransformGlyphVertical ( FontRectangle rect )
7684 {
77- // TODO: Fix this. Vertical text should be rotated at the centre along a different axis.
78- // https://svgwg.org/svg2-draft/ text.html#TextpathLayoutRules
85+ // TODO: Fix this.
86+ // Find the intersection point. Centre-centre for vertical text.
7987 float halfWidth = rect . Width * .5F ;
80- SegmentInfo point = this . path . PointAlongPath ( rect . Left + halfWidth - this . xOffset ) ;
81- Vector2 targetPoint = point . Point + new PointF ( - halfWidth , rect . Top - this . yOffset ) ;
88+ float halfHeight = rect . Height * .5F ;
89+ Vector2 intersectionPoint = new ( rect . Left + halfWidth , rect . Top + halfHeight ) ;
90+
91+ SegmentInfo point = this . path . PointAlongPath ( intersectionPoint . X - this . xOffset ) ;
8292
93+ // Now offset our target point since we're aligning top-left.
94+ Vector2 targetPoint = point . Point + new PointF ( - halfWidth , intersectionPoint . Y - halfHeight - this . yOffset ) ;
95+
96+ // Due to how matrix combining works you have to combine this in the reverse order of operation
97+ // this one rotates the glype then moves it.
8398 Matrix3x2 matrix = Matrix3x2 . CreateTranslation ( targetPoint - rect . Location ) * Matrix3x2 . CreateRotation ( point . Angle - Pi , point . Point ) ;
8499 this . builder . SetTransform ( matrix ) ;
85100 }
0 commit comments