Bug 556052. Compute mViewToWidgetOffset correctly and fix bugs by adding subpixel translation when painting. r=mats

This commit is contained in:
Robert O'Callahan 2010-04-23 12:21:54 +12:00
Родитель 5d682b15be
Коммит 4e63b1f54f
4 изменённых файлов: 35 добавлений и 21 удалений

Просмотреть файл

@ -5655,8 +5655,11 @@ PresShell::Paint(nsIView* aDisplayRoot,
nsPoint offsetToRoot = aViewToPaint->GetOffsetTo(aDisplayRoot);
nsRegion dirtyRegion = aDirtyRegion;
dirtyRegion.MoveBy(offsetToRoot);
nsPoint translate = -offsetToRoot + aViewToPaint->ViewToWidgetOffset();
nsIRenderingContext::AutoPushTranslation
push(rc, -offsetToRoot.x, -offsetToRoot.y);
push(rc, translate.x, translate.y);
nsLayoutUtils::PaintFrame(rc, frame, dirtyRegion, bgcolor);
}
} else {

Просмотреть файл

@ -339,6 +339,24 @@ public:
PRBool IsEffectivelyVisible();
// 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 {
nsIView* parent = reinterpret_cast<nsIView*>(mParent);
if (parent && parent->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
// its parent's.
return parent->ViewToWidgetOffset();
}
return mViewToWidgetOffset;
}
protected:
friend class nsWeakView;
nsViewManager *mViewManager;

Просмотреть файл

@ -347,25 +347,35 @@ nsIntRect nsIView::CalcWidgetBounds(nsWindowType aType)
nsRect viewBounds(mDimBounds);
if (GetParent()) {
// put offset into screen coordinates
nsPoint offset;
nsIWidget* parentWidget = GetParent()->GetNearestWidget(&offset);
// make viewBounds be relative to the parent widget, in appunits
viewBounds += offset;
if (parentWidget && aType == eWindowType_popup &&
IsEffectivelyVisible()) {
// put offset into screen coordinates
nsIntPoint screenPoint = parentWidget->WidgetToScreenOffset();
viewBounds += nsPoint(NSIntPixelsToAppUnits(screenPoint.x, p2a),
NSIntPixelsToAppUnits(screenPoint.y, p2a));
}
}
// Compute widget bounds in device pixels
nsIntRect newBounds = viewBounds.ToNearestPixels(p2a);
// Compute where the top-left of the widget ended up relative to the
// parent widget, in appunits
nsPoint roundedOffset(NSIntPixelsToAppUnits(newBounds.x, p2a),
NSIntPixelsToAppUnits(newBounds.y, p2a));
// mViewToWidgetOffset is added to view coordinates to get widget coordinates
mViewToWidgetOffset = roundedOffset - viewBounds.TopLeft();
// mViewToWidgetOffset is added to coordinates relative to the view origin
// to get coordinates relative to the widget.
// The view origin, relative to the parent widget, is at
// (mPosX,mPosY) - mDimBounds.TopLeft() + viewBounds.TopLeft().
// Our widget, relative to the parent widget, is roundedOffset.
mViewToWidgetOffset = nsPoint(mPosX, mPosY)
- mDimBounds.TopLeft() + viewBounds.TopLeft() - roundedOffset;
return newBounds;
}

Просмотреть файл

@ -178,23 +178,6 @@ public:
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
// its parent's.
return mParent->ViewToWidgetOffset();
}
return mViewToWidgetOffset;
}
protected:
// Do the actual work of ResetWidgetBounds, unconditionally. Don't
// call this method if we have no widget.