// This could be greatly optimized by caching the outputs and only updating when something is moved // in the parent planar space. To do that we need to track z-order in the parent space as well public ArrayList GetClippingRectangles() { ArrayList masks = new ArrayList(); if (x < 0) { masks.Add(new Rectangle_(0, 0, x * -1, Height)); if (y < 0) { masks.Add(new Rectangle_(x * -1, 0, Width, y * -1)); } } else if (y < 0) { masks.Add(new Rectangle_(0, 0, Width, y * -1)); } foreach (Hwnd child in children) { if (child.visible) { masks.Add(new Rectangle_(child.X, child.Y, child.Width, child.Height)); } } if (parent == null) { return(masks); } ArrayList siblings = parent.children; foreach (Hwnd sibling in siblings) { IntPtr sibling_handle = whole_window; if (sibling == this) { continue; } // This entire method should be cached to find all higher views at the time of query do { sibling_handle = XplatUI.GetPreviousWindow(sibling_handle); if (sibling_handle == sibling.WholeWindow && sibling.visible) { Rectangle_ intersect = Rectangle.Intersect(new Rectangle_(X, Y, Width, Height), new Rectangle_(sibling.X, sibling.Y, sibling.Width, sibling.Height)); if (intersect == Rectangle_.Empty) { continue; } intersect.X -= X; intersect.Y -= Y; masks.Add(intersect); } } while (sibling_handle != IntPtr.Zero); } return(masks); }