private void RenderNodeRecursively(Node n, RenderContext rc, RenderDevice rs) { if (n == null) { return; } if (!n.Visible) // 'Visible == false' would hide all children { return; } // 两个说明: // 1) m_localPosDocked 并非一个累积量,因此不需在使用完之后重置 // 2) m_localPosScrolled 并非一个累积量,因此不需在使用完之后重置 // 3) m_accumTranslate 只需计算一次,结果可供整个 Children 列表共享使用 // // 上面这三点决定了 m_localPosDocked 和 m_localPosScrolled 作用于当前节点 // 而 m_accumTranslate 作用于当前节点的 Children 列表 Point localPosDocked = n.GetDockedPos(); rc.m_localPosDocked = localPosDocked; Point localScrolled = Point.Empty - (Size)n.CurrentScrollOffset; rc.m_localPosScrolled = localScrolled; rs.RenderNode(n, rc); rc.m_accumTranslate.X += (localPosDocked.X + localScrolled.X); rc.m_accumTranslate.Y += (localPosDocked.Y + localScrolled.Y); Rectangle oldClip = rs.GetCurrentClip(rc); if (n.IsScrollable()) { rs.SetCurrentClip(rc, n.GetWorldBounds()); } n.TraverseChildren((Node child) => { RenderNodeRecursively(child, rc, rs); }); if (n.IsScrollable()) { rs.SetCurrentClip(rc, oldClip); } rc.m_accumTranslate.X -= (localPosDocked.X + localScrolled.X); rc.m_accumTranslate.Y -= (localPosDocked.Y + localScrolled.Y); }