package routing

import (
	

	
	
	
)

// TraceEdgesToShapeBorder trims every route endpoint to the rendered shape.
func ( context.Context,  *layoutgraph.Graph) error {
	return traceEdgesToShapeBorderWithWorkLimit(, , maxRouteStageWorkUnits)
}

func traceEdgesToShapeBorderWithWorkLimit( context.Context,  *layoutgraph.Graph,  uint64) error {
	return runAtomicRouteStage(, "TraceEdgesToShapeBorder", , nil, , func( *routeWorkGuard) error {
		for ,  := range .Edges {
			if  := traceToShapeBorderGuarded(, );  != nil {
				return 
			}
		}
		return nil
	})
}

func traceToShapeBorder( *layoutgraph.Edge) {
	if  == nil || .From == nil || .To == nil || len(.Points) < 2 {
		return
	}
	,  := .From, .To
	var ,  *geo.Point
	var ,  *geo.Point
	defer func() {
		// Restore in reverse mutation order in case both endpoints share a node.
		if  != nil {
			* = *
			.TopLeft = 
		}
		if  != nil {
			* = *
			.TopLeft = 
		}
	}()

	// If an edge passes through a 3D/multiple modifier, use the offset box for
	// tracing to the rendered border.
	if ,  := .From.ModifierElementAdjustments();  != 0 ||  != 0 {
		 := .Points[0]
		if .X > .From.TopLeft.X+ &&
			.Y < .From.TopLeft.Y+.From.Height- {
			 = .From.TopLeft
			 = .From.TopLeft.Copy()
			 := .From.PortOrientation()

			// If connected to the top or right side, move the segment back
			// before tracing to the border.
			 := .Points[1]
			if  == geo.Right || .X == .X+.From.Width {
				.From.TopLeft.X += 
				 := .From.TopLeft.AddVector(geo.Vector{.From.Width, 0})
				 := .AddVector(geo.Vector{0, .From.Height})
				 := geo.IntersectionPoint(, , , )
				if  != nil {
					.X = .X
					.Y = .Y
				}
			} else if  == geo.Top || .Y == .Y {
				.From.TopLeft.Y -= 
				 := .From.TopLeft.AddVector(geo.Vector{.From.Width, 0})
				 := geo.IntersectionPoint(, , .From.TopLeft, )
				if  != nil {
					.X = .X
					.Y = .Y
				}
			}
		}
	}
	if ,  := .To.ModifierElementAdjustments();  != 0 ||  != 0 {
		 := .Points[len(.Points)-1]
		if .X > .To.TopLeft.X+ &&
			.Y < .To.TopLeft.Y+.To.Height- {
			 = .To.TopLeft
			 = .To.TopLeft.Copy()
			 := .To.PortOrientation()

			 := .Points[len(.Points)-2]
			if  == geo.Right || .X == .X+.To.Width {
				.To.TopLeft.X += 
				 := .To.TopLeft.AddVector(geo.Vector{.To.Width, 0})
				 := .AddVector(geo.Vector{0, .To.Height})
				 := geo.IntersectionPoint(, , , )
				if  != nil {
					.X = .X
					.Y = .Y
				}
			} else if  == geo.Top || .Y == .Y {
				.To.TopLeft.Y -= 
				 := .To.TopLeft.AddVector(geo.Vector{.To.Width, 0})
				 := geo.IntersectionPoint(, , .To.TopLeft, )
				if  != nil {
					.X = .X
					.Y = .Y
				}
			}
		}
	}

	 := shape.TraceToShapeBorder(.From.Shape, .Points[0], .Points[1])
	if  != nil {
		.Points[0] = 
	}
	 = shape.TraceToShapeBorder(.To.Shape, .Points[len(.Points)-1], .Points[len(.Points)-2])
	if  != nil {
		.Points[len(.Points)-1] = 
	}
}