static void DebugVerifyRectsDisjoint(Rectangle rect1, Rectangle rect2, double dblPaddingX, double dblPaddingY, double dblEpsilon) { rect1.PadWidth(dblPaddingX/2.0 - dblEpsilon); rect1.PadHeight(dblPaddingY/2.0 - dblEpsilon); rect2.PadWidth(dblPaddingX/2.0 - dblEpsilon); rect2.PadHeight(dblPaddingY/2.0 - dblEpsilon); Debug.Assert(!rect1.Intersects(rect2)); }
List<Event> CreateEvents(Solver solver, ref Rectangle boundaryRect) { var events = new List<Event>(); int cNodes = this.nodeList.Count; // cache for perf double leftBorderWidth = CalcBorderWidth(this.OpenBorderInfo.InnerMargin); double rightBorderWidth = CalcBorderWidth(this.CloseBorderInfo.InnerMargin); double openBorderWidth = CalcBorderWidth(this.OpenBorderInfoP.InnerMargin); double closeBorderWidth = CalcBorderWidth(this.CloseBorderInfoP.InnerMargin); for (int nodeIndex = 0; nodeIndex < cNodes; ++nodeIndex) { OverlapRemovalNode node = this.nodeList[nodeIndex]; var cluster = node as OverlapRemovalCluster; if (null != cluster) { // Child Clusters have already "recursively" been processed before the current cluster, // so we just need to check to see if it had any events. If so, then it has created its // two fake nodes (and their variables) along the primary axis, but these are only put // into the event list at the nested level; at this level, we put Node underlying the // entire Cluster span (in both directions) into the event list. // If a child cluster is empty, it will have zero size and no way to set its position. // That includes clusters containing nothing but empty clusters. We skip those here. if (!cluster.IsInSolver) { continue; } } else { // Not a cluster; just have it add its variable to the solver. node.CreateVariable(solver); } // Now add the Node to the ScanLine event list. Use paddingP because the scan line moves // perpendicularly to the direction we're generating the constraints in. AddEvents(node, events); // Update our boundaries if this node goes past any of them. if (!this.IsRootCluster) { double pad = node.Size / 2 + ClusterPadding; double padP = node.SizeP / 2 + ClusterPaddingP; double newLeft = node.Position - pad - leftBorderWidth; double newRight = node.Position + pad + rightBorderWidth; double newBottom = node.PositionP - padP - openBorderWidth; double newTop = node.PositionP + padP + closeBorderWidth; boundaryRect.Left = Math.Min(boundaryRect.Left, newLeft); boundaryRect.Right = Math.Max(boundaryRect.Right, newRight); boundaryRect.Bottom = Math.Min(boundaryRect.Bottom, newBottom); boundaryRect.Top = Math.Max(boundaryRect.Top, newTop); #if VERBOSE Console.WriteLine(" {0} BoundaryRect after AddEvents: L/R T/B {1:F5}/{2:F5} {3:F5}/{4:F5}" , this.Name, boundaryRect.Left, boundaryRect.Right, boundaryRect.Top, boundaryRect.Bottom); #endif } } if (!this.IsRootCluster) { // Force the cluster borders to the full minimum sizes if any were specified. // Without the full cluster boundaries being available at constraint generation time, Tuvalu was // getting unresolved overlaps when dragging an external node over the corner of a cluster boundary. double padMinSize = this.MinimumSize - boundaryRect.Width; if (padMinSize > 0) { boundaryRect.PadWidth(padMinSize / 2); } double padMinSizeP = this.MinimumSizeP - boundaryRect.Height; if (padMinSizeP > 0) { boundaryRect.PadHeight(padMinSizeP / 2); } #if VERBOSE Console.WriteLine(" {0} BoundaryRect after CreateEvents: L/R T/B {1:F5}/{2:F5} {3:F5}/{4:F5}" , this.Name, boundaryRect.Left, boundaryRect.Right, boundaryRect.Top, boundaryRect.Bottom); #endif } return events; }
static void DebugVerifyRectContains(Rectangle rectOuter, Rectangle rectInner, double dblPaddingX, double dblPaddingY, double dblEpsilon) { rectInner.PadWidth(dblPaddingX/2.0 - dblEpsilon); rectInner.PadHeight(dblPaddingY/2.0 - dblEpsilon); Debug.Assert(rectOuter.Contains(rectInner) , "Inner Node/Cluster rectangle is not contained within outer Cluster" ); }
internal void UpdateBoundary(Rectangle bounds) { Rectangle r = bounds; if (RectangularBoundary != null) { r = new Rectangle( r.Left - RectangularBoundary.LeftMargin, r.Bottom - RectangularBoundary.BottomMargin, r.Right + RectangularBoundary.RightMargin, r.Top + RectangularBoundary.TopMargin); double widthPad = (RectangularBoundary.MinWidth - r.Width)/2; if (widthPad > 0) { r.PadWidth(widthPad); } double heightPad = (RectangularBoundary.MinHeight - r.Height)/2; if (heightPad > 0) { r.PadHeight(heightPad); } RectangularBoundary.Rect = r; } BoundingBox = r; }