Adjust the dirty region consistently with the coordinate transformation. b=445932 r+sr=roc
authorKarl Tomlinson <karlt+@karlt.net>
Mon, 21 Jul 2008 20:24:38 +1200
changeset 16082 769de6b90612a7dab133dda990ea4ee00203eda6
parent 16081 413b9387b0e8857e41041eb893108f492ac84701
child 16083 af91b0f5f3e3dfd5b945f9178e3466723ad3a7cb
push idunknown
push userunknown
push dateunknown
bugs445932
milestone1.9.1a1pre
Adjust the dirty region consistently with the coordinate transformation. b=445932 r+sr=roc
view/src/nsView.cpp
view/src/nsView.h
view/src/nsViewManager.cpp
view/src/nsViewManager.h
--- a/view/src/nsView.cpp
+++ b/view/src/nsView.cpp
@@ -774,17 +774,16 @@ void nsIView::List(FILE* out, PRInt32 aI
     fprintf(out, "(widget=%p[%d] z=%d pos={%d,%d,%d,%d}) ",
             (void*)mWindow, widgetRefCnt, Z,
             nonclientBounds.x, nonclientBounds.y,
             windowBounds.width, windowBounds.height);
   }
   nsRect brect = GetBounds();
   fprintf(out, "{%d,%d,%d,%d}",
           brect.x, brect.y, brect.width, brect.height);
-  const nsView* v = static_cast<const nsView*>(this);
   fprintf(out, " z=%d vis=%d clientData=%p <\n",
           mZIndex, mVis, mClientData);
   for (nsView* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
     NS_ASSERTION(kid->GetParent() == this, "incorrect parent");
     kid->List(out, aIndent + 1);
   }
   for (i = aIndent; --i >= 0; ) fputs("  ", out);
   fputs(">\n", out);
--- a/view/src/nsView.h
+++ b/view/src/nsView.h
@@ -170,16 +170,19 @@ public:
   // Update the cached RootViewManager for all view manager descendents,
   // If the hierarchy is being removed, aViewManagerParent points to the view
   // manager for the hierarchy's old parent, and will have its mouse grab
   // released if it points to any view in this view hierarchy.
   void InvalidateHierarchy(nsViewManager *aViewManagerParent);
 
   virtual ~nsView();
 
