@@ -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 }
0 commit comments