Skip to content

Commit b29a440

Browse files
Apply DestinationOffset for path point translation
1 parent 6f97c13 commit b29a440

1 file changed

Lines changed: 10 additions & 11 deletions

File tree

src/ImageSharp.Drawing.WebGPU/WebGPUSceneEncoder.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -583,19 +583,18 @@ private static int EncodePath(
583583
out int lineCount,
584584
out int pathSegmentCount)
585585
{
586-
Rectangle interest = command.RasterizerOptions.Interest;
587586
float samplingOffset = command.RasterizerOptions.SamplingOrigin == RasterizerSamplingOrigin.PixelCenter ? 0.5F : 0F;
588-
float targetOffsetX = command.TargetBounds.X - rootTargetBounds.X;
589-
float targetOffsetY = command.TargetBounds.Y - rootTargetBounds.Y;
590-
float translateX = targetOffsetX + command.DestinationRegion.X - command.SourceOffset.X;
591-
float translateY = targetOffsetY + command.DestinationRegion.Y - command.SourceOffset.Y;
592-
593-
// Move path points from interest-local coverage space into target-local space.
594-
float pointTranslateX = translateX + samplingOffset - interest.Left;
595-
float pointTranslateY = translateY + samplingOffset - interest.Top;
587+
float pointTranslateX = (command.DestinationOffset.X - rootTargetBounds.X) + samplingOffset;
588+
float pointTranslateY = (command.DestinationOffset.Y - rootTargetBounds.Y) + samplingOffset;
596589
pathSegmentCount = 0;
597590
lineCount = 0;
598591

592+
// Prepared path points stay in the command's own path space until backend encoding.
593+
// Ordinary shapes often already live in target coordinates, but text glyphs are emitted
594+
// as local outlines plus a separate DestinationOffset. We therefore place every point by
595+
// applying the command's absolute destination offset directly rather than trying to
596+
// reconstruct placement from Interest/DestinationRegion/SourceOffset, which are clipping
597+
// artifacts in absolute destination space and can cancel the text offset entirely.
599598
// The lowered geometry is already contour-ordered, so the encoder walks the segment
600599
// stream once and emits each contour as: starting point, then one end point per segment.
601600
SegmentEnumerator segments = geometry.GetSegments();
@@ -625,8 +624,8 @@ private static int EncodePath(
625624
pathTags.Add(PathTagLineToF32);
626625
pathSegmentCount++;
627626

628-
float y0 = ((segment.Start.Y - interest.Top) + samplingOffset) + translateY;
629-
float y1 = ((segment.End.Y - interest.Top) + samplingOffset) + translateY;
627+
float y0 = segment.Start.Y + pointTranslateY;
628+
float y1 = segment.End.Y + pointTranslateY;
630629
int fy0 = (int)MathF.Round(y0 * FixedOne);
631630
int fy1 = (int)MathF.Round(y1 * FixedOne);
632631
if (fy0 != fy1)

0 commit comments

Comments
 (0)