@@ -74,7 +74,6 @@ public RichTextGlyphRenderer(
7474 // Turn of caching. The chances of a hit are near-zero.
7575 this . rasterizationRequired = true ;
7676 this . noCache = true ;
77-
7877 if ( path is IPathInternals internals )
7978 {
8079 this . path = internals ;
@@ -142,11 +141,16 @@ protected override void BeginGlyph(in FontRectangle bounds, in GlyphRendererPara
142141 new RectangleF ( bounds . Location , new ( bounds . Width , bounds . Height ) ) ,
143142 this . drawingOptions . Transform ) ;
144143
144+ PointF currentBoundsDelta = currentBounds . Location - ClampToPixel ( currentBounds . Location ) ;
145+ PointF subPixelLocation = new (
146+ MathF . Round ( currentBoundsDelta . X * AccuracyMultiple ) / AccuracyMultiple ,
147+ MathF . Round ( currentBoundsDelta . Y * AccuracyMultiple ) / AccuracyMultiple ) ;
148+
145149 SizeF subPixelSize = new (
146150 MathF . Round ( currentBounds . Width * AccuracyMultiple ) / AccuracyMultiple ,
147151 MathF . Round ( currentBounds . Height * AccuracyMultiple ) / AccuracyMultiple ) ;
148152
149- this . currentCacheKey = ( parameters , new RectangleF ( new ( 0 , 0 ) , subPixelSize ) ) ;
153+ this . currentCacheKey = ( parameters , new RectangleF ( subPixelLocation , subPixelSize ) ) ;
150154 if ( this . glyphData . ContainsKey ( this . currentCacheKey ) )
151155 {
152156 // We have already drawn the glyph vectors.
@@ -345,7 +349,32 @@ protected override void EndGlyph()
345349 renderData = this . glyphData [ this . currentCacheKey ] ;
346350
347351 // Offset the render location by the delta from the cached glyph and this one.
348- renderLocation = ( Point ) ( path . Bounds . Location - ( PointF ) renderData . LocationDelta ) ;
352+ Vector2 previousDelta = renderData . LocationDelta ;
353+ Vector2 currentLocation = path . Bounds . Location ;
354+ Vector2 currentDelta = path . Bounds . Location - ClampToPixel ( path . Bounds . Location ) ;
355+
356+ if ( previousDelta . Y > currentDelta . Y )
357+ {
358+ // Move the location down to match the previous location offset.
359+ currentLocation += new Vector2 ( 0 , previousDelta . Y - currentDelta . Y ) ;
360+ }
361+ else if ( previousDelta . Y < currentDelta . Y )
362+ {
363+ // Move the location up to match the previous location offset.
364+ currentLocation -= new Vector2 ( 0 , currentDelta . Y - previousDelta . Y ) ;
365+ }
366+ else if ( previousDelta . X > currentDelta . X )
367+ {
368+ // Move the location right to match the previous location offset.
369+ currentLocation += new Vector2 ( previousDelta . X - currentDelta . X , 0 ) ;
370+ }
371+ else if ( previousDelta . X < currentDelta . X )
372+ {
373+ // Move the location left to match the previous location offset.
374+ currentLocation -= new Vector2 ( currentDelta . X - previousDelta . X , 0 ) ;
375+ }
376+
377+ renderLocation = ClampToPixel ( currentLocation ) ;
349378 }
350379
351380 if ( renderData . FillMap != null )
@@ -482,7 +511,8 @@ private Matrix3x2 ComputeTransform(in FontRectangle bounds)
482511
483512 private Buffer2D < float > Render ( IPath path )
484513 {
485- // We need to offset the path now against the equivalent pixel position of [0,0] for rasterization.
514+ // We need to offset the path now by the difference between the clamped location and the
515+ // path location.
486516 IPath offsetPath = path . Translate ( - ClampToPixel ( path . Bounds . Location ) ) ;
487517 Size size = Rectangle . Ceiling ( offsetPath . Bounds ) . Size ;
488518
0 commit comments