From 7c34e3887654e2b3c36f830bcf0fd732d5a09711 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan <robert@ocallahan.org> Date: Tue, 10 Apr 2012 23:24:18 +1200 Subject: [PATCH] Bug 733607. Restructure logic to compute snapped bounds of display items in layer coordinates. Moves responsibility for computing snapped bounds from within the display items to callers of GetBounds/GetOpaqueRegion. r=tnikkel Previously we snapped the results of nsDisplayItem::GetBounds and nsDisplayItem::GetOpaqueRegion internally. By tracking which display items were inside transforms, we disabled snapping quite conservatively whenever an ancestor had a transform, which is undesirable. With this patch, we don't snap inside GetBounds or GetOpaqueRegion, but just return a boolean flag indicating whether the item will draw with snapping or not. This flag is conservative so that "true" means we will snap (if the graphics context has a transform that allows snapping), but "false" means we might or might not snap (so it's always safe to return false). FrameLayerBuilder takes over responsibility for snapping item bounds. When it converts display item bounds to layer pixel coordinates, it checks the snap flag returned from the display item and checks whether the transform when we draw into the layer will be a known scale (the ContainerParameters scale factors) plus integer translation. If both are true, we snap the item bounds when converting to layer pixel coordinates. With this approach, we can snap item bounds even when the items have ancestors with active transforms. --- layout/base/FrameLayerBuilder.cpp | 124 +++++++++------- layout/base/FrameLayerBuilder.h | 11 ++ layout/base/nsDisplayList.cpp | 158 ++++++++++----------- layout/base/nsDisplayList.h | 106 +++++++------- layout/base/nsLayoutDebugger.cpp | 6 +- layout/base/nsLayoutUtils.cpp | 4 - layout/base/nsPresShell.cpp | 3 +- layout/forms/nsButtonFrameRenderer.cpp | 5 +- layout/forms/nsSelectsAreaFrame.cpp | 3 +- layout/generic/TextOverflow.cpp | 3 +- layout/generic/nsBulletFrame.cpp | 6 +- layout/generic/nsCanvasFrame.cpp | 3 +- layout/generic/nsCanvasFrame.h | 25 ++-- layout/generic/nsHTMLCanvasFrame.cpp | 13 +- layout/generic/nsObjectFrame.cpp | 35 +++-- layout/generic/nsObjectFrame.h | 5 +- layout/generic/nsTextFrameThebes.cpp | 6 +- layout/generic/nsVideoFrame.cpp | 3 +- layout/ipc/RenderFrameParent.h | 3 +- layout/mathml/nsMathMLChar.cpp | 6 +- layout/reftests/text-overflow/reftest.list | 2 +- layout/tables/nsTableCellFrame.cpp | 7 +- layout/tables/nsTableFrame.cpp | 3 +- layout/tables/nsTableFrame.h | 2 +- layout/xul/base/src/nsTextBoxFrame.cpp | 5 +- 25 files changed, 301 insertions(+), 246 deletions(-) diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index f55d559734048..0aff68adb64e7 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -145,6 +145,13 @@ public: mNextFreeRecycledThebesLayer(0), mNextFreeRecycledColorLayer(0), mNextFreeRecycledImageLayer(0), mInvalidateAllThebesContent(false) { + nsPresContext* presContext = aContainerFrame->PresContext(); + mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); + // When AllowResidualTranslation is false, display items will be drawn + // scaled with a translation by integer pixels, so we know how the snapping + // will work. + mSnappingEnabled = aManager->IsSnappingEffectiveTransforms() && + !mParameters.AllowResidualTranslation(); CollectOldLayers(); } @@ -176,6 +183,30 @@ public: nsRect GetChildrenBounds() { return mBounds; } + nscoord GetAppUnitsPerDevPixel() { return mAppUnitsPerDevPixel; } + + nsIntRect ScaleToNearestPixels(const nsRect& aRect) + { + return aRect.ScaleToNearestPixels(mParameters.mXScale, mParameters.mYScale, + mAppUnitsPerDevPixel); + } + nsIntRect ScaleToOutsidePixels(const nsRect& aRect, bool aSnap) + { + if (aSnap && mSnappingEnabled) { + return ScaleToNearestPixels(aRect); + } + return aRect.ScaleToOutsidePixels(mParameters.mXScale, mParameters.mYScale, + mAppUnitsPerDevPixel); + } + nsIntRect ScaleToInsidePixels(const nsRect& aRect, bool aSnap) + { + if (aSnap && mSnappingEnabled) { + return ScaleToNearestPixels(aRect); + } + return aRect.ScaleToInsidePixels(mParameters.mXScale, mParameters.mYScale, + mAppUnitsPerDevPixel); + } + protected: /** * We keep a stack of these to represent the ThebesLayers that are @@ -391,7 +422,9 @@ protected: PRUint32 mNextFreeRecycledThebesLayer; PRUint32 mNextFreeRecycledColorLayer; PRUint32 mNextFreeRecycledImageLayer; + nscoord mAppUnitsPerDevPixel; bool mInvalidateAllThebesContent; + bool mSnappingEnabled; }; class ThebesDisplayItemLayerUserData : public LayerUserData @@ -851,11 +884,7 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot) } data->mXScale = mParameters.mXScale; data->mYScale = mParameters.mYScale; - // If we're in a transformed subtree, but no ancestor transform is actively - // changing, we'll use the residual translation when drawing into the - // ThebesLayer to ensure that snapping exactly matches the ideal transform. - layer->SetAllowResidualTranslation( - mParameters.mInTransformedSubtree && !mParameters.mInActiveTransformedSubtree); + layer->SetAllowResidualTranslation(mParameters.AllowResidualTranslation()); mBuilder->LayerBuilder()->SaveLastPaintOffset(layer); @@ -960,10 +989,8 @@ ContainerState::FindOpaqueBackgroundColorFor(PRInt32 aThebesLayerIndex) // The candidate intersects our target. If any layer has a solid-color // area behind our target, this must be it. Scan its display items. - nsPresContext* presContext = mContainerFrame->PresContext(); - nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); nsRect rect = - target->mVisibleRegion.GetBounds().ToAppUnits(appUnitsPerDevPixel); + target->mVisibleRegion.GetBounds().ToAppUnits(mAppUnitsPerDevPixel); rect.ScaleInverseRoundOut(mParameters.mXScale, mParameters.mYScale); return mBuilder->LayerBuilder()-> FindOpaqueColorCovering(mBuilder, candidate->mLayer, rect); @@ -1009,10 +1036,7 @@ ContainerState::PopThebesLayerData() NS_ASSERTION(data->mImageClip.mRoundedClipRects.IsEmpty(), "How did we get rounded clip rects here?"); if (data->mImageClip.mHaveClipRect) { - nsPresContext* presContext = mContainerFrame->PresContext(); - nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); - nsIntRect clip = data->mImageClip.mClipRect.ScaleToNearestPixels( - mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel); + nsIntRect clip = ScaleToNearestPixels(data->mImageClip.mClipRect); imageLayer->IntersectClipRect(clip); } layer = imageLayer; @@ -1178,10 +1202,17 @@ ContainerState::ThebesLayerData::Accumulate(ContainerState* aState, // below) but don't draw anything. They'll return true for isUniform but // a color with opacity 0. if (!isUniform || NS_GET_A(uniformColor) > 0) { - if (isUniform && - aItem->GetBounds(aState->mBuilder).ScaleToInsidePixels( - aState->mParameters.mXScale, aState->mParameters.mYScale, - AppUnitsPerDevPixel(aItem)).Contains(aVisibleRect)) { + // Make sure that the visible area is covered by uniform pixels. In + // particular this excludes cases where the edges of the item are not + // pixel-aligned (thus the item will not be truly uniform). + if (isUniform) { + bool snap; + nsRect bounds = aItem->GetBounds(aState->mBuilder, &snap); + if (!aState->ScaleToInsidePixels(bounds, snap).Contains(aVisibleRect)) { + isUniform = false; + } + } + if (isUniform) { if (mVisibleRegion.IsEmpty()) { // This color is all we have mSolidColor = uniformColor; @@ -1203,20 +1234,20 @@ ContainerState::ThebesLayerData::Accumulate(ContainerState* aState, mDrawRegion.SimplifyOutward(4); } - bool forceTransparentSurface = false; - nsRegion opaque = aItem->GetOpaqueRegion(aState->mBuilder, &forceTransparentSurface); + bool forceTransparentSurface; + bool snap; + nsRegion opaque = aItem->GetOpaqueRegion(aState->mBuilder, &snap, + &forceTransparentSurface); if (!opaque.IsEmpty()) { nsRegionRectIterator iter(opaque); - nscoord appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem); for (const nsRect* r = iter.Next(); r; r = iter.Next()) { // We don't use SimplifyInward here since it's not defined exactly // what it will discard. For our purposes the most important case // is a large opaque background at the bottom of z-order (e.g., // a canvas background), so we need to make sure that the first rect // we see doesn't get discarded. - nsIntRect rect = aClip.ApproximateIntersect(*r).ScaleToInsidePixels( - aState->mParameters.mXScale, aState->mParameters.mYScale, - appUnitsPerDevPixel); + nsIntRect rect = + aState->ScaleToInsidePixels(aClip.ApproximateIntersect(*r), snap); nsIntRegion tmp; tmp.Or(mOpaqueRegion, rect); // Opaque display items in chrome documents whose window is partially @@ -1237,11 +1268,10 @@ ContainerState::ThebesLayerData::Accumulate(ContainerState* aState, aItem->DisableComponentAlpha(); } else { nsRect componentAlpha = aItem->GetComponentAlphaBounds(aState->mBuilder); - componentAlpha.IntersectRect(componentAlpha, aItem->GetVisibleRect()); if (!componentAlpha.IsEmpty()) { - nscoord appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem); - if (!mOpaqueRegion.Contains(componentAlpha.ScaleToOutsidePixels( - aState->mParameters.mXScale, aState->mParameters.mYScale, appUnitsPerDevPixel))) { + nsIntRect componentAlphaRect = + aState->ScaleToOutsidePixels(componentAlpha, false).Intersect(aVisibleRect); + if (!mOpaqueRegion.Contains(componentAlphaRect)) { if (SuppressComponentAlpha(aState->mBuilder, aItem, componentAlpha)) { aItem->DisableComponentAlpha(); } else { @@ -1398,9 +1428,6 @@ void ContainerState::ProcessDisplayItems(const nsDisplayList& aList, FrameLayerBuilder::Clip& aClip) { - PRInt32 appUnitsPerDevPixel = - mContainerFrame->PresContext()->AppUnitsPerDevPixel(); - for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) { nsDisplayItem::Type type = item->GetType(); if (type == nsDisplayItem::TYPE_CLIP || @@ -1410,19 +1437,20 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList, continue; } - NS_ASSERTION(appUnitsPerDevPixel == AppUnitsPerDevPixel(item), + NS_ASSERTION(mAppUnitsPerDevPixel == AppUnitsPerDevPixel(item), "items in a container layer should all have the same app units per dev pixel"); nsIntRect itemVisibleRect = - item->GetVisibleRect().ScaleToOutsidePixels( - mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel); - nsRect itemContent = item->GetBounds(mBuilder); + ScaleToOutsidePixels(item->GetVisibleRect(), false); + bool snap; + nsRect itemContent = item->GetBounds(mBuilder, &snap); if (aClip.mHaveClipRect) { itemContent.IntersectRect(aClip.mClipRect, itemContent); } mBounds.UnionRect(mBounds, itemContent); - nsIntRect itemDrawRect = itemContent.ScaleToOutsidePixels( - mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel); + nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap); + itemVisibleRect.IntersectRect(itemVisibleRect, itemDrawRect); + LayerState layerState = item->GetLayerState(mBuilder, mManager); nsIFrame* activeScrolledRoot = @@ -1481,8 +1509,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList, // It has its own layer. Update that layer's clip and visible rects. if (aClip.mHaveClipRect) { ownLayer->IntersectClipRect( - aClip.NonRoundedIntersection().ScaleToNearestPixels( - mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel)); + ScaleToNearestPixels(aClip.NonRoundedIntersection())); } ThebesLayerData* data = GetTopThebesLayerData(); if (data) { @@ -1542,8 +1569,8 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer) // The bounds might have changed, but we assume that any difference // in the bounds will have been invalidated for all Thebes layers // in the container via regular frame invalidation. - nsRect bounds = aItem->GetBounds(mBuilder); - PRInt32 appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem); + bool snap; + nsRect bounds = aItem->GetBounds(mBuilder, &snap); ThebesLayer* t = oldLayer->AsThebesLayer(); if (t) { @@ -1553,7 +1580,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer) // so it doesn't matter whether we are using the old scale at last paint // or a new scale here InvalidatePostTransformRegion(t, - bounds.ScaleToOutsidePixels(data->mXScale, data->mYScale, appUnitsPerDevPixel), + bounds.ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel), mBuilder->LayerBuilder()->GetLastPaintOffset(t)); } if (aNewLayer) { @@ -1562,14 +1589,11 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer) ThebesDisplayItemLayerUserData* data = static_cast<ThebesDisplayItemLayerUserData*>(newLayer->GetUserData(&gThebesDisplayItemLayerUserData)); InvalidatePostTransformRegion(newLayer, - bounds.ScaleToOutsidePixels(data->mXScale, data->mYScale, appUnitsPerDevPixel), + bounds.ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel), GetTranslationForThebesLayer(newLayer)); } } - NS_ASSERTION(appUnitsPerDevPixel == - mContainerFrame->PresContext()->AppUnitsPerDevPixel(), - "app units per dev pixel should be constant in a container"); mContainerFrame->InvalidateWithFlags( bounds - mBuilder->ToReferenceFrame(mContainerFrame), nsIFrame::INVALIDATE_NO_THEBES_LAYERS | @@ -1860,7 +1884,6 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, containerLayer); ContainerState state(aBuilder, aManager, aContainerFrame, containerLayer, scaleParameters); - nscoord appUnitsPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel(); if (aManager == mRetainingManager) { DisplayItemDataEntry* entry = mNewDisplayItemData.PutEntry(aContainerFrame); @@ -1880,7 +1903,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, invalidThebesContent->MoveBy(offset); state.SetInvalidThebesContent(invalidThebesContent-> ScaleToOutsidePixels(scaleParameters.mXScale, scaleParameters.mYScale, - appUnitsPerDevPixel)); + state.GetAppUnitsPerDevPixel())); // We have to preserve the current contents of invalidThebesContent // because there might be multiple container layers for the same // frame and we need to invalidate the ThebesLayer children of all @@ -1905,15 +1928,13 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, nsRect bounds = state.GetChildrenBounds(); NS_ASSERTION(bounds.IsEqualInterior(aChildren.GetBounds(aBuilder)), "Wrong bounds"); - nsIntRect pixBounds = - bounds.ScaleToOutsidePixels(scaleParameters.mXScale, scaleParameters.mYScale, - appUnitsPerDevPixel); + nsIntRect pixBounds = state.ScaleToOutsidePixels(bounds, false); containerLayer->SetVisibleRegion(pixBounds); // Make sure that rounding the visible region out didn't add any area // we won't paint if (aChildren.IsOpaque() && !aChildren.NeedsTransparentSurface()) { bounds.ScaleRoundIn(scaleParameters.mXScale, scaleParameters.mYScale); - if (bounds.Contains(pixBounds.ToAppUnits(appUnitsPerDevPixel))) { + if (bounds.Contains(pixBounds.ToAppUnits(state.GetAppUnitsPerDevPixel()))) { // Clear CONTENT_COMPONENT_ALPHA flags = Layer::CONTENT_OPAQUE; } @@ -2046,7 +2067,8 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey) #ifdef MOZ_DUMP_PAINTING static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDisplayListBuilder* aBuilder) { - nsRect appUnitBounds = aItem->GetBounds(aBuilder); + bool snap; + nsRect appUnitBounds = aItem->GetBounds(aBuilder, &snap); gfxRect bounds(appUnitBounds.x, appUnitBounds.y, appUnitBounds.width, appUnitBounds.height); bounds.ScaleInverse(aDest->AppUnitsPerDevPixel()); diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 3ada391b5819c..9f2a1be9c5e8f 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -163,6 +163,17 @@ public: bool mInTransformedSubtree; bool mInActiveTransformedSubtree; bool mDisableSubpixelAntialiasingInDescendants; + /** + * When this is false, ThebesLayer coordinates are drawn to with an integer + * translation and the scale in mXScale/mYScale. + */ + bool AllowResidualTranslation() + { + // If we're in a transformed subtree, but no ancestor transform is actively + // changing, we'll use the residual translation when drawing into the + // ThebesLayer to ensure that snapping exactly matches the ideal transform. + return mInTransformedSubtree && !mInActiveTransformedSubtree; + } }; /** * Build a container layer for a display item that contains a child diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 7a139c1bebffb..f3d918dfc83ac 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -88,7 +88,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, mInTransform(false), mSyncDecodeImages(false), mIsPaintingToWindow(false), - mSnappingEnabled(mMode != EVENT_DELIVERY), mHasDisplayPort(false), mHasFixedItems(false) { @@ -415,7 +414,8 @@ nsRect nsDisplayList::GetBounds(nsDisplayListBuilder* aBuilder) const { nsRect bounds; for (nsDisplayItem* i = GetBottom(); i != nsnull; i = i->GetAbove()) { - bounds.UnionRect(bounds, i->GetBounds(aBuilder)); + bool snap; + bounds.UnionRect(bounds, i->GetBounds(aBuilder, &snap)); } return bounds; } @@ -432,7 +432,8 @@ static nsRegion TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder, bool* aTransparentBackground) { - nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, aTransparentBackground); + bool snap; + nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, &snap, aTransparentBackground); if (aBuilder->IsForPluginGeometry()) { // Treat all chrome items as opaque, unless their frames are opacity:0. // Since opacity:0 frames generate an nsDisplayOpacity, that item will @@ -440,7 +441,7 @@ TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder, // effectively ignored, as it should be. nsIFrame* f = aItem->GetUnderlyingFrame(); if (f && f->PresContext()->IsChrome() && f->GetStyleDisplay()->mOpacity != 0.0) { - opaque = aItem->GetBounds(aBuilder); + opaque = aItem->GetBounds(aBuilder, &snap); } } return opaque; @@ -473,6 +474,7 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, const nsRect& aListVisibleBounds, const nsRect& aAllowVisibleRegionExpansion) { + bool snap; #ifdef DEBUG nsRegion r; r.And(*aVisibleRegion, GetBounds(aBuilder)); @@ -507,7 +509,7 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder, continue; } - nsRect bounds = item->GetBounds(aBuilder); + nsRect bounds = item->GetBounds(aBuilder, &snap); nsRegion itemVisible; if (ForceVisiblityForFixedItem(aBuilder, item)) { @@ -742,7 +744,8 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, item = aState->mItemBuffer[i]; aState->mItemBuffer.SetLength(i); - if (aRect.Intersects(item->GetBounds(aBuilder))) { + bool snap; + if (aRect.Intersects(item->GetBounds(aBuilder, &snap))) { nsAutoTArray<nsIFrame*, 16> outFrames; item->HitTest(aBuilder, aRect, aState, &outFrames); @@ -895,7 +898,8 @@ void nsDisplayList::Sort(nsDisplayListBuilder* aBuilder, bool nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion) { - nsRect bounds = GetBounds(aBuilder); + bool snap; + nsRect bounds = GetBounds(aBuilder, &snap); nsRegion itemVisible; if (ForceVisiblityForFixedItem(aBuilder, this)) { @@ -917,26 +921,11 @@ bool nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder, return true; } -// Note that even if the rectangle we draw and snap is smaller than aRect, -// it's OK to call this to get a bounding rect for what we'll draw, because -// snapping a rectangle which is contained in R always gives you a -// rectangle which is contained in the snapped R. -static nsRect -SnapBounds(bool aSnappingEnabled, nsPresContext* aPresContext, - const nsRect& aRect) { - nsRect r = aRect; - if (aSnappingEnabled) { - nscoord appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel(); - r = r.ToNearestPixels(appUnitsPerDevPixel).ToAppUnits(appUnitsPerDevPixel); - } - return r; -} - nsRect -nsDisplaySolidColor::GetBounds(nsDisplayListBuilder* aBuilder) +nsDisplaySolidColor::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { - nsPresContext* presContext = mFrame->PresContext(); - return SnapBounds(mSnappingEnabled, presContext, mBounds); + *aSnap = true; + return mBounds; } void @@ -968,8 +957,7 @@ RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) nsDisplayBackground::nsDisplayBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) - : nsDisplayItem(aBuilder, aFrame), - mSnappingEnabled(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform()) + : nsDisplayItem(aBuilder, aFrame) { MOZ_COUNT_CTOR(nsDisplayBackground); const nsStyleDisplay* disp = mFrame->GetStyleDisplay(); @@ -1126,7 +1114,8 @@ nsDisplayBackground::ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion nsDisplayBackground::GetInsideClipRegion(nsPresContext* aPresContext, - PRUint8 aClip, const nsRect& aRect) + PRUint8 aClip, const nsRect& aRect, + bool* aSnap) { nsRegion result; if (aRect.IsEmpty()) @@ -1153,14 +1142,12 @@ nsDisplayBackground::GetInsideClipRegion(nsPresContext* aPresContext, return result; } - nsRect inputRect = SnapBounds(mSnappingEnabled, aPresContext, aRect); - clipRect = SnapBounds(mSnappingEnabled, aPresContext, clipRect); - if (haveRadii) { - result = nsLayoutUtils::RoundedRectIntersectRect(clipRect, radii, inputRect); + *aSnap = false; + result = nsLayoutUtils::RoundedRectIntersectRect(clipRect, radii, aRect); } else { nsRect r; - r.IntersectRect(clipRect, inputRect); + r.IntersectRect(clipRect, aRect); result = r; } return result; @@ -1168,11 +1155,11 @@ nsDisplayBackground::GetInsideClipRegion(nsPresContext* aPresContext, nsRegion nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, + bool* aSnap, bool* aForceTransparentSurface) { nsRegion result; - if (aForceTransparentSurface) { - *aForceTransparentSurface = false; - } + *aSnap = false; + *aForceTransparentSurface = false; // theme background overrides any other background if (mIsThemed) { if (aForceTransparentSurface) { @@ -1181,7 +1168,7 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, disp->mAppearance == NS_THEME_WIN_GLASS; } if (mThemeTransparency == nsITheme::eOpaque) { - result = GetBounds(aBuilder); + result = GetBounds(aBuilder, aSnap); } return result; } @@ -1193,10 +1180,12 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, const nsStyleBackground* bg = bgSC->GetStyleBackground(); const nsStyleBackground::Layer& bottomLayer = bg->BottomLayer(); + *aSnap = true; + nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize()); if (NS_GET_A(bg->mBackgroundColor) == 255 && !nsCSSRendering::IsCanvasFrame(mFrame)) { - result = GetInsideClipRegion(presContext, bottomLayer.mClip, borderBox); + result = GetInsideClipRegion(presContext, bottomLayer.mClip, borderBox, aSnap); } // For policies other than EACH_BOX, don't try to optimize here, since @@ -1211,7 +1200,7 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, if (layer.mImage.IsOpaque()) { nsRect r = nsCSSRendering::GetBackgroundLayerRect(presContext, mFrame, borderBox, *bg, layer); - result.Or(result, GetInsideClipRegion(presContext, layer.mClip, r)); + result.Or(result, GetInsideClipRegion(presContext, layer.mClip, r, aSnap)); } } } @@ -1310,7 +1299,8 @@ nsDisplayBackground::ShouldFixToViewport(nsDisplayListBuilder* aBuilder) if (nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius)) return false; - nsRect bounds = GetBounds(aBuilder); + bool snap; + nsRect bounds = GetBounds(aBuilder, &snap); nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame(); if (!rootScrollFrame) return false; @@ -1337,7 +1327,7 @@ nsDisplayBackground::Paint(nsDisplayListBuilder* aBuilder, } nsRect -nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder) { +nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { nsRect r(nsPoint(0,0), mFrame->GetSize()); nsPresContext* presContext = mFrame->PresContext(); @@ -1347,11 +1337,13 @@ nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder) { mFrame->GetStyleDisplay()->mAppearance, &r); } - return SnapBounds(mSnappingEnabled, presContext, r + ToReferenceFrame()); + *aSnap = true; + return r + ToReferenceFrame(); } nsRect -nsDisplayOutline::GetBounds(nsDisplayListBuilder* aBuilder) { +nsDisplayOutline::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); } @@ -1450,11 +1442,12 @@ nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder, } nsRect -nsDisplayBorder::GetBounds(nsDisplayListBuilder* aBuilder) +nsDisplayBorder::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { nsRect borderBounds(ToReferenceFrame(), mFrame->GetSize()); borderBounds.Inflate(mFrame->GetStyleBorder()->GetImageOutset()); - return SnapBounds(mSnappingEnabled, mFrame->PresContext(), borderBounds); + *aSnap = true; + return borderBounds; } // Given a region, compute a conservative approximation to it as a list @@ -1507,7 +1500,8 @@ nsDisplayBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder, } nsRect -nsDisplayBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder) { +nsDisplayBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); } @@ -1599,7 +1593,8 @@ nsDisplayWrapList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, } nsRect -nsDisplayWrapList::GetBounds(nsDisplayListBuilder* aBuilder) { +nsDisplayWrapList::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mList.GetBounds(aBuilder); } @@ -1614,13 +1609,13 @@ nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion nsDisplayWrapList::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, + bool* aSnap, bool* aForceTransparentSurface) { - if (aForceTransparentSurface) { - *aForceTransparentSurface = false; - } + *aForceTransparentSurface = false; + *aSnap = false; nsRegion result; if (mList.IsOpaque()) { - result = GetBounds(aBuilder); + result = GetBounds(aBuilder, aSnap); } return result; } @@ -1760,10 +1755,10 @@ nsDisplayOpacity::~nsDisplayOpacity() { #endif nsRegion nsDisplayOpacity::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, + bool* aSnap, bool* aForceTransparentSurface) { - if (aForceTransparentSurface) { - *aForceTransparentSurface = false; - } + *aForceTransparentSurface = false; + *aSnap = false; // We are never opaque, if our opacity was < 1 then we wouldn't have // been created. return nsRegion(); @@ -1820,7 +1815,8 @@ nsDisplayOpacity::ComputeVisibility(nsDisplayListBuilder* aBuilder, // our children in the temporary compositing buffer, because if our children // paint our entire bounds opaquely then we don't need an alpha channel in // the temporary compositing buffer. - nsRect bounds = GetBounds(aBuilder); + bool snap; + nsRect bounds = GetBounds(aBuilder, &snap); nsRegion visibleUnderChildren; visibleUnderChildren.And(*aVisibleRegion, bounds); nsRect allowExpansion; @@ -2095,23 +2091,20 @@ nsDisplayScrollInfoLayer::ShouldFlattenAway(nsDisplayListBuilder* aBuilder) nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayItem* aItem, const nsRect& aRect) - : nsDisplayWrapList(aBuilder, aFrame, aItem) { + : nsDisplayWrapList(aBuilder, aFrame, aItem), mClip(aRect) { MOZ_COUNT_CTOR(nsDisplayClip); - mClip = SnapBounds(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform(), - aBuilder->CurrentPresContext(), aRect); } nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, const nsRect& aRect) - : nsDisplayWrapList(aBuilder, aFrame, aList) { + : nsDisplayWrapList(aBuilder, aFrame, aList), mClip(aRect) { MOZ_COUNT_CTOR(nsDisplayClip); - mClip = SnapBounds(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform(), - aBuilder->CurrentPresContext(), aRect); } -nsRect nsDisplayClip::GetBounds(nsDisplayListBuilder* aBuilder) { - nsRect r = nsDisplayWrapList::GetBounds(aBuilder); +nsRect nsDisplayClip::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + nsRect r = nsDisplayWrapList::GetBounds(aBuilder, aSnap); + *aSnap = true; r.IntersectRect(mClip, r); return r; } @@ -2193,11 +2186,11 @@ nsDisplayClipRoundedRect::~nsDisplayClipRoundedRect() nsRegion nsDisplayClipRoundedRect::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, + bool* aSnap, bool* aForceTransparentSurface) { - if (aForceTransparentSurface) { - *aForceTransparentSurface = false; - } + *aSnap = false; + *aForceTransparentSurface = false; return nsRegion(); } @@ -2267,9 +2260,10 @@ nsDisplayZoom::~nsDisplayZoom() { } #endif -nsRect nsDisplayZoom::GetBounds(nsDisplayListBuilder* aBuilder) +nsRect nsDisplayZoom::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { - nsRect bounds = nsDisplayWrapList::GetBounds(aBuilder); + nsRect bounds = nsDisplayWrapList::GetBounds(aBuilder, aSnap); + *aSnap = false; return bounds.ConvertAppUnitsRoundOut(mAPD, mParentAPD); } @@ -2297,8 +2291,8 @@ void nsDisplayZoom::Paint(nsDisplayListBuilder* aBuilder, } bool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder, - nsRegion *aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion) + nsRegion *aVisibleRegion, + const nsRect& aAllowVisibleRegionExpansion) { // Convert the passed in visible region to our appunits. nsRegion visibleRegion = @@ -2800,12 +2794,13 @@ nsDisplayTransform::GetHitDepthAtPoint(const nsPoint& aPoint) /* The bounding rectangle for the object is the overflow rectangle translated * by the reference point. */ -nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder) +nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap) { nsRect untransformedBounds = ShouldPrerenderTransformedContent(aBuilder, mFrame) ? mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame() : - mStoredList.GetBounds(aBuilder); + mStoredList.GetBounds(aBuilder, aSnap); + *aSnap = false; float factor = nsPresContext::AppUnitsPerCSSPixel(); return nsLayoutUtils::MatrixTransformRect(untransformedBounds, GetTransform(factor), @@ -2829,11 +2824,11 @@ nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder) * certainly contains the actual (non-axis-aligned) untransformed rect. */ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder, + bool* aSnap, bool* aForceTransparentSurface) { - if (aForceTransparentSurface) { - *aForceTransparentSurface = false; - } + *aForceTransparentSurface = false; + *aSnap = false; nsRect untransformedVisible; float factor = nsPresContext::AppUnitsPerCSSPixel(); if (!UntransformRectMatrix(mVisibleRect, GetTransform(factor), factor, &untransformedVisible)) { @@ -2841,12 +2836,15 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder, } const gfx3DMatrix& matrix = GetTransform(nsPresContext::AppUnitsPerCSSPixel()); - + nsRegion result; gfxMatrix matrix2d; + bool tmpSnap; + bool forceTransparentSurface; if (matrix.Is2D(&matrix2d) && matrix2d.PreservesAxisAlignedRectangles() && - mStoredList.GetOpaqueRegion(aBuilder).Contains(untransformedVisible)) { + mStoredList.GetOpaqueRegion(aBuilder, &tmpSnap, &forceTransparentSurface). + Contains(untransformedVisible)) { result = mVisibleRect; } return result; @@ -3007,11 +3005,11 @@ nsDisplaySVGEffects::~nsDisplaySVGEffects() #endif nsRegion nsDisplaySVGEffects::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, + bool* aSnap, bool* aForceTransparentSurface) { - if (aForceTransparentSurface) { - *aForceTransparentSurface = false; - } + *aForceTransparentSurface = false; + *aSnap = false; return nsRegion(); } diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index d65ad3b297b00..307f332f2085a 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -306,16 +306,6 @@ public: void SetHasFixedItems() { mHasFixedItems = true; } bool GetHasFixedItems() { return mHasFixedItems; } - /** - * Returns true if snapping is enabled for the final drawing context. - * The default is true. - */ - bool IsSnappingEnabled() { return mSnappingEnabled; } - /** - * Set if snapping is enabled for the final drawing context. - */ - void SetSnappingEnabled(bool aSnappingEnabled) { mSnappingEnabled = aSnappingEnabled; } - /** * @return true if images have been set to decode synchronously. */ @@ -520,7 +510,6 @@ private: bool mInTransform; bool mSyncDecodeImages; bool mIsPaintingToWindow; - bool mSnappingEnabled; bool mHasDisplayPort; bool mHasFixedItems; }; @@ -646,24 +635,33 @@ public: inline nsIFrame* GetUnderlyingFrame() const { return mFrame; } /** * The default bounds is the frame border rect. + * @param aSnap *aSnap is set to true if the returned rect will be + * snapped to nearest device pixel edges during actual drawing. + * It might be set to false and snap anyway, so code computing the set of + * pixels affected by this display item needs to round outwards to pixel + * boundaries when *aSnap is set to false. * @return a rectangle relative to aBuilder->ReferenceFrame() that * contains the area drawn by this display item */ - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) + { + *aSnap = false; return nsRect(ToReferenceFrame(), GetUnderlyingFrame()->GetSize()); } /** + * @param aSnap set to true if the edges of the rectangles of the opaque + * region would be snapped to device pixels when drawing * @return a region of the item that is opaque --- every pixel painted * with an opaque color. This is useful for determining when one piece * of content completely obscures another so that we can do occlusion * culling. */ virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aForceTransparentSurface = nsnull) + bool* aSnap, + bool* aForceTransparentSurface) { - if (aForceTransparentSurface) { - *aForceTransparentSurface = false; - } + *aSnap = false; + *aForceTransparentSurface = false; return nsRegion(); } /** @@ -1332,8 +1330,10 @@ public: NS_DISPLAY_DECL_NAME(mName, mType) virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) { - if (mType == nsDisplayItem::TYPE_HEADER_FOOTER) - return GetBounds(aBuilder); + if (mType == nsDisplayItem::TYPE_HEADER_FOOTER) { + bool snap; + return GetBounds(aBuilder, &snap); + } return nsRect(); } @@ -1441,7 +1441,8 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; // The caret returns a rect in the coordinates of mFrame. return mCaret->GetCaretRect() + ToReferenceFrame(); } @@ -1457,8 +1458,8 @@ protected: class nsDisplayBorder : public nsDisplayItem { public: nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : - nsDisplayItem(aBuilder, aFrame), - mSnappingEnabled(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform()) { + nsDisplayItem(aBuilder, aFrame) + { MOZ_COUNT_CTOR(nsDisplayBorder); } #ifdef NS_BUILD_REFCNT_LOGGING @@ -1467,15 +1468,12 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, const nsRect& aAllowVisibleRegionExpansion); NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER) - -protected: - bool mSnappingEnabled; }; /** @@ -1493,8 +1491,8 @@ class nsDisplaySolidColor : public nsDisplayItem { public: nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const nsRect& aBounds, nscolor aColor) - : nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor), - mSnappingEnabled(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform()) { + : nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor) + { NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!"); MOZ_COUNT_CTOR(nsDisplaySolidColor); } @@ -1504,16 +1502,16 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aOutTransparentBackground = nsnull) { - if (aOutTransparentBackground) { - *aOutTransparentBackground = false; - } + bool* aSnap, + bool* aOutTransparentBackground) { + *aSnap = false; + *aOutTransparentBackground = false; nsRegion result; if (NS_GET_A(mColor) == 255) { - result = GetBounds(aBuilder); + result = GetBounds(aBuilder, aSnap); } return result; } @@ -1531,7 +1529,6 @@ public: private: nsRect mBounds; nscolor mColor; - bool mSnappingEnabled; }; /** @@ -1552,21 +1549,21 @@ public: nsRegion* aVisibleRegion, const nsRect& aAllowVisibleRegionExpansion); virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aForceTransparentSurface = nsnull); + bool* aSnap, + bool* aForceTransparentSurface); virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame); virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor); virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND) protected: nsRegion GetInsideClipRegion(nsPresContext* aPresContext, PRUint8 aClip, - const nsRect& aRect); + const nsRect& aRect, bool* aSnap); /* Used to cache mFrame->IsThemed() since it isn't a cheap call */ bool mIsThemed; - bool mSnappingEnabled; nsITheme::Transparency mThemeTransparency; }; @@ -1586,7 +1583,7 @@ public: #endif virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, const nsRect& aAllowVisibleRegionExpansion); @@ -1636,7 +1633,7 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, @@ -1694,9 +1691,10 @@ public: virtual ~nsDisplayWrapList(); virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aForceTransparentSurface = nsnull); + bool* aSnap, + bool* aForceTransparentSurface); virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor); virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame); @@ -1781,7 +1779,8 @@ public: #endif virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aForceTransparentSurface = nsnull); + bool* aSnap, + bool* aForceTransparentSurface); virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerParameters& aContainerParameters); @@ -1946,7 +1945,7 @@ public: virtual ~nsDisplayClip(); #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, @@ -1987,7 +1986,8 @@ public: #endif virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aForceTransparentSurface = nsnull); + bool* aSnap, + bool* aForceTransparentSurface); virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames); virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, @@ -2027,7 +2027,7 @@ public: virtual ~nsDisplayZoom(); #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames); @@ -2058,10 +2058,12 @@ public: #endif virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aForceTransparentSurface = nsnull); + bool* aSnap, + bool* aForceTransparentSurface); virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mBounds + aBuilder->ToReferenceFrame(mEffectsFrame); } virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); @@ -2130,16 +2132,18 @@ public: { if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty()) return nsRect(); - return GetBounds(aBuilder); + bool snap; + return GetBounds(aBuilder, &snap); } nsDisplayWrapList* GetStoredList() { return &mStoredList; } virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect, HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames); - virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap); virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder, - bool* aForceTransparentSurface = nsnull); + bool* aSnap, + bool* aForceTransparentSurface); virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor); virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager); diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index df4e25996748a..07fe3ad972cdb 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -170,7 +170,8 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList, f->GetFrameName(fName); } #endif - nsRect rect = i->GetBounds(aBuilder); + bool snap; + nsRect rect = i->GetBounds(aBuilder, &snap); switch (i->GetType()) { case nsDisplayItem::TYPE_CLIP: case nsDisplayItem::TYPE_CLIP_ROUNDED_RECT: { @@ -191,7 +192,8 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList, } #ifdef DEBUG if (!list || list->DidComputeVisibility()) { - opaque = i->GetOpaqueRegion(aBuilder); + bool forceTransparentSurface; + opaque = i->GetOpaqueRegion(aBuilder, &snap, &forceTransparentSurface); } #endif if (i->Painted()) { diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 228d5ced5f1ec..f2c5592153f44 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1607,10 +1607,6 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram if (aFlags & PAINT_IGNORE_SUPPRESSION) { builder.IgnorePaintSuppression(); } - if (aRenderingContext && - aRenderingContext->ThebesContext()->GetFlags() & gfxContext::FLAG_DISABLE_SNAPPING) { - builder.SetSnappingEnabled(false); - } nsRect canvasArea(nsPoint(0, 0), aFrame->GetSize()); #ifdef DEBUG diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 47462f0bc2342..fda916aae9a80 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -4603,7 +4603,8 @@ PresShell::ClipListToRange(nsDisplayListBuilder *aBuilder, nsRange::CompareNodeToRange(content, aRange, &before, &after); if (NS_SUCCEEDED(rv) && !before && !after) { itemToInsert = i; - surfaceRect.UnionRect(surfaceRect, i->GetBounds(aBuilder)); + bool snap; + surfaceRect.UnionRect(surfaceRect, i->GetBounds(aBuilder, &snap)); } } } diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp index 916438376fcc7..c72939fa50520 100644 --- a/layout/forms/nsButtonFrameRenderer.cpp +++ b/layout/forms/nsButtonFrameRenderer.cpp @@ -106,14 +106,15 @@ public: virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); NS_DISPLAY_DECL_NAME("ButtonBoxShadowOuter", TYPE_BUTTON_BOX_SHADOW_OUTER) private: nsButtonFrameRenderer* mBFR; }; nsRect -nsDisplayButtonBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder) { +nsDisplayButtonBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); } diff --git a/layout/forms/nsSelectsAreaFrame.cpp b/layout/forms/nsSelectsAreaFrame.cpp index 10506d92ce78f..e760f6b1a4ee4 100644 --- a/layout/forms/nsSelectsAreaFrame.cpp +++ b/layout/forms/nsSelectsAreaFrame.cpp @@ -149,7 +149,8 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; // override bounds because the list item focus ring may extend outside // the nsSelectsAreaFrame nsListControlFrame* listFrame = GetEnclosingListFrame(GetUnderlyingFrame()); diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index 8b1ee71f3a7aa..d9d9f0d2142fc 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -190,7 +190,8 @@ public: MOZ_COUNT_DTOR(nsDisplayTextOverflowMarker); } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; nsRect shadowRect = nsLayoutUtils::GetTextShadowRectsUnion(mRect, mFrame); return mRect.Union(shadowRect); diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp index 5426c298f0e72..f350fe97cf440 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -213,8 +213,9 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); } virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, @@ -227,7 +228,8 @@ public: virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) { - return GetBounds(aBuilder); + bool snap; + return GetBounds(aBuilder, &snap); } }; diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 45c9b9c714eab..010c38994dae4 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -253,8 +253,9 @@ public: MOZ_COUNT_DTOR(nsDisplayCanvasFocus); } - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; // This is an overestimate, but that's not a problem. nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame); return frame->CanvasArea() + ToReferenceFrame(); diff --git a/layout/generic/nsCanvasFrame.h b/layout/generic/nsCanvasFrame.h index 0aaeee552a38c..00e7aed9af847 100644 --- a/layout/generic/nsCanvasFrame.h +++ b/layout/generic/nsCanvasFrame.h @@ -162,22 +162,23 @@ public: } virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, - nsRegion* aVisibleRegion, - const nsRect& aAllowVisibleRegionExpansion) + nsRegion* aVisibleRegion, + const nsRect& aAllowVisibleRegionExpansion) { return NS_GET_A(mExtraBackgroundColor) > 0 || nsDisplayBackground::ComputeVisibility(aBuilder, aVisibleRegion, aAllowVisibleRegionExpansion); } virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aForceTransparentSurface = nsnull) + bool* aSnap, + bool* aForceTransparentSurface) { - if (aForceTransparentSurface) { + if (NS_GET_A(mExtraBackgroundColor) == 255) { *aForceTransparentSurface = false; + return nsRegion(GetBounds(aBuilder, aSnap)); } - if (NS_GET_A(mExtraBackgroundColor) == 255) - return nsRegion(GetBounds(aBuilder)); - return nsDisplayBackground::GetOpaqueRegion(aBuilder); + return nsDisplayBackground::GetOpaqueRegion(aBuilder, aSnap, + aForceTransparentSurface); } virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { @@ -190,15 +191,11 @@ public: *aColor = mExtraBackgroundColor; return true; } - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame); - nsRect r = frame->CanvasArea() + ToReferenceFrame(); - if (mSnappingEnabled) { - nscoord appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel(); - r = r.ToNearestPixels(appUnitsPerDevPixel).ToAppUnits(appUnitsPerDevPixel); - } - return r; + *aSnap = true; + return frame->CanvasArea() + ToReferenceFrame(); } virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp index b3ccd18749cb2..8c30d86da31de 100644 --- a/layout/generic/nsHTMLCanvasFrame.cpp +++ b/layout/generic/nsHTMLCanvasFrame.cpp @@ -82,20 +82,21 @@ public: NS_DISPLAY_DECL_NAME("nsDisplayCanvas", TYPE_CANVAS) virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aForceTransparentSurface = nsnull) { - if (aForceTransparentSurface) { - *aForceTransparentSurface = false; - } + bool* aSnap, + bool* aForceTransparentSurface) { + *aForceTransparentSurface = false; + *aSnap = false; nsIFrame* f = GetUnderlyingFrame(); nsHTMLCanvasElement *canvas = CanvasElementFromContent(f->GetContent()); nsRegion result; if (canvas->GetIsOpaque()) { - result = GetBounds(aBuilder); + result = GetBounds(aBuilder, aSnap); } return result; } - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; nsHTMLCanvasFrame* f = static_cast<nsHTMLCanvasFrame*>(GetUnderlyingFrame()); return f->GetInnerArea() + ToReferenceFrame(); } diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index 5d6aede911098..7d572a043d070 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -917,7 +917,7 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, const nsRect& aAllowVisibleRegionExpansion); @@ -946,8 +946,9 @@ GetDisplayItemBounds(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, nsIFr } nsRect -nsDisplayPluginReadback::GetBounds(nsDisplayListBuilder* aBuilder) +nsDisplayPluginReadback::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return GetDisplayItemBounds(aBuilder, this, mFrame); } @@ -961,7 +962,8 @@ nsDisplayPluginReadback::ComputeVisibility(nsDisplayListBuilder* aBuilder, return false; nsRect expand; - expand.IntersectRect(aAllowVisibleRegionExpansion, GetBounds(aBuilder)); + bool snap; + expand.IntersectRect(aAllowVisibleRegionExpansion, GetBounds(aBuilder, &snap)); // *Add* our bounds to the visible region so that stuff underneath us is // likely to be made visible, so we can use it for a background! This is // a bit crazy since we normally only subtract from the visible region. @@ -970,8 +972,9 @@ nsDisplayPluginReadback::ComputeVisibility(nsDisplayListBuilder* aBuilder, } nsRect -nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder) +nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return GetDisplayItemBounds(aBuilder, this, mFrame); } @@ -980,7 +983,8 @@ nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame); - f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder)); + bool snap; + f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder, &snap)); } bool @@ -988,18 +992,19 @@ nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion, const nsRect& aAllowVisibleRegionExpansion) { - mVisibleRegion.And(*aVisibleRegion, GetBounds(aBuilder)); + bool snap; + mVisibleRegion.And(*aVisibleRegion, GetBounds(aBuilder, &snap)); return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion, aAllowVisibleRegionExpansion); } nsRegion nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, + bool* aSnap, bool* aForceTransparentSurface) { - if (aForceTransparentSurface) { - *aForceTransparentSurface = false; - } + *aForceTransparentSurface = false; + *aSnap = false; nsRegion result; nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame); if (!aBuilder->IsForPluginGeometry()) { @@ -1018,11 +1023,13 @@ nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, } } } - if (f->IsOpaque() && - (aBuilder->IsForPluginGeometry() || - (f->GetPaintedRect(this) + ToReferenceFrame()).Contains(GetBounds(aBuilder)))) { - // We can treat this as opaque - result = GetBounds(aBuilder); + if (f->IsOpaque()) { + nsRect bounds = GetBounds(aBuilder, aSnap); + if (aBuilder->IsForPluginGeometry() || + (f->GetPaintedRect(this) + ToReferenceFrame()).Contains(bounds)) { + // We can treat this as opaque + result = bounds; + } } return result; } diff --git a/layout/generic/nsObjectFrame.h b/layout/generic/nsObjectFrame.h index c7f1342a2ded8..2ff61630e0fb0 100644 --- a/layout/generic/nsObjectFrame.h +++ b/layout/generic/nsObjectFrame.h @@ -299,9 +299,10 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, - bool* aForceTransparentSurface = nsnull); + bool* aSnap, + bool* aForceTransparentSurface); virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index e3bd79942d045..865be5851dfac 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -4389,7 +4389,8 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); } virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, @@ -4404,7 +4405,8 @@ public: virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) { - return GetBounds(aBuilder); + bool snap; + return GetBounds(aBuilder, &snap); } virtual void DisableComponentAlpha() { mDisableSubpixelAA = true; } diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index a5efc76f32560..447f966d37287 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -345,8 +345,9 @@ public: // away completely (e.g. because of a decoder error). The problem would // be especially acute if we have off-main-thread rendering. - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; nsIFrame* f = GetUnderlyingFrame(); return f->GetContentRect() - f->GetPosition() + ToReferenceFrame(); } diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h index bbccbe0e6f4e5..1c262d5e26795 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -198,8 +198,9 @@ public: , mId(aId) {} - NS_OVERRIDE nsRect GetBounds(nsDisplayListBuilder* aBuilder) + NS_OVERRIDE nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mRect; } diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp index 9de6ecf0600a3..b3b58adfb6869 100644 --- a/layout/mathml/nsMathMLChar.cpp +++ b/layout/mathml/nsMathMLChar.cpp @@ -1909,7 +1909,8 @@ public: } #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; nsRect rect; mChar->GetRect(rect); nsPoint offset = ToReferenceFrame() + rect.TopLeft(); @@ -1930,7 +1931,8 @@ public: virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) { - return GetBounds(aBuilder); + bool snap; + return GetBounds(aBuilder, &snap); } private: diff --git a/layout/reftests/text-overflow/reftest.list b/layout/reftests/text-overflow/reftest.list index c328e0c15aad6..c16de238144be 100644 --- a/layout/reftests/text-overflow/reftest.list +++ b/layout/reftests/text-overflow/reftest.list @@ -7,7 +7,7 @@ HTTP(..) == scroll-rounding.html scroll-rounding-ref.html HTTP(..) == anonymous-block.html anonymous-block-ref.html HTTP(..) == false-marker-overlap.html false-marker-overlap-ref.html HTTP(..) == visibility-hidden.html visibility-hidden-ref.html -fails-if(Android&&layersOpenGL) HTTP(..) == block-padding.html block-padding-ref.html +fails-if(Android) HTTP(..) == block-padding.html block-padding-ref.html HTTP(..) == quirks-decorations.html quirks-decorations-ref.html HTTP(..) == quirks-line-height.html quirks-line-height-ref.html HTTP(..) == standards-decorations.html standards-decorations-ref.html diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index cb57b71f566bd..92e8bea82113e 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -401,7 +401,7 @@ public: } virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); NS_DISPLAY_DECL_NAME("TableCellBackground", TYPE_TABLE_CELL_BACKGROUND) }; @@ -415,11 +415,12 @@ void nsDisplayTableCellBackground::Paint(nsDisplayListBuilder* aBuilder, } nsRect -nsDisplayTableCellBackground::GetBounds(nsDisplayListBuilder* aBuilder) +nsDisplayTableCellBackground::GetBounds(nsDisplayListBuilder* aBuilder, + bool* aSnap) { // revert from nsDisplayTableItem's implementation ... cell backgrounds // don't overflow the cell - return nsDisplayItem::GetBounds(aBuilder); + return nsDisplayItem::GetBounds(aBuilder, aSnap); } static void diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 96d6faa95df70..a2e0cb5b3b4d5 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1062,7 +1062,8 @@ nsTableFrame::GetChildLists(nsTArray<ChildList>* aLists) const } nsRect -nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder) { +nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); } diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 39f1f6fa7551f..778e35686ac32 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -78,7 +78,7 @@ public: // the table part frames, so allow this display element to blow out to our // overflow rect. This is also useful for row frames that have spanning // cells extending outside them. - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); void UpdateForFrameBackground(nsIFrame* aFrame); diff --git a/layout/xul/base/src/nsTextBoxFrame.cpp b/layout/xul/base/src/nsTextBoxFrame.cpp index 0c1fde0da955e..d8115f50145f1 100644 --- a/layout/xul/base/src/nsTextBoxFrame.cpp +++ b/layout/xul/base/src/nsTextBoxFrame.cpp @@ -325,7 +325,7 @@ public: virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder); + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); NS_DISPLAY_DECL_NAME("XULTextBox", TYPE_XUL_TEXT_BOX) virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder); @@ -378,7 +378,8 @@ nsDisplayXULTextBox::PaintTextToContext(nsRenderingContext* aCtx, } nsRect -nsDisplayXULTextBox::GetBounds(nsDisplayListBuilder* aBuilder) { +nsDisplayXULTextBox::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { + *aSnap = false; return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); } -- GitLab