+  // This is an app unit offset to add when converting view coordinates to
+  // widget coordinates.  It is the offset in view coordinates from widget
+  // top-left to view top-left.
   nsPoint ViewToWidgetOffset() const {
     if (mParent && mParent->GetViewManager() != GetViewManager()) {
       // The document root view's mViewToWidgetOffset is always (0,0).
       // If it has a parent view, the parent view must be the inner view
       // for an nsSubdocumentFrame; its top-left position in appunits
       // is always positioned at that inner view's top-left, and its
       // widget top-left is always positioned at that inner view's widget's
       // top-left, so its ViewToWidgetOffset is actually the same as
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -424,23 +424,24 @@ void nsViewManager::Refresh(nsView *aVie
 {
   NS_ASSERTION(aRegion != nsnull, "Null aRegion");
 
   if (! IsRefreshEnabled())
     return;
 
   nsRect viewRect;
   aView->GetDimensions(viewRect);
+  nsPoint vtowoffset = aView->ViewToWidgetOffset();
 
   // damageRegion is the damaged area, in twips, relative to the view origin
   nsRegion damageRegion;
   // convert pixels-relative-to-widget-origin to twips-relative-to-widget-origin
   ConvertNativeRegionToAppRegion(aRegion, &damageRegion, mContext);
   // move it from widget coordinates into view coordinates
-  damageRegion.MoveBy(viewRect.x, viewRect.y);
+  damageRegion.MoveBy(viewRect.TopLeft() - vtowoffset);
 
   if (damageRegion.IsEmpty()) {
 #ifdef DEBUG_roc
     nsRect damageRect = damageRegion.GetBounds();
     printf("XXX Damage rectangle (%d,%d,%d,%d) does not intersect the widget's view (%d,%d,%d,%d)!\n",
            damageRect.x, damageRect.y, damageRect.width, damageRect.height,
            viewRect.x, viewRect.y, viewRect.width, viewRect.height);
 #endif
@@ -483,17 +484,16 @@ void nsViewManager::Refresh(nsView *aVie
       }
 
     PRInt32 p2a = mContext->AppUnitsPerDevPixel();
 
     nsRefPtr<gfxContext> ctx = localcx->ThebesContext();
 
     ctx->Save();
 
-    nsPoint vtowoffset = aView->ViewToWidgetOffset();
     ctx->Translate(gfxPoint(gfxFloat(vtowoffset.x) / p2a,
                             gfxFloat(vtowoffset.y) / p2a));
 
     ctx->Translate(gfxPoint(-gfxFloat(viewRect.x) / p2a,
                             -gfxFloat(viewRect.y) / p2a));
 
     nsRegion opaqueRegion;
     AddCoveringWidgetsToOpaqueRegion(opaqueRegion, mContext, aView);
@@ -517,16 +517,17 @@ void nsViewManager::Refresh(nsView *aVie
   MOZ_TIMER_DEBUGLOG(("Stop: nsViewManager::Refresh(region), this=%p\n", this));
   MOZ_TIMER_STOP(mWatch);
   MOZ_TIMER_LOG(("vm2 Paint time (this=%p): ", this));
   MOZ_TIMER_PRINT(mWatch);
 #endif
 
 }
 
+// aRect is in app units and relative to the top-left of the aView->GetWidget()
 void nsViewManager::DefaultRefresh(nsView* aView, nsIRenderingContext *aContext, const nsRect* aRect)
 {
   NS_PRECONDITION(aView, "Must have a view to work with!");
   nsIWidget* widget = aView->GetNearestWidget(nsnull);
   if (! widget)
     return;
 
   nsCOMPtr<nsIRenderingContext> context = aContext;
@@ -595,16 +596,17 @@ void nsViewManager::AddCoveringWidgetsTo
             aRgn.Or(aRgn, bounds);
           }
         }
       }
     }
   }
 }
 
+// aRC and aRegion are in view coordinates
 void nsViewManager::RenderViews(nsView *aView, nsIRenderingContext& aRC,
                                 const nsRegion& aRegion)
 {
   if (mObserver) {
     nsView* displayRoot = GetDisplayRootFor(aView);
     nsPoint offsetToRoot = aView->GetOffsetTo(displayRoot); 
     nsRegion damageRegion(aRegion);
     damageRegion.MoveBy(offsetToRoot);
@@ -1875,18 +1877,25 @@ nsViewManager::CreateRenderingContext(ns
         }
 
       par = par->GetParent();
     }
   while (nsnull != par);
 
   if (nsnull != win)
     {
+      // XXXkt this has an origin at top-left of win ...
       mContext->CreateRenderingContext(par, cx);
 
+      // XXXkt ... but the translation is between the origins of views
+      NS_ASSERTION(aView.ViewToWidgetOffset()
+                   - aView.GetDimensions().TopLeft() ==
+                   par->ViewToWidgetOffset()
+                   - par->GetDimensions().TopLeft(),
+                   "ViewToWidgetOffset not handled!");
       if (nsnull != cx)
         cx->Translate(ax, ay);
     }
 
   return cx;
 }
 
 NS_IMETHODIMP nsViewManager::DisableRefresh(void)
--- a/view/src/nsViewManager.h
+++ b/view/src/nsViewManager.h
@@ -281,18 +281,19 @@ private:
 
   /**
    * Function to recursively call Update() on all widgets belonging to
    * a view or its kids.
    */
   void UpdateWidgetsForView(nsView* aView);
 
   /**
-   * Transforms a rectangle from specified view's coordinate system to
-   * the first parent that has an attached widget.
+   * Transforms a rectangle from aView's coordinate system to the coordinate
+   * system of the widget attached to aWidgetView, which should be an ancestor
+   * of aView.
    */
   void ViewToWidget(nsView *aView, nsView* aWidgetView, nsRect &aRect) const;
 
   /**
    * Transforms a rectangle from specified view's coordinate system to
    * an absolute coordinate rectangle which can be compared against the
    * rectangle returned by GetVisibleRect to determine visibility.
    * @param aView view that aRect coordinates are specified relative to