public void InvalidateGraphicArea(RenderElement fromElement, ref Rectangle elemClientRect) { //total bounds = total bounds at level if (this.IsInRenderPhase) { return; } //-------------------------------------- //bubble up ,find global rect coord //and then merge to accumulate rect //int globalX = 0; //int globalY = 0; Point globalPoint = new Point(); bool isBubbleUp = false; #if DEBUG int dbug_ncount = 0; dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, dbug_ncount, ">> :" + elemClientRect.ToString()); #endif do { if (!fromElement.Visible) { #if DEBUG dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, 0, "EARLY-RET: "); #endif return; } else if (fromElement.BlockGraphicUpdateBubble) { #if DEBUG dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, 0, "BLOCKED2: "); #endif return; } //--------------------------------------------------------------------- #if DEBUG dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, dbug_ncount, ">> "); #endif globalPoint.Offset(fromElement.X, fromElement.Y); //globalX += fromElement.BubbleUpX; //globalY += fromElement.BubbleUpY; if (fromElement.MayHasViewport && isBubbleUp) { //elemClientRect.Offset(globalX, globalY); elemClientRect.Offset(globalPoint); if (fromElement.HasDoubleScrollableSurface) { //container.VisualScrollableSurface.WindowRootNotifyInvalidArea(elementClientRect); } Rectangle elementRect = fromElement.RectBounds; elementRect.Offset(fromElement.ViewportX, fromElement.ViewportY); elemClientRect.Intersect(elementRect); globalPoint.X = -fromElement.ViewportX; globalPoint.Y = -fromElement.ViewportY; //globalX = -fromElement.ViewportX; //globalY = -fromElement.ViewportY; } if (fromElement.IsTopWindow) { break; } else { #if DEBUG if (fromElement.dbugParentVisualElement == null) { dbugWriteStopGfxBubbleUp(fromElement, ref dbug_ncount, 0, "BLOCKED3: "); } #endif var parentLink = fromElement.MyParentLink; if (parentLink == null) { return; } parentLink.AdjustLocation(ref globalPoint); //move up fromElement = parentLink.ParentRenderElement;// fromElement.ParentRenderElement; if (fromElement == null) { return; } } isBubbleUp = true; } while (true); #if DEBUG var dbugMyroot = this; if (dbugMyroot.dbugEnableGraphicInvalidateTrace && dbugMyroot.dbugGraphicInvalidateTracer != null) { while (dbug_ncount > 0) { dbugMyroot.dbugGraphicInvalidateTracer.PopElement(); dbug_ncount--; } } #endif //---------------------------------------- //elemClientRect.Offset(globalX, globalY); elemClientRect.Offset(globalPoint); if (elemClientRect.Top > this.Height || elemClientRect.Left > this.Width || elemClientRect.Bottom < 0 || elemClientRect.Right < 0) { //no intersect with #if DEBUG if (dbugMyroot.dbugEnableGraphicInvalidateTrace && dbugMyroot.dbugGraphicInvalidateTracer != null) { dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("ZERO-EEX"); dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("\r\n"); } #endif return; } //-------------------------------------------------------------------------------------------------- if (!hasAccumRect) { accumulateInvalidRect = elemClientRect; hasAccumRect = true; } else { accumulateInvalidRect = Rectangle.Union(accumulateInvalidRect, elemClientRect); } #if DEBUG if (dbugMyroot.dbugEnableGraphicInvalidateTrace && dbugMyroot.dbugGraphicInvalidateTracer != null) { string state_str = "ACC: "; if (this.dbugNeedContentArrangement || this.dbugNeedReCalculateContentSize) { state_str = "!!" + state_str; } dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("ACC: " + accumulateInvalidRect.ToString()); dbugMyroot.dbugGraphicInvalidateTracer.WriteInfo("\r\n"); } #endif }