Skip to content

Commit c6fc3ab

Browse files
Fix GPU stroking and ImageBrush
1 parent d5d1d76 commit c6fc3ab

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

src/ImageSharp.Drawing.WebGPU/Shaders/WgslSource/flatten.wgsl

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -588,19 +588,34 @@ fn draw_join(
588588
if 2. * hypot < (hypot + d) * miter_limit * miter_limit
589589
&& abs(cr) > TANGENT_THRESH * TANGENT_THRESH
590590
{
591-
let v = outer_next - outer_prev;
591+
let fp_last = select(front0, back1, is_backside);
592+
let fp_this = select(front1, back0, is_backside);
593+
let p = select(front0, back0, is_backside);
594+
595+
let v = fp_this - fp_last;
592596
let h = (tan_prev.x * v.y - tan_prev.y * v.x) / cr;
593-
let miter_pt = outer_next - tan_next * h;
597+
let miter_pt = fp_this - tan_next * h;
594598

595599
line_ix = atomicAdd(&bump.lines, 3u);
596-
write_line_with_transform(line_ix, path_ix, outer_prev, miter_pt, transform);
597-
write_line_with_transform(line_ix + 1u, path_ix, miter_pt, outer_next, transform);
598-
write_line_with_transform(line_ix + 2u, path_ix, inner_prev, inner_next, transform);
600+
write_line_with_transform(line_ix, path_ix, p, miter_pt, transform);
601+
602+
// Preserve the contour winding on backside turns by stitching the outer
603+
// edge as back0 -> miter -> back1 rather than reversing the join wedge.
604+
if is_backside {
605+
back0 = miter_pt;
606+
} else {
607+
front0 = miter_pt;
608+
}
609+
610+
write_line_with_transform(line_ix + 1u, path_ix, front0, front1, transform);
611+
write_line_with_transform(line_ix + 2u, path_ix, back0, back1, transform);
599612
} else {
600613
let use_round_overflow = (style_flags & STYLE_FLAGS_JOIN_MITER_ROUND) != 0u;
601614
let use_revert_overflow = (style_flags & STYLE_FLAGS_JOIN_MITER_REVERT) != 0u;
602615
if use_round_overflow {
603-
flatten_arc(path_ix, outer_prev, outer_next, p0, abs(atan2(cr, d)), transform);
616+
let arc_start = select(outer_prev, outer_next, is_backside);
617+
let arc_end = select(outer_next, outer_prev, is_backside);
618+
flatten_arc(path_ix, arc_start, arc_end, p0, abs(atan2(cr, d)), transform);
604619
output_line_with_transform(path_ix, inner_prev, inner_next, transform);
605620
} else if use_revert_overflow || abs(cr) <= TANGENT_THRESH * TANGENT_THRESH {
606621
output_two_lines_with_transform(path_ix, front0, front1, back0, back1, transform);
@@ -617,10 +632,14 @@ fn draw_join(
617632
let ratio = (limit - bevel_distance) / (intersection_distance - bevel_distance);
618633
let clipped_prev = outer_prev + ((miter_pt - outer_prev) * ratio);
619634
let clipped_next = outer_next + ((miter_pt - outer_next) * ratio);
635+
let outer_start = select(outer_prev, outer_next, is_backside);
636+
let clipped_start = select(clipped_prev, clipped_next, is_backside);
637+
let clipped_end = select(clipped_next, clipped_prev, is_backside);
638+
let outer_end = select(outer_next, outer_prev, is_backside);
620639
line_ix = atomicAdd(&bump.lines, 4u);
621-
write_line_with_transform(line_ix, path_ix, outer_prev, clipped_prev, transform);
622-
write_line_with_transform(line_ix + 1u, path_ix, clipped_prev, clipped_next, transform);
623-
write_line_with_transform(line_ix + 2u, path_ix, clipped_next, outer_next, transform);
640+
write_line_with_transform(line_ix, path_ix, outer_start, clipped_start, transform);
641+
write_line_with_transform(line_ix + 1u, path_ix, clipped_start, clipped_end, transform);
642+
write_line_with_transform(line_ix + 2u, path_ix, clipped_end, outer_end, transform);
624643
write_line_with_transform(line_ix + 3u, path_ix, inner_prev, inner_next, transform);
625644
}
626645
}

src/ImageSharp.Drawing.WebGPU/WebGPUSceneEncoder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ private static bool TryResolveCommand(in CompositionCommand command, out Resolve
929929
command.GraphicsOptions,
930930
command.RasterizerOptions,
931931
command.DestinationOffset,
932-
command.Brush is ImageBrush img ? new Rectangle(command.DestinationOffset, img.UntypedImage.Size) : default);
932+
command.Brush is ImageBrush ? command.RasterizerOptions.Interest : default);
933933
return true;
934934
}
935935

@@ -943,7 +943,7 @@ private static bool TryResolveCommand(in StrokeLineSegmentCommand command, out R
943943
command.GraphicsOptions,
944944
command.RasterizerOptions,
945945
command.DestinationOffset,
946-
command.Brush is ImageBrush img ? new Rectangle(command.DestinationOffset, img.UntypedImage.Size) : default);
946+
command.Brush is ImageBrush ? command.RasterizerOptions.Interest : default);
947947
return true;
948948
}
949949

@@ -956,7 +956,7 @@ private static bool TryResolveCommand(in StrokePolylineCommand command, out Reso
956956
command.GraphicsOptions,
957957
command.RasterizerOptions,
958958
command.DestinationOffset,
959-
command.Brush is ImageBrush img ? new Rectangle(command.DestinationOffset, img.UntypedImage.Size) : default);
959+
command.Brush is ImageBrush ? command.RasterizerOptions.Interest : default);
960960
return true;
961961
}
962962

0 commit comments

Comments
 (0)