mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 539356 - Part 9 - Implement DLBI. r=roc,bz,jwatt
This commit is contained in:
parent
e7b2e75e9a
commit
31125260ee
@ -108,14 +108,6 @@ public:
|
|||||||
nsRefPtr<nsIDocShell> mDocShell;
|
nsRefPtr<nsIDocShell> mDocShell;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void InvalidateFrame(nsIFrame* aFrame, PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
if (!aFrame)
|
|
||||||
return;
|
|
||||||
nsRect rect = nsRect(nsPoint(0, 0), aFrame->GetRect().Size());
|
|
||||||
aFrame->InvalidateWithFlags(rect, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsContentView, nsIContentView)
|
NS_IMPL_ISUPPORTS1(nsContentView, nsIContentView)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -150,13 +142,6 @@ nsContentView::Update(const ViewConfig& aConfig)
|
|||||||
rfp->ContentViewScaleChanged(this);
|
rfp->ContentViewScaleChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX could be clever here and compute a smaller invalidation
|
|
||||||
// rect
|
|
||||||
// NB: we pass INVALIDATE_NO_THEBES_LAYERS here to keep view
|
|
||||||
// semantics the same for both in-process and out-of-process
|
|
||||||
// <browser>. This is just a transform of the layer subtree in
|
|
||||||
// both.
|
|
||||||
InvalidateFrame(mFrameLoader->GetPrimaryFrameOfOwningContent(), nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1745,11 +1730,6 @@ nsFrameLoader::SetRenderMode(PRUint32 aRenderMode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mRenderMode = aRenderMode;
|
mRenderMode = aRenderMode;
|
||||||
// NB: we pass INVALIDATE_NO_THEBES_LAYERS here to keep view
|
|
||||||
// semantics the same for both in-process and out-of-process
|
|
||||||
// <browser>. This is just a transform of the layer subtree in
|
|
||||||
// both.
|
|
||||||
InvalidateFrame(GetPrimaryFrameOfOwningContent(), nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1780,7 +1760,7 @@ nsFrameLoader::SetClipSubdocument(bool aClip)
|
|||||||
mClipSubdocument = aClip;
|
mClipSubdocument = aClip;
|
||||||
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
|
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
|
||||||
if (frame) {
|
if (frame) {
|
||||||
InvalidateFrame(frame, 0);
|
frame->InvalidateFrame();
|
||||||
frame->PresContext()->PresShell()->
|
frame->PresContext()->PresShell()->
|
||||||
FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
|
FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
|
||||||
nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
|
nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
|
||||||
|
@ -1100,7 +1100,7 @@ nsObjectLoadingContent::HasNewFrame(nsIObjectFrame* aFrame)
|
|||||||
|
|
||||||
// Set up new frame to draw.
|
// Set up new frame to draw.
|
||||||
objFrame->FixupWindow(objFrame->GetContentRectRelativeToSelf().Size());
|
objFrame->FixupWindow(objFrame->GetContentRectRelativeToSelf().Size());
|
||||||
objFrame->Invalidate(objFrame->GetContentRectRelativeToSelf());
|
objFrame->InvalidateFrame();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,10 @@ nsRegion
|
|||||||
nsDOMNotifyPaintEvent::GetRegion()
|
nsDOMNotifyPaintEvent::GetRegion()
|
||||||
{
|
{
|
||||||
nsRegion r;
|
nsRegion r;
|
||||||
bool isTrusted = nsContentUtils::IsCallerTrustedForRead();
|
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
for (PRUint32 i = 0; i < mInvalidateRequests.Length(); ++i) {
|
for (PRUint32 i = 0; i < mInvalidateRequests.Length(); ++i) {
|
||||||
if (!isTrusted &&
|
|
||||||
(mInvalidateRequests[i].mFlags & nsIFrame::INVALIDATE_CROSS_DOC))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
r.Or(r, mInvalidateRequests[i].mRect);
|
r.Or(r, mInvalidateRequests[i].mRect);
|
||||||
r.SimplifyOutward(10);
|
r.SimplifyOutward(10);
|
||||||
}
|
}
|
||||||
@ -98,17 +96,15 @@ nsDOMNotifyPaintEvent::GetPaintRequests(nsIDOMPaintRequestList** aResult)
|
|||||||
if (!requests)
|
if (!requests)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
bool isTrusted = nsContentUtils::IsCallerTrustedForRead();
|
if (nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
for (PRUint32 i = 0; i < mInvalidateRequests.Length(); ++i) {
|
for (PRUint32 i = 0; i < mInvalidateRequests.Length(); ++i) {
|
||||||
if (!isTrusted &&
|
nsRefPtr<nsPaintRequest> r = new nsPaintRequest();
|
||||||
(mInvalidateRequests[i].mFlags & nsIFrame::INVALIDATE_CROSS_DOC))
|
if (!r)
|
||||||
continue;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
nsRefPtr<nsPaintRequest> r = new nsPaintRequest();
|
r->SetRequest(mInvalidateRequests[i]);
|
||||||
if (!r)
|
requests->Append(r);
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
}
|
||||||
r->SetRequest(mInvalidateRequests[i]);
|
|
||||||
requests->Append(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
requests.forget(aResult);
|
requests.forget(aResult);
|
||||||
|
@ -35,17 +35,7 @@ nsPaintRequest::GetClientRect(nsIDOMClientRect** aResult)
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsPaintRequest::GetReason(nsAString& aResult)
|
nsPaintRequest::GetReason(nsAString& aResult)
|
||||||
{
|
{
|
||||||
switch (mRequest.mFlags & nsIFrame::INVALIDATE_REASON_MASK) {
|
aResult.AssignLiteral("repaint");
|
||||||
case nsIFrame::INVALIDATE_REASON_SCROLL_BLIT:
|
|
||||||
aResult.AssignLiteral("scroll copy");
|
|
||||||
break;
|
|
||||||
case nsIFrame::INVALIDATE_REASON_SCROLL_REPAINT:
|
|
||||||
aResult.AssignLiteral("scroll repaint");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
aResult.Truncate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,32 +650,22 @@ nsHTMLCanvasElement::InvalidateCanvasContent(const gfxRect* damageRect)
|
|||||||
|
|
||||||
frame->MarkLayersActive(nsChangeHint(0));
|
frame->MarkLayersActive(nsChangeHint(0));
|
||||||
|
|
||||||
nsRect invalRect;
|
Layer* layer;
|
||||||
nsRect contentArea = frame->GetContentRect();
|
|
||||||
if (damageRect) {
|
if (damageRect) {
|
||||||
nsIntSize size = GetWidthHeight();
|
nsIntSize size = GetWidthHeight();
|
||||||
if (size.width != 0 && size.height != 0) {
|
if (size.width != 0 && size.height != 0) {
|
||||||
|
|
||||||
// damageRect and size are in CSS pixels; contentArea is in appunits
|
|
||||||
// We want a rect in appunits; so avoid doing pixels-to-appunits and
|
|
||||||
// vice versa conversion here.
|
|
||||||
gfxRect realRect(*damageRect);
|
gfxRect realRect(*damageRect);
|
||||||
realRect.Scale(contentArea.width / gfxFloat(size.width),
|
|
||||||
contentArea.height / gfxFloat(size.height));
|
|
||||||
realRect.RoundOut();
|
realRect.RoundOut();
|
||||||
|
|
||||||
// then make it a nsRect
|
nsIntRect invalRect(realRect.X(), realRect.Y(),
|
||||||
invalRect = nsRect(realRect.X(), realRect.Y(),
|
realRect.Width(), realRect.Height());
|
||||||
realRect.Width(), realRect.Height());
|
layer = frame->InvalidateLayer(nsDisplayItem::TYPE_CANVAS, &invalRect);
|
||||||
|
|
||||||
invalRect = invalRect.Intersect(nsRect(nsPoint(0,0), contentArea.Size()));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
invalRect = nsRect(nsPoint(0, 0), contentArea.Size());
|
layer = frame->InvalidateLayer(nsDisplayItem::TYPE_CANVAS);
|
||||||
}
|
}
|
||||||
invalRect.MoveBy(contentArea.TopLeft() - frame->GetPosition());
|
|
||||||
|
|
||||||
Layer* layer = frame->InvalidateLayer(invalRect, nsDisplayItem::TYPE_CANVAS);
|
|
||||||
if (layer) {
|
if (layer) {
|
||||||
static_cast<CanvasLayer*>(layer)->Updated();
|
static_cast<CanvasLayer*>(layer)->Updated();
|
||||||
}
|
}
|
||||||
@ -703,7 +693,7 @@ nsHTMLCanvasElement::InvalidateCanvas()
|
|||||||
if (!frame)
|
if (!frame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
frame->Invalidate(frame->GetContentRect() - frame->GetPosition());
|
frame->InvalidateFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
PRInt32
|
PRInt32
|
||||||
|
@ -79,11 +79,10 @@ void VideoFrameContainer::Invalidate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (frame) {
|
if (frame) {
|
||||||
nsRect contentRect = frame->GetContentRect() - frame->GetPosition();
|
|
||||||
if (invalidateFrame) {
|
if (invalidateFrame) {
|
||||||
frame->Invalidate(contentRect);
|
frame->InvalidateFrame();
|
||||||
} else {
|
} else {
|
||||||
frame->InvalidateLayer(contentRect, nsDisplayItem::TYPE_VIDEO);
|
frame->InvalidateLayer(nsDisplayItem::TYPE_VIDEO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,12 +206,10 @@ nsDOMWindowUtils::Redraw(PRUint32 aCount, PRUint32 *aDurationOut)
|
|||||||
nsIFrame *rootFrame = presShell->GetRootFrame();
|
nsIFrame *rootFrame = presShell->GetRootFrame();
|
||||||
|
|
||||||
if (rootFrame) {
|
if (rootFrame) {
|
||||||
nsRect r(nsPoint(0, 0), rootFrame->GetSize());
|
|
||||||
|
|
||||||
PRIntervalTime iStart = PR_IntervalNow();
|
PRIntervalTime iStart = PR_IntervalNow();
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < aCount; i++)
|
for (PRUint32 i = 0; i < aCount; i++)
|
||||||
rootFrame->InvalidateWithFlags(r, nsIFrame::INVALIDATE_IMMEDIATE);
|
rootFrame->InvalidateFrame();
|
||||||
|
|
||||||
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
|
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
|
||||||
XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
|
XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
|
||||||
@ -356,14 +354,7 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
|
|||||||
|
|
||||||
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
|
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
|
||||||
if (rootFrame) {
|
if (rootFrame) {
|
||||||
nsIContent* rootContent =
|
rootFrame->InvalidateFrame();
|
||||||
rootScrollFrame ? rootScrollFrame->GetContent() : nsnull;
|
|
||||||
nsRect rootDisplayport;
|
|
||||||
bool usingDisplayport = rootContent &&
|
|
||||||
nsLayoutUtils::GetDisplayPort(rootContent, &rootDisplayport);
|
|
||||||
rootFrame->InvalidateWithFlags(
|
|
||||||
usingDisplayport ? rootDisplayport : rootFrame->GetVisualOverflowRect(),
|
|
||||||
nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
|
|
||||||
|
|
||||||
// If we are hiding something that is a display root then send empty paint
|
// If we are hiding something that is a display root then send empty paint
|
||||||
// transaction in order to release retained layers because it won't get
|
// transaction in order to release retained layers because it won't get
|
||||||
|
@ -633,23 +633,11 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsPresContext* presContext = mObjectFrame->PresContext();
|
nsIntRect rect(invalidRect->left,
|
||||||
nsRect rect(presContext->DevPixelsToAppUnits(invalidRect->left),
|
invalidRect->top,
|
||||||
presContext->DevPixelsToAppUnits(invalidRect->top),
|
invalidRect->right - invalidRect->left,
|
||||||
presContext->DevPixelsToAppUnits(invalidRect->right - invalidRect->left),
|
invalidRect->bottom - invalidRect->top);
|
||||||
presContext->DevPixelsToAppUnits(invalidRect->bottom - invalidRect->top));
|
mObjectFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN, &rect);
|
||||||
if (container) {
|
|
||||||
gfxIntSize newSize = container->GetCurrentSize();
|
|
||||||
if (newSize != oldSize) {
|
|
||||||
// The image size has changed - invalidate the old area too, bug 635405.
|
|
||||||
nsRect oldRect = nsRect(0, 0,
|
|
||||||
presContext->DevPixelsToAppUnits(oldSize.width),
|
|
||||||
presContext->DevPixelsToAppUnits(oldSize.height));
|
|
||||||
rect.UnionRect(rect, oldRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rect.MoveBy(mObjectFrame->GetContentRectRelativeToSelf().TopLeft());
|
|
||||||
mObjectFrame->InvalidateLayer(rect, nsDisplayItem::TYPE_PLUGIN);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -662,7 +650,7 @@ NS_IMETHODIMP
|
|||||||
nsPluginInstanceOwner::RedrawPlugin()
|
nsPluginInstanceOwner::RedrawPlugin()
|
||||||
{
|
{
|
||||||
if (mObjectFrame) {
|
if (mObjectFrame) {
|
||||||
mObjectFrame->InvalidateLayer(mObjectFrame->GetContentRectRelativeToSelf(), nsDisplayItem::TYPE_PLUGIN);
|
mObjectFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -3768,7 +3756,7 @@ void nsPluginInstanceOwner::SetFrame(nsObjectFrame *aFrame)
|
|||||||
mObjectFrame->PrepForDrawing(mWidget);
|
mObjectFrame->PrepForDrawing(mWidget);
|
||||||
}
|
}
|
||||||
mObjectFrame->FixupWindow(mObjectFrame->GetContentRectRelativeToSelf().Size());
|
mObjectFrame->FixupWindow(mObjectFrame->GetContentRectRelativeToSelf().Size());
|
||||||
mObjectFrame->Invalidate(mObjectFrame->GetContentRectRelativeToSelf());
|
mObjectFrame->InvalidateFrame();
|
||||||
|
|
||||||
// Scroll position listening is only required for Carbon event model plugins on Mac OS X.
|
// Scroll position listening is only required for Carbon event model plugins on Mac OS X.
|
||||||
#if defined(XP_MACOSX) && !defined(NP_NO_QUICKDRAW)
|
#if defined(XP_MACOSX) && !defined(NP_NO_QUICKDRAW)
|
||||||
|
@ -606,9 +606,10 @@ public:
|
|||||||
mScaleMode = aMode;
|
mScaleMode = aMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ImageContainer* GetContainer() { return mContainer; }
|
ImageContainer* GetContainer() { return mContainer; }
|
||||||
gfxPattern::GraphicsFilter GetFilter() { return mFilter; }
|
gfxPattern::GraphicsFilter GetFilter() { return mFilter; }
|
||||||
|
const gfxIntSize& GetScaleToSize() { return mScaleToSize; }
|
||||||
|
ScaleMode GetScaleMode() { return mScaleMode; }
|
||||||
|
|
||||||
MOZ_LAYER_DECL_NAME("ImageLayer", TYPE_IMAGE)
|
MOZ_LAYER_DECL_NAME("ImageLayer", TYPE_IMAGE)
|
||||||
|
|
||||||
|
331
gfx/layers/LayerTreeInvalidation.cpp
Normal file
331
gfx/layers/LayerTreeInvalidation.cpp
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
/*-*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "LayerTreeInvalidation.h"
|
||||||
|
#include "gfxUtils.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace layers {
|
||||||
|
|
||||||
|
struct LayerPropertiesBase;
|
||||||
|
LayerPropertiesBase* CloneLayerTreePropertiesInternal(Layer* aRoot);
|
||||||
|
|
||||||
|
static nsIntRect
|
||||||
|
TransformRect(const nsIntRect& aRect, const gfx3DMatrix& aTransform)
|
||||||
|
{
|
||||||
|
if (aRect.IsEmpty()) {
|
||||||
|
return nsIntRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxRect rect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||||
|
rect = aTransform.TransformBounds(rect);
|
||||||
|
rect.RoundOut();
|
||||||
|
|
||||||
|
nsIntRect intRect;
|
||||||
|
if (!gfxUtils::GfxRectToIntRect(rect, &intRect)) {
|
||||||
|
return nsIntRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return intRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Walks over this layer, and all descendant layers.
|
||||||
|
* If any of these are a ContainerLayer that reports invalidations to a PresShell,
|
||||||
|
* then report that the entire bounds have changed.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
NotifySubdocumentInvalidationRecursive(Layer* aLayer, NotifySubDocInvalidationFunc aCallback)
|
||||||
|
{
|
||||||
|
aLayer->ClearInvalidRect();
|
||||||
|
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||||
|
|
||||||
|
if (aLayer->GetMaskLayer()) {
|
||||||
|
NotifySubdocumentInvalidationRecursive(aLayer->GetMaskLayer(), aCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||||
|
NotifySubdocumentInvalidationRecursive(child, aCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
aCallback(container, container->GetVisibleRegion());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LayerPropertiesBase : public LayerProperties
|
||||||
|
{
|
||||||
|
LayerPropertiesBase(Layer* aLayer)
|
||||||
|
: mLayer(aLayer)
|
||||||
|
, mMaskLayer(nsnull)
|
||||||
|
, mVisibleBounds(aLayer->GetVisibleRegion().GetBounds())
|
||||||
|
, mTransform(aLayer->GetTransform())
|
||||||
|
, mOpacity(aLayer->GetOpacity())
|
||||||
|
, mUseClipRect(!!aLayer->GetClipRect())
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(LayerPropertiesBase);
|
||||||
|
if (aLayer->GetMaskLayer()) {
|
||||||
|
mMaskLayer = CloneLayerTreePropertiesInternal(aLayer->GetMaskLayer());
|
||||||
|
}
|
||||||
|
if (mUseClipRect) {
|
||||||
|
mClipRect = *aLayer->GetClipRect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LayerPropertiesBase()
|
||||||
|
: mLayer(nsnull)
|
||||||
|
, mMaskLayer(nsnull)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(LayerPropertiesBase);
|
||||||
|
}
|
||||||
|
~LayerPropertiesBase()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(LayerPropertiesBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual nsIntRect ComputeDifferences(Layer* aRoot,
|
||||||
|
NotifySubDocInvalidationFunc aCallback);
|
||||||
|
|
||||||
|
nsIntRect ComputeChange(NotifySubDocInvalidationFunc aCallback)
|
||||||
|
{
|
||||||
|
bool transformChanged = mTransform != mLayer->GetTransform();
|
||||||
|
Layer* otherMask = mLayer->GetMaskLayer();
|
||||||
|
const nsIntRect* otherClip = mLayer->GetClipRect();
|
||||||
|
nsIntRect result;
|
||||||
|
if ((mMaskLayer ? mMaskLayer->mLayer : nsnull) != otherMask ||
|
||||||
|
(mUseClipRect != !!otherClip) ||
|
||||||
|
mLayer->GetOpacity() != mOpacity ||
|
||||||
|
transformChanged)
|
||||||
|
{
|
||||||
|
result = OldTransformedBounds();
|
||||||
|
if (transformChanged) {
|
||||||
|
result = result.Union(NewTransformedBounds());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't have to generate invalidations separately for child
|
||||||
|
// layers then we can just stop here since we've already invalidated the entire
|
||||||
|
// old and new bounds.
|
||||||
|
if (!aCallback) {
|
||||||
|
ClearInvalidations(mLayer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = result.Union(ComputeChangeInternal(aCallback));
|
||||||
|
result = result.Union(TransformRect(mLayer->GetInvalidRect(), mTransform));
|
||||||
|
|
||||||
|
if (mMaskLayer && otherMask) {
|
||||||
|
nsIntRect maskDiff = mMaskLayer->ComputeChange(aCallback);
|
||||||
|
result = result.Union(TransformRect(maskDiff, mTransform));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mUseClipRect && otherClip) {
|
||||||
|
if (!mClipRect.IsEqualInterior(*otherClip)) {
|
||||||
|
nsIntRegion tmp;
|
||||||
|
tmp.Xor(mClipRect, *otherClip);
|
||||||
|
result = result.Union(tmp.GetBounds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mLayer->ClearInvalidRect();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntRect NewTransformedBounds()
|
||||||
|
{
|
||||||
|
return TransformRect(mLayer->GetVisibleRegion().GetBounds(), mLayer->GetTransform());
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntRect OldTransformedBounds()
|
||||||
|
{
|
||||||
|
return TransformRect(mVisibleBounds, mTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual nsIntRect ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback) { return nsIntRect(); }
|
||||||
|
|
||||||
|
Layer* mLayer;
|
||||||
|
nsAutoPtr<LayerPropertiesBase> mMaskLayer;
|
||||||
|
nsIntRect mVisibleBounds;
|
||||||
|
gfx3DMatrix mTransform;
|
||||||
|
float mOpacity;
|
||||||
|
nsIntRect mClipRect;
|
||||||
|
bool mUseClipRect;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ContainerLayerProperties : public LayerPropertiesBase
|
||||||
|
{
|
||||||
|
ContainerLayerProperties(ContainerLayer* aLayer)
|
||||||
|
: LayerPropertiesBase(aLayer)
|
||||||
|
{
|
||||||
|
for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||||
|
mChildren.AppendElement(CloneLayerTreePropertiesInternal(child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual nsIntRect ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback)
|
||||||
|
{
|
||||||
|
ContainerLayer* container = mLayer->AsContainerLayer();
|
||||||
|
nsIntRegion result;
|
||||||
|
|
||||||
|
PRUint32 i = 0;
|
||||||
|
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||||
|
if (i >= mChildren.Length() || child != mChildren[i]->mLayer) {
|
||||||
|
// Child change. Invalidate the full areas.
|
||||||
|
// TODO: We could be smarter here if non-overlapping children
|
||||||
|
// swap order.
|
||||||
|
result.Or(result, TransformRect(child->GetVisibleRegion().GetBounds(), child->GetTransform()));
|
||||||
|
if (i < mChildren.Length()) {
|
||||||
|
result.Or(result, mChildren[i]->OldTransformedBounds());
|
||||||
|
}
|
||||||
|
if (aCallback) {
|
||||||
|
NotifySubdocumentInvalidationRecursive(child, aCallback);
|
||||||
|
} else {
|
||||||
|
ClearInvalidations(child);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Same child, check for differences within the child
|
||||||
|
result.Or(result, mChildren[i]->ComputeChange(aCallback));
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process remaining removed children.
|
||||||
|
while (i < mChildren.Length()) {
|
||||||
|
result.Or(result, mChildren[i]->OldTransformedBounds());
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aCallback) {
|
||||||
|
aCallback(container, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TransformRect(result.GetBounds(), mLayer->GetTransform());
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoTArray<nsAutoPtr<LayerPropertiesBase>,1> mChildren;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ColorLayerProperties : public LayerPropertiesBase
|
||||||
|
{
|
||||||
|
ColorLayerProperties(ColorLayer *aLayer)
|
||||||
|
: LayerPropertiesBase(aLayer)
|
||||||
|
, mColor(aLayer->GetColor())
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual nsIntRect ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback)
|
||||||
|
{
|
||||||
|
ColorLayer* color = static_cast<ColorLayer*>(mLayer);
|
||||||
|
|
||||||
|
if (mColor != color->GetColor()) {
|
||||||
|
return NewTransformedBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsIntRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxRGBA mColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImageLayerProperties : public LayerPropertiesBase
|
||||||
|
{
|
||||||
|
ImageLayerProperties(ImageLayer* aImage)
|
||||||
|
: LayerPropertiesBase(aImage)
|
||||||
|
, mVisibleRegion(aImage->GetVisibleRegion())
|
||||||
|
, mContainer(aImage->GetContainer())
|
||||||
|
, mFilter(aImage->GetFilter())
|
||||||
|
, mScaleToSize(aImage->GetScaleToSize())
|
||||||
|
, mScaleMode(aImage->GetScaleMode())
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual nsIntRect ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback)
|
||||||
|
{
|
||||||
|
ImageLayer* image = static_cast<ImageLayer*>(mLayer);
|
||||||
|
|
||||||
|
if (!image->GetVisibleRegion().IsEqual(mVisibleRegion)) {
|
||||||
|
nsIntRect result = NewTransformedBounds();
|
||||||
|
result = result.Union(OldTransformedBounds());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mContainer != image->GetContainer() ||
|
||||||
|
mFilter != image->GetFilter() ||
|
||||||
|
mScaleToSize != image->GetScaleToSize() ||
|
||||||
|
mScaleMode != image->GetScaleMode()) {
|
||||||
|
return NewTransformedBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsIntRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntRegion mVisibleRegion;
|
||||||
|
nsRefPtr<ImageContainer> mContainer;
|
||||||
|
gfxPattern::GraphicsFilter mFilter;
|
||||||
|
gfxIntSize mScaleToSize;
|
||||||
|
ImageLayer::ScaleMode mScaleMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
LayerPropertiesBase*
|
||||||
|
CloneLayerTreePropertiesInternal(Layer* aRoot)
|
||||||
|
{
|
||||||
|
if (!aRoot) {
|
||||||
|
return new LayerPropertiesBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (aRoot->GetType()) {
|
||||||
|
case Layer::TYPE_CONTAINER: return new ContainerLayerProperties(aRoot->AsContainerLayer());
|
||||||
|
case Layer::TYPE_COLOR: return new ColorLayerProperties(static_cast<ColorLayer*>(aRoot));
|
||||||
|
case Layer::TYPE_IMAGE: return new ImageLayerProperties(static_cast<ImageLayer*>(aRoot));
|
||||||
|
default: return new LayerPropertiesBase(aRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ LayerProperties*
|
||||||
|
LayerProperties::CloneFrom(Layer* aRoot)
|
||||||
|
{
|
||||||
|
return CloneLayerTreePropertiesInternal(aRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
LayerProperties::ClearInvalidations(Layer *aLayer)
|
||||||
|
{
|
||||||
|
aLayer->ClearInvalidRect();
|
||||||
|
if (aLayer->GetMaskLayer()) {
|
||||||
|
ClearInvalidations(aLayer->GetMaskLayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||||
|
if (!container) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||||
|
ClearInvalidations(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntRect
|
||||||
|
LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFunc aCallback)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aRoot, "Must have a layer tree to compare against!");
|
||||||
|
if (mLayer != aRoot) {
|
||||||
|
if (aCallback) {
|
||||||
|
NotifySubdocumentInvalidationRecursive(aRoot, aCallback);
|
||||||
|
} else {
|
||||||
|
ClearInvalidations(aRoot);
|
||||||
|
}
|
||||||
|
nsIntRect result = TransformRect(aRoot->GetVisibleRegion().GetBounds(), aRoot->GetTransform());
|
||||||
|
result = result.Union(OldTransformedBounds());
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return ComputeChange(aCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace layers
|
||||||
|
} // namespace mozilla
|
64
gfx/layers/LayerTreeInvalidation.h
Normal file
64
gfx/layers/LayerTreeInvalidation.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*-*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef GFX_LAYER_TREE_INVALIDATION_H
|
||||||
|
#define GFX_LAYER_TREE_INVALIDATION_H
|
||||||
|
|
||||||
|
#include "Layers.h"
|
||||||
|
|
||||||
|
class nsPresContext;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace layers {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for ContainerLayer invalidations.
|
||||||
|
*
|
||||||
|
* @param aContainer ContainerLayer being invalidated.
|
||||||
|
* @param aRegion Invalidated region in the ContainerLayer's coordinate
|
||||||
|
* space.
|
||||||
|
*/
|
||||||
|
typedef void (*NotifySubDocInvalidationFunc)(ContainerLayer* aLayer,
|
||||||
|
const nsIntRegion& aRegion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of cached layer properties (including those of child layers),
|
||||||
|
* used for comparing differences in layer trees.
|
||||||
|
*/
|
||||||
|
struct LayerProperties
|
||||||
|
{
|
||||||
|
virtual ~LayerProperties() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the current layer tree properties into
|
||||||
|
* a new LayerProperties object.
|
||||||
|
*
|
||||||
|
* @param Layer tree to copy, or nsnull if we have no
|
||||||
|
* initial layer tree.
|
||||||
|
*/
|
||||||
|
static LayerProperties* CloneFrom(Layer* aRoot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all invalidation status from this layer tree.
|
||||||
|
*/
|
||||||
|
static void ClearInvalidations(Layer* aRoot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares a set of existing layer tree properties to the current layer
|
||||||
|
* tree and generates the changed rectangle.
|
||||||
|
*
|
||||||
|
* @param aRoot Root layer of the layer tree to compare against.
|
||||||
|
* @param aCallback If specified, callback to call when ContainerLayers
|
||||||
|
* are invalidated.
|
||||||
|
* @return Painted area changed by the layer tree changes.
|
||||||
|
*/
|
||||||
|
virtual nsIntRect ComputeDifferences(Layer* aRoot,
|
||||||
|
NotifySubDocInvalidationFunc aCallback) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace layers
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif /* GFX_LAYER_TREE_INVALIDATON_H */
|
@ -912,6 +912,29 @@ public:
|
|||||||
|
|
||||||
static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); }
|
static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current area of the layer (in layer-space coordinates)
|
||||||
|
* marked as needed to be recomposited.
|
||||||
|
*/
|
||||||
|
const nsIntRect& GetInvalidRect() { return mInvalidRect; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the entirety of the layer's visible region as being invalid.
|
||||||
|
*/
|
||||||
|
void SetInvalidRectToVisibleRegion() { mInvalidRect = GetVisibleRegion().GetBounds(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds to the current invalid rect.
|
||||||
|
*/
|
||||||
|
void AddInvalidRect(const nsIntRect& aRect) { mInvalidRect = mInvalidRect.Union(aRect); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the invalid rect, marking the layer as being identical to what is currently
|
||||||
|
* composited.
|
||||||
|
*/
|
||||||
|
void ClearInvalidRect() { mInvalidRect.SetEmpty(); }
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void SetDebugColorIndex(PRUint32 aIndex) { mDebugColorIndex = aIndex; }
|
void SetDebugColorIndex(PRUint32 aIndex) { mDebugColorIndex = aIndex; }
|
||||||
PRUint32 GetDebugColorIndex() { return mDebugColorIndex; }
|
PRUint32 GetDebugColorIndex() { return mDebugColorIndex; }
|
||||||
@ -976,6 +999,7 @@ protected:
|
|||||||
float mOpacity;
|
float mOpacity;
|
||||||
nsIntRect mClipRect;
|
nsIntRect mClipRect;
|
||||||
nsIntRect mTileSourceRect;
|
nsIntRect mTileSourceRect;
|
||||||
|
nsIntRect mInvalidRect;
|
||||||
PRUint32 mContentFlags;
|
PRUint32 mContentFlags;
|
||||||
bool mUseClipRect;
|
bool mUseClipRect;
|
||||||
bool mUseTileSourceRect;
|
bool mUseTileSourceRect;
|
||||||
@ -1298,7 +1322,7 @@ public:
|
|||||||
* Notify this CanvasLayer that the canvas surface contents have
|
* Notify this CanvasLayer that the canvas surface contents have
|
||||||
* changed (or will change) before the next transaction.
|
* changed (or will change) before the next transaction.
|
||||||
*/
|
*/
|
||||||
void Updated() { mDirty = true; }
|
void Updated() { mDirty = true; SetInvalidRectToVisibleRegion(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a callback to be called at the end of each transaction.
|
* Register a callback to be called at the end of each transaction.
|
||||||
|
@ -38,6 +38,7 @@ EXPORTS = \
|
|||||||
LayerManagerOGLProgram.h \
|
LayerManagerOGLProgram.h \
|
||||||
ReadbackLayer.h \
|
ReadbackLayer.h \
|
||||||
LayerSorter.h \
|
LayerSorter.h \
|
||||||
|
LayerTreeInvalidation.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
@ -65,6 +66,7 @@ CPPSRCS = \
|
|||||||
ReusableTileStoreOGL.cpp \
|
ReusableTileStoreOGL.cpp \
|
||||||
LayerManagerOGLProgram.cpp \
|
LayerManagerOGLProgram.cpp \
|
||||||
LayerSorter.cpp \
|
LayerSorter.cpp \
|
||||||
|
LayerTreeInvalidation.cpp \
|
||||||
ImageLayers.cpp \
|
ImageLayers.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
NS_ASSERTION(BasicManager()->InConstruction(),
|
NS_ASSERTION(BasicManager()->InConstruction(),
|
||||||
"Can only set properties in construction phase");
|
"Can only set properties in construction phase");
|
||||||
mValidRegion.Sub(mValidRegion, aRegion);
|
mValidRegion.Sub(mValidRegion, aRegion);
|
||||||
|
AddInvalidRect(aRegion.GetBounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PaintThebes(gfxContext* aContext,
|
virtual void PaintThebes(gfxContext* aContext,
|
||||||
|
@ -168,7 +168,9 @@ public:
|
|||||||
// Thebes Layer
|
// Thebes Layer
|
||||||
virtual Layer* AsLayer() { return this; }
|
virtual Layer* AsLayer() { return this; }
|
||||||
virtual void InvalidateRegion(const nsIntRegion& aRegion) {
|
virtual void InvalidateRegion(const nsIntRegion& aRegion) {
|
||||||
mValidRegion.Sub(mValidRegion, aRegion);
|
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
||||||
|
mInvalidRegion.SimplifyOutward(10);
|
||||||
|
mValidRegion.Sub(mValidRegion, mInvalidRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasicImplData
|
// BasicImplData
|
||||||
|
@ -54,6 +54,7 @@ void
|
|||||||
ThebesLayerD3D10::InvalidateRegion(const nsIntRegion &aRegion)
|
ThebesLayerD3D10::InvalidateRegion(const nsIntRegion &aRegion)
|
||||||
{
|
{
|
||||||
mValidRegion.Sub(mValidRegion, aRegion);
|
mValidRegion.Sub(mValidRegion, aRegion);
|
||||||
|
AddInvalidRect(aRegion.GetBounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThebesLayerD3D10::CopyRegion(ID3D10Texture2D* aSrc, const nsIntPoint &aSrcOffset,
|
void ThebesLayerD3D10::CopyRegion(ID3D10Texture2D* aSrc, const nsIntPoint &aSrcOffset,
|
||||||
|
@ -48,6 +48,7 @@ void
|
|||||||
ThebesLayerD3D9::InvalidateRegion(const nsIntRegion &aRegion)
|
ThebesLayerD3D9::InvalidateRegion(const nsIntRegion &aRegion)
|
||||||
{
|
{
|
||||||
mValidRegion.Sub(mValidRegion, aRegion);
|
mValidRegion.Sub(mValidRegion, aRegion);
|
||||||
|
AddInvalidRect(aRegion.GetBounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -785,6 +785,7 @@ void
|
|||||||
ThebesLayerOGL::InvalidateRegion(const nsIntRegion &aRegion)
|
ThebesLayerOGL::InvalidateRegion(const nsIntRegion &aRegion)
|
||||||
{
|
{
|
||||||
mValidRegion.Sub(mValidRegion, aRegion);
|
mValidRegion.Sub(mValidRegion, aRegion);
|
||||||
|
AddInvalidRect(aRegion.GetBounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -112,6 +112,13 @@ gfx3DMatrix::operator==(const gfx3DMatrix& o) const
|
|||||||
_41 == o._41 && _42 == o._42 && _43 == o._43 && _44 == o._44;
|
_41 == o._41 && _42 == o._42 && _43 == o._43 && _44 == o._44;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
gfx3DMatrix::operator!=(const gfx3DMatrix& o) const
|
||||||
|
{
|
||||||
|
return !((*this) == o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gfx3DMatrix&
|
gfx3DMatrix&
|
||||||
gfx3DMatrix::operator/=(const gfxFloat scalar)
|
gfx3DMatrix::operator/=(const gfxFloat scalar)
|
||||||
{
|
{
|
||||||
|
@ -56,6 +56,7 @@ public:
|
|||||||
* Return true if this matrix and |aMatrix| are the same matrix.
|
* Return true if this matrix and |aMatrix| are the same matrix.
|
||||||
*/
|
*/
|
||||||
bool operator==(const gfx3DMatrix& aMatrix) const;
|
bool operator==(const gfx3DMatrix& aMatrix) const;
|
||||||
|
bool operator!=(const gfx3DMatrix& aMatrix) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Divide all values in the matrix by a scalar value
|
* Divide all values in the matrix by a scalar value
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,8 @@
|
|||||||
#include "nsRegion.h"
|
#include "nsRegion.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
#include "Layers.h"
|
#include "Layers.h"
|
||||||
|
#include "nsDisplayListInvalidation.h"
|
||||||
|
#include "LayerTreeInvalidation.h"
|
||||||
|
|
||||||
class nsDisplayListBuilder;
|
class nsDisplayListBuilder;
|
||||||
class nsDisplayList;
|
class nsDisplayList;
|
||||||
@ -22,6 +24,7 @@ class nsRootPresContext;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class FrameLayerBuilder;
|
class FrameLayerBuilder;
|
||||||
|
class LayerManagerData;
|
||||||
|
|
||||||
enum LayerState {
|
enum LayerState {
|
||||||
LAYER_NONE,
|
LAYER_NONE,
|
||||||
@ -52,13 +55,6 @@ public:
|
|||||||
|
|
||||||
extern PRUint8 gLayerManagerLayerBuilder;
|
extern PRUint8 gLayerManagerLayerBuilder;
|
||||||
|
|
||||||
class ContainerLayerPresContext : public layers::LayerUserData {
|
|
||||||
public:
|
|
||||||
nsPresContext* mPresContext;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern PRUint8 gContainerLayerPresContext;
|
|
||||||
|
|
||||||
static inline FrameLayerBuilder *GetLayerBuilderForManager(layers::LayerManager* aManager)
|
static inline FrameLayerBuilder *GetLayerBuilderForManager(layers::LayerManager* aManager)
|
||||||
{
|
{
|
||||||
LayerManagerLayerBuilder *data = static_cast<LayerManagerLayerBuilder*>(aManager->GetUserData(&gLayerManagerLayerBuilder));
|
LayerManagerLayerBuilder *data = static_cast<LayerManagerLayerBuilder*>(aManager->GetUserData(&gLayerManagerLayerBuilder));
|
||||||
@ -140,14 +136,14 @@ public:
|
|||||||
* is not the retained layer manager then it must be a temporary layer
|
* is not the retained layer manager then it must be a temporary layer
|
||||||
* manager that will not be used again.
|
* manager that will not be used again.
|
||||||
*/
|
*/
|
||||||
void WillEndTransaction(LayerManager* aManager);
|
void WillEndTransaction();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this after we end a transaction on aManager. If aManager
|
* Call this after we end a transaction on aManager. If aManager
|
||||||
* is not the retained layer manager then it must be a temporary layer
|
* is not the retained layer manager then it must be a temporary layer
|
||||||
* manager that will not be used again.
|
* manager that will not be used again.
|
||||||
*/
|
*/
|
||||||
void DidEndTransaction(LayerManager* aManager);
|
void DidEndTransaction();
|
||||||
|
|
||||||
struct ContainerParameters {
|
struct ContainerParameters {
|
||||||
ContainerParameters() :
|
ContainerParameters() :
|
||||||
@ -220,26 +216,8 @@ public:
|
|||||||
* region.
|
* region.
|
||||||
*/
|
*/
|
||||||
Layer* GetLeafLayerFor(nsDisplayListBuilder* aBuilder,
|
Layer* GetLeafLayerFor(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager,
|
|
||||||
nsDisplayItem* aItem);
|
nsDisplayItem* aItem);
|
||||||
|
|
||||||
/**
|
|
||||||
* Call this during invalidation if aFrame has
|
|
||||||
* the NS_FRAME_HAS_CONTAINER_LAYER state bit. Only the nearest
|
|
||||||
* ancestor frame of the damaged frame that has
|
|
||||||
* NS_FRAME_HAS_CONTAINER_LAYER needs to be invalidated this way.
|
|
||||||
*/
|
|
||||||
static void InvalidateThebesLayerContents(nsIFrame* aFrame,
|
|
||||||
const nsRect& aRect);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For any descendant frame of aFrame (including across documents) that
|
|
||||||
* has an associated container layer, invalidate all the contents of
|
|
||||||
* all ThebesLayer children of the container. Useful when aFrame is
|
|
||||||
* being moved and we need to invalidate everything in aFrame's subtree.
|
|
||||||
*/
|
|
||||||
static void InvalidateThebesLayersInSubtree(nsIFrame* aFrame);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this to force all retained layers to be discarded and recreated at
|
* Call this to force all retained layers to be discarded and recreated at
|
||||||
* the next paint.
|
* the next paint.
|
||||||
@ -252,7 +230,7 @@ public:
|
|||||||
* otherwise we return the layer.
|
* otherwise we return the layer.
|
||||||
*/
|
*/
|
||||||
static Layer* GetDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
|
static Layer* GetDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This callback must be provided to EndTransaction. The callback data
|
* This callback must be provided to EndTransaction. The callback data
|
||||||
* must be the nsDisplayListBuilder containing this FrameLayerBuilder.
|
* must be the nsDisplayListBuilder containing this FrameLayerBuilder.
|
||||||
@ -278,10 +256,17 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Record aItem as a display item that is rendered by aLayer.
|
* Record aItem as a display item that is rendered by aLayer.
|
||||||
|
*
|
||||||
|
* @param aLayer Layer that the display item will be rendered into
|
||||||
|
* @param aItem Display item to be drawn.
|
||||||
|
* @param aLayerState What LayerState the item is using.
|
||||||
|
* @param aManager If the layer is in the LAYER_INACTIVE state,
|
||||||
|
* then this is the temporary layer manager to draw with.
|
||||||
*/
|
*/
|
||||||
void AddLayerDisplayItem(Layer* aLayer,
|
void AddLayerDisplayItem(Layer* aLayer,
|
||||||
nsDisplayItem* aItem,
|
nsDisplayItem* aItem,
|
||||||
LayerState aLayerState);
|
LayerState aLayerState,
|
||||||
|
LayerManager* aManager = nsnull);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record aItem as a display item that is rendered by the ThebesLayer
|
* Record aItem as a display item that is rendered by the ThebesLayer
|
||||||
@ -303,9 +288,17 @@ public:
|
|||||||
* This could be a dedicated layer for the display item, or a ThebesLayer
|
* This could be a dedicated layer for the display item, or a ThebesLayer
|
||||||
* that renders many display items.
|
* that renders many display items.
|
||||||
*/
|
*/
|
||||||
Layer* GetOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
|
Layer* GetOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey, nsDisplayItemGeometry** aOldGeometry = nsnull);
|
||||||
|
|
||||||
static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
|
static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the display item was previously drawn as an inactive layer,
|
||||||
|
* then return the layer manager used for the inactive transaction.
|
||||||
|
* Returns nsnull if no manager could be found.
|
||||||
|
*/
|
||||||
|
LayerManager* GetInactiveLayerManagerFor(nsDisplayItem* aItem);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to determine whether the ThebesLayer aLayer paints an opaque
|
* Try to determine whether the ThebesLayer aLayer paints an opaque
|
||||||
* single color everywhere it's visible in aRect.
|
* single color everywhere it's visible in aRect.
|
||||||
@ -340,8 +333,11 @@ public:
|
|||||||
* into a retained layer.
|
* into a retained layer.
|
||||||
* Returns false if it was rendered into a temporary layer manager and then
|
* Returns false if it was rendered into a temporary layer manager and then
|
||||||
* into a retained layer.
|
* into a retained layer.
|
||||||
|
*
|
||||||
|
* Since display items can belong to multiple retained LayerManagers, we need to
|
||||||
|
* specify which LayerManager to check.
|
||||||
*/
|
*/
|
||||||
static bool HasRetainedLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
|
static bool HasRetainedLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey, LayerManager* aManager);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save transform that was in aLayer when we last painted. It must be an integer
|
* Save transform that was in aLayer when we last painted. It must be an integer
|
||||||
@ -457,11 +453,35 @@ protected:
|
|||||||
class DisplayItemData {
|
class DisplayItemData {
|
||||||
public:
|
public:
|
||||||
DisplayItemData(Layer* aLayer, PRUint32 aKey, LayerState aLayerState)
|
DisplayItemData(Layer* aLayer, PRUint32 aKey, LayerState aLayerState)
|
||||||
: mLayer(aLayer), mDisplayItemKey(aKey), mLayerState(aLayerState) {}
|
: mLayer(aLayer), mDisplayItemKey(aKey), mLayerState(aLayerState), mUsed(false) {}
|
||||||
|
|
||||||
|
DisplayItemData()
|
||||||
|
: mUsed(false)
|
||||||
|
{}
|
||||||
|
DisplayItemData(DisplayItemData &toCopy)
|
||||||
|
{
|
||||||
|
// This isn't actually a copy-constructor; notice that it steals toCopy's
|
||||||
|
// mGeometry pointer. Be careful.
|
||||||
|
mLayer = toCopy.mLayer;
|
||||||
|
mInactiveManager = toCopy.mInactiveManager;
|
||||||
|
mGeometry = toCopy.mGeometry;
|
||||||
|
mDisplayItemKey = toCopy.mDisplayItemKey;
|
||||||
|
mLayerState = toCopy.mLayerState;
|
||||||
|
mUsed = toCopy.mUsed;
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<Layer> mLayer;
|
nsRefPtr<Layer> mLayer;
|
||||||
|
nsRefPtr<LayerManager> mInactiveManager;
|
||||||
|
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
|
||||||
PRUint32 mDisplayItemKey;
|
PRUint32 mDisplayItemKey;
|
||||||
LayerState mLayerState;
|
LayerState mLayerState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to track if data currently stored in mFramesWithLayers (from an existing
|
||||||
|
* paint) is also used in the current paint and has an equivalent data object
|
||||||
|
* in mNewDisplayItemData.
|
||||||
|
*/
|
||||||
|
bool mUsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue);
|
static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue);
|
||||||
@ -476,14 +496,16 @@ protected:
|
|||||||
*/
|
*/
|
||||||
class DisplayItemDataEntry : public nsPtrHashKey<nsIFrame> {
|
class DisplayItemDataEntry : public nsPtrHashKey<nsIFrame> {
|
||||||
public:
|
public:
|
||||||
DisplayItemDataEntry(const nsIFrame *key) : nsPtrHashKey<nsIFrame>(key) {}
|
DisplayItemDataEntry(const nsIFrame *key) : nsPtrHashKey<nsIFrame>(key) { MOZ_COUNT_CTOR(DisplayItemDataEntry); }
|
||||||
DisplayItemDataEntry(DisplayItemDataEntry &toCopy) :
|
DisplayItemDataEntry(DisplayItemDataEntry &toCopy) :
|
||||||
nsPtrHashKey<nsIFrame>(toCopy.mKey)
|
nsPtrHashKey<nsIFrame>(toCopy.mKey)
|
||||||
{
|
{
|
||||||
|
MOZ_COUNT_CTOR(DisplayItemDataEntry);
|
||||||
// This isn't actually a copy-constructor; notice that it steals toCopy's
|
// This isn't actually a copy-constructor; notice that it steals toCopy's
|
||||||
// array. Be careful.
|
// array. Be careful.
|
||||||
mData.SwapElements(toCopy.mData);
|
mData.SwapElements(toCopy.mData);
|
||||||
}
|
}
|
||||||
|
~DisplayItemDataEntry() { MOZ_COUNT_DTOR(DisplayItemDataEntry); }
|
||||||
|
|
||||||
bool HasNonEmptyContainerLayer();
|
bool HasNonEmptyContainerLayer();
|
||||||
|
|
||||||
@ -495,6 +517,12 @@ protected:
|
|||||||
// LayerManagerData needs to see DisplayItemDataEntry.
|
// LayerManagerData needs to see DisplayItemDataEntry.
|
||||||
friend class LayerManagerData;
|
friend class LayerManagerData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores DisplayItemData associated with aFrame, stores the data in
|
||||||
|
* mNewDisplayItemData.
|
||||||
|
*/
|
||||||
|
void StoreDataForFrame(nsIFrame* aFrame, DisplayItemData& data);
|
||||||
|
|
||||||
// Flash the area within the context clip if paint flashing is enabled.
|
// Flash the area within the context clip if paint flashing is enabled.
|
||||||
static void FlashPaint(gfxContext *aContext);
|
static void FlashPaint(gfxContext *aContext);
|
||||||
|
|
||||||
@ -505,7 +533,16 @@ protected:
|
|||||||
* Note that the pointer returned here is only valid so long as you don't
|
* Note that the pointer returned here is only valid so long as you don't
|
||||||
* poke the LayerManagerData's mFramesWithLayers hashtable.
|
* poke the LayerManagerData's mFramesWithLayers hashtable.
|
||||||
*/
|
*/
|
||||||
static nsTArray<DisplayItemData>* GetDisplayItemDataArrayForFrame(nsIFrame *aFrame);
|
nsTArray<DisplayItemData>* GetDisplayItemDataArrayForFrame(nsIFrame *aFrame);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the DisplayItemData associated with this frame / display item pair,
|
||||||
|
* using the LayerManager instead of FrameLayerBuilder.
|
||||||
|
*/
|
||||||
|
static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame,
|
||||||
|
PRUint32 aDisplayItemKey,
|
||||||
|
LayerManager* aManager);
|
||||||
|
static DisplayItemData* GetDisplayItemDataForManager(nsDisplayItem* aItem, LayerManager* aManager);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A useful hashtable iteration function that removes the
|
* A useful hashtable iteration function that removes the
|
||||||
@ -514,10 +551,7 @@ protected:
|
|||||||
* aClosure is ignored.
|
* aClosure is ignored.
|
||||||
*/
|
*/
|
||||||
static PLDHashOperator RemoveDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
|
static PLDHashOperator RemoveDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
|
||||||
void* aClosure)
|
void* aClosure);
|
||||||
{
|
|
||||||
return UpdateDisplayItemDataForFrame(aEntry, nsnull);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We store one of these for each display item associated with a
|
* We store one of these for each display item associated with a
|
||||||
@ -535,9 +569,18 @@ protected:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~ClippedDisplayItem();
|
||||||
|
|
||||||
nsDisplayItem* mItem;
|
nsDisplayItem* mItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the display item is being rendered as an inactive
|
||||||
|
* layer, then this stores the layer manager being
|
||||||
|
* used for the inactive transaction.
|
||||||
|
*/
|
||||||
|
nsRefPtr<LayerManager> mInactiveLayer;
|
||||||
|
|
||||||
Clip mClip;
|
Clip mClip;
|
||||||
bool mInactiveLayer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -580,11 +623,14 @@ public:
|
|||||||
return mThebesLayerItems.GetEntry(aLayer);
|
return mThebesLayerItems.GetEntry(aLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PLDHashOperator ProcessRemovedDisplayItems(DisplayItemDataEntry* aEntry,
|
||||||
|
void* aUserArg);
|
||||||
protected:
|
protected:
|
||||||
void RemoveThebesItemsForLayerSubtree(Layer* aLayer);
|
void RemoveThebesItemsForLayerSubtree(Layer* aLayer);
|
||||||
|
|
||||||
static PLDHashOperator UpdateDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
|
static PLDHashOperator UpdateDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
|
||||||
void* aUserArg);
|
void* aUserArg);
|
||||||
|
|
||||||
static PLDHashOperator StoreNewDisplayItemData(DisplayItemDataEntry* aEntry,
|
static PLDHashOperator StoreNewDisplayItemData(DisplayItemDataEntry* aEntry,
|
||||||
void* aUserArg);
|
void* aUserArg);
|
||||||
|
|
||||||
@ -604,6 +650,11 @@ protected:
|
|||||||
* The root prescontext for the display list builder reference frame
|
* The root prescontext for the display list builder reference frame
|
||||||
*/
|
*/
|
||||||
nsRootPresContext* mRootPresContext;
|
nsRootPresContext* mRootPresContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The display list builder being used.
|
||||||
|
*/
|
||||||
|
nsDisplayListBuilder* mDisplayListBuilder;
|
||||||
/**
|
/**
|
||||||
* A map from frames to a list of (display item key, layer) pairs that
|
* A map from frames to a list of (display item key, layer) pairs that
|
||||||
* describes what layers various parts of the frame are assigned to.
|
* describes what layers various parts of the frame are assigned to.
|
||||||
|
@ -38,6 +38,7 @@ EXPORTS = \
|
|||||||
nsCompatibility.h \
|
nsCompatibility.h \
|
||||||
nsDisplayItemTypes.h \
|
nsDisplayItemTypes.h \
|
||||||
nsDisplayList.h \
|
nsDisplayList.h \
|
||||||
|
nsDisplayListInvalidation.h \
|
||||||
nsFrameManager.h \
|
nsFrameManager.h \
|
||||||
nsFrameManagerBase.h \
|
nsFrameManagerBase.h \
|
||||||
nsFrameTraversal.h \
|
nsFrameTraversal.h \
|
||||||
|
@ -7585,11 +7585,6 @@ UpdateViewsForTree(nsIFrame* aFrame,
|
|||||||
DoApplyRenderingChangeToTree(child, aFrameManager,
|
DoApplyRenderingChangeToTree(child, aFrameManager,
|
||||||
aChange);
|
aChange);
|
||||||
} else { // regular frame
|
} else { // regular frame
|
||||||
if ((child->GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER) &&
|
|
||||||
(aChange & nsChangeHint_RepaintFrame)) {
|
|
||||||
FrameLayerBuilder::InvalidateThebesLayerContents(child,
|
|
||||||
child->GetVisualOverflowRectRelativeToSelf());
|
|
||||||
}
|
|
||||||
UpdateViewsForTree(child, aFrameManager, aChange);
|
UpdateViewsForTree(child, aFrameManager, aChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7631,21 +7626,17 @@ DoApplyRenderingChangeToTree(nsIFrame* aFrame,
|
|||||||
nsSVGUtils::InvalidateBounds(aFrame);
|
nsSVGUtils::InvalidateBounds(aFrame);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
aFrame->InvalidateOverflowRect();
|
aFrame->InvalidateFrameSubtree();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aChange & nsChangeHint_UpdateOpacityLayer) {
|
if (aChange & nsChangeHint_UpdateOpacityLayer) {
|
||||||
aFrame->MarkLayersActive(nsChangeHint_UpdateOpacityLayer);
|
aFrame->MarkLayersActive(nsChangeHint_UpdateOpacityLayer);
|
||||||
aFrame->InvalidateLayer(aFrame->GetVisualOverflowRectRelativeToSelf(),
|
|
||||||
nsDisplayItem::TYPE_OPACITY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aChange & nsChangeHint_UpdateTransformLayer) {
|
if (aChange & nsChangeHint_UpdateTransformLayer) {
|
||||||
aFrame->MarkLayersActive(nsChangeHint_UpdateTransformLayer);
|
aFrame->MarkLayersActive(nsChangeHint_UpdateTransformLayer);
|
||||||
// Invalidate the old transformed area. The new transformed area
|
|
||||||
// will be invalidated by nsFrame::FinishAndStoreOverflowArea.
|
|
||||||
aFrame->InvalidateTransformLayer();
|
|
||||||
}
|
}
|
||||||
|
aFrame->SchedulePaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12247,6 +12238,8 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aFrame->SchedulePaint();
|
||||||
|
|
||||||
// For relative positioning, we can simply update the frame rect
|
// For relative positioning, we can simply update the frame rect
|
||||||
if (display->mPosition == NS_STYLE_POSITION_RELATIVE) {
|
if (display->mPosition == NS_STYLE_POSITION_RELATIVE) {
|
||||||
nsIFrame* cb = aFrame->GetContainingBlock();
|
nsIFrame* cb = aFrame->GetContainingBlock();
|
||||||
@ -12254,9 +12247,6 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
|
|||||||
const nsPoint oldOffsets = aFrame->GetRelativeOffset();
|
const nsPoint oldOffsets = aFrame->GetRelativeOffset();
|
||||||
nsMargin newOffsets;
|
nsMargin newOffsets;
|
||||||
|
|
||||||
// Invalidate the old rect
|
|
||||||
aFrame->InvalidateOverflowRect();
|
|
||||||
|
|
||||||
// Move the frame
|
// Move the frame
|
||||||
nsHTMLReflowState::ComputeRelativeOffsets(
|
nsHTMLReflowState::ComputeRelativeOffsets(
|
||||||
cb->GetStyleVisibility()->mDirection,
|
cb->GetStyleVisibility()->mDirection,
|
||||||
@ -12267,9 +12257,6 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
|
|||||||
aFrame->SetPosition(aFrame->GetPosition() - oldOffsets +
|
aFrame->SetPosition(aFrame->GetPosition() - oldOffsets +
|
||||||
nsPoint(newOffsets.left, newOffsets.top));
|
nsPoint(newOffsets.left, newOffsets.top));
|
||||||
|
|
||||||
// Invalidate the new rect
|
|
||||||
aFrame->InvalidateFrameSubtree();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12340,10 +12327,7 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
|
|||||||
size.height -
|
size.height -
|
||||||
reflowState.mComputedMargin.top;
|
reflowState.mComputedMargin.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invalidate the old rect
|
|
||||||
aFrame->InvalidateFrameSubtree();
|
|
||||||
|
|
||||||
// Move the frame
|
// Move the frame
|
||||||
nsPoint pos(parentBorder.left + reflowState.mComputedOffsets.left +
|
nsPoint pos(parentBorder.left + reflowState.mComputedOffsets.left +
|
||||||
reflowState.mComputedMargin.left,
|
reflowState.mComputedMargin.left,
|
||||||
@ -12351,9 +12335,6 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
|
|||||||
reflowState.mComputedMargin.top);
|
reflowState.mComputedMargin.top);
|
||||||
aFrame->SetPosition(pos);
|
aFrame->SetPosition(pos);
|
||||||
|
|
||||||
// Invalidate the new rect
|
|
||||||
aFrame->InvalidateFrameSubtree();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,8 +483,9 @@ void nsCaret::InvalidateOutsideCaret()
|
|||||||
nsIFrame *frame = GetCaretFrame();
|
nsIFrame *frame = GetCaretFrame();
|
||||||
|
|
||||||
// Only invalidate if we are not fully contained by our frame's rect.
|
// Only invalidate if we are not fully contained by our frame's rect.
|
||||||
if (frame && !frame->GetVisualOverflowRect().Contains(GetCaretRect()))
|
if (frame && !frame->GetVisualOverflowRect().Contains(GetCaretRect())) {
|
||||||
InvalidateRects(mCaretRect, GetHookRect(), frame);
|
frame->SchedulePaint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsCaret::UpdateCaretPosition()
|
void nsCaret::UpdateCaretPosition()
|
||||||
@ -613,31 +614,9 @@ nsresult nsCaret::PrimeTimer()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsCaret::InvalidateTextOverflowBlock()
|
|
||||||
{
|
|
||||||
// If the nearest block has a potential 'text-overflow' marker then
|
|
||||||
// invalidate it.
|
|
||||||
if (mLastContent) {
|
|
||||||
nsIFrame* caretFrame = mLastContent->GetPrimaryFrame();
|
|
||||||
if (caretFrame) {
|
|
||||||
nsIFrame* block = nsLayoutUtils::GetAsBlock(caretFrame) ? caretFrame :
|
|
||||||
nsLayoutUtils::FindNearestBlockAncestor(caretFrame);
|
|
||||||
if (block) {
|
|
||||||
const nsStyleTextReset* style = block->GetStyleTextReset();
|
|
||||||
if (style->mTextOverflow.mLeft.mType != NS_STYLE_TEXT_OVERFLOW_CLIP ||
|
|
||||||
style->mTextOverflow.mRight.mType != NS_STYLE_TEXT_OVERFLOW_CLIP) {
|
|
||||||
block->InvalidateOverflowRect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void nsCaret::StartBlinking()
|
void nsCaret::StartBlinking()
|
||||||
{
|
{
|
||||||
InvalidateTextOverflowBlock();
|
|
||||||
|
|
||||||
if (mReadOnly) {
|
if (mReadOnly) {
|
||||||
// Make sure the one draw command we use for a readonly caret isn't
|
// Make sure the one draw command we use for a readonly caret isn't
|
||||||
// done until the selection is set
|
// done until the selection is set
|
||||||
@ -661,8 +640,6 @@ void nsCaret::StartBlinking()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void nsCaret::StopBlinking()
|
void nsCaret::StopBlinking()
|
||||||
{
|
{
|
||||||
InvalidateTextOverflowBlock();
|
|
||||||
|
|
||||||
if (mDrawn) // erase the caret if necessary
|
if (mDrawn) // erase the caret if necessary
|
||||||
DrawCaret(true);
|
DrawCaret(true);
|
||||||
|
|
||||||
@ -721,7 +698,7 @@ nsCaret::DrawAtPositionWithHint(nsIDOMNode* aNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (aInvalidate)
|
if (aInvalidate)
|
||||||
InvalidateRects(mCaretRect, mHookRect, theFrame);
|
theFrame->SchedulePaint();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1137,16 +1114,6 @@ nsCaret::UpdateCaretRects(nsIFrame* aFrame, PRInt32 aFrameOffset)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
void nsCaret::InvalidateRects(const nsRect &aRect, const nsRect &aHook,
|
|
||||||
nsIFrame *aFrame)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aFrame, "Must have a frame to invalidate");
|
|
||||||
nsRect rect;
|
|
||||||
rect.UnionRect(aRect, aHook);
|
|
||||||
aFrame->Invalidate(rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/* static */
|
/* static */
|
||||||
void nsCaret::CaretBlinkCallback(nsITimer *aTimer, void *aClosure)
|
void nsCaret::CaretBlinkCallback(nsITimer *aTimer, void *aClosure)
|
||||||
|
@ -173,10 +173,6 @@ protected:
|
|||||||
void StartBlinking();
|
void StartBlinking();
|
||||||
void StopBlinking();
|
void StopBlinking();
|
||||||
|
|
||||||
// If the nearest block has a potential 'text-overflow' marker then
|
|
||||||
// invalidate it.
|
|
||||||
void InvalidateTextOverflowBlock();
|
|
||||||
|
|
||||||
bool DrawAtPositionWithHint(nsIDOMNode* aNode,
|
bool DrawAtPositionWithHint(nsIDOMNode* aNode,
|
||||||
PRInt32 aOffset,
|
PRInt32 aOffset,
|
||||||
nsFrameSelection::HINT aFrameHint,
|
nsFrameSelection::HINT aFrameHint,
|
||||||
@ -203,8 +199,6 @@ protected:
|
|||||||
void DrawCaret(bool aInvalidate);
|
void DrawCaret(bool aInvalidate);
|
||||||
void DrawCaretAfterBriefDelay();
|
void DrawCaretAfterBriefDelay();
|
||||||
bool UpdateCaretRects(nsIFrame* aFrame, PRInt32 aFrameOffset);
|
bool UpdateCaretRects(nsIFrame* aFrame, PRInt32 aFrameOffset);
|
||||||
static void InvalidateRects(const nsRect &aRect, const nsRect &aHook,
|
|
||||||
nsIFrame *aFrame);
|
|
||||||
nsRect GetHookRect()
|
nsRect GetHookRect()
|
||||||
{
|
{
|
||||||
#ifdef IBMBIDI
|
#ifdef IBMBIDI
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsIScrollableFrame.h"
|
#include "nsIScrollableFrame.h"
|
||||||
#include "nsThemeConstants.h"
|
#include "nsThemeConstants.h"
|
||||||
|
#include "LayerTreeInvalidation.h"
|
||||||
|
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
#include "nsIInterfaceRequestorUtils.h"
|
||||||
@ -35,6 +36,7 @@
|
|||||||
#include "nsSVGEffects.h"
|
#include "nsSVGEffects.h"
|
||||||
#include "nsSVGClipPathFrame.h"
|
#include "nsSVGClipPathFrame.h"
|
||||||
#include "sampler.h"
|
#include "sampler.h"
|
||||||
|
#include "nsIViewManager.h"
|
||||||
|
|
||||||
#include "mozilla/StandardInteger.h"
|
#include "mozilla/StandardInteger.h"
|
||||||
|
|
||||||
@ -564,8 +566,10 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
|||||||
nsRefPtr<LayerManager> layerManager;
|
nsRefPtr<LayerManager> layerManager;
|
||||||
bool allowRetaining = false;
|
bool allowRetaining = false;
|
||||||
bool doBeginTransaction = true;
|
bool doBeginTransaction = true;
|
||||||
|
nsIView *view = nsnull;
|
||||||
if (aFlags & PAINT_USE_WIDGET_LAYERS) {
|
if (aFlags & PAINT_USE_WIDGET_LAYERS) {
|
||||||
nsIFrame* referenceFrame = aBuilder->ReferenceFrame();
|
nsIFrame* referenceFrame = aBuilder->ReferenceFrame();
|
||||||
|
view = referenceFrame->GetView();
|
||||||
NS_ASSERTION(referenceFrame == nsLayoutUtils::GetDisplayRootFrame(referenceFrame),
|
NS_ASSERTION(referenceFrame == nsLayoutUtils::GetDisplayRootFrame(referenceFrame),
|
||||||
"Reference frame must be a display root for us to use the layer manager");
|
"Reference frame must be a display root for us to use the layer manager");
|
||||||
nsIWidget* window = referenceFrame->GetNearestWidget();
|
nsIWidget* window = referenceFrame->GetNearestWidget();
|
||||||
@ -606,11 +610,25 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
|||||||
nsPresContext* presContext = aForFrame->PresContext();
|
nsPresContext* presContext = aForFrame->PresContext();
|
||||||
nsIPresShell* presShell = presContext->GetPresShell();
|
nsIPresShell* presShell = presContext->GetPresShell();
|
||||||
|
|
||||||
|
NotifySubDocInvalidationFunc computeInvalidFunc =
|
||||||
|
presContext->MayHavePaintEventListenerInSubDocument() ? nsPresContext::NotifySubDocInvalidation : 0;
|
||||||
|
bool computeInvalidRect = (computeInvalidFunc ||
|
||||||
|
(layerManager->GetBackendType() == LayerManager::LAYERS_BASIC)) &&
|
||||||
|
widgetTransaction;
|
||||||
|
|
||||||
|
nsAutoPtr<LayerProperties> props(computeInvalidRect ?
|
||||||
|
LayerProperties::CloneFrom(layerManager->GetRoot()) :
|
||||||
|
nsnull);
|
||||||
|
|
||||||
nsDisplayItem::ContainerParameters containerParameters
|
nsDisplayItem::ContainerParameters containerParameters
|
||||||
(presShell->GetXResolution(), presShell->GetYResolution());
|
(presShell->GetXResolution(), presShell->GetYResolution());
|
||||||
nsRefPtr<ContainerLayer> root = layerBuilder->
|
nsRefPtr<ContainerLayer> root = layerBuilder->
|
||||||
BuildContainerLayerFor(aBuilder, layerManager, aForFrame, nsnull, *this,
|
BuildContainerLayerFor(aBuilder, layerManager, aForFrame, nsnull, *this,
|
||||||
containerParameters, nsnull);
|
containerParameters, nsnull);
|
||||||
|
|
||||||
|
if (widgetTransaction) {
|
||||||
|
aForFrame->ClearInvalidationStateBits();
|
||||||
|
}
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
layerManager->RemoveUserData(&gLayerManagerLayerBuilder);
|
layerManager->RemoveUserData(&gLayerManagerLayerBuilder);
|
||||||
@ -646,10 +664,30 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
layerManager->SetRoot(root);
|
layerManager->SetRoot(root);
|
||||||
layerBuilder->WillEndTransaction(layerManager);
|
layerBuilder->WillEndTransaction();
|
||||||
layerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer,
|
layerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer,
|
||||||
aBuilder, (aFlags & PAINT_NO_COMPOSITE) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT);
|
aBuilder, (aFlags & PAINT_NO_COMPOSITE) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT);
|
||||||
layerBuilder->DidEndTransaction(layerManager);
|
layerBuilder->DidEndTransaction();
|
||||||
|
|
||||||
|
nsIntRect invalid;
|
||||||
|
if (props) {
|
||||||
|
invalid = props->ComputeDifferences(root, computeInvalidFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (view) {
|
||||||
|
if (props) {
|
||||||
|
if (!invalid.IsEmpty()) {
|
||||||
|
nsRect rect(presContext->DevPixelsToAppUnits(invalid.x),
|
||||||
|
presContext->DevPixelsToAppUnits(invalid.y),
|
||||||
|
presContext->DevPixelsToAppUnits(invalid.width),
|
||||||
|
presContext->DevPixelsToAppUnits(invalid.height));
|
||||||
|
view->GetViewManager()->InvalidateViewNoSuppression(view, rect);
|
||||||
|
presContext->NotifyInvalidation(invalid, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
view->GetViewManager()->InvalidateView(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (aFlags & PAINT_FLUSH_LAYERS) {
|
if (aFlags & PAINT_FLUSH_LAYERS) {
|
||||||
FrameLayerBuilder::InvalidateAllLayers(layerManager);
|
FrameLayerBuilder::InvalidateAllLayers(layerManager);
|
||||||
@ -1310,7 +1348,7 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
|||||||
// theme background overrides any other background
|
// theme background overrides any other background
|
||||||
if (mIsThemed) {
|
if (mIsThemed) {
|
||||||
if (mThemeTransparency == nsITheme::eOpaque) {
|
if (mThemeTransparency == nsITheme::eOpaque) {
|
||||||
result = GetBounds(aBuilder, aSnap);
|
result = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1411,6 +1449,36 @@ nsDisplayBackground::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuild
|
|||||||
nsLayoutUtils::IsProperAncestorFrame(aFrame, mFrame));
|
nsLayoutUtils::IsProperAncestorFrame(aFrame, mFrame));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsDisplayBackground::RenderingMightDependOnFrameSize()
|
||||||
|
{
|
||||||
|
// theme background overrides any other background and we don't know what to do here
|
||||||
|
if (mIsThemed)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// We could be smarter with rounded corners and only invalidate the new area + the piece that was previously
|
||||||
|
// clipped out.
|
||||||
|
nscoord radii[8];
|
||||||
|
if (mFrame->GetBorderRadii(radii))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
nsPresContext* presContext = mFrame->PresContext();
|
||||||
|
nsStyleContext *bgSC;
|
||||||
|
bool hasBG =
|
||||||
|
nsCSSRendering::FindBackground(presContext, mFrame, &bgSC);
|
||||||
|
if (!hasBG)
|
||||||
|
return false;
|
||||||
|
const nsStyleBackground* bg = bgSC->GetStyleBackground();
|
||||||
|
|
||||||
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
||||||
|
const nsStyleBackground::Layer &layer = bg->mLayers[i];
|
||||||
|
if (layer.RenderingMightDependOnFrameSize()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsDisplayBackground::ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
|
nsDisplayBackground::ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
|
||||||
{
|
{
|
||||||
@ -1468,6 +1536,28 @@ nsDisplayBackground::Paint(nsDisplayListBuilder* aBuilder,
|
|||||||
flags);
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsDisplayBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion)
|
||||||
|
{
|
||||||
|
const nsDisplayBackgroundGeometry* geometry = static_cast<const nsDisplayBackgroundGeometry*>(aGeometry);
|
||||||
|
if (ShouldFixToViewport(aBuilder)) {
|
||||||
|
// This is incorrect, We definitely need to check more things here.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool snap;
|
||||||
|
if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
|
||||||
|
!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect()) ||
|
||||||
|
!geometry->mContentRect.IsEqualInterior(GetContentRect())) {
|
||||||
|
if (!RenderingMightDependOnFrameSize() && geometry->mBounds.TopLeft() == GetBounds(aBuilder, &snap).TopLeft()) {
|
||||||
|
aInvalidRegion->Xor(GetBounds(aBuilder, &snap), geometry->mBounds);
|
||||||
|
} else {
|
||||||
|
aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsRect
|
nsRect
|
||||||
nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
|
nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
|
||||||
nsRect r(nsPoint(0,0), mFrame->GetSize());
|
nsRect r(nsPoint(0,0), mFrame->GetSize());
|
||||||
@ -1477,6 +1567,10 @@ nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
|
|||||||
presContext->GetTheme()->
|
presContext->GetTheme()->
|
||||||
GetWidgetOverflow(presContext->DeviceContext(), mFrame,
|
GetWidgetOverflow(presContext->DeviceContext(), mFrame,
|
||||||
mFrame->GetStyleDisplay()->mAppearance, &r);
|
mFrame->GetStyleDisplay()->mAppearance, &r);
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
// Bug 748219
|
||||||
|
r.Inflate(mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
*aSnap = true;
|
*aSnap = true;
|
||||||
@ -1571,7 +1665,33 @@ nsDisplayBorder::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsDisplayItemGeometry*
|
||||||
|
nsDisplayBorder::AllocateGeometry(nsDisplayListBuilder* aBuilder)
|
||||||
|
{
|
||||||
|
bool snap;
|
||||||
|
nsDisplayBorderGeometry* geometry = new nsDisplayBorderGeometry;
|
||||||
|
geometry->mBounds = GetBounds(aBuilder, &snap);
|
||||||
|
geometry->mPaddingRect = GetContentRect();
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDisplayBorder::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion)
|
||||||
|
{
|
||||||
|
const nsDisplayBorderGeometry* geometry = static_cast<const nsDisplayBorderGeometry*>(aGeometry);
|
||||||
|
bool snap;
|
||||||
|
if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
|
||||||
|
!geometry->mPaddingRect.IsEqualInterior(GetContentRect())) {
|
||||||
|
// We can probably get away with only invalidating the difference
|
||||||
|
// between the border and padding rects, but the XUL ui at least
|
||||||
|
// is apparently painting a background with this?
|
||||||
|
aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder,
|
nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder,
|
||||||
nsRenderingContext* aCtx) {
|
nsRenderingContext* aCtx) {
|
||||||
@ -1986,8 +2106,10 @@ bool nsDisplayOpacity::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* a
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsDisplayOwnLayer::nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder,
|
nsDisplayOwnLayer::nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder,
|
||||||
nsIFrame* aFrame, nsDisplayList* aList)
|
nsIFrame* aFrame, nsDisplayList* aList,
|
||||||
: nsDisplayWrapList(aBuilder, aFrame, aList) {
|
PRUint32 aFlags)
|
||||||
|
: nsDisplayWrapList(aBuilder, aFrame, aList)
|
||||||
|
, mFlags(aFlags) {
|
||||||
MOZ_COUNT_CTOR(nsDisplayOwnLayer);
|
MOZ_COUNT_CTOR(nsDisplayOwnLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2005,6 +2127,12 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||||||
nsRefPtr<Layer> layer = GetLayerBuilderForManager(aManager)->
|
nsRefPtr<Layer> layer = GetLayerBuilderForManager(aManager)->
|
||||||
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
|
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
|
||||||
aContainerParameters, nsnull);
|
aContainerParameters, nsnull);
|
||||||
|
|
||||||
|
if (mFlags & GENERATE_SUBDOC_INVALIDATIONS) {
|
||||||
|
ContainerLayerPresContext* pres = new ContainerLayerPresContext;
|
||||||
|
pres->mPresContext = mFrame->PresContext();
|
||||||
|
layer->SetUserData(&gNotifySubDocInvalidationData, pres);
|
||||||
|
}
|
||||||
return layer.forget();
|
return layer.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2461,9 +2589,10 @@ bool nsDisplayClipRoundedRect::TryMerge(nsDisplayListBuilder* aBuilder, nsDispla
|
|||||||
|
|
||||||
nsDisplayZoom::nsDisplayZoom(nsDisplayListBuilder* aBuilder,
|
nsDisplayZoom::nsDisplayZoom(nsDisplayListBuilder* aBuilder,
|
||||||
nsIFrame* aFrame, nsDisplayList* aList,
|
nsIFrame* aFrame, nsDisplayList* aList,
|
||||||
PRInt32 aAPD, PRInt32 aParentAPD)
|
PRInt32 aAPD, PRInt32 aParentAPD,
|
||||||
: nsDisplayOwnLayer(aBuilder, aFrame, aList), mAPD(aAPD),
|
PRUint32 aFlags)
|
||||||
mParentAPD(aParentAPD) {
|
: nsDisplayOwnLayer(aBuilder, aFrame, aList, aFlags)
|
||||||
|
, mAPD(aAPD), mParentAPD(aParentAPD) {
|
||||||
MOZ_COUNT_CTOR(nsDisplayZoom);
|
MOZ_COUNT_CTOR(nsDisplayZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "nsThemeConstants.h"
|
#include "nsThemeConstants.h"
|
||||||
#include "ImageLayers.h"
|
#include "ImageLayers.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
|
#include "nsDisplayListInvalidation.h"
|
||||||
|
|
||||||
#include "mozilla/StandardInteger.h"
|
#include "mozilla/StandardInteger.h"
|
||||||
|
|
||||||
@ -677,6 +678,72 @@ public:
|
|||||||
*aSnap = false;
|
*aSnap = false;
|
||||||
return nsRect(ToReferenceFrame(), GetUnderlyingFrame()->GetSize());
|
return nsRect(ToReferenceFrame(), GetUnderlyingFrame()->GetSize());
|
||||||
}
|
}
|
||||||
|
nsRect GetBorderRect() {
|
||||||
|
return nsRect(ToReferenceFrame(), GetUnderlyingFrame()->GetSize());
|
||||||
|
}
|
||||||
|
nsRect GetPaddingRect() {
|
||||||
|
return GetUnderlyingFrame()->GetPaddingRectRelativeToSelf() + ToReferenceFrame();
|
||||||
|
}
|
||||||
|
nsRect GetContentRect() {
|
||||||
|
return GetUnderlyingFrame()->GetContentRectRelativeToSelf() + ToReferenceFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the frame(s) owning this display item have been marked as invalid,
|
||||||
|
* and needing repainting.
|
||||||
|
*/
|
||||||
|
virtual bool IsInvalid() { return mFrame ? mFrame->IsInvalid() : false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and initializes an nsDisplayItemGeometry object that retains the current
|
||||||
|
* areas covered by this display item. These need to retain enough information
|
||||||
|
* such that they can be compared against a future nsDisplayItem of the same type,
|
||||||
|
* and determine if repainting needs to happen.
|
||||||
|
*
|
||||||
|
* Subclasses wishing to store more information need to override both this
|
||||||
|
* and ComputeInvalidationRegion, as well as implementing an nsDisplayItemGeometry
|
||||||
|
* subclass.
|
||||||
|
*
|
||||||
|
* The default implementation tracks both the display item bounds, and the frame's
|
||||||
|
* border rect.
|
||||||
|
*/
|
||||||
|
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
|
||||||
|
{
|
||||||
|
nsDisplayItemGenericGeometry* geometry = new nsDisplayItemGenericGeometry();
|
||||||
|
bool snap;
|
||||||
|
geometry->mBounds = GetBounds(aBuilder, &snap);
|
||||||
|
geometry->mBorderRect = GetBorderRect();
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares an nsDisplayItemGeometry object from a previous paint against the
|
||||||
|
* current item. Computes if the geometry of the item has changed, and the
|
||||||
|
* invalidation area required for correct repainting.
|
||||||
|
*
|
||||||
|
* The existing geometry will have been created from a display item with a
|
||||||
|
* matching GetPerFrameKey()/mFrame pair to the current item.
|
||||||
|
*
|
||||||
|
* The default implementation compares the display item bounds, and the frame's
|
||||||
|
* border rect, and invalidates the entire bounds if either rect changes.
|
||||||
|
*
|
||||||
|
* @param aGeometry The geometry of the matching display item from the
|
||||||
|
* previous paint.
|
||||||
|
* @param aInvalidRegion Output param, the region to invalidate, or
|
||||||
|
* unchanged if none.
|
||||||
|
*/
|
||||||
|
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion)
|
||||||
|
{
|
||||||
|
const nsDisplayItemGenericGeometry* geometry = static_cast<const nsDisplayItemGenericGeometry*>(aGeometry);
|
||||||
|
bool snap;
|
||||||
|
if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
|
||||||
|
!geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
|
||||||
|
aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param aSnap set to true if the edges of the rectangles of the opaque
|
* @param aSnap set to true if the edges of the rectangles of the opaque
|
||||||
* region would be snapped to device pixels when drawing
|
* region would be snapped to device pixels when drawing
|
||||||
@ -1509,6 +1576,12 @@ public:
|
|||||||
nsRegion* aVisibleRegion,
|
nsRegion* aVisibleRegion,
|
||||||
const nsRect& aAllowVisibleRegionExpansion);
|
const nsRect& aAllowVisibleRegionExpansion);
|
||||||
NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
|
NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
|
||||||
|
|
||||||
|
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder);
|
||||||
|
|
||||||
|
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1601,6 +1674,27 @@ public:
|
|||||||
// Returns the value of GetUnderlyingFrame()->IsThemed(), but cached
|
// Returns the value of GetUnderlyingFrame()->IsThemed(), but cached
|
||||||
bool IsThemed() { return mIsThemed; }
|
bool IsThemed() { return mIsThemed; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if existing rendered pixels of this display item may need
|
||||||
|
* to be redrawn if the frame size changes.
|
||||||
|
* If false, only the changed area needs to be redrawn.
|
||||||
|
*/
|
||||||
|
bool RenderingMightDependOnFrameSize();
|
||||||
|
|
||||||
|
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
|
||||||
|
{
|
||||||
|
bool snap;
|
||||||
|
nsDisplayBackgroundGeometry* geometry = new nsDisplayBackgroundGeometry;
|
||||||
|
geometry->mBounds = GetBounds(aBuilder, &snap);
|
||||||
|
geometry->mPaddingRect = GetPaddingRect();
|
||||||
|
geometry->mContentRect = GetContentRect();
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef class mozilla::layers::ImageContainer ImageContainer;
|
typedef class mozilla::layers::ImageContainer ImageContainer;
|
||||||
typedef class mozilla::layers::ImageLayer ImageLayer;
|
typedef class mozilla::layers::ImageLayer ImageLayer;
|
||||||
@ -1641,6 +1735,21 @@ public:
|
|||||||
nsRegion* aVisibleRegion,
|
nsRegion* aVisibleRegion,
|
||||||
const nsRect& aAllowVisibleRegionExpansion);
|
const nsRect& aAllowVisibleRegionExpansion);
|
||||||
NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
|
NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
|
||||||
|
|
||||||
|
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion)
|
||||||
|
{
|
||||||
|
const nsDisplayItemGenericGeometry* geometry = static_cast<const nsDisplayItemGenericGeometry*>(aGeometry);
|
||||||
|
bool snap;
|
||||||
|
if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
|
||||||
|
!geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
|
||||||
|
nsRegion oldShadow, newShadow;
|
||||||
|
oldShadow = oldShadow.Sub(geometry->mBounds, geometry->mBorderRect);
|
||||||
|
newShadow = newShadow.Sub(GetBounds(aBuilder, &snap), GetBorderRect());
|
||||||
|
aInvalidRegion->Or(oldShadow, newShadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRegion mVisibleRegion;
|
nsRegion mVisibleRegion;
|
||||||
@ -1666,6 +1775,28 @@ public:
|
|||||||
nsRegion* aVisibleRegion,
|
nsRegion* aVisibleRegion,
|
||||||
const nsRect& aAllowVisibleRegionExpansion);
|
const nsRect& aAllowVisibleRegionExpansion);
|
||||||
NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
|
NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
|
||||||
|
|
||||||
|
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
|
||||||
|
{
|
||||||
|
nsDisplayBoxShadowInnerGeometry* geometry = new nsDisplayBoxShadowInnerGeometry;
|
||||||
|
bool snap;
|
||||||
|
geometry->mBounds = GetBounds(aBuilder, &snap);
|
||||||
|
geometry->mPaddingRect = GetPaddingRect();
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion)
|
||||||
|
{
|
||||||
|
const nsDisplayBoxShadowInnerGeometry* geometry = static_cast<const nsDisplayBoxShadowInnerGeometry*>(aGeometry);
|
||||||
|
if (!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())) {
|
||||||
|
// nsDisplayBoxShadowInner is based around the padding rect, but it can
|
||||||
|
// touch pixels outside of this. We should invalidate the entire bounds.
|
||||||
|
bool snap;
|
||||||
|
aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRegion mVisibleRegion;
|
nsRegion mVisibleRegion;
|
||||||
@ -1772,6 +1903,18 @@ public:
|
|||||||
{
|
{
|
||||||
aFrames->AppendElements(mMergedFrames);
|
aFrames->AppendElements(mMergedFrames);
|
||||||
}
|
}
|
||||||
|
virtual bool IsInvalid()
|
||||||
|
{
|
||||||
|
if (mFrame->IsInvalid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (PRUint32 i = 0; i < mMergedFrames.Length(); i++) {
|
||||||
|
if (mMergedFrames[i]->IsInvalid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
|
NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
|
||||||
|
|
||||||
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder);
|
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder);
|
||||||
@ -1882,8 +2025,21 @@ public:
|
|||||||
*/
|
*/
|
||||||
class nsDisplayOwnLayer : public nsDisplayWrapList {
|
class nsDisplayOwnLayer : public nsDisplayWrapList {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nsDisplayOwnLayer constructor flags
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
GENERATE_SUBDOC_INVALIDATIONS = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param aFlags GENERATE_SUBDOC_INVALIDATIONS :
|
||||||
|
* Add UserData to the created ContainerLayer, so that invalidations
|
||||||
|
* for this layer are send to our nsPresContext.
|
||||||
|
*/
|
||||||
nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||||
nsDisplayList* aList);
|
nsDisplayList* aList, PRUint32 aFlags = 0);
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
virtual ~nsDisplayOwnLayer();
|
virtual ~nsDisplayOwnLayer();
|
||||||
#endif
|
#endif
|
||||||
@ -1903,6 +2059,8 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
|
NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
|
||||||
|
private:
|
||||||
|
PRUint32 mFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2123,10 +2281,14 @@ public:
|
|||||||
* @param aAPD is the app units per dev pixel ratio of the subdocument.
|
* @param aAPD is the app units per dev pixel ratio of the subdocument.
|
||||||
* @param aParentAPD is the app units per dev pixel ratio of the parent
|
* @param aParentAPD is the app units per dev pixel ratio of the parent
|
||||||
* document.
|
* document.
|
||||||
|
* @param aFlags GENERATE_SUBDOC_INVALIDATIONS :
|
||||||
|
* Add UserData to the created ContainerLayer, so that invalidations
|
||||||
|
* for this layer are send to our nsPresContext.
|
||||||
*/
|
*/
|
||||||
nsDisplayZoom(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
nsDisplayZoom(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||||
nsDisplayList* aList,
|
nsDisplayList* aList,
|
||||||
PRInt32 aAPD, PRInt32 aParentAPD);
|
PRInt32 aAPD, PRInt32 aParentAPD,
|
||||||
|
PRUint32 aFlags = 0);
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
virtual ~nsDisplayZoom();
|
virtual ~nsDisplayZoom();
|
||||||
#endif
|
#endif
|
||||||
|
118
layout/base/nsDisplayListInvalidation.h
Normal file
118
layout/base/nsDisplayListInvalidation.h
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*-*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef NSDISPLAYLISTINVALIDATION_H_
|
||||||
|
#define NSDISPLAYLISTINVALIDATION_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This stores the geometry of an nsDisplayItem, and the area
|
||||||
|
* that will be affected when painting the item.
|
||||||
|
*
|
||||||
|
* It is used to retain information about display items so they
|
||||||
|
* can be compared against new display items in the next paint.
|
||||||
|
*/
|
||||||
|
class nsDisplayItemGeometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsDisplayItemGeometry()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(nsDisplayItemGeometry);
|
||||||
|
}
|
||||||
|
virtual ~nsDisplayItemGeometry()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(nsDisplayItemGeometry);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Compute the area required to be invalidated if this
|
||||||
|
* display item is removed.
|
||||||
|
*/
|
||||||
|
nsRegion ComputeInvalidationRegion() { return mBounds; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifts all retained areas of the nsDisplayItemGeometry by the given offset.
|
||||||
|
*
|
||||||
|
* This is used to compensate for scrolling, since the destination buffer
|
||||||
|
* can scroll without requiring a full repaint.
|
||||||
|
*
|
||||||
|
* @param aOffset Offset to shift by.
|
||||||
|
*/
|
||||||
|
virtual void MoveBy(const nsPoint& aOffset) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The appunits per dev pixel for the item's frame.
|
||||||
|
*/
|
||||||
|
nscoord mAppUnitsPerDevPixel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The offset (in pixels) of the TopLeft() of the ThebesLayer
|
||||||
|
* this display item was drawn into.
|
||||||
|
*/
|
||||||
|
nsIntPoint mPaintOffset;
|
||||||
|
|
||||||
|
gfxPoint mActiveScrolledRootPosition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bounds of the display item
|
||||||
|
*/
|
||||||
|
nsRect mBounds;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A default geometry implementation, used by nsDisplayItem. Retains
|
||||||
|
* and compares the bounds, and border rect.
|
||||||
|
*
|
||||||
|
* This should be sufficient for the majority of display items.
|
||||||
|
*/
|
||||||
|
class nsDisplayItemGenericGeometry : public nsDisplayItemGeometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void MoveBy(const nsPoint& aOffset)
|
||||||
|
{
|
||||||
|
mBounds.MoveBy(aOffset);
|
||||||
|
mBorderRect.MoveBy(aOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect mBorderRect;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsDisplayBorderGeometry : public nsDisplayItemGeometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void MoveBy(const nsPoint& aOffset)
|
||||||
|
{
|
||||||
|
mBounds.MoveBy(aOffset);
|
||||||
|
mPaddingRect.MoveBy(aOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect mPaddingRect;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsDisplayBackgroundGeometry : public nsDisplayItemGeometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void MoveBy(const nsPoint& aOffset)
|
||||||
|
{
|
||||||
|
mBounds.MoveBy(aOffset);
|
||||||
|
mPaddingRect.MoveBy(aOffset);
|
||||||
|
mContentRect.MoveBy(aOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect mPaddingRect;
|
||||||
|
nsRect mContentRect;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsDisplayBoxShadowInnerGeometry : public nsDisplayItemGeometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void MoveBy(const nsPoint& aOffset)
|
||||||
|
{
|
||||||
|
mBounds.MoveBy(aOffset);
|
||||||
|
mPaddingRect.MoveBy(aOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect mPaddingRect;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*NSDISPLAYLISTINVALIDATION_H_*/
|
@ -2886,8 +2886,7 @@ DocumentViewerImpl::SetFullZoom(float aFullZoom)
|
|||||||
|
|
||||||
nsIFrame* rootFrame = shell->GetRootFrame();
|
nsIFrame* rootFrame = shell->GetRootFrame();
|
||||||
if (rootFrame) {
|
if (rootFrame) {
|
||||||
nsRect rect(nsPoint(0, 0), rootFrame->GetSize());
|
rootFrame->InvalidateFrame();
|
||||||
rootFrame->Invalidate(rect);
|
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -468,22 +468,11 @@ nsFrameManager::InsertFrames(nsIFrame* aParentFrame,
|
|||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsFrameManager::RemoveFrame(ChildListID aListID,
|
nsFrameManager::RemoveFrame(ChildListID aListID,
|
||||||
nsIFrame* aOldFrame,
|
nsIFrame* aOldFrame)
|
||||||
bool aInvalidate /* = true */)
|
|
||||||
{
|
{
|
||||||
bool wasDestroyingFrames = mIsDestroyingFrames;
|
bool wasDestroyingFrames = mIsDestroyingFrames;
|
||||||
mIsDestroyingFrames = true;
|
mIsDestroyingFrames = true;
|
||||||
|
|
||||||
// In case the reflow doesn't invalidate anything since it just leaves
|
|
||||||
// a gap where the old frame was, we invalidate it here. (This is
|
|
||||||
// reasonably likely to happen when removing a last child in a way
|
|
||||||
// that doesn't change the size of the parent.)
|
|
||||||
// This has to sure to invalidate the entire overflow rect; this
|
|
||||||
// is important in the presence of absolute positioning
|
|
||||||
if (aInvalidate) {
|
|
||||||
aOldFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(!aOldFrame->GetPrevContinuation() ||
|
NS_ASSERTION(!aOldFrame->GetPrevContinuation() ||
|
||||||
// exception for nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames
|
// exception for nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames
|
||||||
aOldFrame->GetType() == nsGkAtoms::textFrame,
|
aOldFrame->GetType() == nsGkAtoms::textFrame,
|
||||||
|
@ -95,8 +95,7 @@ public:
|
|||||||
nsFrameList& aFrameList);
|
nsFrameList& aFrameList);
|
||||||
|
|
||||||
NS_HIDDEN_(nsresult) RemoveFrame(ChildListID aListID,
|
NS_HIDDEN_(nsresult) RemoveFrame(ChildListID aListID,
|
||||||
nsIFrame* aOldFrame,
|
nsIFrame* aOldFrame);
|
||||||
bool aInvalidate = true);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notification that a frame is about to be destroyed. This allows any
|
* Notification that a frame is about to be destroyed. This allows any
|
||||||
|
@ -213,39 +213,7 @@ nsImageLoader::DoRedraw(const nsRect* aDamageRect)
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Invalidate the entire frame
|
// Invalidate the entire frame
|
||||||
// XXX We really only need to invalidate the client area of the frame...
|
|
||||||
|
|
||||||
nsRect bounds(nsPoint(0, 0), mFrame->GetSize());
|
|
||||||
|
|
||||||
if (mFrame->GetType() == nsGkAtoms::canvasFrame) {
|
|
||||||
// The canvas's background covers the whole viewport.
|
|
||||||
bounds = mFrame->GetVisualOverflowRect();
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX this should be ok, but there is some crappy ass bug causing it not to work
|
|
||||||
// XXX seems related to the "body fixup rule" dealing with the canvas and body frames...
|
|
||||||
#if 0
|
|
||||||
// Invalidate the entire frame only if the frame has a tiled background
|
|
||||||
// image, otherwise just invalidate the intersection of the frame's bounds
|
|
||||||
// with the damaged rect.
|
|
||||||
nsStyleContext* styleContext;
|
|
||||||
mFrame->GetStyleContext(&styleContext);
|
|
||||||
const nsStyleBackground* bg = styleContext->GetStyleBackground();
|
|
||||||
|
|
||||||
if ((bg->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) ||
|
|
||||||
(bg->mBackgroundRepeat == NS_STYLE_BG_REPEAT_OFF)) {
|
|
||||||
// The frame does not have a background image so we are free
|
|
||||||
// to invalidate only the intersection of the damage rect and
|
|
||||||
// the frame's bounds.
|
|
||||||
|
|
||||||
if (aDamageRect) {
|
|
||||||
bounds.IntersectRect(*aDamageRect, bounds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mFrame->GetStyleVisibility()->IsVisible()) {
|
if (mFrame->GetStyleVisibility()->IsVisible()) {
|
||||||
mFrame->Invalidate(bounds);
|
mFrame->InvalidateFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3988,6 +3988,8 @@ nsLayoutUtils::IsPopup(nsIFrame* aFrame)
|
|||||||
/* static */ nsIFrame*
|
/* static */ nsIFrame*
|
||||||
nsLayoutUtils::GetDisplayRootFrame(nsIFrame* aFrame)
|
nsLayoutUtils::GetDisplayRootFrame(nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
|
// We could use GetRootPresContext() here if the
|
||||||
|
// NS_FRAME_IN_POPUP frame bit is set.
|
||||||
nsIFrame* f = aFrame;
|
nsIFrame* f = aFrame;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (IsPopup(f))
|
if (IsPopup(f))
|
||||||
|
@ -83,6 +83,8 @@
|
|||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
|
PRUint8 gNotifySubDocInvalidationData;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class CharSetChangingRunnable : public nsRunnable
|
class CharSetChangingRunnable : public nsRunnable
|
||||||
@ -136,6 +138,21 @@ nsPresContext::PrefChangedCallback(const char* aPrefName, void* instance_data)
|
|||||||
return 0; // PREF_OK
|
return 0; // PREF_OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsPresContext::IsDOMPaintEventPending()
|
||||||
|
{
|
||||||
|
if (!mInvalidateRequests.mRequests.IsEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (GetRootPresContext()->mRefreshDriver->ViewManagerFlushIsPending()) {
|
||||||
|
// Since we're promising that there will be a MozAfterPaint event
|
||||||
|
// fired, we record an empty invalidation in case display list
|
||||||
|
// invalidation doesn't invalidate anything further.
|
||||||
|
NotifyInvalidation(nsRect(0, 0, 0, 0), 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsPresContext::PrefChangedUpdateTimerCallback(nsITimer *aTimer, void *aClosure)
|
nsPresContext::PrefChangedUpdateTimerCallback(nsITimer *aTimer, void *aClosure)
|
||||||
@ -801,7 +818,7 @@ nsPresContext::InvalidateThebesLayers()
|
|||||||
// FrameLayerBuilder caches invalidation-related values that depend on the
|
// FrameLayerBuilder caches invalidation-related values that depend on the
|
||||||
// appunits-per-dev-pixel ratio, so ensure that all ThebesLayer drawing
|
// appunits-per-dev-pixel ratio, so ensure that all ThebesLayer drawing
|
||||||
// is completely flushed.
|
// is completely flushed.
|
||||||
FrameLayerBuilder::InvalidateThebesLayersInSubtree(rootFrame);
|
rootFrame->InvalidateFrameSubtree();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2056,29 +2073,14 @@ nsPresContext::FireDOMPaintEvent()
|
|||||||
|
|
||||||
nsCOMPtr<nsIDOMEventTarget> dispatchTarget = do_QueryInterface(ourWindow);
|
nsCOMPtr<nsIDOMEventTarget> dispatchTarget = do_QueryInterface(ourWindow);
|
||||||
nsCOMPtr<nsIDOMEventTarget> eventTarget = dispatchTarget;
|
nsCOMPtr<nsIDOMEventTarget> eventTarget = dispatchTarget;
|
||||||
if (!IsChrome()) {
|
if (!IsChrome() && !mSendAfterPaintToContent) {
|
||||||
bool notifyContent = mSendAfterPaintToContent;
|
// Don't tell the window about this event, it should not know that
|
||||||
|
// something happened in a subdocument. Tell only the chrome event handler.
|
||||||
if (notifyContent) {
|
// (Events sent to the window get propagated to the chrome event handler
|
||||||
// If the pref is set, we still don't post events when they're
|
// automatically.)
|
||||||
// entirely cross-doc.
|
dispatchTarget = do_QueryInterface(ourWindow->GetParentTarget());
|
||||||
notifyContent = false;
|
if (!dispatchTarget) {
|
||||||
for (PRUint32 i = 0; i < mInvalidateRequests.mRequests.Length(); ++i) {
|
return;
|
||||||
if (!(mInvalidateRequests.mRequests[i].mFlags &
|
|
||||||
nsIFrame::INVALIDATE_CROSS_DOC)) {
|
|
||||||
notifyContent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!notifyContent) {
|
|
||||||
// Don't tell the window about this event, it should not know that
|
|
||||||
// something happened in a subdocument. Tell only the chrome event handler.
|
|
||||||
// (Events sent to the window get propagated to the chrome event handler
|
|
||||||
// automatically.)
|
|
||||||
dispatchTarget = do_QueryInterface(ourWindow->GetParentTarget());
|
|
||||||
if (!dispatchTarget) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Events sent to the window get propagated to the chrome event handler
|
// Events sent to the window get propagated to the chrome event handler
|
||||||
@ -2102,6 +2104,24 @@ nsPresContext::FireDOMPaintEvent()
|
|||||||
nsEventDispatcher::DispatchDOMEvent(dispatchTarget, nsnull, event, this, nsnull);
|
nsEventDispatcher::DispatchDOMEvent(dispatchTarget, nsnull, event, this, nsnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
MayHavePaintEventListenerSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
||||||
|
{
|
||||||
|
bool *result = static_cast<bool*>(aData);
|
||||||
|
nsIPresShell* shell = aDocument->GetShell();
|
||||||
|
if (shell) {
|
||||||
|
nsPresContext* pc = shell->GetPresContext();
|
||||||
|
if (pc) {
|
||||||
|
*result = pc->MayHavePaintEventListenerInSubDocument();
|
||||||
|
|
||||||
|
// If we found a paint event listener, then we can stop enumerating
|
||||||
|
// sub documents.
|
||||||
|
return !*result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
MayHavePaintEventListener(nsPIDOMWindow* aInnerWindow)
|
MayHavePaintEventListener(nsPIDOMWindow* aInnerWindow)
|
||||||
{
|
{
|
||||||
@ -2153,6 +2173,28 @@ nsPresContext::MayHavePaintEventListener()
|
|||||||
return ::MayHavePaintEventListener(mDocument->GetInnerWindow());
|
return ::MayHavePaintEventListener(mDocument->GetInnerWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsPresContext::MayHavePaintEventListenerInSubDocument()
|
||||||
|
{
|
||||||
|
if (MayHavePaintEventListener()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
mDocument->EnumerateSubDocuments(MayHavePaintEventListenerSubdocumentCallback, &result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsPresContext::NotifyInvalidation(const nsIntRect& aRect, PRUint32 aFlags)
|
||||||
|
{
|
||||||
|
nsRect rect(DevPixelsToAppUnits(aRect.x),
|
||||||
|
DevPixelsToAppUnits(aRect.y),
|
||||||
|
DevPixelsToAppUnits(aRect.width),
|
||||||
|
DevPixelsToAppUnits(aRect.height));
|
||||||
|
NotifyInvalidation(rect, aFlags);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsPresContext::NotifyInvalidation(const nsRect& aRect, PRUint32 aFlags)
|
nsPresContext::NotifyInvalidation(const nsRect& aRect, PRUint32 aFlags)
|
||||||
{
|
{
|
||||||
@ -2161,8 +2203,6 @@ nsPresContext::NotifyInvalidation(const nsRect& aRect, PRUint32 aFlags)
|
|||||||
// MayHavePaintEventListener is pretty cheap and we could make it
|
// MayHavePaintEventListener is pretty cheap and we could make it
|
||||||
// even cheaper by providing a more efficient
|
// even cheaper by providing a more efficient
|
||||||
// nsPIDOMWindow::GetListenerManager.
|
// nsPIDOMWindow::GetListenerManager.
|
||||||
if (aRect.IsEmpty() || !MayHavePaintEventListener())
|
|
||||||
return;
|
|
||||||
|
|
||||||
nsPresContext* pc;
|
nsPresContext* pc;
|
||||||
for (pc = this; pc; pc = pc->GetParentPresContext()) {
|
for (pc = this; pc; pc = pc->GetParentPresContext()) {
|
||||||
@ -2186,6 +2226,30 @@ nsPresContext::NotifyInvalidation(const nsRect& aRect, PRUint32 aFlags)
|
|||||||
request->mFlags = aFlags;
|
request->mFlags = aFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
nsPresContext::NotifySubDocInvalidation(ContainerLayer* aContainer,
|
||||||
|
const nsIntRegion& aRegion)
|
||||||
|
{
|
||||||
|
ContainerLayerPresContext *data =
|
||||||
|
static_cast<ContainerLayerPresContext*>(
|
||||||
|
aContainer->GetUserData(&gNotifySubDocInvalidationData));
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntPoint topLeft = aContainer->GetVisibleRegion().GetBounds().TopLeft();
|
||||||
|
|
||||||
|
nsIntRegionRectIterator iter(aRegion);
|
||||||
|
while (const nsIntRect* r = iter.Next()) {
|
||||||
|
nsIntRect rect = *r;
|
||||||
|
//PresContext coordinate space is relative to the start of our visible
|
||||||
|
// region. Is this really true? This feels like the wrong way to get the right
|
||||||
|
// answer.
|
||||||
|
rect.MoveBy(-topLeft);
|
||||||
|
data->mPresContext->NotifyInvalidation(rect, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
||||||
{
|
{
|
||||||
@ -2202,19 +2266,18 @@ NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
|||||||
void
|
void
|
||||||
nsPresContext::NotifyDidPaintForSubtree()
|
nsPresContext::NotifyDidPaintForSubtree()
|
||||||
{
|
{
|
||||||
if (!mFireAfterPaintEvents)
|
|
||||||
return;
|
|
||||||
mFireAfterPaintEvents = false;
|
|
||||||
|
|
||||||
if (IsRoot()) {
|
if (IsRoot()) {
|
||||||
|
if (!mFireAfterPaintEvents)
|
||||||
|
return;
|
||||||
|
|
||||||
static_cast<nsRootPresContext*>(this)->CancelDidPaintTimer();
|
static_cast<nsRootPresContext*>(this)->CancelDidPaintTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mInvalidateRequests.mRequests.IsEmpty()) {
|
mFireAfterPaintEvents = false;
|
||||||
nsCOMPtr<nsIRunnable> ev =
|
|
||||||
NS_NewRunnableMethod(this, &nsPresContext::FireDOMPaintEvent);
|
nsCOMPtr<nsIRunnable> ev =
|
||||||
nsContentUtils::AddScriptRunner(ev);
|
NS_NewRunnableMethod(this, &nsPresContext::FireDOMPaintEvent);
|
||||||
}
|
nsContentUtils::AddScriptRunner(ev);
|
||||||
|
|
||||||
mDocument->EnumerateSubDocuments(NotifyDidPaintSubdocumentCallback, nsnull);
|
mDocument->EnumerateSubDocuments(NotifyDidPaintSubdocumentCallback, nsnull);
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,17 @@ public:
|
|||||||
nsTArray<Request> mRequests;
|
nsTArray<Request> mRequests;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layer UserData for ContainerLayers that want to be notified
|
||||||
|
* of local invalidations of them and their descendant layers.
|
||||||
|
* Pass a callback to ComputeDifferences to have these called.
|
||||||
|
*/
|
||||||
|
class ContainerLayerPresContext : public mozilla::layers::LayerUserData {
|
||||||
|
public:
|
||||||
|
nsPresContext* mPresContext;
|
||||||
|
};
|
||||||
|
extern PRUint8 gNotifySubDocInvalidationData;
|
||||||
|
|
||||||
/* Used by nsPresContext::HasAuthorSpecifiedRules */
|
/* Used by nsPresContext::HasAuthorSpecifiedRules */
|
||||||
#define NS_AUTHOR_SPECIFIED_BACKGROUND (1 << 0)
|
#define NS_AUTHOR_SPECIFIED_BACKGROUND (1 << 0)
|
||||||
#define NS_AUTHOR_SPECIFIED_BORDER (1 << 1)
|
#define NS_AUTHOR_SPECIFIED_BORDER (1 << 1)
|
||||||
@ -840,12 +851,16 @@ public:
|
|||||||
bool EnsureSafeToHandOutCSSRules();
|
bool EnsureSafeToHandOutCSSRules();
|
||||||
|
|
||||||
void NotifyInvalidation(const nsRect& aRect, PRUint32 aFlags);
|
void NotifyInvalidation(const nsRect& aRect, PRUint32 aFlags);
|
||||||
|
// aRect is in device pixels
|
||||||
|
void NotifyInvalidation(const nsIntRect& aRect, PRUint32 aFlags);
|
||||||
void NotifyDidPaintForSubtree();
|
void NotifyDidPaintForSubtree();
|
||||||
void FireDOMPaintEvent();
|
void FireDOMPaintEvent();
|
||||||
|
|
||||||
bool IsDOMPaintEventPending() {
|
// Callback for catching invalidations in ContainerLayers
|
||||||
return !mInvalidateRequests.mRequests.IsEmpty();
|
// Passed to LayerProperties::ComputeDifference
|
||||||
}
|
static void NotifySubDocInvalidation(mozilla::layers::ContainerLayer* aContainer,
|
||||||
|
const nsIntRegion& aRegion);
|
||||||
|
bool IsDOMPaintEventPending();
|
||||||
void ClearMozAfterPaintEvents() {
|
void ClearMozAfterPaintEvents() {
|
||||||
mInvalidateRequests.mRequests.Clear();
|
mInvalidateRequests.mRequests.Clear();
|
||||||
}
|
}
|
||||||
@ -1060,12 +1075,22 @@ protected:
|
|||||||
public:
|
public:
|
||||||
void DoChangeCharSet(const nsCString& aCharSet);
|
void DoChangeCharSet(const nsCString& aCharSet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for MozAfterPaint listeners on the document
|
||||||
|
*/
|
||||||
|
bool MayHavePaintEventListener();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for MozAfterPaint listeners on the document and
|
||||||
|
* any subdocuments, except for subdocuments that are non-top-level
|
||||||
|
* content documents.
|
||||||
|
*/
|
||||||
|
bool MayHavePaintEventListenerInSubDocument();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void InvalidateThebesLayers();
|
void InvalidateThebesLayers();
|
||||||
void AppUnitsPerDevPixelChanged();
|
void AppUnitsPerDevPixelChanged();
|
||||||
|
|
||||||
bool MayHavePaintEventListener();
|
|
||||||
|
|
||||||
void HandleRebuildUserFontSet() {
|
void HandleRebuildUserFontSet() {
|
||||||
mPostedFlushUserFontSet = false;
|
mPostedFlushUserFontSet = false;
|
||||||
FlushUserFontSet();
|
FlushUserFontSet();
|
||||||
|
@ -3550,8 +3550,7 @@ PresShell::UnsuppressAndInvalidate()
|
|||||||
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
|
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
|
||||||
if (rootFrame) {
|
if (rootFrame) {
|
||||||
// let's assume that outline on a root frame is not supported
|
// let's assume that outline on a root frame is not supported
|
||||||
nsRect rect(nsPoint(0, 0), rootFrame->GetSize());
|
rootFrame->InvalidateFrame();
|
||||||
rootFrame->Invalidate(rect);
|
|
||||||
|
|
||||||
if (mCaretEnabled && mCaret) {
|
if (mCaretEnabled && mCaret) {
|
||||||
mCaret->CheckCaretDrawingState();
|
mCaret->CheckCaretDrawingState();
|
||||||
@ -3949,12 +3948,7 @@ PresShell::DocumentStatesChanged(nsIDocument* aDocument,
|
|||||||
VERIFY_STYLE_TREE;
|
VERIFY_STYLE_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aStateMask.HasState(NS_DOCUMENT_STATE_WINDOW_INACTIVE)) {
|
ScheduleViewManagerFlush();
|
||||||
nsIFrame* root = mFrameConstructor->GetRootFrame();
|
|
||||||
if (root) {
|
|
||||||
root->InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -6094,13 +6088,11 @@ PresShell::ShowEventTargetDebug()
|
|||||||
if (nsFrame::GetShowEventTargetFrameBorder() &&
|
if (nsFrame::GetShowEventTargetFrameBorder() &&
|
||||||
GetCurrentEventFrame()) {
|
GetCurrentEventFrame()) {
|
||||||
if (mDrawEventTargetFrame) {
|
if (mDrawEventTargetFrame) {
|
||||||
mDrawEventTargetFrame->Invalidate(
|
mDrawEventTargetFrame->InvalidateFrame();
|
||||||
nsRect(nsPoint(0, 0), mDrawEventTargetFrame->GetSize()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mDrawEventTargetFrame = mCurrentEventFrame;
|
mDrawEventTargetFrame = mCurrentEventFrame;
|
||||||
mDrawEventTargetFrame->Invalidate(
|
mDrawEventTargetFrame->InvalidateFrame();
|
||||||
nsRect(nsPoint(0, 0), mDrawEventTargetFrame->GetSize()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -7308,6 +7300,8 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
|
|||||||
NS_TIME_FUNCTION_WITH_DOCURL;
|
NS_TIME_FUNCTION_WITH_DOCURL;
|
||||||
SAMPLE_LABEL("layout", "DoReflow");
|
SAMPLE_LABEL("layout", "DoReflow");
|
||||||
|
|
||||||
|
target->SchedulePaint();
|
||||||
|
|
||||||
if (mReflowContinueTimer) {
|
if (mReflowContinueTimer) {
|
||||||
mReflowContinueTimer->Cancel();
|
mReflowContinueTimer->Cancel();
|
||||||
mReflowContinueTimer = nsnull;
|
mReflowContinueTimer = nsnull;
|
||||||
@ -7333,11 +7327,6 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
|
|||||||
nsSize size;
|
nsSize size;
|
||||||
if (target == rootFrame) {
|
if (target == rootFrame) {
|
||||||
size = mPresContext->GetVisibleArea().Size();
|
size = mPresContext->GetVisibleArea().Size();
|
||||||
|
|
||||||
// target->GetRect() has the old size of the frame,
|
|
||||||
// mPresContext->GetVisibleArea() has the new size.
|
|
||||||
target->InvalidateRectDifference(mPresContext->GetVisibleArea(),
|
|
||||||
target->GetRect());
|
|
||||||
} else {
|
} else {
|
||||||
size = target->GetSize();
|
size = target->GetSize();
|
||||||
}
|
}
|
||||||
|
@ -155,6 +155,9 @@ public:
|
|||||||
void RevokeViewManagerFlush() {
|
void RevokeViewManagerFlush() {
|
||||||
mViewManagerFlushIsPending = false;
|
mViewManagerFlushIsPending = false;
|
||||||
}
|
}
|
||||||
|
bool ViewManagerFlushIsPending() {
|
||||||
|
return mViewManagerFlushIsPending;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a document for which we have nsIFrameRequestCallbacks
|
* Add a document for which we have nsIFrameRequestCallbacks
|
||||||
|
@ -117,11 +117,18 @@ public:
|
|||||||
}
|
}
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||||
nsRenderingContext* aCtx);
|
nsRenderingContext* aCtx);
|
||||||
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
|
||||||
NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND)
|
NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND)
|
||||||
private:
|
private:
|
||||||
nsButtonFrameRenderer* mBFR;
|
nsButtonFrameRenderer* mBFR;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nsRect
|
||||||
|
nsDisplayButtonBorderBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
|
||||||
|
*aSnap = false;
|
||||||
|
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
|
||||||
|
}
|
||||||
|
|
||||||
class nsDisplayButtonForeground : public nsDisplayItem {
|
class nsDisplayButtonForeground : public nsDisplayItem {
|
||||||
public:
|
public:
|
||||||
nsDisplayButtonForeground(nsDisplayListBuilder* aBuilder,
|
nsDisplayButtonForeground(nsDisplayListBuilder* aBuilder,
|
||||||
|
@ -356,7 +356,7 @@ nsComboboxControlFrame::SetFocus(bool aOn, bool aRepaint)
|
|||||||
// This is needed on a temporary basis. It causes the focus
|
// This is needed on a temporary basis. It causes the focus
|
||||||
// rect to be drawn. This is much faster than ReResolvingStyle
|
// rect to be drawn. This is much faster than ReResolvingStyle
|
||||||
// Bug 32920
|
// Bug 32920
|
||||||
Invalidate(nsRect(0,0,mRect.width,mRect.height));
|
InvalidateFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -584,7 +584,7 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, mContentFrame);
|
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, mContentFrame);
|
||||||
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
|
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||||
|
|
||||||
Invalidate(aDesiredSize.VisualOverflow());
|
InvalidateFrame();
|
||||||
|
|
||||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -257,15 +257,7 @@ nsListControlFrame::InvalidateFocus()
|
|||||||
|
|
||||||
nsIFrame* containerFrame = GetOptionsContainer();
|
nsIFrame* containerFrame = GetOptionsContainer();
|
||||||
if (containerFrame) {
|
if (containerFrame) {
|
||||||
// Invalidating from the containerFrame because that's where our focus
|
containerFrame->InvalidateFrame();
|
||||||
// is drawn.
|
|
||||||
// The origin of the scrollport is the origin of containerFrame.
|
|
||||||
float inflation = nsLayoutUtils::FontSizeInflationFor(this);
|
|
||||||
nsRect invalidateArea = containerFrame->GetVisualOverflowRect();
|
|
||||||
nsRect emptyFallbackArea(0, 0, GetScrollPortRect().width,
|
|
||||||
CalcFallbackRowHeight(inflation));
|
|
||||||
invalidateArea.UnionRect(invalidateArea, emptyFallbackArea);
|
|
||||||
containerFrame->Invalidate(invalidateArea);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1000,6 +992,8 @@ nsListControlFrame::Init(nsIContent* aContent,
|
|||||||
|
|
||||||
mLastDropdownBackstopColor = PresContext()->DefaultBackgroundColor();
|
mLastDropdownBackstopColor = PresContext()->DefaultBackgroundColor();
|
||||||
|
|
||||||
|
AddStateBits(NS_FRAME_IN_POPUP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1679,18 +1673,6 @@ nsListControlFrame::GetType() const
|
|||||||
return nsGkAtoms::listControlFrame;
|
return nsGkAtoms::listControlFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsListControlFrame::InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
if (!IsInDropDownMode()) {
|
|
||||||
nsHTMLScrollFrame::InvalidateInternal(aDamageRect, aX, aY, this, aFlags);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
InvalidateRoot(aDamageRect + nsPoint(aX, aY), aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsListControlFrame::GetFrameName(nsAString& aResult) const
|
nsListControlFrame::GetFrameName(nsAString& aResult) const
|
||||||
|
@ -91,10 +91,6 @@ public:
|
|||||||
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
|
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
||||||
#endif
|
#endif
|
||||||
|
@ -210,7 +210,7 @@ nsMeterFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||||||
PresContext()->PresShell()->FrameNeedsReflow(barFrame,
|
PresContext()->PresShell()->FrameNeedsReflow(barFrame,
|
||||||
nsIPresShell::eResize,
|
nsIPresShell::eResize,
|
||||||
NS_FRAME_IS_DIRTY);
|
NS_FRAME_IS_DIRTY);
|
||||||
Invalidate(GetVisualOverflowRectRelativeToSelf());
|
InvalidateFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
|
return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
|
||||||
|
@ -225,7 +225,7 @@ nsProgressFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||||||
NS_ASSERTION(barFrame, "The progress frame should have a child with a frame!");
|
NS_ASSERTION(barFrame, "The progress frame should have a child with a frame!");
|
||||||
PresContext()->PresShell()->FrameNeedsReflow(barFrame, nsIPresShell::eResize,
|
PresContext()->PresShell()->FrameNeedsReflow(barFrame, nsIPresShell::eResize,
|
||||||
NS_FRAME_IS_DIRTY);
|
NS_FRAME_IS_DIRTY);
|
||||||
Invalidate(GetVisualOverflowRectRelativeToSelf());
|
InvalidateFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||||
|
@ -456,23 +456,6 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
|
|||||||
nsContainerFrame::PositionChildViews(aKidFrame);
|
nsContainerFrame::PositionChildViews(aKidFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldRect.TopLeft() != rect.TopLeft() ||
|
|
||||||
(aDelegatingFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
|
||||||
// The frame moved
|
|
||||||
aKidFrame->GetParent()->Invalidate(oldOverflowRect);
|
|
||||||
aKidFrame->InvalidateFrameSubtree();
|
|
||||||
} else if (oldRect.Size() != rect.Size()) {
|
|
||||||
// Invalidate the area where the frame changed size.
|
|
||||||
nscoord innerWidth = NS_MIN(oldRect.width, rect.width);
|
|
||||||
nscoord innerHeight = NS_MIN(oldRect.height, rect.height);
|
|
||||||
nscoord outerWidth = NS_MAX(oldRect.width, rect.width);
|
|
||||||
nscoord outerHeight = NS_MAX(oldRect.height, rect.height);
|
|
||||||
aKidFrame->GetParent()->Invalidate(
|
|
||||||
nsRect(rect.x + innerWidth, rect.y, outerWidth - innerWidth, outerHeight));
|
|
||||||
// Invalidate the horizontal strip
|
|
||||||
aKidFrame->GetParent()->Invalidate(
|
|
||||||
nsRect(rect.x, rect.y + innerHeight, outerWidth, outerHeight - innerHeight));
|
|
||||||
}
|
|
||||||
aKidFrame->DidReflow(aPresContext, &kidReflowState, NS_FRAME_REFLOW_FINISHED);
|
aKidFrame->DidReflow(aPresContext, &kidReflowState, NS_FRAME_REFLOW_FINISHED);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -487,32 +487,6 @@ nsBlockFrame::GetType() const
|
|||||||
return nsGkAtoms::blockFrame;
|
return nsGkAtoms::blockFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsBlockFrame::InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
// Optimize by suppressing invalidation of areas that are clipped out
|
|
||||||
// with CSS 'clip'. Don't suppress invalidation of *this* frame directly,
|
|
||||||
// because when 'clip' shrinks we need to invalidate this frame and
|
|
||||||
// be able to invalidate areas outside the 'clip'.
|
|
||||||
if (aForChild) {
|
|
||||||
const nsStyleDisplay* disp = GetStyleDisplay();
|
|
||||||
nsRect clipRect;
|
|
||||||
if (GetClipPropClipRect(disp, &clipRect, GetSize())) {
|
|
||||||
// Restrict the invalidated area to abs-pos clip rect
|
|
||||||
// abs-pos clipping clips everything in the frame
|
|
||||||
nsRect r;
|
|
||||||
if (r.IntersectRect(aDamageRect, clipRect - nsPoint(aX, aY))) {
|
|
||||||
nsBlockFrameSuper::InvalidateInternal(r, aX, aY, this, aFlags);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsBlockFrameSuper::InvalidateInternal(aDamageRect, aX, aY, this, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
nscoord
|
nscoord
|
||||||
nsBlockFrame::GetBaseline() const
|
nsBlockFrame::GetBaseline() const
|
||||||
{
|
{
|
||||||
@ -1213,9 +1187,6 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if we need to repaint our border, background or outline
|
|
||||||
CheckInvalidateSizeChange(aMetrics);
|
|
||||||
|
|
||||||
FinishAndStoreOverflow(&aMetrics);
|
FinishAndStoreOverflow(&aMetrics);
|
||||||
|
|
||||||
// Clear the float manager pointer in the block reflow state so we
|
// Clear the float manager pointer in the block reflow state so we
|
||||||
@ -2475,18 +2446,6 @@ nsBlockFrame::DeleteLine(nsBlockReflowState& aState,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
InvalidateThebesLayersInLineBox(nsIFrame* aBlock, nsLineBox* aLine)
|
|
||||||
{
|
|
||||||
if (aBlock->GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT) {
|
|
||||||
PRInt32 childCount = aLine->GetChildCount();
|
|
||||||
for (nsIFrame* f = aLine->mFirstChild; childCount;
|
|
||||||
--childCount, f = f->GetNextSibling()) {
|
|
||||||
FrameLayerBuilder::InvalidateThebesLayersInSubtree(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflow a line. The line will either contain a single block frame
|
* Reflow a line. The line will either contain a single block frame
|
||||||
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
||||||
@ -2509,78 +2468,10 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
|
|||||||
|
|
||||||
// Now that we know what kind of line we have, reflow it
|
// Now that we know what kind of line we have, reflow it
|
||||||
if (aLine->IsBlock()) {
|
if (aLine->IsBlock()) {
|
||||||
nsRect oldBounds = aLine->mFirstChild->GetRect();
|
|
||||||
nsRect oldVisOverflow(aLine->GetVisualOverflowArea());
|
|
||||||
rv = ReflowBlockFrame(aState, aLine, aKeepReflowGoing);
|
rv = ReflowBlockFrame(aState, aLine, aKeepReflowGoing);
|
||||||
nsRect newBounds = aLine->mFirstChild->GetRect();
|
} else {
|
||||||
|
|
||||||
// We expect blocks to damage any area inside their bounds that is
|
|
||||||
// dirty; however, if the frame changes size or position then we
|
|
||||||
// need to do some repainting.
|
|
||||||
// XXX roc --- the above statement is ambiguous about whether 'bounds'
|
|
||||||
// means the frame's bounds or overflowArea, and in fact this is a source
|
|
||||||
// of much confusion and bugs. Thus the following hack considers *both*
|
|
||||||
// overflowArea and bounds. This should be considered a temporary hack
|
|
||||||
// until we decide how it's really supposed to work.
|
|
||||||
// Note that we have a similar hack in nsTableFrame::InvalidateFrame.
|
|
||||||
nsRect visOverflow(aLine->GetVisualOverflowArea());
|
|
||||||
if (oldVisOverflow.TopLeft() != visOverflow.TopLeft() ||
|
|
||||||
oldBounds.TopLeft() != newBounds.TopLeft()) {
|
|
||||||
// The block has moved, and so to be safe we need to repaint
|
|
||||||
// XXX We need to improve on this...
|
|
||||||
nsRect dirtyRect;
|
|
||||||
dirtyRect.UnionRect(oldVisOverflow, visOverflow);
|
|
||||||
#ifdef NOISY_BLOCK_INVALIDATE
|
|
||||||
printf("%p invalidate 6 (%d, %d, %d, %d)\n",
|
|
||||||
this, dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);
|
|
||||||
#endif
|
|
||||||
Invalidate(dirtyRect);
|
|
||||||
FrameLayerBuilder::InvalidateThebesLayersInSubtree(aLine->mFirstChild);
|
|
||||||
} else {
|
|
||||||
nsRect combinedAreaHStrip, combinedAreaVStrip;
|
|
||||||
nsRect boundsHStrip, boundsVStrip;
|
|
||||||
nsLayoutUtils::GetRectDifferenceStrips(oldBounds, newBounds,
|
|
||||||
&boundsHStrip, &boundsVStrip);
|
|
||||||
nsLayoutUtils::GetRectDifferenceStrips(oldVisOverflow, visOverflow,
|
|
||||||
&combinedAreaHStrip,
|
|
||||||
&combinedAreaVStrip);
|
|
||||||
|
|
||||||
#ifdef NOISY_BLOCK_INVALIDATE
|
|
||||||
printf("%p invalidate boundsVStrip (%d, %d, %d, %d)\n",
|
|
||||||
this, boundsVStrip.x, boundsVStrip.y, boundsVStrip.width, boundsVStrip.height);
|
|
||||||
printf("%p invalidate boundsHStrip (%d, %d, %d, %d)\n",
|
|
||||||
this, boundsHStrip.x, boundsHStrip.y, boundsHStrip.width, boundsHStrip.height);
|
|
||||||
printf("%p invalidate combinedAreaVStrip (%d, %d, %d, %d)\n",
|
|
||||||
this, combinedAreaVStrip.x, combinedAreaVStrip.y, combinedAreaVStrip.width, combinedAreaVStrip.height);
|
|
||||||
printf("%p invalidate combinedAreaHStrip (%d, %d, %d, %d)\n",
|
|
||||||
this, combinedAreaHStrip.x, combinedAreaHStrip.y, combinedAreaHStrip.width, combinedAreaHStrip.height);
|
|
||||||
#endif
|
|
||||||
// The first thing Invalidate does is check if the rect is empty, so
|
|
||||||
// don't bother doing that here.
|
|
||||||
Invalidate(boundsVStrip);
|
|
||||||
Invalidate(boundsHStrip);
|
|
||||||
Invalidate(combinedAreaVStrip);
|
|
||||||
Invalidate(combinedAreaHStrip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nsRect oldVisOverflow(aLine->GetVisualOverflowArea());
|
|
||||||
aLine->SetLineWrapped(false);
|
aLine->SetLineWrapped(false);
|
||||||
|
|
||||||
rv = ReflowInlineFrames(aState, aLine, aKeepReflowGoing);
|
rv = ReflowInlineFrames(aState, aLine, aKeepReflowGoing);
|
||||||
|
|
||||||
// We don't really know what changed in the line, so use the union
|
|
||||||
// of the old and new combined areas
|
|
||||||
nsRect dirtyRect;
|
|
||||||
dirtyRect.UnionRect(oldVisOverflow, aLine->GetVisualOverflowArea());
|
|
||||||
#ifdef NOISY_BLOCK_INVALIDATE
|
|
||||||
printf("%p invalidate (%d, %d, %d, %d)\n",
|
|
||||||
this, dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);
|
|
||||||
if (aLine->IsForceInvalidate())
|
|
||||||
printf(" dirty line is %p\n", static_cast<void*>(aLine.get()));
|
|
||||||
#endif
|
|
||||||
Invalidate(dirtyRect);
|
|
||||||
InvalidateThebesLayersInLineBox(this, aLine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@ -2684,9 +2575,6 @@ nsBlockFrame::PullFrameFrom(nsBlockReflowState& aState,
|
|||||||
} else {
|
} else {
|
||||||
// Free up the fromLine now that it's empty
|
// Free up the fromLine now that it's empty
|
||||||
// Its bounds might need to be redrawn, though.
|
// Its bounds might need to be redrawn, though.
|
||||||
// XXX WHY do we invalidate the bounds AND the combined area? doesn't
|
|
||||||
// the combined area always enclose the bounds?
|
|
||||||
Invalidate(fromLine->mBounds);
|
|
||||||
FrameLines* overflowLines =
|
FrameLines* overflowLines =
|
||||||
aFromOverflowLine ? aFromContainer->RemoveOverflowLines() : nsnull;
|
aFromOverflowLine ? aFromContainer->RemoveOverflowLines() : nsnull;
|
||||||
nsLineList* fromLineList =
|
nsLineList* fromLineList =
|
||||||
@ -2694,7 +2582,6 @@ nsBlockFrame::PullFrameFrom(nsBlockReflowState& aState,
|
|||||||
if (aFromLine.next() != fromLineList->end())
|
if (aFromLine.next() != fromLineList->end())
|
||||||
aFromLine.next()->MarkPreviousMarginDirty();
|
aFromLine.next()->MarkPreviousMarginDirty();
|
||||||
|
|
||||||
Invalidate(fromLine->GetVisualOverflowArea());
|
|
||||||
fromLineList->erase(aFromLine);
|
fromLineList->erase(aFromLine);
|
||||||
// aFromLine is now invalid
|
// aFromLine is now invalid
|
||||||
aFromContainer->FreeLineBox(fromLine);
|
aFromContainer->FreeLineBox(fromLine);
|
||||||
@ -2734,11 +2621,8 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
|
|||||||
{
|
{
|
||||||
NS_PRECONDITION(aDY != 0, "why slide a line nowhere?");
|
NS_PRECONDITION(aDY != 0, "why slide a line nowhere?");
|
||||||
|
|
||||||
Invalidate(aLine->GetVisualOverflowArea());
|
|
||||||
// Adjust line state
|
// Adjust line state
|
||||||
aLine->SlideBy(aDY);
|
aLine->SlideBy(aDY);
|
||||||
Invalidate(aLine->GetVisualOverflowArea());
|
|
||||||
InvalidateThebesLayersInLineBox(this, aLine);
|
|
||||||
|
|
||||||
// Adjust the frames in the line
|
// Adjust the frames in the line
|
||||||
nsIFrame* kid = aLine->mFirstChild;
|
nsIFrame* kid = aLine->mFirstChild;
|
||||||
@ -3036,9 +2920,6 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||||||
// its view as needed.
|
// its view as needed.
|
||||||
nsPoint originalPosition = frame->GetPosition();
|
nsPoint originalPosition = frame->GetPosition();
|
||||||
while (true) {
|
while (true) {
|
||||||
// Save the frame's current position. We might need it later.
|
|
||||||
nscoord passOriginalY = frame->GetRect().y;
|
|
||||||
|
|
||||||
clearance = 0;
|
clearance = 0;
|
||||||
nscoord topMargin = 0;
|
nscoord topMargin = 0;
|
||||||
bool mayNeedRetry = false;
|
bool mayNeedRetry = false;
|
||||||
@ -3205,14 +3086,6 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||||||
clearance, aState.IsAdjacentWithTop(),
|
clearance, aState.IsAdjacentWithTop(),
|
||||||
aLine.get(), blockHtmlRS, frameReflowStatus, aState);
|
aLine.get(), blockHtmlRS, frameReflowStatus, aState);
|
||||||
|
|
||||||
// If this was a second-pass reflow and the block's vertical position
|
|
||||||
// changed, invalidates from the first pass might have happened in the
|
|
||||||
// wrong places. Invalidate the entire overflow rect at the new position.
|
|
||||||
if (!mayNeedRetry && clearanceFrame &&
|
|
||||||
frame->GetRect().y != passOriginalY) {
|
|
||||||
Invalidate(frame->GetVisualOverflowRect() + frame->GetPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (mayNeedRetry && clearanceFrame) {
|
if (mayNeedRetry && clearanceFrame) {
|
||||||
@ -5547,7 +5420,6 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aDeletedFrame, PRUint32 aFlags)
|
|||||||
this, visOverflow.x, visOverflow.y,
|
this, visOverflow.x, visOverflow.y,
|
||||||
visOverflow.width, visOverflow.height);
|
visOverflow.width, visOverflow.height);
|
||||||
#endif
|
#endif
|
||||||
Invalidate(visOverflow);
|
|
||||||
} else {
|
} else {
|
||||||
// XXX update searchingOverflowList directly, remove only when empty
|
// XXX update searchingOverflowList directly, remove only when empty
|
||||||
FrameLines* overflowLines = RemoveOverflowLines();
|
FrameLines* overflowLines = RemoveOverflowLines();
|
||||||
@ -6006,24 +5878,8 @@ nsBlockFrame::ReflowPushedFloats(nsBlockReflowState& aState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (NS_SUBTREE_DIRTY(f) || aState.mReflowState.ShouldReflowAllKids()) {
|
if (NS_SUBTREE_DIRTY(f) || aState.mReflowState.ShouldReflowAllKids()) {
|
||||||
// Cache old bounds
|
|
||||||
nsRect oldRect = f->GetRect();
|
|
||||||
nsRect oldOverflow = f->GetVisualOverflowRect();
|
|
||||||
|
|
||||||
// Reflow
|
// Reflow
|
||||||
aState.FlowAndPlaceFloat(f);
|
aState.FlowAndPlaceFloat(f);
|
||||||
|
|
||||||
// Invalidate if there was a position or size change
|
|
||||||
nsRect rect = f->GetRect();
|
|
||||||
if (!rect.IsEqualInterior(oldRect)) {
|
|
||||||
nsRect dirtyRect = oldOverflow;
|
|
||||||
dirtyRect.MoveBy(oldRect.x, oldRect.y);
|
|
||||||
Invalidate(dirtyRect);
|
|
||||||
|
|
||||||
dirtyRect = f->GetVisualOverflowRect();
|
|
||||||
dirtyRect.MoveBy(rect.x, rect.y);
|
|
||||||
Invalidate(dirtyRect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Just reload the float region into the space manager
|
// Just reload the float region into the space manager
|
||||||
|
@ -158,9 +158,6 @@ public:
|
|||||||
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
const nsDisplayListSet& aLists);
|
const nsDisplayListSet& aLists);
|
||||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags);
|
|
||||||
virtual nsIAtom* GetType() const;
|
virtual nsIAtom* GetType() const;
|
||||||
virtual bool IsFrameOfType(PRUint32 aFlags) const
|
virtual bool IsFrameOfType(PRUint32 aFlags) const
|
||||||
{
|
{
|
||||||
|
@ -790,7 +790,6 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||||||
aFloat->SetPosition(origin);
|
aFloat->SetPosition(origin);
|
||||||
nsContainerFrame::PositionFrameView(aFloat);
|
nsContainerFrame::PositionFrameView(aFloat);
|
||||||
nsContainerFrame::PositionChildViews(aFloat);
|
nsContainerFrame::PositionChildViews(aFloat);
|
||||||
FrameLayerBuilder::InvalidateThebesLayersInSubtree(aFloat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the float combined area state
|
// Update the float combined area state
|
||||||
|
@ -1478,7 +1478,7 @@ NS_IMETHODIMP nsBulletFrame::OnDataAvailable(imgIRequest *aRequest,
|
|||||||
// The image has changed.
|
// The image has changed.
|
||||||
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
||||||
// always correct, and I'll be a stunned mullet if it ever matters for performance
|
// always correct, and I'll be a stunned mullet if it ever matters for performance
|
||||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
InvalidateFrame();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -1520,7 +1520,7 @@ NS_IMETHODIMP nsBulletFrame::FrameChanged(imgIRequest *aRequest,
|
|||||||
{
|
{
|
||||||
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
||||||
// always correct.
|
// always correct.
|
||||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
InvalidateFrame();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -156,12 +156,6 @@ nsCanvasFrame::RemoveFrame(ChildListID aListID,
|
|||||||
if (aOldFrame != mFrames.FirstChild())
|
if (aOldFrame != mFrames.FirstChild())
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
// It's our one and only child frame
|
|
||||||
// Damage the area occupied by the deleted frame
|
|
||||||
// The child of the canvas probably can't have an outline, but why bother
|
|
||||||
// thinking about that?
|
|
||||||
Invalidate(aOldFrame->GetVisualOverflowRect() + aOldFrame->GetPosition());
|
|
||||||
|
|
||||||
// Remove the frame and destroy it
|
// Remove the frame and destroy it
|
||||||
mFrames.DestroyFrame(aOldFrame);
|
mFrames.DestroyFrame(aOldFrame);
|
||||||
|
|
||||||
@ -460,15 +454,7 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
// could also include overflow to our top and left (out of the viewport)
|
// could also include overflow to our top and left (out of the viewport)
|
||||||
// which doesn't need to be painted.
|
// which doesn't need to be painted.
|
||||||
nsIFrame* viewport = PresContext()->GetPresShell()->GetRootFrame();
|
nsIFrame* viewport = PresContext()->GetPresShell()->GetRootFrame();
|
||||||
viewport->Invalidate(nsRect(nsPoint(0, 0), viewport->GetSize()));
|
viewport->InvalidateFrame();
|
||||||
} else {
|
|
||||||
nsRect newKidRect = kidFrame->GetRect();
|
|
||||||
if (newKidRect.TopLeft() == oldKidRect.TopLeft()) {
|
|
||||||
InvalidateRectDifference(oldKidRect, kidFrame->GetRect());
|
|
||||||
} else {
|
|
||||||
Invalidate(oldKidRect);
|
|
||||||
Invalidate(newKidRect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return our desired size. Normally it's what we're told, but
|
// Return our desired size. Normally it's what we're told, but
|
||||||
@ -512,7 +498,7 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
const nsStyleBackground::Layer& layer = bg->mLayers[i];
|
const nsStyleBackground::Layer& layer = bg->mLayers[i];
|
||||||
if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
|
if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
|
||||||
layer.RenderingMightDependOnFrameSize()) {
|
layer.RenderingMightDependOnFrameSize()) {
|
||||||
Invalidate(nsRect(nsPoint(0, 0), GetSize()));
|
InvalidateFrame();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,22 @@ protected:
|
|||||||
bool mAddedScrollPositionListener;
|
bool mAddedScrollPositionListener;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class nsDisplayCanvasBackgroundGeometry : public nsDisplayItemGeometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void MoveBy(const nsPoint& aOffset)
|
||||||
|
{
|
||||||
|
mBounds.MoveBy(aOffset);
|
||||||
|
mChildBorder.MoveBy(aOffset);
|
||||||
|
mPaddingRect.MoveBy(aOffset);
|
||||||
|
mContentRect.MoveBy(aOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect mChildBorder;
|
||||||
|
nsRect mPaddingRect;
|
||||||
|
nsRect mContentRect;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override nsDisplayBackground methods so that we pass aBGClipRect to
|
* Override nsDisplayBackground methods so that we pass aBGClipRect to
|
||||||
* PaintBackground, covering the whole overflow area.
|
* PaintBackground, covering the whole overflow area.
|
||||||
@ -168,7 +184,46 @@ public:
|
|||||||
// We need to override so we don't consider border-radius.
|
// We need to override so we don't consider border-radius.
|
||||||
aOutFrames->AppendElement(mFrame);
|
aOutFrames->AppendElement(mFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
|
||||||
|
{
|
||||||
|
nsDisplayCanvasBackgroundGeometry* geometry = new nsDisplayCanvasBackgroundGeometry;
|
||||||
|
nsIFrame *child = mFrame->GetFirstPrincipalChild();
|
||||||
|
bool snap;
|
||||||
|
geometry->mBounds = GetBounds(aBuilder, &snap);
|
||||||
|
if (child) {
|
||||||
|
geometry->mChildBorder = child->GetRect();
|
||||||
|
}
|
||||||
|
geometry->mPaddingRect = GetPaddingRect();
|
||||||
|
geometry->mContentRect = GetContentRect();
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion)
|
||||||
|
{
|
||||||
|
const nsDisplayCanvasBackgroundGeometry* geometry = static_cast<const nsDisplayCanvasBackgroundGeometry*>(aGeometry);
|
||||||
|
if (ShouldFixToViewport(aBuilder)) {
|
||||||
|
// This is incorrect, We definitely need to check more things here.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIFrame *child = mFrame->GetFirstPrincipalChild();
|
||||||
|
|
||||||
|
bool snap;
|
||||||
|
if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
|
||||||
|
(child && !geometry->mChildBorder.IsEqualInterior(child->GetRect())) ||
|
||||||
|
!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect()) ||
|
||||||
|
!geometry->mContentRect.IsEqualInterior(GetContentRect())) {
|
||||||
|
if (!RenderingMightDependOnFrameSize() && geometry->mBounds.TopLeft() == GetBounds(aBuilder, &snap).TopLeft()) {
|
||||||
|
aInvalidRegion->Xor(GetBounds(aBuilder, &snap), geometry->mBounds);
|
||||||
|
} else {
|
||||||
|
aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||||
nsRenderingContext* aCtx);
|
nsRenderingContext* aCtx);
|
||||||
|
|
||||||
|
@ -433,13 +433,7 @@ static void MoveChildTo(nsIFrame* aParent, nsIFrame* aChild, nsPoint aOrigin) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect r = aChild->GetVisualOverflowRect();
|
|
||||||
r += aChild->GetPosition();
|
|
||||||
aParent->Invalidate(r);
|
|
||||||
r -= aChild->GetPosition();
|
|
||||||
aChild->SetPosition(aOrigin);
|
aChild->SetPosition(aOrigin);
|
||||||
r += aOrigin;
|
|
||||||
aParent->Invalidate(r);
|
|
||||||
PlaceFrameView(aChild);
|
PlaceFrameView(aChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1057,8 +1051,6 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
aStatus = NS_FRAME_COMPLETE;
|
aStatus = NS_FRAME_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckInvalidateSizeChange(aDesiredSize);
|
|
||||||
|
|
||||||
// XXXjwir3: This call should be replaced with FinishWithAbsoluteFrames
|
// XXXjwir3: This call should be replaced with FinishWithAbsoluteFrames
|
||||||
// when bug 724978 is fixed and nsColumnSetFrame is a full absolute
|
// when bug 724978 is fixed and nsColumnSetFrame is a full absolute
|
||||||
// container.
|
// container.
|
||||||
|
@ -890,11 +890,6 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
|
|||||||
aKidFrame->WillReflow(aPresContext);
|
aKidFrame->WillReflow(aPresContext);
|
||||||
|
|
||||||
if (NS_FRAME_NO_MOVE_FRAME != (aFlags & NS_FRAME_NO_MOVE_FRAME)) {
|
if (NS_FRAME_NO_MOVE_FRAME != (aFlags & NS_FRAME_NO_MOVE_FRAME)) {
|
||||||
if ((aFlags & NS_FRAME_INVALIDATE_ON_MOVE) &&
|
|
||||||
!(aKidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) &&
|
|
||||||
aKidFrame->GetPosition() != nsPoint(aX, aY)) {
|
|
||||||
aKidFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
aKidFrame->SetPosition(nsPoint(aX, aY));
|
aKidFrame->SetPosition(nsPoint(aX, aY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1003,13 +998,6 @@ nsContainerFrame::FinishReflowChild(nsIFrame* aKidFrame,
|
|||||||
// correctly positioned
|
// correctly positioned
|
||||||
PositionChildViews(aKidFrame);
|
PositionChildViews(aKidFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We also need to redraw everything associated with the frame
|
|
||||||
// because if the frame's Reflow issued any invalidates, then they
|
|
||||||
// will be at the wrong offset ... note that this includes
|
|
||||||
// invalidates issued against the frame's children, so we need to
|
|
||||||
// invalidate the overflow area too.
|
|
||||||
aKidFrame->Invalidate(aDesiredSize.VisualOverflow());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return aKidFrame->DidReflow(aPresContext, aReflowState, NS_FRAME_REFLOW_FINISHED);
|
return aKidFrame->DidReflow(aPresContext, aReflowState, NS_FRAME_REFLOW_FINISHED);
|
||||||
@ -1089,10 +1077,6 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres
|
|||||||
frame, availSpace);
|
frame, availSpace);
|
||||||
nsReflowStatus frameStatus = NS_FRAME_COMPLETE;
|
nsReflowStatus frameStatus = NS_FRAME_COMPLETE;
|
||||||
|
|
||||||
// Cache old bounds
|
|
||||||
nsRect oldRect = frame->GetRect();
|
|
||||||
nsRect oldOverflow = frame->GetVisualOverflowRect();
|
|
||||||
|
|
||||||
// Reflow
|
// Reflow
|
||||||
rv = ReflowChild(frame, aPresContext, desiredSize, frameState,
|
rv = ReflowChild(frame, aPresContext, desiredSize, frameState,
|
||||||
prevRect.x, 0, aFlags, frameStatus, &tracker);
|
prevRect.x, 0, aFlags, frameStatus, &tracker);
|
||||||
@ -1103,18 +1087,6 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres
|
|||||||
prevRect.x, 0, aFlags);
|
prevRect.x, 0, aFlags);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// Invalidate if there was a position or size change
|
|
||||||
nsRect rect = frame->GetRect();
|
|
||||||
if (!rect.IsEqualInterior(oldRect)) {
|
|
||||||
nsRect dirtyRect = oldOverflow;
|
|
||||||
dirtyRect.MoveBy(oldRect.x, oldRect.y);
|
|
||||||
Invalidate(dirtyRect);
|
|
||||||
|
|
||||||
dirtyRect = frame->GetVisualOverflowRect();
|
|
||||||
dirtyRect.MoveBy(rect.x, rect.y);
|
|
||||||
Invalidate(dirtyRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle continuations
|
// Handle continuations
|
||||||
if (!NS_FRAME_IS_FULLY_COMPLETE(frameStatus)) {
|
if (!NS_FRAME_IS_FULLY_COMPLETE(frameStatus)) {
|
||||||
if (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
|
if (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
|
||||||
@ -1329,8 +1301,6 @@ nsContainerFrame::DeleteNextInFlowChild(nsPresContext* aPresContext,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aNextInFlow->InvalidateFrameSubtree();
|
|
||||||
|
|
||||||
// Take the next-in-flow out of the parent's child list
|
// Take the next-in-flow out of the parent's child list
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
|
@ -86,6 +86,7 @@
|
|||||||
#include "nsChangeHint.h"
|
#include "nsChangeHint.h"
|
||||||
#include "nsDeckFrame.h"
|
#include "nsDeckFrame.h"
|
||||||
#include "nsTableFrame.h"
|
#include "nsTableFrame.h"
|
||||||
|
#include "nsSubDocumentFrame.h"
|
||||||
|
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
#include "nsRenderingContext.h"
|
#include "nsRenderingContext.h"
|
||||||
@ -490,7 +491,8 @@ nsFrame::Init(nsIContent* aContent,
|
|||||||
|
|
||||||
// Make bits that are currently off (see constructor) the same:
|
// Make bits that are currently off (see constructor) the same:
|
||||||
mState |= state & (NS_FRAME_INDEPENDENT_SELECTION |
|
mState |= state & (NS_FRAME_INDEPENDENT_SELECTION |
|
||||||
NS_FRAME_GENERATED_CONTENT);
|
NS_FRAME_GENERATED_CONTENT |
|
||||||
|
NS_FRAME_IN_POPUP);
|
||||||
}
|
}
|
||||||
const nsStyleDisplay *disp = GetStyleDisplay();
|
const nsStyleDisplay *disp = GetStyleDisplay();
|
||||||
if (disp->HasTransform()) {
|
if (disp->HasTransform()) {
|
||||||
@ -1207,6 +1209,23 @@ nsFrame::GetChildLists(nsTArray<ChildList>* aLists) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsIFrame::GetCrossDocChildLists(nsTArray<ChildList>* aLists)
|
||||||
|
{
|
||||||
|
nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(this);
|
||||||
|
if (subdocumentFrame) {
|
||||||
|
// Descend into the subdocument
|
||||||
|
nsIFrame* root = subdocumentFrame->GetSubdocumentRootFrame();
|
||||||
|
if (root) {
|
||||||
|
aLists->AppendElement(nsIFrame::ChildList(
|
||||||
|
nsFrameList(root, nsLayoutUtils::GetLastSibling(root)),
|
||||||
|
nsIFrame::kPrincipalList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetChildLists(aLists);
|
||||||
|
}
|
||||||
|
|
||||||
static nsIFrame*
|
static nsIFrame*
|
||||||
GetActiveSelectionFrame(nsPresContext* aPresContext, nsIFrame* aFrame)
|
GetActiveSelectionFrame(nsPresContext* aPresContext, nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
@ -4411,46 +4430,6 @@ nsIFrame::IsLeaf() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer*
|
|
||||||
nsIFrame::InvalidateLayer(const nsRect& aDamageRect, PRUint32 aDisplayItemKey)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aDisplayItemKey > 0, "Need a key");
|
|
||||||
|
|
||||||
Layer* layer = FrameLayerBuilder::GetDedicatedLayer(this, aDisplayItemKey);
|
|
||||||
if (!layer) {
|
|
||||||
Invalidate(aDamageRect);
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRUint32 flags = INVALIDATE_NO_THEBES_LAYERS;
|
|
||||||
if (aDisplayItemKey == nsDisplayItem::TYPE_VIDEO ||
|
|
||||||
aDisplayItemKey == nsDisplayItem::TYPE_PLUGIN ||
|
|
||||||
aDisplayItemKey == nsDisplayItem::TYPE_CANVAS) {
|
|
||||||
flags |= INVALIDATE_NO_UPDATE_LAYER_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
InvalidateWithFlags(aDamageRect, flags);
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsIFrame::InvalidateTransformLayer()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mParent, "How can a viewport frame have a transform?");
|
|
||||||
|
|
||||||
bool hasLayer =
|
|
||||||
FrameLayerBuilder::GetDedicatedLayer(this, nsDisplayItem::TYPE_TRANSFORM) != nsnull;
|
|
||||||
// Invalidate post-transform area in the parent. We have to invalidate
|
|
||||||
// in the parent because our transform style may have changed from what was
|
|
||||||
// used to paint this frame.
|
|
||||||
// It's OK to bypass the SVG effects processing and other processing
|
|
||||||
// performed if we called this->InvalidateWithFlags, because those effects
|
|
||||||
// are performed before applying transforms.
|
|
||||||
mParent->InvalidateInternal(GetVisualOverflowRect() + GetPosition(),
|
|
||||||
0, 0, this,
|
|
||||||
hasLayer ? INVALIDATE_NO_THEBES_LAYERS : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
class LayerActivity {
|
class LayerActivity {
|
||||||
public:
|
public:
|
||||||
LayerActivity(nsIFrame* aFrame) : mFrame(aFrame), mChangeHint(nsChangeHint(0)) {}
|
LayerActivity(nsIFrame* aFrame) : mFrame(aFrame), mChangeHint(nsChangeHint(0)) {}
|
||||||
@ -4547,135 +4526,6 @@ nsFrame::ShutdownLayerActivityTimer()
|
|||||||
gLayerActivityTracker = nsnull;
|
gLayerActivityTracker = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsIFrame::InvalidateWithFlags(const nsRect& aDamageRect, PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
if (aDamageRect.IsEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't allow invalidates to do anything when
|
|
||||||
// painting is suppressed.
|
|
||||||
nsIPresShell *shell = PresContext()->GetPresShell();
|
|
||||||
if (shell) {
|
|
||||||
if (shell->IsPaintingSuppressed())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
InvalidateInternal(aDamageRect, 0, 0, nsnull, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function that funnels an InvalidateInternal request up to the
|
|
||||||
* parent. This function is used so that if MOZ_SVG is not defined, we still
|
|
||||||
* have unified control paths in the InvalidateInternal chain.
|
|
||||||
*
|
|
||||||
* @param aDamageRect The rect to invalidate.
|
|
||||||
* @param aX The x offset from the origin of this frame to the rectangle.
|
|
||||||
* @param aY The y offset from the origin of this frame to the rectangle.
|
|
||||||
* @param aImmediate Whether to redraw immediately.
|
|
||||||
* @return None, though this funnels the request up to the parent frame.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
nsIFrame::InvalidateInternalAfterResize(const nsRect& aDamageRect, nscoord aX,
|
|
||||||
nscoord aY, PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
if (aDamageRect.IsEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we're a transformed frame, then we need to apply our transform to the
|
|
||||||
* damage rectangle so that the redraw correctly redraws the transformed
|
|
||||||
* region. We're moved over aX and aY from our origin, but since this aX
|
|
||||||
* and aY is contained within our border, we need to scoot back by -aX and
|
|
||||||
* -aY to get back to the origin of the transform.
|
|
||||||
*
|
|
||||||
* There's one more problem, though, and that's that we don't know what
|
|
||||||
* coordinate space this rectangle is in. Sometimes it's in the local
|
|
||||||
* coordinate space for the frame, and sometimes its in the transformed
|
|
||||||
* coordinate space. If we get it wrong, we'll display incorrectly. Until I
|
|
||||||
* find a better fix for this problem, we'll invalidate the union of the two
|
|
||||||
* rectangles (original rectangle and transformed rectangle). At least one of
|
|
||||||
* these will be correct.
|
|
||||||
*
|
|
||||||
* When we are preserving-3d, we can have arbitrary hierarchies of preserved 3d
|
|
||||||
* children. The computed transform on these children is relative to the root
|
|
||||||
* transform object in the hierarchy, not necessarily their direct ancestor.
|
|
||||||
* In this case we transform by the child's transform, and mark the rectangle
|
|
||||||
* as being transformed until it is passed up to the root of the hierarchy.
|
|
||||||
*
|
|
||||||
* See bug #452496 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Check the transformed flags and remove it
|
|
||||||
bool rectIsTransformed = (aFlags & INVALIDATE_ALREADY_TRANSFORMED);
|
|
||||||
if (!Preserves3D()) {
|
|
||||||
// We only want to remove the flag if we aren't preserving 3d. Otherwise
|
|
||||||
// the rect will already have been transformed into the root preserve-3d
|
|
||||||
// frame coordinate space, and we should continue passing it up without
|
|
||||||
// further transforms.
|
|
||||||
aFlags &= ~INVALIDATE_ALREADY_TRANSFORMED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((mState & NS_FRAME_HAS_CONTAINER_LAYER) &&
|
|
||||||
!(aFlags & INVALIDATE_NO_THEBES_LAYERS)) {
|
|
||||||
// XXX for now I'm going to assume this is in the local coordinate space
|
|
||||||
// This only matters for frames with transforms and retained layers,
|
|
||||||
// which can't happen right now since transforms trigger fallback
|
|
||||||
// rendering and the display items that trigger layers are nested inside
|
|
||||||
// the nsDisplayTransform
|
|
||||||
// XXX need to set INVALIDATE_NO_THEBES_LAYERS for certain kinds of
|
|
||||||
// invalidation, e.g. video update, 'opacity' change
|
|
||||||
FrameLayerBuilder::InvalidateThebesLayerContents(this,
|
|
||||||
aDamageRect + nsPoint(aX, aY));
|
|
||||||
// Don't need to invalidate any more Thebes layers
|
|
||||||
aFlags |= INVALIDATE_NO_THEBES_LAYERS;
|
|
||||||
if (aFlags & INVALIDATE_ONLY_THEBES_LAYERS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (IsTransformed() && !rectIsTransformed) {
|
|
||||||
nsRect newDamageRect = nsDisplayTransform::TransformRectOut
|
|
||||||
(aDamageRect, this, nsPoint(-aX, -aY));
|
|
||||||
if (!(GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
|
|
||||||
newDamageRect.UnionRect(newDamageRect, aDamageRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are preserving 3d, then our computed transform includes that of any
|
|
||||||
// ancestor frames that also preserve 3d. Mark the rectangle as already being
|
|
||||||
// transformed into the parent's coordinate space.
|
|
||||||
if (Preserves3D()) {
|
|
||||||
aFlags |= INVALIDATE_ALREADY_TRANSFORMED;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetParent()->
|
|
||||||
InvalidateInternal(newDamageRect, aX + mRect.x, aY + mRect.y, this,
|
|
||||||
aFlags);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
GetParent()->
|
|
||||||
InvalidateInternal(aDamageRect, aX + mRect.x, aY + mRect.y, this, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsIFrame::InvalidateInternal(const nsRect& aDamageRect, nscoord aX, nscoord aY,
|
|
||||||
nsIFrame* aForChild, PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
nsSVGEffects::InvalidateDirectRenderingObservers(this);
|
|
||||||
if (nsSVGIntegrationUtils::UsingEffectsForFrame(this)) {
|
|
||||||
nsRect r = nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(this,
|
|
||||||
aDamageRect + nsPoint(aX, aY));
|
|
||||||
/* Rectangle is now in our own local space, so aX and aY are effectively
|
|
||||||
* zero. Thus we'll pretend that the entire time this was in our own
|
|
||||||
* local coordinate space and do any remaining processing.
|
|
||||||
*/
|
|
||||||
InvalidateInternalAfterResize(r, 0, 0, aFlags);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
InvalidateInternalAfterResize(aDamageRect, aX, aY, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx3DMatrix
|
gfx3DMatrix
|
||||||
nsIFrame::GetTransformMatrix(nsIFrame* aStopAtAncestor,
|
nsIFrame::GetTransformMatrix(nsIFrame* aStopAtAncestor,
|
||||||
nsIFrame** aOutAncestor)
|
nsIFrame** aOutAncestor)
|
||||||
@ -4744,63 +4594,104 @@ nsIFrame::GetTransformMatrix(nsIFrame* aStopAtAncestor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsIFrame::InvalidateRectDifference(const nsRect& aR1, const nsRect& aR2)
|
nsIFrame::InvalidateFrameSubtree(PRUint32 aFlags)
|
||||||
{
|
{
|
||||||
nsRect sizeHStrip, sizeVStrip;
|
InvalidateFrame(aFlags);
|
||||||
nsLayoutUtils::GetRectDifferenceStrips(aR1, aR2, &sizeHStrip, &sizeVStrip);
|
|
||||||
Invalidate(sizeVStrip);
|
nsAutoTArray<nsIFrame::ChildList,4> childListArray;
|
||||||
Invalidate(sizeHStrip);
|
GetCrossDocChildLists(&childListArray);
|
||||||
|
|
||||||
|
nsIFrame::ChildListArrayIterator lists(childListArray);
|
||||||
|
for (; !lists.IsDone(); lists.Next()) {
|
||||||
|
nsFrameList::Enumerator childFrames(lists.CurrentList());
|
||||||
|
for (; !childFrames.AtEnd(); childFrames.Next()) {
|
||||||
|
childFrames.get()->
|
||||||
|
InvalidateFrameSubtree(aFlags | INVALIDATE_DONT_SCHEDULE_PAINT);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsIFrame::InvalidateFrameSubtree()
|
nsIFrame::ClearInvalidationStateBits()
|
||||||
{
|
{
|
||||||
Invalidate(GetVisualOverflowRectRelativeToSelf());
|
if (HasAnyStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT)) {
|
||||||
FrameLayerBuilder::InvalidateThebesLayersInSubtree(this);
|
nsAutoTArray<nsIFrame::ChildList,4> childListArray;
|
||||||
}
|
GetCrossDocChildLists(&childListArray);
|
||||||
|
|
||||||
void
|
nsIFrame::ChildListArrayIterator lists(childListArray);
|
||||||
nsIFrame::InvalidateOverflowRect()
|
for (; !lists.IsDone(); lists.Next()) {
|
||||||
{
|
nsFrameList::Enumerator childFrames(lists.CurrentList());
|
||||||
Invalidate(GetVisualOverflowRectRelativeToSelf());
|
for (; !childFrames.AtEnd(); childFrames.Next()) {
|
||||||
}
|
childFrames.get()->ClearInvalidationStateBits();
|
||||||
|
}
|
||||||
NS_DECLARE_FRAME_PROPERTY(DeferInvalidatesProperty, nsIFrame::DestroyRegion)
|
|
||||||
|
|
||||||
void
|
|
||||||
nsIFrame::InvalidateRoot(const nsRect& aDamageRect, PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(nsLayoutUtils::GetDisplayRootFrame(this) == this,
|
|
||||||
"Can only call this on display roots");
|
|
||||||
|
|
||||||
if ((mState & NS_FRAME_HAS_CONTAINER_LAYER) &&
|
|
||||||
!(aFlags & INVALIDATE_NO_THEBES_LAYERS)) {
|
|
||||||
FrameLayerBuilder::InvalidateThebesLayerContents(this, aDamageRect);
|
|
||||||
if (aFlags & INVALIDATE_ONLY_THEBES_LAYERS) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect rect = aDamageRect;
|
RemoveStateBits(NS_FRAME_NEEDS_PAINT | NS_FRAME_DESCENDANT_NEEDS_PAINT);
|
||||||
nsRegion* excludeRegion = static_cast<nsRegion*>
|
|
||||||
(Properties().Get(DeferInvalidatesProperty()));
|
|
||||||
if (excludeRegion && (aFlags & INVALIDATE_EXCLUDE_CURRENT_PAINT)) {
|
|
||||||
nsRegion r;
|
|
||||||
r.Sub(rect, *excludeRegion);
|
|
||||||
if (r.IsEmpty())
|
|
||||||
return;
|
|
||||||
rect = r.GetBounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(aFlags & INVALIDATE_NO_UPDATE_LAYER_TREE)) {
|
|
||||||
AddStateBits(NS_FRAME_UPDATE_LAYER_TREE);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIView* view = GetView();
|
|
||||||
NS_ASSERTION(view, "This can only be called on frames with views");
|
|
||||||
view->GetViewManager()->InvalidateViewNoSuppression(view, rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsIFrame::InvalidateFrame(PRUint32 aFlags)
|
||||||
|
{
|
||||||
|
AddStateBits(NS_FRAME_NEEDS_PAINT);
|
||||||
|
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(this);
|
||||||
|
while (parent && !parent->HasAnyStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT)) {
|
||||||
|
parent->AddStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT);
|
||||||
|
parent = nsLayoutUtils::GetCrossDocParentFrame(parent);
|
||||||
|
}
|
||||||
|
if (!(aFlags & INVALIDATE_DONT_SCHEDULE_PAINT)) {
|
||||||
|
SchedulePaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsIFrame::IsInvalid()
|
||||||
|
{
|
||||||
|
return HasAnyStateBits(NS_FRAME_NEEDS_PAINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsIFrame::SchedulePaint()
|
||||||
|
{
|
||||||
|
nsPresContext *pres = PresContext()->GetRootPresContext();
|
||||||
|
if (HasAnyStateBits(NS_FRAME_IN_POPUP) || !pres) {
|
||||||
|
nsIFrame *displayRoot = nsLayoutUtils::GetDisplayRootFrame(this);
|
||||||
|
NS_ASSERTION(displayRoot, "Need a display root to schedule a paint!");
|
||||||
|
if (!displayRoot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pres = displayRoot->PresContext();
|
||||||
|
}
|
||||||
|
pres->PresShell()->ScheduleViewManagerFlush();
|
||||||
|
}
|
||||||
|
|
||||||
|
Layer*
|
||||||
|
nsIFrame::InvalidateLayer(PRUint32 aDisplayItemKey, const nsIntRect* aDamageRect)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aDisplayItemKey > 0, "Need a key");
|
||||||
|
|
||||||
|
Layer* layer = FrameLayerBuilder::GetDedicatedLayer(this, aDisplayItemKey);
|
||||||
|
if (aDamageRect && aDamageRect->IsEmpty()) {
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!layer) {
|
||||||
|
InvalidateFrame();
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aDamageRect) {
|
||||||
|
layer->AddInvalidRect(*aDamageRect);
|
||||||
|
} else {
|
||||||
|
layer->SetInvalidRectToVisibleRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
SchedulePaint();
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_DECLARE_FRAME_PROPERTY(DeferInvalidatesProperty, nsIFrame::DestroyRegion)
|
||||||
|
|
||||||
void
|
void
|
||||||
nsIFrame::BeginDeferringInvalidatesForDisplayRoot(const nsRegion& aExcludeRegion)
|
nsIFrame::BeginDeferringInvalidatesForDisplayRoot(const nsRegion& aExcludeRegion)
|
||||||
{
|
{
|
||||||
@ -5047,107 +4938,6 @@ nsFrame::UpdateOverflow()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsFrame::CheckInvalidateSizeChange(nsHTMLReflowMetrics& aNewDesiredSize)
|
|
||||||
{
|
|
||||||
nsIFrame::CheckInvalidateSizeChange(mRect, GetVisualOverflowRect(),
|
|
||||||
nsSize(aNewDesiredSize.width, aNewDesiredSize.height));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
InvalidateRectForFrameSizeChange(nsIFrame* aFrame, const nsRect& aRect)
|
|
||||||
{
|
|
||||||
nsStyleContext *bgSC;
|
|
||||||
if (!nsCSSRendering::FindBackground(aFrame->PresContext(), aFrame, &bgSC)) {
|
|
||||||
nsIFrame* rootFrame =
|
|
||||||
aFrame->PresContext()->PresShell()->FrameManager()->GetRootFrame();
|
|
||||||
rootFrame->Invalidate(nsRect(nsPoint(0, 0), rootFrame->GetSize()));
|
|
||||||
}
|
|
||||||
|
|
||||||
aFrame->Invalidate(aRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsIFrame::CheckInvalidateSizeChange(const nsRect& aOldRect,
|
|
||||||
const nsRect& aOldVisualOverflowRect,
|
|
||||||
const nsSize& aNewDesiredSize)
|
|
||||||
{
|
|
||||||
if (aNewDesiredSize == aOldRect.Size())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Below, we invalidate the old frame area (or, in the case of
|
|
||||||
// outline, combined area) if the outline, border or background
|
|
||||||
// settings indicate that something other than the difference
|
|
||||||
// between the old and new areas needs to be painted. We are
|
|
||||||
// assuming that the difference between the old and new areas will
|
|
||||||
// be invalidated by some other means. That also means invalidating
|
|
||||||
// the old frame area is the same as invalidating the new frame area
|
|
||||||
// (since in either case the UNION of old and new areas will be
|
|
||||||
// invalidated)
|
|
||||||
|
|
||||||
// We use InvalidateRectForFrameSizeChange throughout this method, even
|
|
||||||
// though root-invalidation is technically only needed in the case where
|
|
||||||
// layer.RenderingMightDependOnFrameSize(). This allows us to simplify the
|
|
||||||
// code somewhat and return immediately after invalidation in the earlier
|
|
||||||
// cases.
|
|
||||||
|
|
||||||
// Invalidate the entire old frame+outline if the frame has an outline
|
|
||||||
bool anyOutlineOrEffects;
|
|
||||||
nsRect r = ComputeOutlineAndEffectsRect(this, &anyOutlineOrEffects,
|
|
||||||
aOldVisualOverflowRect,
|
|
||||||
aNewDesiredSize,
|
|
||||||
false);
|
|
||||||
if (anyOutlineOrEffects) {
|
|
||||||
r.UnionRect(aOldVisualOverflowRect, r);
|
|
||||||
InvalidateRectForFrameSizeChange(this, r);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalidate the old frame border box if the frame has borders. Those
|
|
||||||
// borders may be moving.
|
|
||||||
const nsStyleBorder* border = GetStyleBorder();
|
|
||||||
NS_FOR_CSS_SIDES(side) {
|
|
||||||
if (border->GetComputedBorderWidth(side) != 0) {
|
|
||||||
if ((side == NS_SIDE_LEFT || side == NS_SIDE_TOP) &&
|
|
||||||
!nsLayoutUtils::HasNonZeroCornerOnSide(border->mBorderRadius, side) &&
|
|
||||||
!border->GetBorderImage() &&
|
|
||||||
border->GetBorderStyle(side) == NS_STYLE_BORDER_STYLE_SOLID) {
|
|
||||||
// We also need to be sure that the bottom-left or top-right
|
|
||||||
// corner is simple. For example, if the bottom or right border
|
|
||||||
// has a different color, we would need to invalidate the corner
|
|
||||||
// area. But that's OK because if there is a right or bottom border,
|
|
||||||
// we'll invalidate the entire border-box here anyway.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
InvalidateRectForFrameSizeChange(this, nsRect(0, 0, aOldRect.width, aOldRect.height));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsStyleBackground *bg = GetStyleBackground();
|
|
||||||
if (!bg->IsTransparent()) {
|
|
||||||
// Invalidate the old frame background if the frame has a background
|
|
||||||
// whose position depends on the size of the frame
|
|
||||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
|
||||||
const nsStyleBackground::Layer &layer = bg->mLayers[i];
|
|
||||||
if (layer.RenderingMightDependOnFrameSize()) {
|
|
||||||
InvalidateRectForFrameSizeChange(this, nsRect(0, 0, aOldRect.width, aOldRect.height));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalidate the old frame background if the frame has a background
|
|
||||||
// that is being clipped by border-radius, since the old or new area
|
|
||||||
// clipped off by the radius is not necessarily in the area that has
|
|
||||||
// already been invalidated (even if only the top-left corner has a
|
|
||||||
// border radius).
|
|
||||||
if (nsLayoutUtils::HasNonZeroCorner(border->mBorderRadius)) {
|
|
||||||
InvalidateRectForFrameSizeChange(this, nsRect(0, 0, aOldRect.width, aOldRect.height));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define the MAX_FRAME_DEPTH to be the ContentSink's MAX_REFLOW_DEPTH plus
|
// Define the MAX_FRAME_DEPTH to be the ContentSink's MAX_REFLOW_DEPTH plus
|
||||||
// 4 for the frames above the document's frames:
|
// 4 for the frames above the document's frames:
|
||||||
// the Viewport, GFXScroll, ScrollPort, and Canvas
|
// the Viewport, GFXScroll, ScrollPort, and Canvas
|
||||||
@ -6883,7 +6673,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
|
|||||||
// If there is no outline or other effects now, then we don't have
|
// If there is no outline or other effects now, then we don't have
|
||||||
// to do anything here since removing those styles can't require
|
// to do anything here since removing those styles can't require
|
||||||
// repainting of areas that weren't in the old overflow area.
|
// repainting of areas that weren't in the old overflow area.
|
||||||
Invalidate(aOverflowAreas.VisualOverflow());
|
InvalidateFrame();
|
||||||
} else if (hasClipPropClip || didHaveClipPropClip) {
|
} else if (hasClipPropClip || didHaveClipPropClip) {
|
||||||
// If we are (or were) clipped by the 'clip' property, and our
|
// If we are (or were) clipped by the 'clip' property, and our
|
||||||
// overflow area changes, it might be because the clipping changed.
|
// overflow area changes, it might be because the clipping changed.
|
||||||
@ -6891,31 +6681,9 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
|
|||||||
// repaint the old overflow area, so if the overflow area has
|
// repaint the old overflow area, so if the overflow area has
|
||||||
// changed (in particular, if it grows), we have to repaint the
|
// changed (in particular, if it grows), we have to repaint the
|
||||||
// new area here.
|
// new area here.
|
||||||
Invalidate(aOverflowAreas.VisualOverflow());
|
InvalidateFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXXSDL For SVG the invalidation happens in UpdateBounds for now, so we
|
|
||||||
// don't currently invalidate SVG here:
|
|
||||||
if (anyOverflowChanged && hasTransform &&
|
|
||||||
!(GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
|
|
||||||
// When there's a transform, changes to that style might require
|
|
||||||
// repainting of the old and new overflow areas in the widget.
|
|
||||||
// Repainting of the frame itself will not be required if there's
|
|
||||||
// a retained layer, so we can call InvalidateLayer here
|
|
||||||
// which will avoid repainting ThebesLayers if possible.
|
|
||||||
// nsCSSFrameConstructor::DoApplyRenderingChangeToTree repaints
|
|
||||||
// the old overflow area in the widget in response to
|
|
||||||
// nsChangeHint_UpdateTransformLayer. But since the new overflow
|
|
||||||
// area is not known at that time, we have to handle it here.
|
|
||||||
// If the overflow area hasn't changed, then it doesn't matter that
|
|
||||||
// we didn't reach here since repainting the old overflow area was enough.
|
|
||||||
// If there is no transform now, then the container layer for
|
|
||||||
// the transform will go away and the frame contents will change
|
|
||||||
// ThebesLayers, forcing it to be invalidated, so it doesn't matter
|
|
||||||
// that we didn't reach here.
|
|
||||||
InvalidateLayer(aOverflowAreas.VisualOverflow(),
|
|
||||||
nsDisplayItem::TYPE_TRANSFORM);
|
|
||||||
}
|
|
||||||
|
|
||||||
return anyOverflowChanged;
|
return anyOverflowChanged;
|
||||||
}
|
}
|
||||||
@ -7392,11 +7160,8 @@ nsFrame::RefreshSizeCache(nsBoxLayoutState& aState)
|
|||||||
if (!DoesNeedRecalc(metrics->mBlockPrefSize))
|
if (!DoesNeedRecalc(metrics->mBlockPrefSize))
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
// get the old rect.
|
|
||||||
nsRect oldRect = GetRect();
|
|
||||||
|
|
||||||
// the rect we plan to size to.
|
// the rect we plan to size to.
|
||||||
nsRect rect(oldRect);
|
nsRect rect = GetRect();
|
||||||
|
|
||||||
nsMargin bp(0,0,0,0);
|
nsMargin bp(0,0,0,0);
|
||||||
GetBorderAndPadding(bp);
|
GetBorderAndPadding(bp);
|
||||||
@ -7418,15 +7183,6 @@ nsFrame::RefreshSizeCache(nsBoxLayoutState& aState)
|
|||||||
rect.x, rect.y,
|
rect.x, rect.y,
|
||||||
metrics->mBlockPrefSize.width, NS_UNCONSTRAINEDSIZE);
|
metrics->mBlockPrefSize.width, NS_UNCONSTRAINEDSIZE);
|
||||||
|
|
||||||
nsRect newRect = GetRect();
|
|
||||||
|
|
||||||
// make sure we draw any size change
|
|
||||||
if (oldRect.width != newRect.width || oldRect.height != newRect.height) {
|
|
||||||
newRect.x = 0;
|
|
||||||
newRect.y = 0;
|
|
||||||
Redraw(aState, &newRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
metrics->mBlockMinSize.height = 0;
|
metrics->mBlockMinSize.height = 0;
|
||||||
// ok we need the max ascent of the items on the line. So to do this
|
// ok we need the max ascent of the items on the line. So to do this
|
||||||
// ask the block for its line iterator. Get the max ascent.
|
// ask the block for its line iterator. Get the max ascent.
|
||||||
@ -7943,6 +7699,55 @@ nsFrame::BoxMetrics() const
|
|||||||
return metrics;
|
return metrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the NS_FRAME_IN_POPUP state bit to the current frame,
|
||||||
|
* and all descendant frames (including cross-doc ones).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
AddInPopupStateBitToDescendants(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
aFrame->AddStateBits(NS_FRAME_IN_POPUP);
|
||||||
|
|
||||||
|
nsAutoTArray<nsIFrame::ChildList,4> childListArray;
|
||||||
|
aFrame->GetCrossDocChildLists(&childListArray);
|
||||||
|
|
||||||
|
nsIFrame::ChildListArrayIterator lists(childListArray);
|
||||||
|
for (; !lists.IsDone(); lists.Next()) {
|
||||||
|
nsFrameList::Enumerator childFrames(lists.CurrentList());
|
||||||
|
for (; !childFrames.AtEnd(); childFrames.Next()) {
|
||||||
|
AddInPopupStateBitToDescendants(childFrames.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the NS_FRAME_IN_POPUP state bit from the current
|
||||||
|
* frames and all descendant frames (including cross-doc ones),
|
||||||
|
* unless the frame is a popup itself.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
RemoveInPopupStateBitFromDescendants(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
if (!aFrame->HasAnyStateBits(NS_FRAME_IN_POPUP) ||
|
||||||
|
aFrame->GetType() == nsGkAtoms::listControlFrame ||
|
||||||
|
aFrame->GetType() == nsGkAtoms::menuPopupFrame) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aFrame->RemoveStateBits(NS_FRAME_IN_POPUP);
|
||||||
|
|
||||||
|
nsAutoTArray<nsIFrame::ChildList,4> childListArray;
|
||||||
|
aFrame->GetCrossDocChildLists(&childListArray);
|
||||||
|
|
||||||
|
nsIFrame::ChildListArrayIterator lists(childListArray);
|
||||||
|
for (; !lists.IsDone(); lists.Next()) {
|
||||||
|
nsFrameList::Enumerator childFrames(lists.CurrentList());
|
||||||
|
for (; !childFrames.AtEnd(); childFrames.Next()) {
|
||||||
|
RemoveInPopupStateBitFromDescendants(childFrames.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsFrame::SetParent(nsIFrame* aParent)
|
nsFrame::SetParent(nsIFrame* aParent)
|
||||||
{
|
{
|
||||||
@ -7961,14 +7766,20 @@ nsFrame::SetParent(nsIFrame* aParent)
|
|||||||
f->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW);
|
f->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT) {
|
if (HasInvalidFrameInSubtree()) {
|
||||||
for (nsIFrame* f = aParent;
|
for (nsIFrame* f = aParent;
|
||||||
f && !(f->GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT);
|
f && !f->HasAnyStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT);
|
||||||
f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
|
f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
|
||||||
f->AddStateBits(NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT);
|
f->AddStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aParent->HasAnyStateBits(NS_FRAME_IN_POPUP)) {
|
||||||
|
AddInPopupStateBitToDescendants(this);
|
||||||
|
} else {
|
||||||
|
RemoveInPopupStateBitFromDescendants(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -363,16 +363,6 @@ public:
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// Additional methods
|
// Additional methods
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to invalidate portions of a standard container frame if the
|
|
||||||
* desired size indicates that the size has changed (specifically border,
|
|
||||||
* background and outline).
|
|
||||||
* We assume that the difference between the old frame area and the new
|
|
||||||
* frame area is invalidated by some other means.
|
|
||||||
* @param aDesiredSize the new size of the frame
|
|
||||||
*/
|
|
||||||
void CheckInvalidateSizeChange(nsHTMLReflowMetrics& aNewDesiredSize);
|
|
||||||
|
|
||||||
// Helper function that tests if the frame tree is too deep; if it is
|
// Helper function that tests if the frame tree is too deep; if it is
|
||||||
// it marks the frame as "unflowable", zeroes out the metrics, sets
|
// it marks the frame as "unflowable", zeroes out the metrics, sets
|
||||||
// the reflow status, and returns true. Otherwise, the frame is
|
// the reflow status, and returns true. Otherwise, the frame is
|
||||||
|
@ -156,94 +156,6 @@ nsHTMLScrollFrame::GetType() const
|
|||||||
return nsGkAtoms::scrollFrame;
|
return nsGkAtoms::scrollFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsHTMLScrollFrame::InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
if (aForChild) {
|
|
||||||
if (aForChild == mInner.mScrolledFrame) {
|
|
||||||
nsRect damage = aDamageRect + nsPoint(aX, aY);
|
|
||||||
// This is the damage rect that we're going to pass up to our parent.
|
|
||||||
nsRect parentDamage;
|
|
||||||
if (mInner.IsIgnoringViewportClipping()) {
|
|
||||||
parentDamage = damage;
|
|
||||||
} else {
|
|
||||||
// If we're using a displayport, we might be displaying an area
|
|
||||||
// different than our scroll port and the damage needs to be
|
|
||||||
// clipped to that instead.
|
|
||||||
nsRect displayport;
|
|
||||||
bool usingDisplayport = nsLayoutUtils::GetDisplayPort(GetContent(),
|
|
||||||
&displayport);
|
|
||||||
if (usingDisplayport) {
|
|
||||||
parentDamage.IntersectRect(damage, displayport);
|
|
||||||
} else {
|
|
||||||
parentDamage.IntersectRect(damage, mInner.mScrollPort);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsScrollingActive()) {
|
|
||||||
// This is the damage rect that we're going to pass up and
|
|
||||||
// only request invalidation of ThebesLayers for.
|
|
||||||
// damage is now in our coordinate system, which means it was
|
|
||||||
// translated using the current scroll position. Adjust it to
|
|
||||||
// reflect the scroll position at last paint, since that's what
|
|
||||||
// the ThebesLayers are currently set up for.
|
|
||||||
// This should not be clipped to the scrollport since ThebesLayers
|
|
||||||
// can contain content outside the scrollport that may need to be
|
|
||||||
// invalidated.
|
|
||||||
nsRect thebesLayerDamage = damage + GetScrollPosition() - mInner.mScrollPosAtLastPaint;
|
|
||||||
if (parentDamage.IsEqualInterior(thebesLayerDamage)) {
|
|
||||||
// This single call will take care of both rects
|
|
||||||
nsContainerFrame::InvalidateInternal(parentDamage, 0, 0, aForChild, aFlags);
|
|
||||||
} else {
|
|
||||||
// Invalidate rects separately
|
|
||||||
if (!(aFlags & INVALIDATE_NO_THEBES_LAYERS)) {
|
|
||||||
nsContainerFrame::InvalidateInternal(thebesLayerDamage, 0, 0, aForChild,
|
|
||||||
aFlags | INVALIDATE_ONLY_THEBES_LAYERS);
|
|
||||||
}
|
|
||||||
if (!(aFlags & INVALIDATE_ONLY_THEBES_LAYERS) && !parentDamage.IsEmpty()) {
|
|
||||||
nsContainerFrame::InvalidateInternal(parentDamage, 0, 0, aForChild,
|
|
||||||
aFlags | INVALIDATE_NO_THEBES_LAYERS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!parentDamage.IsEmpty()) {
|
|
||||||
nsContainerFrame::InvalidateInternal(parentDamage, 0, 0, aForChild, aFlags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mInner.mIsRoot && !parentDamage.IsEqualInterior(damage)) {
|
|
||||||
// Make sure we notify our prescontext about invalidations outside
|
|
||||||
// viewport clipping.
|
|
||||||
// This is important for things that are snapshotting the viewport,
|
|
||||||
// possibly outside the scrolled bounds.
|
|
||||||
// We don't need to propagate this any further up, though. Anyone who
|
|
||||||
// cares about scrolled-out-of-view invalidates had better be listening
|
|
||||||
// to our window directly.
|
|
||||||
PresContext()->NotifyInvalidation(damage, aFlags);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (aForChild == mInner.mHScrollbarBox) {
|
|
||||||
if (!mInner.mHasHorizontalScrollbar) {
|
|
||||||
// Our scrollbars may send up invalidations even when they're collapsed,
|
|
||||||
// because we just size a collapsed scrollbar to empty and some
|
|
||||||
// descendants may be non-empty. Suppress that invalidation here.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (aForChild == mInner.mVScrollbarBox) {
|
|
||||||
if (!mInner.mHasVerticalScrollbar) {
|
|
||||||
// Our scrollbars may send up invalidations even when they're collapsed,
|
|
||||||
// because we just size a collapsed scrollbar to empty and some
|
|
||||||
// descendants may be non-empty. Suppress that invalidation here.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsContainerFrame::InvalidateInternal(aDamageRect, aX, aY, aForChild, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
HTML scrolling implementation
|
HTML scrolling implementation
|
||||||
|
|
||||||
@ -909,8 +821,6 @@ nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
state.mContentsOverflowAreas + mInner.mScrolledFrame->GetPosition());
|
state.mContentsOverflowAreas + mInner.mScrolledFrame->GetPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckInvalidateSizeChange(aDesiredSize);
|
|
||||||
|
|
||||||
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
|
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||||
|
|
||||||
if (!InInitialReflow() && !mInner.mHadNonInitialReflow) {
|
if (!InInitialReflow() && !mInner.mHadNonInitialReflow) {
|
||||||
@ -1093,63 +1003,6 @@ nsXULScrollFrame::GetType() const
|
|||||||
return nsGkAtoms::scrollFrame;
|
return nsGkAtoms::scrollFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsXULScrollFrame::InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
if (aForChild == mInner.mScrolledFrame) {
|
|
||||||
nsRect damage = aDamageRect + nsPoint(aX, aY);
|
|
||||||
// This is the damage rect that we're going to pass up to our parent.
|
|
||||||
nsRect parentDamage;
|
|
||||||
// If we're using a displayport, we might be displaying an area
|
|
||||||
// different than our scroll port and the damage needs to be
|
|
||||||
// clipped to that instead.
|
|
||||||
nsRect displayport;
|
|
||||||
bool usingDisplayport = nsLayoutUtils::GetDisplayPort(GetContent(),
|
|
||||||
&displayport);
|
|
||||||
if (usingDisplayport) {
|
|
||||||
parentDamage.IntersectRect(damage, displayport);
|
|
||||||
} else {
|
|
||||||
parentDamage.IntersectRect(damage, mInner.mScrollPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsScrollingActive()) {
|
|
||||||
// This is the damage rect that we're going to pass up and
|
|
||||||
// only request invalidation of ThebesLayers for.
|
|
||||||
// damage is now in our coordinate system, which means it was
|
|
||||||
// translated using the current scroll position. Adjust it to
|
|
||||||
// reflect the scroll position at last paint, since that's what
|
|
||||||
// the ThebesLayers are currently set up for.
|
|
||||||
// This should not be clipped to the scrollport since ThebesLayers
|
|
||||||
// can contain content outside the scrollport that may need to be
|
|
||||||
// invalidated.
|
|
||||||
nsRect thebesLayerDamage = damage + GetScrollPosition() - mInner.mScrollPosAtLastPaint;
|
|
||||||
if (parentDamage.IsEqualInterior(thebesLayerDamage)) {
|
|
||||||
// This single call will take care of both rects
|
|
||||||
nsBoxFrame::InvalidateInternal(parentDamage, 0, 0, aForChild, aFlags);
|
|
||||||
} else {
|
|
||||||
// Invalidate rects separately
|
|
||||||
if (!(aFlags & INVALIDATE_NO_THEBES_LAYERS)) {
|
|
||||||
nsBoxFrame::InvalidateInternal(thebesLayerDamage, 0, 0, aForChild,
|
|
||||||
aFlags | INVALIDATE_ONLY_THEBES_LAYERS);
|
|
||||||
}
|
|
||||||
if (!(aFlags & INVALIDATE_ONLY_THEBES_LAYERS) && !parentDamage.IsEmpty()) {
|
|
||||||
nsBoxFrame::InvalidateInternal(parentDamage, 0, 0, aForChild,
|
|
||||||
aFlags | INVALIDATE_NO_THEBES_LAYERS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!parentDamage.IsEmpty()) {
|
|
||||||
nsBoxFrame::InvalidateInternal(parentDamage, 0, 0, aForChild, aFlags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsBoxFrame::InvalidateInternal(aDamageRect, aX, aY, aForChild, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
nscoord
|
nscoord
|
||||||
nsXULScrollFrame::GetBoxAscent(nsBoxLayoutState& aState)
|
nsXULScrollFrame::GetBoxAscent(nsBoxLayoutState& aState)
|
||||||
{
|
{
|
||||||
@ -1820,7 +1673,7 @@ InvalidateFixedBackgroundFramesFromList(nsDisplayListBuilder* aBuilder,
|
|||||||
item->IsVaryingRelativeToMovingFrame(aBuilder, aMovingFrame)) {
|
item->IsVaryingRelativeToMovingFrame(aBuilder, aMovingFrame)) {
|
||||||
if (FrameLayerBuilder::NeedToInvalidateFixedDisplayItem(aBuilder, item)) {
|
if (FrameLayerBuilder::NeedToInvalidateFixedDisplayItem(aBuilder, item)) {
|
||||||
// FrameLayerBuilder does not take care of scrolling this one
|
// FrameLayerBuilder does not take care of scrolling this one
|
||||||
f->Invalidate(item->GetVisibleRect() - item->ToReferenceFrame());
|
f->InvalidateFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1918,34 +1771,23 @@ void nsGfxScrollFrameInner::ScrollVisual(nsPoint aOldScrolledFramePos)
|
|||||||
AdjustViews(mScrolledFrame);
|
AdjustViews(mScrolledFrame);
|
||||||
// We need to call this after fixing up the view positions
|
// We need to call this after fixing up the view positions
|
||||||
// to be consistent with the frame hierarchy.
|
// to be consistent with the frame hierarchy.
|
||||||
PRUint32 flags = nsIFrame::INVALIDATE_REASON_SCROLL_REPAINT;
|
bool invalidate = false;
|
||||||
bool canScrollWithBlitting = CanScrollWithBlitting(mOuter);
|
bool canScrollWithBlitting = CanScrollWithBlitting(mOuter);
|
||||||
mOuter->RemoveStateBits(NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL);
|
mOuter->RemoveStateBits(NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL);
|
||||||
if (IsScrollingActive()) {
|
if (IsScrollingActive()) {
|
||||||
if (!canScrollWithBlitting) {
|
if (!canScrollWithBlitting) {
|
||||||
MarkInactive();
|
MarkInactive();
|
||||||
} else {
|
} else {
|
||||||
flags |= nsIFrame::INVALIDATE_NO_THEBES_LAYERS;
|
invalidate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (canScrollWithBlitting) {
|
if (canScrollWithBlitting) {
|
||||||
MarkActive();
|
MarkActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect invalidateRect, displayport;
|
mOuter->SchedulePaint();
|
||||||
if (IsIgnoringViewportClipping()) {
|
|
||||||
nsRect visualOverflow = mScrolledFrame->GetVisualOverflowRect();
|
|
||||||
invalidateRect.UnionRect(visualOverflow + mScrolledFrame->GetPosition(),
|
|
||||||
visualOverflow + aOldScrolledFramePos);
|
|
||||||
} else {
|
|
||||||
invalidateRect =
|
|
||||||
(nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayport)) ?
|
|
||||||
displayport : mScrollPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
mOuter->InvalidateWithFlags(invalidateRect, flags);
|
if (invalidate) {
|
||||||
|
|
||||||
if (flags & nsIFrame::INVALIDATE_NO_THEBES_LAYERS) {
|
|
||||||
nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(mOuter);
|
nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(mOuter);
|
||||||
nsRect update =
|
nsRect update =
|
||||||
GetScrollPortRect() + mOuter->GetOffsetToCrossDoc(displayRoot);
|
GetScrollPortRect() + mOuter->GetOffsetToCrossDoc(displayRoot);
|
||||||
@ -3144,28 +2986,6 @@ nsXULScrollFrame::LayoutScrollArea(nsBoxLayoutState& aState,
|
|||||||
ClampAndSetBounds(aState, childRect, aScrollPosition, true);
|
ClampAndSetBounds(aState, childRect, aScrollPosition, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect finalRect = mInner.mScrolledFrame->GetRect();
|
|
||||||
nsRect finalVisOverflow = mInner.mScrolledFrame->GetVisualOverflowRect();
|
|
||||||
// The position of the scrolled frame shouldn't change, but if it does or
|
|
||||||
// the position of the overflow rect changes just invalidate both the old
|
|
||||||
// and new overflow rect.
|
|
||||||
if (originalRect.TopLeft() != finalRect.TopLeft() ||
|
|
||||||
originalVisOverflow.TopLeft() != finalVisOverflow.TopLeft())
|
|
||||||
{
|
|
||||||
// The old overflow rect needs to be adjusted if the frame's position
|
|
||||||
// changed.
|
|
||||||
mInner.mScrolledFrame->Invalidate(
|
|
||||||
originalVisOverflow + originalRect.TopLeft() - finalRect.TopLeft());
|
|
||||||
mInner.mScrolledFrame->Invalidate(finalVisOverflow);
|
|
||||||
} else if (!originalVisOverflow.IsEqualInterior(finalVisOverflow)) {
|
|
||||||
// If the overflow rect changed then invalidate the difference between the
|
|
||||||
// old and new overflow rects.
|
|
||||||
mInner.mScrolledFrame->CheckInvalidateSizeChange(
|
|
||||||
originalRect, originalVisOverflow, finalRect.Size());
|
|
||||||
mInner.mScrolledFrame->InvalidateRectDifference(
|
|
||||||
originalVisOverflow, finalVisOverflow);
|
|
||||||
}
|
|
||||||
|
|
||||||
aState.SetLayoutFlags(oldflags);
|
aState.SetLayoutFlags(oldflags);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -3576,40 +3396,6 @@ nsGfxScrollFrameInner::ReflowCallbackCanceled()
|
|||||||
mPostedReflowCallback = false;
|
mPostedReflowCallback = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LayoutAndInvalidate(nsBoxLayoutState& aState,
|
|
||||||
nsIFrame* aBox, const nsRect& aRect,
|
|
||||||
bool aScrollbarIsBeingHidden)
|
|
||||||
{
|
|
||||||
// When a child box changes shape of position, the parent
|
|
||||||
// is responsible for invalidation; the overflow rect must be invalidated
|
|
||||||
// to make sure to catch any overflow.
|
|
||||||
// We invalidate the parent (i.e. the scrollframe) directly, because
|
|
||||||
// invalidates coming from scrollbars are suppressed by nsHTMLScrollFrame when
|
|
||||||
// mHasVScrollbar/mHasHScrollbar is false, and this is called after those
|
|
||||||
// flags have been set ... if a scrollbar is being hidden, we still need
|
|
||||||
// to invalidate the scrollbar area here.
|
|
||||||
// But we also need to invalidate the scrollbar itself in case it has
|
|
||||||
// its own layer; we need to ensure that layer is updated.
|
|
||||||
bool rectChanged = !aBox->GetRect().IsEqualInterior(aRect);
|
|
||||||
if (rectChanged) {
|
|
||||||
if (aScrollbarIsBeingHidden) {
|
|
||||||
aBox->GetParent()->Invalidate(aBox->GetVisualOverflowRect() +
|
|
||||||
aBox->GetPosition());
|
|
||||||
} else {
|
|
||||||
aBox->InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsBoxFrame::LayoutChildAt(aState, aBox, aRect);
|
|
||||||
if (rectChanged) {
|
|
||||||
if (aScrollbarIsBeingHidden) {
|
|
||||||
aBox->GetParent()->Invalidate(aBox->GetVisualOverflowRect() +
|
|
||||||
aBox->GetPosition());
|
|
||||||
} else {
|
|
||||||
aBox->InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsGfxScrollFrameInner::UpdateOverflow()
|
nsGfxScrollFrameInner::UpdateOverflow()
|
||||||
{
|
{
|
||||||
@ -3704,7 +3490,7 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mScrollCornerBox) {
|
if (mScrollCornerBox) {
|
||||||
LayoutAndInvalidate(aState, mScrollCornerBox, r, false);
|
nsBoxFrame::LayoutChildAt(aState, mScrollCornerBox, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasResizer) {
|
if (hasResizer) {
|
||||||
@ -3727,11 +3513,11 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
r.y = aContentArea.YMost() - r.height;
|
r.y = aContentArea.YMost() - r.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutAndInvalidate(aState, mResizerBox, r, false);
|
nsBoxFrame::LayoutChildAt(aState, mResizerBox, r);
|
||||||
}
|
}
|
||||||
else if (mResizerBox) {
|
else if (mResizerBox) {
|
||||||
// otherwise lay out the resizer with an empty rectangle
|
// otherwise lay out the resizer with an empty rectangle
|
||||||
LayoutAndInvalidate(aState, mResizerBox, nsRect(), false);
|
nsBoxFrame::LayoutChildAt(aState, mResizerBox, nsRect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3745,7 +3531,7 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
mVScrollbarBox->GetMargin(margin);
|
mVScrollbarBox->GetMargin(margin);
|
||||||
vRect.Deflate(margin);
|
vRect.Deflate(margin);
|
||||||
AdjustScrollbarRectForResizer(mOuter, presContext, vRect, hasResizer, true);
|
AdjustScrollbarRectForResizer(mOuter, presContext, vRect, hasResizer, true);
|
||||||
LayoutAndInvalidate(aState, mVScrollbarBox, vRect, !mHasVerticalScrollbar);
|
nsBoxFrame::LayoutChildAt(aState, mVScrollbarBox, vRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mHScrollbarBox) {
|
if (mHScrollbarBox) {
|
||||||
@ -3757,7 +3543,7 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
mHScrollbarBox->GetMargin(margin);
|
mHScrollbarBox->GetMargin(margin);
|
||||||
hRect.Deflate(margin);
|
hRect.Deflate(margin);
|
||||||
AdjustScrollbarRectForResizer(mOuter, presContext, hRect, hasResizer, false);
|
AdjustScrollbarRectForResizer(mOuter, presContext, hRect, hasResizer, false);
|
||||||
LayoutAndInvalidate(aState, mHScrollbarBox, hRect, !mHasHorizontalScrollbar);
|
nsBoxFrame::LayoutChildAt(aState, mHScrollbarBox, hRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// may need to update fixed position children of the viewport,
|
// may need to update fixed position children of the viewport,
|
||||||
|
@ -412,10 +412,6 @@ public:
|
|||||||
return mInner.GetScrolledFrame()->GetContentInsertionFrame();
|
return mInner.GetScrolledFrame()->GetContentInsertionFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags);
|
|
||||||
|
|
||||||
virtual bool DoesClipChildren() { return true; }
|
virtual bool DoesClipChildren() { return true; }
|
||||||
virtual nsSplittableType GetSplittableType() const;
|
virtual nsSplittableType GetSplittableType() const;
|
||||||
|
|
||||||
@ -621,10 +617,6 @@ public:
|
|||||||
return mInner.GetScrolledFrame()->GetContentInsertionFrame();
|
return mInner.GetScrolledFrame()->GetContentInsertionFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags);
|
|
||||||
|
|
||||||
virtual bool DoesClipChildren() { return true; }
|
virtual bool DoesClipChildren() { return true; }
|
||||||
virtual nsSplittableType GetSplittableType() const;
|
virtual nsSplittableType GetSplittableType() const;
|
||||||
|
|
||||||
|
@ -212,10 +212,6 @@ nsHTMLCanvasFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
aMetrics.SetOverflowAreasToDesiredBounds();
|
aMetrics.SetOverflowAreasToDesiredBounds();
|
||||||
FinishAndStoreOverflow(&aMetrics);
|
FinishAndStoreOverflow(&aMetrics);
|
||||||
|
|
||||||
if (mRect.width != aMetrics.width || mRect.height != aMetrics.height) {
|
|
||||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reflow the single anon block child.
|
// Reflow the single anon block child.
|
||||||
nsReflowStatus childStatus;
|
nsReflowStatus childStatus;
|
||||||
nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
|
nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
|
||||||
@ -263,7 +259,7 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
CanvasLayer* oldLayer = static_cast<CanvasLayer*>
|
CanvasLayer* oldLayer = static_cast<CanvasLayer*>
|
||||||
(GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
|
(GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aItem));
|
||||||
nsRefPtr<CanvasLayer> layer = element->GetCanvasLayer(aBuilder, oldLayer, aManager);
|
nsRefPtr<CanvasLayer> layer = element->GetCanvasLayer(aBuilder, oldLayer, aManager);
|
||||||
if (!layer)
|
if (!layer)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
@ -140,10 +140,6 @@ typedef PRUint64 nsFrameState;
|
|||||||
// continuation, e.g. a bidi continuation.
|
// continuation, e.g. a bidi continuation.
|
||||||
#define NS_FRAME_IS_FLUID_CONTINUATION NS_FRAME_STATE_BIT(2)
|
#define NS_FRAME_IS_FLUID_CONTINUATION NS_FRAME_STATE_BIT(2)
|
||||||
|
|
||||||
// This bit is set whenever the frame has one or more associated
|
|
||||||
// container layers.
|
|
||||||
#define NS_FRAME_HAS_CONTAINER_LAYER NS_FRAME_STATE_BIT(3)
|
|
||||||
|
|
||||||
// If this bit is set, then a reference to the frame is being held
|
// If this bit is set, then a reference to the frame is being held
|
||||||
// elsewhere. The frame may want to send a notification when it is
|
// elsewhere. The frame may want to send a notification when it is
|
||||||
// destroyed to allow these references to be cleared.
|
// destroyed to allow these references to be cleared.
|
||||||
@ -243,10 +239,6 @@ typedef PRUint64 nsFrameState;
|
|||||||
// This bit acts as a loop flag for recursive paint server drawing.
|
// This bit acts as a loop flag for recursive paint server drawing.
|
||||||
#define NS_FRAME_DRAWING_AS_PAINTSERVER NS_FRAME_STATE_BIT(33)
|
#define NS_FRAME_DRAWING_AS_PAINTSERVER NS_FRAME_STATE_BIT(33)
|
||||||
|
|
||||||
// Frame or one of its (cross-doc) descendants may have the
|
|
||||||
// NS_FRAME_HAS_CONTAINER_LAYER bit.
|
|
||||||
#define NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT NS_FRAME_STATE_BIT(34)
|
|
||||||
|
|
||||||
// Frame's overflow area was clipped by the 'clip' property.
|
// Frame's overflow area was clipped by the 'clip' property.
|
||||||
#define NS_FRAME_HAS_CLIP NS_FRAME_STATE_BIT(35)
|
#define NS_FRAME_HAS_CLIP NS_FRAME_STATE_BIT(35)
|
||||||
|
|
||||||
@ -288,6 +280,16 @@ typedef PRUint64 nsFrameState;
|
|||||||
// Is this frame allowed to have generated (::before/::after) content?
|
// Is this frame allowed to have generated (::before/::after) content?
|
||||||
#define NS_FRAME_MAY_HAVE_GENERATED_CONTENT NS_FRAME_STATE_BIT(44)
|
#define NS_FRAME_MAY_HAVE_GENERATED_CONTENT NS_FRAME_STATE_BIT(44)
|
||||||
|
|
||||||
|
// Frame is marked as needing painting
|
||||||
|
#define NS_FRAME_NEEDS_PAINT NS_FRAME_STATE_BIT(45)
|
||||||
|
|
||||||
|
// Frame has a descendant frame that needs painting - This includes
|
||||||
|
// cross-doc children.
|
||||||
|
#define NS_FRAME_DESCENDANT_NEEDS_PAINT NS_FRAME_STATE_BIT(46)
|
||||||
|
|
||||||
|
// Frame is a descendant of a popup
|
||||||
|
#define NS_FRAME_IN_POPUP NS_FRAME_STATE_BIT(47)
|
||||||
|
|
||||||
// Box layout bits
|
// Box layout bits
|
||||||
#define NS_STATE_IS_HORIZONTAL NS_FRAME_STATE_BIT(22)
|
#define NS_STATE_IS_HORIZONTAL NS_FRAME_STATE_BIT(22)
|
||||||
#define NS_STATE_IS_DIRECTION_NORMAL NS_FRAME_STATE_BIT(31)
|
#define NS_STATE_IS_DIRECTION_NORMAL NS_FRAME_STATE_BIT(31)
|
||||||
@ -1040,6 +1042,13 @@ public:
|
|||||||
virtual const nsFrameList& GetChildList(ChildListID aListID) const = 0;
|
virtual const nsFrameList& GetChildList(ChildListID aListID) const = 0;
|
||||||
const nsFrameList& PrincipalChildList() { return GetChildList(kPrincipalList); }
|
const nsFrameList& PrincipalChildList() { return GetChildList(kPrincipalList); }
|
||||||
virtual void GetChildLists(nsTArray<ChildList>* aLists) const = 0;
|
virtual void GetChildLists(nsTArray<ChildList>* aLists) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the child lists for this frame, including
|
||||||
|
* ones belong to a child document.
|
||||||
|
*/
|
||||||
|
void GetCrossDocChildLists(nsTArray<ChildList>* aLists);
|
||||||
|
|
||||||
// XXXbz this method should go away
|
// XXXbz this method should go away
|
||||||
nsIFrame* GetFirstChild(ChildListID aListID) const {
|
nsIFrame* GetFirstChild(ChildListID aListID) const {
|
||||||
return GetChildList(aListID).FirstChild();
|
return GetChildList(aListID).FirstChild();
|
||||||
@ -1361,6 +1370,16 @@ public:
|
|||||||
void AddStateBits(nsFrameState aBits) { mState |= aBits; }
|
void AddStateBits(nsFrameState aBits) { mState |= aBits; }
|
||||||
void RemoveStateBits(nsFrameState aBits) { mState &= ~aBits; }
|
void RemoveStateBits(nsFrameState aBits) { mState &= ~aBits; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the current frame-state includes all of the listed bits
|
||||||
|
*/
|
||||||
|
bool HasAllStateBits(nsFrameState aBits) { return (mState & aBits) == aBits; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the current frame-state includes any of the listed bits
|
||||||
|
*/
|
||||||
|
bool HasAnyStateBits(nsFrameState aBits) { return mState & aBits; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This call is invoked on the primary frame for a character data content
|
* This call is invoked on the primary frame for a character data content
|
||||||
* node, when it is changed in the content tree.
|
* node, when it is changed in the content tree.
|
||||||
@ -2090,141 +2109,71 @@ public:
|
|||||||
bool AreLayersMarkedActive(nsChangeHint aChangeHint);
|
bool AreLayersMarkedActive(nsChangeHint aChangeHint);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param aFlags see InvalidateInternal below
|
* Marks all display items created by this frame as needing a repaint,
|
||||||
*/
|
* and calls SchedulePaint() if requested.
|
||||||
void InvalidateWithFlags(const nsRect& aDamageRect, PRUint32 aFlags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate part of the frame by asking the view manager to repaint.
|
|
||||||
* aDamageRect is allowed to extend outside the frame's bounds. We'll do the right
|
|
||||||
* thing.
|
|
||||||
* We deliberately don't have an Invalidate() method that defaults to the frame's bounds.
|
|
||||||
* We want all callers to *think* about what has changed in the frame and what area might
|
|
||||||
* need to be repainted.
|
|
||||||
*
|
*
|
||||||
* @param aDamageRect is in the frame's local coordinate space
|
* This includes all display items created by this frame, including
|
||||||
*/
|
* container types.
|
||||||
void Invalidate(const nsRect& aDamageRect)
|
* @param aFlags INVALIDATE_DONT_SCHEDULE_PAINT: Don't call SchedulePaint()
|
||||||
{ return InvalidateWithFlags(aDamageRect, 0); }
|
* when invalidating.
|
||||||
|
|
||||||
/**
|
|
||||||
* As Invalidate above, except that this should be called when the
|
|
||||||
* rendering that has changed is performed using layers so we can avoid
|
|
||||||
* updating the contents of ThebesLayers.
|
|
||||||
* If the frame has a dedicated layer rendering this display item, we
|
|
||||||
* return that layer.
|
|
||||||
* @param aDisplayItemKey must not be zero; indicates the kind of display
|
|
||||||
* item that is being invalidated.
|
|
||||||
*/
|
|
||||||
Layer* InvalidateLayer(const nsRect& aDamageRect, PRUint32 aDisplayItemKey);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate the area of the parent that's covered by the transformed
|
|
||||||
* visual overflow rect of this frame. Don't depend on the transform style
|
|
||||||
* for this frame, in case that's changed since this frame was painted.
|
|
||||||
*/
|
|
||||||
void InvalidateTransformLayer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function that can be overridden by frame classes. The rectangle
|
|
||||||
* (plus aOffsetX/aOffsetY) is relative to this frame.
|
|
||||||
*
|
|
||||||
* The offset is given as two coords rather than as an nsPoint because
|
|
||||||
* gcc optimizes it better that way, in particular in the default
|
|
||||||
* implementation that passes the area to the parent frame becomes a tail
|
|
||||||
* call.
|
|
||||||
*
|
|
||||||
* The default implementation will crash if the frame has no parent so
|
|
||||||
* frames without parents MUST* override.
|
|
||||||
*
|
|
||||||
* @param aForChild if the invalidation is coming from a child frame, this
|
|
||||||
* is the frame; otherwise, this is null.
|
|
||||||
* @param aFlags INVALIDATE_IMMEDIATE: repaint now if true, repaint later if false.
|
|
||||||
* In case it's true, pending notifications will be flushed which
|
|
||||||
* could cause frames to be deleted (including |this|).
|
|
||||||
* @param aFlags INVALIDATE_CROSS_DOC: true if the invalidation
|
|
||||||
* originated in a subdocument
|
|
||||||
* @param aFlags INVALIDATE_REASON_SCROLL_BLIT: set if the invalidation
|
|
||||||
* was really just the scroll machinery copying pixels from one
|
|
||||||
* part of the window to another
|
|
||||||
* @param aFlags INVALIDATE_REASON_SCROLL_REPAINT: set if the invalidation
|
|
||||||
* was triggered by scrolling
|
|
||||||
* @param aFlags INVALIDATE_NO_THEBES_LAYERS: don't invalidate the
|
|
||||||
* ThebesLayers of any container layer owned by an ancestor. Set this
|
|
||||||
* only if ThebesLayers definitely don't need to be updated.
|
|
||||||
* @param aFlags INVALIDATE_ONLY_THEBES_LAYERS: invalidate only in the
|
|
||||||
* ThebesLayers of the nearest container layer.
|
|
||||||
* @param aFlags INVALIDATE_EXCLUDE_CURRENT_PAINT: if the invalidation
|
|
||||||
* occurs while we're painting (to be precise, while
|
|
||||||
* BeginDeferringInvalidatesForDisplayRoot is active on the display root),
|
|
||||||
* then invalidation in the current paint region is simply discarded.
|
|
||||||
* Use this flag if areas that are being painted do not need
|
|
||||||
* to be invalidated. By default, when this flag is not specified,
|
|
||||||
* areas that are invalidated while currently being painted will be repainted
|
|
||||||
* again.
|
|
||||||
* This flag is useful when, during painting, FrameLayerBuilder discovers that
|
|
||||||
* a region of the window needs to be drawn differently, and that region
|
|
||||||
* may or may not be contained in the currently painted region.
|
|
||||||
* @param aFlags INVALIDATE_NO_UPDATE_LAYER_TREE: display lists and the
|
|
||||||
* layer tree do not need to be updated. This can be used when the layer
|
|
||||||
* tree has already been updated outside a transaction, e.g. via
|
|
||||||
* ImageContainer::SetCurrentImage.
|
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
INVALIDATE_IMMEDIATE = 0x01,
|
INVALIDATE_DONT_SCHEDULE_PAINT
|
||||||
INVALIDATE_CROSS_DOC = 0x02,
|
|
||||||
INVALIDATE_REASON_SCROLL_BLIT = 0x04,
|
|
||||||
INVALIDATE_REASON_SCROLL_REPAINT = 0x08,
|
|
||||||
INVALIDATE_REASON_MASK = INVALIDATE_REASON_SCROLL_BLIT |
|
|
||||||
INVALIDATE_REASON_SCROLL_REPAINT,
|
|
||||||
INVALIDATE_NO_THEBES_LAYERS = 0x10,
|
|
||||||
INVALIDATE_ONLY_THEBES_LAYERS = 0x20,
|
|
||||||
INVALIDATE_EXCLUDE_CURRENT_PAINT = 0x40,
|
|
||||||
INVALIDATE_NO_UPDATE_LAYER_TREE = 0x80,
|
|
||||||
INVALIDATE_ALREADY_TRANSFORMED = 0x100
|
|
||||||
};
|
};
|
||||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
virtual void InvalidateFrame(PRUint32 aFlags = 0);
|
||||||
nscoord aOffsetX, nscoord aOffsetY,
|
|
||||||
nsIFrame* aForChild, PRUint32 aFlags);
|
/**
|
||||||
|
* Calls InvalidateFrame() on all frames descendant frames (including
|
||||||
|
* this one).
|
||||||
|
*
|
||||||
|
* This function doesn't walk through placeholder frames to invalidate
|
||||||
|
* the out-of-flow frames.
|
||||||
|
*/
|
||||||
|
void InvalidateFrameSubtree(PRUint32 aFlags = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a frame has had InvalidateFrame() called on it since the
|
||||||
|
* last paint.
|
||||||
|
*/
|
||||||
|
bool IsInvalid();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if any frame within the frame subtree (including this frame)
|
||||||
|
* returns true for IsInvalid().
|
||||||
|
*/
|
||||||
|
bool HasInvalidFrameInSubtree()
|
||||||
|
{
|
||||||
|
return HasAnyStateBits(NS_FRAME_NEEDS_PAINT | NS_FRAME_DESCENDANT_NEEDS_PAINT);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function that funnels an InvalidateInternal request up to the
|
* Removes the invalid state from the current frame and all
|
||||||
* parent. This function is used so that if MOZ_SVG is not defined, we still
|
* descendant frames.
|
||||||
* have unified control paths in the InvalidateInternal chain.
|
*/
|
||||||
|
void ClearInvalidationStateBits();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that the refresh driver is running, and schedules a view
|
||||||
|
* manager flush on the next tick.
|
||||||
*
|
*
|
||||||
* @param aDamageRect The rect to invalidate.
|
* The view manager flush will update the layer tree, repaint any
|
||||||
* @param aX The x offset from the origin of this frame to the rectangle.
|
* invalid areas in the layer tree and schedule a layer tree
|
||||||
* @param aY The y offset from the origin of this frame to the rectangle.
|
* composite operation to display the layer tree.
|
||||||
* @param aImmediate Whether to redraw immediately.
|
|
||||||
* @return None, though this funnels the request up to the parent frame.
|
|
||||||
*/
|
*/
|
||||||
void InvalidateInternalAfterResize(const nsRect& aDamageRect, nscoord aX,
|
void SchedulePaint();
|
||||||
nscoord aY, PRUint32 aFlags);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take two rectangles in the coordinate system of this frame which
|
* Checks if the layer tree includes a dedicated layer for this
|
||||||
* have the same origin and invalidate the difference between them.
|
* frame/display item key pair, and invalidates at least aDamageRect
|
||||||
* This is a helper method to be used when a frame is being resized.
|
* area within that layer.
|
||||||
*
|
*
|
||||||
* @param aR1 the first rectangle
|
* If no layer is found, calls InvalidateFrame() instead.
|
||||||
* @param aR2 the second rectangle
|
*
|
||||||
|
* @param aDamageRect Area of the layer to invalidate.
|
||||||
|
* @param aDisplayItemKey Display item type.
|
||||||
|
* @return Layer, if found, nsnull otherwise.
|
||||||
*/
|
*/
|
||||||
void InvalidateRectDifference(const nsRect& aR1, const nsRect& aR2);
|
Layer* InvalidateLayer(PRUint32 aDisplayItemKey, const nsIntRect* aDamageRect = nsnull);
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate the entire frame subtree for this frame. Invalidates this
|
|
||||||
* frame's overflow rect, and also ensures that all ThebesLayer children
|
|
||||||
* of ContainerLayers associated with frames in this subtree are
|
|
||||||
* completely invalidated.
|
|
||||||
*/
|
|
||||||
void InvalidateFrameSubtree();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidates this frame's visual overflow rect. Does not necessarily
|
|
||||||
* cause ThebesLayers for descendant frames to be repainted; only this
|
|
||||||
* frame can be relied on to be repainted.
|
|
||||||
*/
|
|
||||||
void InvalidateOverflowRect();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a rect that encompasses everything that might be painted by
|
* Returns a rect that encompasses everything that might be painted by
|
||||||
@ -2681,7 +2630,7 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty()))
|
|||||||
bool IsHorizontal() const { return (mState & NS_STATE_IS_HORIZONTAL) != 0; }
|
bool IsHorizontal() const { return (mState & NS_STATE_IS_HORIZONTAL) != 0; }
|
||||||
bool IsNormalDirection() const { return (mState & NS_STATE_IS_DIRECTION_NORMAL) != 0; }
|
bool IsNormalDirection() const { return (mState & NS_STATE_IS_DIRECTION_NORMAL) != 0; }
|
||||||
|
|
||||||
NS_HIDDEN_(nsresult) Redraw(nsBoxLayoutState& aState, const nsRect* aRect = nsnull);
|
NS_HIDDEN_(nsresult) Redraw(nsBoxLayoutState& aState);
|
||||||
NS_IMETHOD RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIBox* aChild)=0;
|
NS_IMETHOD RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIBox* aChild)=0;
|
||||||
// XXX take this out after we've branched
|
// XXX take this out after we've branched
|
||||||
virtual bool GetMouseThrough() const { return false; };
|
virtual bool GetMouseThrough() const { return false; };
|
||||||
@ -2730,17 +2679,6 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty()))
|
|||||||
*/
|
*/
|
||||||
CaretPosition GetExtremeCaretPosition(bool aStart);
|
CaretPosition GetExtremeCaretPosition(bool aStart);
|
||||||
|
|
||||||
/**
|
|
||||||
* Same thing as nsFrame::CheckInvalidateSizeChange, but more flexible. The
|
|
||||||
* implementation of this method must not depend on the mRect or
|
|
||||||
* GetVisualOverflowRect() of the frame! Note that it's safe to
|
|
||||||
* assume in this method that the frame origin didn't change. If it
|
|
||||||
* did, whoever moved the frame will invalidate as needed anyway.
|
|
||||||
*/
|
|
||||||
void CheckInvalidateSizeChange(const nsRect& aOldRect,
|
|
||||||
const nsRect& aOldVisualOverflowRect,
|
|
||||||
const nsSize& aNewDesiredSize);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a line iterator for this frame, if supported.
|
* Get a line iterator for this frame, if supported.
|
||||||
*
|
*
|
||||||
@ -2882,12 +2820,6 @@ protected:
|
|||||||
} mOverflow;
|
} mOverflow;
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
/**
|
|
||||||
* For frames that have top-level windows (top-level viewports,
|
|
||||||
* comboboxes, menupoups) this function will invalidate the window.
|
|
||||||
*/
|
|
||||||
void InvalidateRoot(const nsRect& aDamageRect, PRUint32 aFlags);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can we stop inside this frame when we're skipping non-rendered whitespace?
|
* Can we stop inside this frame when we're skipping non-rendered whitespace?
|
||||||
* @param aForward [in] Are we moving forward (or backward) in content order.
|
* @param aForward [in] Are we moving forward (or backward) in content order.
|
||||||
|
@ -587,19 +587,11 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
|||||||
if (!aCurrentFrame)
|
if (!aCurrentFrame)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
// XXX We really need to round this out, now that we're doing better
|
|
||||||
// image scaling!
|
|
||||||
nsRect r = aRect->IsEqualInterior(nsIntRect::GetMaxSizedIntRect()) ?
|
|
||||||
GetInnerArea() :
|
|
||||||
SourceRectToDest(*aRect);
|
|
||||||
|
|
||||||
#ifdef DEBUG_decode
|
#ifdef DEBUG_decode
|
||||||
printf("Source rect (%d,%d,%d,%d) -> invalidate dest rect (%d,%d,%d,%d)\n",
|
printf("Source rect (%d,%d,%d,%d)\n",
|
||||||
aRect->x, aRect->y, aRect->width, aRect->height,
|
aRect->x, aRect->y, aRect->width, aRect->height);
|
||||||
r.x, r.y, r.width, r.height);
|
|
||||||
#endif
|
#endif
|
||||||
|
InvalidateFrame();
|
||||||
Invalidate(r);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -658,10 +650,8 @@ nsImageFrame::NotifyNewCurrentRequest(imgIRequest *aRequest,
|
|||||||
NS_FRAME_IS_DIRTY);
|
NS_FRAME_IS_DIRTY);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nsSize s = GetSize();
|
|
||||||
nsRect r(0, 0, s.width, s.height);
|
|
||||||
// Update border+content to account for image change
|
// Update border+content to account for image change
|
||||||
Invalidate(r);
|
InvalidateFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -680,12 +670,8 @@ nsImageFrame::FrameChanged(imgIRequest *aRequest,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect r = aDirtyRect->IsEqualInterior(nsIntRect::GetMaxSizedIntRect()) ?
|
|
||||||
GetInnerArea() :
|
|
||||||
SourceRectToDest(*aDirtyRect);
|
|
||||||
|
|
||||||
// Update border+content to account for image change
|
// Update border+content to account for image change
|
||||||
Invalidate(r);
|
InvalidateFrame();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,15 +866,6 @@ nsImageFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
aMetrics.SetOverflowAreasToDesiredBounds();
|
aMetrics.SetOverflowAreasToDesiredBounds();
|
||||||
FinishAndStoreOverflow(&aMetrics);
|
FinishAndStoreOverflow(&aMetrics);
|
||||||
|
|
||||||
// Now that that's all done, check whether we're resizing... if we are,
|
|
||||||
// invalidate our rect.
|
|
||||||
// XXXbz we really only want to do this when reflow is completely done, but
|
|
||||||
// we have no way to detect when mRect changes (since SetRect is non-virtual,
|
|
||||||
// so this is the best we can do).
|
|
||||||
if (mRect.width != aMetrics.width || mRect.height != aMetrics.height) {
|
|
||||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
||||||
("exit nsImageFrame::Reflow: size=%d,%d",
|
("exit nsImageFrame::Reflow: size=%d,%d",
|
||||||
aMetrics.width, aMetrics.height));
|
aMetrics.width, aMetrics.height));
|
||||||
@ -2011,7 +1988,7 @@ nsImageFrame::IconLoad::OnStopRequest(imgIRequest *aRequest,
|
|||||||
nsImageFrame *frame;
|
nsImageFrame *frame;
|
||||||
while (iter.HasMore()) {
|
while (iter.HasMore()) {
|
||||||
frame = iter.GetNext();
|
frame = iter.GetNext();
|
||||||
frame->Invalidate(frame->GetRect());
|
frame->InvalidateFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -2032,7 +2009,7 @@ nsImageFrame::IconLoad::FrameChanged(imgIRequest *aRequest,
|
|||||||
nsImageFrame *frame;
|
nsImageFrame *frame;
|
||||||
while (iter.HasMore()) {
|
while (iter.HasMore()) {
|
||||||
frame = iter.GetNext();
|
frame = iter.GetNext();
|
||||||
frame->Invalidate(frame->GetRect());
|
frame->InvalidateFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -981,9 +981,7 @@ nsImageMap::HandleEvent(nsIDOMEvent* aEvent)
|
|||||||
area->HasFocus(focus);
|
area->HasFocus(focus);
|
||||||
//Now invalidate the rect
|
//Now invalidate the rect
|
||||||
if (mImageFrame) {
|
if (mImageFrame) {
|
||||||
nsRect dmgRect;
|
mImageFrame->InvalidateFrame();
|
||||||
area->GetRect(mImageFrame, dmgRect);
|
|
||||||
mImageFrame->Invalidate(dmgRect);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,7 @@ nsObjectFrame::PrepForDrawing(nsIWidget *aWidget)
|
|||||||
// plugins are painted through Thebes and we need to ensure
|
// plugins are painted through Thebes and we need to ensure
|
||||||
// the Thebes layer containing the plugin is updated.
|
// the Thebes layer containing the plugin is updated.
|
||||||
if (parentWidget == GetNearestWidget()) {
|
if (parentWidget == GetNearestWidget()) {
|
||||||
Invalidate(GetContentRectRelativeToSelf());
|
InvalidateFrame();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1530,7 +1530,7 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||||||
// to provide crisper and faster drawing.
|
// to provide crisper and faster drawing.
|
||||||
r.Round();
|
r.Round();
|
||||||
nsRefPtr<Layer> layer =
|
nsRefPtr<Layer> layer =
|
||||||
(GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
|
(GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aItem));
|
||||||
|
|
||||||
if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN) {
|
if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN) {
|
||||||
if (!layer) {
|
if (!layer) {
|
||||||
|
@ -123,7 +123,6 @@ nsPlaceholderFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
|||||||
nsIPresShell* shell = PresContext()->GetPresShell();
|
nsIPresShell* shell = PresContext()->GetPresShell();
|
||||||
nsIFrame* oof = mOutOfFlowFrame;
|
nsIFrame* oof = mOutOfFlowFrame;
|
||||||
if (oof) {
|
if (oof) {
|
||||||
oof->InvalidateFrameSubtree();
|
|
||||||
// Unregister out-of-flow frame
|
// Unregister out-of-flow frame
|
||||||
shell->FrameManager()->UnregisterPlaceholderFrame(this);
|
shell->FrameManager()->UnregisterPlaceholderFrame(this);
|
||||||
mOutOfFlowFrame = nsnull;
|
mOutOfFlowFrame = nsnull;
|
||||||
@ -134,7 +133,7 @@ nsPlaceholderFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
|||||||
((GetStateBits() & PLACEHOLDER_FOR_POPUP) ||
|
((GetStateBits() & PLACEHOLDER_FOR_POPUP) ||
|
||||||
!nsLayoutUtils::IsProperAncestorFrame(aDestructRoot, oof))) {
|
!nsLayoutUtils::IsProperAncestorFrame(aDestructRoot, oof))) {
|
||||||
ChildListID listId = nsLayoutUtils::GetChildListNameFor(oof);
|
ChildListID listId = nsLayoutUtils::GetChildListNameFor(oof);
|
||||||
shell->FrameManager()->RemoveFrame(listId, oof, false);
|
shell->FrameManager()->RemoveFrame(listId, oof);
|
||||||
}
|
}
|
||||||
// else oof will be destroyed by its parent
|
// else oof will be destroyed by its parent
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include "nsObjectFrame.h"
|
#include "nsObjectFrame.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
#include "LayerTreeInvalidation.h"
|
||||||
|
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
#include "nsXULPopupManager.h"
|
#include "nsXULPopupManager.h"
|
||||||
@ -361,14 +362,16 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||||||
|
|
||||||
nsDisplayZoom* zoomItem =
|
nsDisplayZoom* zoomItem =
|
||||||
new (aBuilder) nsDisplayZoom(aBuilder, subdocRootFrame, &childItems,
|
new (aBuilder) nsDisplayZoom(aBuilder, subdocRootFrame, &childItems,
|
||||||
subdocAPD, parentAPD);
|
subdocAPD, parentAPD,
|
||||||
|
nsDisplayOwnLayer::GENERATE_SUBDOC_INVALIDATIONS);
|
||||||
childItems.AppendToTop(zoomItem);
|
childItems.AppendToTop(zoomItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!addedLayer && presContext->IsRootContentDocument()) {
|
if (!addedLayer && presContext->IsRootContentDocument()) {
|
||||||
// We always want top level content documents to be in their own layer.
|
// We always want top level content documents to be in their own layer.
|
||||||
nsDisplayOwnLayer* layerItem = new (aBuilder) nsDisplayOwnLayer(
|
nsDisplayOwnLayer* layerItem = new (aBuilder) nsDisplayOwnLayer(
|
||||||
aBuilder, subdocRootFrame ? subdocRootFrame : this, &childItems);
|
aBuilder, subdocRootFrame ? subdocRootFrame : this,
|
||||||
|
&childItems, nsDisplayOwnLayer::GENERATE_SUBDOC_INVALIDATIONS);
|
||||||
childItems.AppendToTop(layerItem);
|
childItems.AppendToTop(layerItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,9 +591,6 @@ nsSubDocumentFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if we need to repaint our border, background or outline
|
|
||||||
CheckInvalidateSizeChange(aDesiredSize);
|
|
||||||
|
|
||||||
FinishAndStoreOverflow(&aDesiredSize);
|
FinishAndStoreOverflow(&aDesiredSize);
|
||||||
|
|
||||||
if (!aPresContext->IsPaginated() && !mPostedReflowCallback) {
|
if (!aPresContext->IsPaginated() && !mPostedReflowCallback) {
|
||||||
@ -903,6 +903,9 @@ nsSubDocumentFrame::BeginSwapDocShells(nsIFrame* aOther)
|
|||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(HasAnyStateBits(NS_FRAME_IN_POPUP) == other->HasAnyStateBits(NS_FRAME_IN_POPUP),
|
||||||
|
"Can't swap doc shells when only one is within a popup!");
|
||||||
|
|
||||||
if (mInnerView && other->mInnerView) {
|
if (mInnerView && other->mInnerView) {
|
||||||
nsIView* ourSubdocViews = mInnerView->GetFirstChild();
|
nsIView* ourSubdocViews = mInnerView->GetFirstChild();
|
||||||
nsIView* ourRemovedViews = ::BeginSwapDocShellsForViews(ourSubdocViews);
|
nsIView* ourRemovedViews = ::BeginSwapDocShellsForViews(ourSubdocViews);
|
||||||
|
@ -23,11 +23,16 @@ class PropertyProvider;
|
|||||||
|
|
||||||
#define TEXT_HAS_FONT_INFLATION NS_FRAME_STATE_BIT(61)
|
#define TEXT_HAS_FONT_INFLATION NS_FRAME_STATE_BIT(61)
|
||||||
|
|
||||||
|
class nsDisplayTextGeometry;
|
||||||
|
class nsDisplayText;
|
||||||
|
|
||||||
class nsTextFrame : public nsFrame {
|
class nsTextFrame : public nsFrame {
|
||||||
public:
|
public:
|
||||||
NS_DECL_FRAMEARENA_HELPERS
|
NS_DECL_FRAMEARENA_HELPERS
|
||||||
|
|
||||||
friend class nsContinuingTextFrame;
|
friend class nsContinuingTextFrame;
|
||||||
|
friend class nsDisplayTextGeometry;
|
||||||
|
friend class nsDisplayText;
|
||||||
|
|
||||||
nsTextFrame(nsStyleContext* aContext)
|
nsTextFrame(nsStyleContext* aContext)
|
||||||
: nsFrame(aContext)
|
: nsFrame(aContext)
|
||||||
@ -492,6 +497,10 @@ protected:
|
|||||||
mColor == aOther.mColor &&
|
mColor == aOther.mColor &&
|
||||||
mBaselineOffset == aOther.mBaselineOffset;
|
mBaselineOffset == aOther.mBaselineOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator!=(const LineDecoration& aOther) const {
|
||||||
|
return !(*this == aOther);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
struct TextDecorations {
|
struct TextDecorations {
|
||||||
nsAutoTArray<LineDecoration, 1> mOverlines, mUnderlines, mStrikes;
|
nsAutoTArray<LineDecoration, 1> mOverlines, mUnderlines, mStrikes;
|
||||||
@ -510,6 +519,17 @@ protected:
|
|||||||
bool HasStrikeout() const {
|
bool HasStrikeout() const {
|
||||||
return !mStrikes.IsEmpty();
|
return !mStrikes.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const TextDecorations& aOther) const {
|
||||||
|
return mOverlines == aOther.mOverlines &&
|
||||||
|
mUnderlines == aOther.mUnderlines &&
|
||||||
|
mStrikes == aOther.mStrikes;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const TextDecorations& aOther) const {
|
||||||
|
return !(*this == aOther);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
void GetTextDecorations(nsPresContext* aPresContext,
|
void GetTextDecorations(nsPresContext* aPresContext,
|
||||||
TextDecorations& aDecorations);
|
TextDecorations& aDecorations);
|
||||||
|
@ -3307,8 +3307,7 @@ NS_IMETHODIMP nsBlinkTimer::Notify(nsITimer *timer)
|
|||||||
|
|
||||||
// Determine damaged area and tell view manager to redraw it
|
// Determine damaged area and tell view manager to redraw it
|
||||||
// blink doesn't blink outline ... I hope
|
// blink doesn't blink outline ... I hope
|
||||||
nsRect bounds(nsPoint(0, 0), frameData.mFrame->GetSize());
|
frameData.mFrame->InvalidateFrame();
|
||||||
frameData.mFrame->Invalidate(bounds);
|
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -4303,6 +4302,7 @@ nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
|
|||||||
// will do that when it gets called during reflow.
|
// will do that when it gets called during reflow.
|
||||||
textFrame->AddStateBits(NS_FRAME_IS_DIRTY);
|
textFrame->AddStateBits(NS_FRAME_IS_DIRTY);
|
||||||
}
|
}
|
||||||
|
textFrame->InvalidateFrame();
|
||||||
|
|
||||||
// Below, frames that start after the deleted text will be adjusted so that
|
// Below, frames that start after the deleted text will be adjusted so that
|
||||||
// their offsets move with the trailing unchanged text. If this change
|
// their offsets move with the trailing unchanged text. If this change
|
||||||
@ -4343,7 +4343,23 @@ nsTextFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||||||
{
|
{
|
||||||
nsFrame::DidSetStyleContext(aOldStyleContext);
|
nsFrame::DidSetStyleContext(aOldStyleContext);
|
||||||
ClearTextRuns();
|
ClearTextRuns();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class nsDisplayTextGeometry : public nsDisplayItemGenericGeometry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsDisplayTextGeometry(nsTextFrame* aFrame)
|
||||||
|
{
|
||||||
|
aFrame->GetTextDecorations(aFrame->PresContext(), mDecorations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We store the computed text decorations here since they are
|
||||||
|
* computed using style data from parent frames. Any changes to these
|
||||||
|
* styles will only invalidate the parent frame and not this frame.
|
||||||
|
*/
|
||||||
|
nsTextFrame::TextDecorations mDecorations;
|
||||||
|
};
|
||||||
|
|
||||||
class nsDisplayText : public nsCharClipDisplayItem {
|
class nsDisplayText : public nsCharClipDisplayItem {
|
||||||
public:
|
public:
|
||||||
@ -4360,7 +4376,10 @@ public:
|
|||||||
|
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
|
||||||
*aSnap = false;
|
*aSnap = false;
|
||||||
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
|
nsRect temp = mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
|
||||||
|
// Bug 748228
|
||||||
|
temp.Inflate(mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
||||||
@ -4378,6 +4397,37 @@ public:
|
|||||||
return GetBounds(aBuilder, &snap);
|
return GetBounds(aBuilder, &snap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
|
||||||
|
{
|
||||||
|
nsTextFrame* f = static_cast<nsTextFrame*>(mFrame);
|
||||||
|
nsDisplayTextGeometry* geometry = new nsDisplayTextGeometry(f);
|
||||||
|
bool snap;
|
||||||
|
geometry->mBounds = GetBounds(aBuilder, &snap);
|
||||||
|
geometry->mBorderRect = GetBorderRect();
|
||||||
|
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion *aInvalidRegion)
|
||||||
|
{
|
||||||
|
const nsDisplayTextGeometry* geometry = static_cast<const nsDisplayTextGeometry*>(aGeometry);
|
||||||
|
nsTextFrame* f = static_cast<nsTextFrame*>(mFrame);
|
||||||
|
|
||||||
|
nsTextFrame::TextDecorations decorations;
|
||||||
|
f->GetTextDecorations(f->PresContext(), decorations);
|
||||||
|
|
||||||
|
bool snap;
|
||||||
|
nsRect newRect = geometry->mBounds;
|
||||||
|
nsRect oldRect = GetBounds(aBuilder, &snap);
|
||||||
|
if (decorations != geometry->mDecorations ||
|
||||||
|
!oldRect.IsEqualInterior(newRect) ||
|
||||||
|
!geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
|
||||||
|
aInvalidRegion->Or(oldRect, newRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void DisableComponentAlpha() { mDisableSubpixelAA = true; }
|
virtual void DisableComponentAlpha() { mDisableSubpixelAA = true; }
|
||||||
|
|
||||||
bool mDisableSubpixelAA;
|
bool mDisableSubpixelAA;
|
||||||
@ -5971,7 +6021,7 @@ nsTextFrame::SetSelectedRange(PRUint32 aStart, PRUint32 aEnd, bool aSelected,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Selection might change anything. Invalidate the overflow area.
|
// Selection might change anything. Invalidate the overflow area.
|
||||||
f->InvalidateOverflowRect();
|
f->InvalidateFrame();
|
||||||
|
|
||||||
f = static_cast<nsTextFrame*>(f->GetNextContinuation());
|
f = static_cast<nsTextFrame*>(f->GetNextContinuation());
|
||||||
}
|
}
|
||||||
@ -7732,7 +7782,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
|||||||
|
|
||||||
SetLength(contentLength, &aLineLayout, ALLOW_FRAME_CREATION_AND_DESTRUCTION);
|
SetLength(contentLength, &aLineLayout, ALLOW_FRAME_CREATION_AND_DESTRUCTION);
|
||||||
|
|
||||||
Invalidate(aMetrics.VisualOverflow());
|
InvalidateFrame();
|
||||||
|
|
||||||
#ifdef NOISY_REFLOW
|
#ifdef NOISY_REFLOW
|
||||||
ListTag(stdout);
|
ListTag(stdout);
|
||||||
|
@ -191,7 +191,7 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||||||
container->SetScaleHint(scaleHint);
|
container->SetScaleHint(scaleHint);
|
||||||
|
|
||||||
nsRefPtr<ImageLayer> layer = static_cast<ImageLayer*>
|
nsRefPtr<ImageLayer> layer = static_cast<ImageLayer*>
|
||||||
(GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
|
(GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aItem));
|
||||||
if (!layer) {
|
if (!layer) {
|
||||||
layer = aManager->CreateImageLayer();
|
layer = aManager->CreateImageLayer();
|
||||||
if (!layer)
|
if (!layer)
|
||||||
@ -296,10 +296,6 @@ nsVideoFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
FinishAndStoreOverflow(&aMetrics);
|
FinishAndStoreOverflow(&aMetrics);
|
||||||
|
|
||||||
if (mRect.width != aMetrics.width || mRect.height != aMetrics.height) {
|
|
||||||
Invalidate(nsRect(0, 0, mRect.width, mRect.height));
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
||||||
("exit nsVideoFrame::Reflow: size=%d,%d",
|
("exit nsVideoFrame::Reflow: size=%d,%d",
|
||||||
aMetrics.width, aMetrics.height));
|
aMetrics.width, aMetrics.height));
|
||||||
|
@ -34,7 +34,16 @@ ViewportFrame::Init(nsIContent* aContent,
|
|||||||
nsIFrame* aParent,
|
nsIFrame* aParent,
|
||||||
nsIFrame* aPrevInFlow)
|
nsIFrame* aPrevInFlow)
|
||||||
{
|
{
|
||||||
return Super::Init(aContent, aParent, aPrevInFlow);
|
nsresult rv = Super::Init(aContent, aParent, aPrevInFlow);
|
||||||
|
|
||||||
|
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(this);
|
||||||
|
if (parent) {
|
||||||
|
nsFrameState state = parent->GetStateBits();
|
||||||
|
|
||||||
|
mState |= state & (NS_FRAME_IN_POPUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -254,8 +263,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
// If we were dirty then do a repaint
|
// If we were dirty then do a repaint
|
||||||
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
|
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
|
||||||
nsRect damageRect(0, 0, aDesiredSize.width, aDesiredSize.height);
|
InvalidateFrame();
|
||||||
Invalidate(damageRect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clipping is handled by the document container (e.g., nsSubDocumentFrame),
|
// Clipping is handled by the document container (e.g., nsSubDocumentFrame),
|
||||||
@ -283,40 +291,6 @@ ViewportFrame::GetType() const
|
|||||||
return nsGkAtoms::viewportFrame;
|
return nsGkAtoms::viewportFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ViewportFrame::InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
nsRect r = aDamageRect + nsPoint(aX, aY);
|
|
||||||
nsPresContext* presContext = PresContext();
|
|
||||||
presContext->NotifyInvalidation(r, aFlags);
|
|
||||||
|
|
||||||
if ((mState & NS_FRAME_HAS_CONTAINER_LAYER) &&
|
|
||||||
!(aFlags & INVALIDATE_NO_THEBES_LAYERS)) {
|
|
||||||
FrameLayerBuilder::InvalidateThebesLayerContents(this, r);
|
|
||||||
// Don't need to invalidate any more Thebes layers
|
|
||||||
aFlags |= INVALIDATE_NO_THEBES_LAYERS;
|
|
||||||
if (aFlags & INVALIDATE_ONLY_THEBES_LAYERS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(this);
|
|
||||||
if (parent) {
|
|
||||||
if (!presContext->PresShell()->IsActive())
|
|
||||||
return;
|
|
||||||
nsPoint pt = -parent->GetOffsetToCrossDoc(this);
|
|
||||||
PRInt32 ourAPD = presContext->AppUnitsPerDevPixel();
|
|
||||||
PRInt32 parentAPD = parent->PresContext()->AppUnitsPerDevPixel();
|
|
||||||
r = r.ConvertAppUnitsRoundOut(ourAPD, parentAPD);
|
|
||||||
parent->InvalidateInternal(r, pt.x, pt.y, this,
|
|
||||||
aFlags | INVALIDATE_CROSS_DOC);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
InvalidateRoot(r, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ViewportFrame::GetFrameName(nsAString& aResult) const
|
ViewportFrame::GetFrameName(nsAString& aResult) const
|
||||||
|
@ -69,10 +69,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual nsIAtom* GetType() const;
|
virtual nsIAtom* GetType() const;
|
||||||
|
|
||||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
||||||
#endif
|
#endif
|
||||||
|
@ -103,7 +103,7 @@ inFlasher::RepaintElement(nsIDOMElement* aElement)
|
|||||||
nsIFrame* frame = inLayoutUtils::GetFrameFor(aElement);
|
nsIFrame* frame = inLayoutUtils::GetFrameFor(aElement);
|
||||||
if (!frame) return NS_OK;
|
if (!frame) return NS_OK;
|
||||||
|
|
||||||
frame->Invalidate(frame->GetRect());
|
frame->InvalidateFrame();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -507,18 +507,6 @@ RenderFrameParent::ShadowLayersUpdated(bool isFirstPaint)
|
|||||||
// to /dev/null.
|
// to /dev/null.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME/cjones: we should collect the rects/regions updated for
|
|
||||||
// Painted*Layer() calls and pass that region to here, then only
|
|
||||||
// invalidate that rect
|
|
||||||
//
|
|
||||||
// We pass INVALIDATE_NO_THEBES_LAYERS here because we're
|
|
||||||
// invalidating the <browser> on behalf of its counterpart in the
|
|
||||||
// content process. Not only do we not need to invalidate the
|
|
||||||
// shadow layers, things would just break if we did --- we have no
|
|
||||||
// way to repaint shadow layers from this process.
|
|
||||||
nsRect rect = nsRect(nsPoint(0, 0), docFrame->GetRect().Size());
|
|
||||||
docFrame->InvalidateWithFlags(rect, nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Layer>
|
already_AddRefed<Layer>
|
||||||
|
@ -1879,10 +1879,13 @@ public:
|
|||||||
nsPoint offset = ToReferenceFrame() + rect.TopLeft();
|
nsPoint offset = ToReferenceFrame() + rect.TopLeft();
|
||||||
nsBoundingMetrics bm;
|
nsBoundingMetrics bm;
|
||||||
mChar->GetBoundingMetrics(bm);
|
mChar->GetBoundingMetrics(bm);
|
||||||
return nsRect(offset.x + bm.leftBearing, offset.y,
|
nsRect temp(offset.x + bm.leftBearing, offset.y,
|
||||||
bm.rightBearing - bm.leftBearing, bm.ascent + bm.descent);
|
bm.rightBearing - bm.leftBearing, bm.ascent + bm.descent);
|
||||||
|
// Bug 748220
|
||||||
|
temp.Inflate(mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||||
nsRenderingContext* aCtx)
|
nsRenderingContext* aCtx)
|
||||||
{
|
{
|
||||||
|
@ -237,7 +237,7 @@ InvalidateAllContinuations(nsIFrame* aFrame)
|
|||||||
{
|
{
|
||||||
for (nsIFrame* f = aFrame; f;
|
for (nsIFrame* f = aFrame; f;
|
||||||
f = nsLayoutUtils::GetNextContinuationOrSpecialSibling(f)) {
|
f = nsLayoutUtils::GetNextContinuationOrSpecialSibling(f)) {
|
||||||
f->InvalidateOverflowRect();
|
f->InvalidateFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,38 +166,6 @@ nsSVGForeignObjectFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsSVGForeignObjectFrame::InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY,
|
|
||||||
nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
// This is called by our descendants when they change.
|
|
||||||
|
|
||||||
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
|
|
||||||
// Our entire area has been (or will be) invalidated, so no point
|
|
||||||
// keeping track of sub-areas that our descendants dirty.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) {
|
|
||||||
nsSVGEffects::InvalidateRenderingObservers(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mInReflow) {
|
|
||||||
// We can't collect dirty areas, since we don't have a place to reliably
|
|
||||||
// call FlushDirtyRegion before we paint, so we have to invalidate now.
|
|
||||||
InvalidateDirtyRect(aDamageRect + nsPoint(aX, aY), aFlags, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRegion* region = (aFlags & INVALIDATE_CROSS_DOC)
|
|
||||||
? &mSubDocDirtyRegion : &mSameDocDirtyRegion;
|
|
||||||
region->Or(*region, aDamageRect + nsPoint(aX, aY));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the app unit canvas bounds of a userspace rect.
|
* Returns the app unit canvas bounds of a userspace rect.
|
||||||
*
|
*
|
||||||
@ -362,12 +330,6 @@ nsSVGForeignObjectFrame::UpdateBounds()
|
|||||||
// GetCanvasTM includes the x,y translation
|
// GetCanvasTM includes the x,y translation
|
||||||
mCoveredRegion = ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTM(), PresContext());
|
mCoveredRegion = ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTM(), PresContext());
|
||||||
|
|
||||||
// Since we'll invalidate our entire area at the end of this method, we
|
|
||||||
// empty our cached dirty regions to prevent FlushDirtyRegion under DoReflow
|
|
||||||
// from wasting time invalidating:
|
|
||||||
mSameDocDirtyRegion.SetEmpty();
|
|
||||||
mSubDocDirtyRegion.SetEmpty();
|
|
||||||
|
|
||||||
// Fully mark our kid dirty so that it gets resized if necessary
|
// Fully mark our kid dirty so that it gets resized if necessary
|
||||||
// (NS_FRAME_HAS_DIRTY_CHILDREN isn't enough in that case):
|
// (NS_FRAME_HAS_DIRTY_CHILDREN isn't enough in that case):
|
||||||
nsIFrame* kid = GetFirstPrincipalChild();
|
nsIFrame* kid = GetFirstPrincipalChild();
|
||||||
@ -589,51 +551,20 @@ nsSVGForeignObjectFrame::DoReflow()
|
|||||||
NS_FRAME_NO_MOVE_FRAME);
|
NS_FRAME_NO_MOVE_FRAME);
|
||||||
|
|
||||||
mInReflow = false;
|
mInReflow = false;
|
||||||
|
|
||||||
if (!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) {
|
|
||||||
// Since we're a reflow root and can be reflowed independently of our
|
|
||||||
// outer-<svg>, we can't just blindly pass 'true' here.
|
|
||||||
FlushDirtyRegion(0, nsSVGUtils::OuterSVGIsCallingUpdateBounds(this));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
nsRect
|
||||||
nsSVGForeignObjectFrame::InvalidateDirtyRect(const nsRect& aRect,
|
nsSVGForeignObjectFrame::GetInvalidRegion()
|
||||||
PRUint32 aFlags,
|
|
||||||
bool aDuringReflowSVG)
|
|
||||||
{
|
{
|
||||||
if (aRect.IsEmpty())
|
nsIFrame* kid = GetFirstPrincipalChild();
|
||||||
return;
|
if (kid->HasInvalidFrameInSubtree()) {
|
||||||
|
gfxRect r(mRect.x, mRect.y, mRect.width, mRect.height);
|
||||||
// Don't invalidate areas outside our bounds:
|
r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel());
|
||||||
nsRect rect = aRect.Intersect(nsRect(nsPoint(0,0), mRect.Size()));
|
nsRect rect = ToCanvasBounds(r, GetCanvasTM(), PresContext());
|
||||||
if (rect.IsEmpty())
|
rect = nsSVGUtils::GetPostFilterVisualOverflowRect(this, rect);
|
||||||
return;
|
return rect;
|
||||||
|
|
||||||
nsSVGUtils::InvalidateBounds(this, aDuringReflowSVG, &rect, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsSVGForeignObjectFrame::FlushDirtyRegion(PRUint32 aFlags,
|
|
||||||
bool aDuringReflowSVG)
|
|
||||||
{
|
|
||||||
NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
|
||||||
"Should not have been called");
|
|
||||||
|
|
||||||
NS_ASSERTION(!mInReflow,
|
|
||||||
"We shouldn't be flushing while we have a pending flush");
|
|
||||||
|
|
||||||
if (mSameDocDirtyRegion.IsEmpty() && mSubDocDirtyRegion.IsEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return nsRect();
|
||||||
InvalidateDirtyRect(mSameDocDirtyRegion.GetBounds(),
|
|
||||||
aFlags,
|
|
||||||
aDuringReflowSVG);
|
|
||||||
InvalidateDirtyRect(mSubDocDirtyRegion.GetBounds(),
|
|
||||||
aFlags | INVALIDATE_CROSS_DOC,
|
|
||||||
aDuringReflowSVG);
|
|
||||||
|
|
||||||
mSameDocDirtyRegion.SetEmpty();
|
|
||||||
mSubDocDirtyRegion.SetEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,10 +62,6 @@ public:
|
|||||||
~(nsIFrame::eSVG | nsIFrame::eSVGForeignObject));
|
~(nsIFrame::eSVG | nsIFrame::eSVGForeignObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||||
{
|
{
|
||||||
@ -86,6 +82,8 @@ public:
|
|||||||
|
|
||||||
gfxMatrix GetCanvasTM();
|
gfxMatrix GetCanvasTM();
|
||||||
|
|
||||||
|
nsRect GetInvalidRegion();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// implementation helpers:
|
// implementation helpers:
|
||||||
void DoReflow();
|
void DoReflow();
|
||||||
@ -94,21 +92,12 @@ protected:
|
|||||||
// Returns GetCanvasTM followed by a scale from CSS px to Dev px. Used for
|
// Returns GetCanvasTM followed by a scale from CSS px to Dev px. Used for
|
||||||
// painting, because children expect to paint to device space, not userspace.
|
// painting, because children expect to paint to device space, not userspace.
|
||||||
gfxMatrix GetCanvasTMForChildren();
|
gfxMatrix GetCanvasTMForChildren();
|
||||||
void InvalidateDirtyRect(const nsRect& aRect, PRUint32 aFlags,
|
|
||||||
bool aDuringReflowSVG);
|
|
||||||
void FlushDirtyRegion(PRUint32 aFlags, bool aDuringReflowSVG);
|
|
||||||
|
|
||||||
// If width or height is less than or equal to zero we must disable rendering
|
// If width or height is less than or equal to zero we must disable rendering
|
||||||
bool IsDisabled() const { return mRect.width <= 0 || mRect.height <= 0; }
|
bool IsDisabled() const { return mRect.width <= 0 || mRect.height <= 0; }
|
||||||
|
|
||||||
nsAutoPtr<gfxMatrix> mCanvasTM;
|
nsAutoPtr<gfxMatrix> mCanvasTM;
|
||||||
|
|
||||||
// Areas dirtied by changes to decendents that are in our document
|
|
||||||
nsRegion mSameDocDirtyRegion;
|
|
||||||
|
|
||||||
// Areas dirtied by changes to sub-documents embedded by our decendents
|
|
||||||
nsRegion mSubDocDirtyRegion;
|
|
||||||
|
|
||||||
nsRect mCoveredRegion;
|
nsRect mCoveredRegion;
|
||||||
|
|
||||||
bool mInReflow;
|
bool mInReflow;
|
||||||
|
@ -271,9 +271,9 @@ nsRect
|
|||||||
return overflowRect - (aFrame->GetOffsetTo(firstFrame) + firstFrameToUserSpace);
|
return overflowRect - (aFrame->GetOffsetTo(firstFrame) + firstFrameToUserSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect
|
nsIntRect
|
||||||
nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame,
|
nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame,
|
||||||
const nsRect& aInvalidRect)
|
const nsIntRect& aInvalidRect)
|
||||||
{
|
{
|
||||||
// Don't bother calling GetEffectProperties; the filter property should
|
// Don't bother calling GetEffectProperties; the filter property should
|
||||||
// already have been set up during reflow/ComputeFrameEffectsRect
|
// already have been set up during reflow/ComputeFrameEffectsRect
|
||||||
@ -289,22 +289,26 @@ nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame,
|
|||||||
return aInvalidRect;
|
return aInvalidRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRInt32 appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||||
|
|
||||||
nsSVGFilterFrame* filterFrame = prop->GetFilterFrame();
|
nsSVGFilterFrame* filterFrame = prop->GetFilterFrame();
|
||||||
if (!filterFrame) {
|
if (!filterFrame) {
|
||||||
// The frame is either not there or not currently available,
|
// The frame is either not there or not currently available,
|
||||||
// perhaps because we're in the middle of tearing stuff down.
|
// perhaps because we're in the middle of tearing stuff down.
|
||||||
// Be conservative.
|
// Be conservative.
|
||||||
return aFrame->GetVisualOverflowRect();
|
nsRect overflow = aFrame->GetVisualOverflowRect();
|
||||||
|
return overflow.ToOutsidePixels(appUnitsPerDevPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert aInvalidRect into "user space" in app units:
|
// Convert aInvalidRect into "user space" in app units:
|
||||||
nsPoint toUserSpace =
|
nsPoint toUserSpace =
|
||||||
aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame);
|
aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame);
|
||||||
nsRect preEffectsRect = aInvalidRect + toUserSpace;
|
nsRect preEffectsRect = aInvalidRect.ToAppUnits(appUnitsPerDevPixel) + toUserSpace;
|
||||||
|
|
||||||
// Return ther result, relative to aFrame, not in user space:
|
// Return ther result, relative to aFrame, not in user space:
|
||||||
return filterFrame->GetPostFilterDirtyArea(firstFrame, preEffectsRect) -
|
nsRect result = filterFrame->GetPostFilterDirtyArea(firstFrame, preEffectsRect) -
|
||||||
toUserSpace;
|
toUserSpace;
|
||||||
|
return result.ToOutsidePixels(appUnitsPerDevPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect
|
nsRect
|
||||||
|
@ -111,8 +111,8 @@ public:
|
|||||||
* Used to adjust the area of a frame that needs to be invalidated to take
|
* Used to adjust the area of a frame that needs to be invalidated to take
|
||||||
* account of SVG effects.
|
* account of SVG effects.
|
||||||
*/
|
*/
|
||||||
static nsRect
|
static nsIntRect
|
||||||
AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame, const nsRect& aInvalidRect);
|
AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame, const nsIntRect& aInvalidRect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Figure out which area of the source is needed given an area to
|
* Figure out which area of the source is needed given an area to
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "nsSVGForeignObjectFrame.h"
|
#include "nsSVGForeignObjectFrame.h"
|
||||||
#include "nsSVGSVGElement.h"
|
#include "nsSVGSVGElement.h"
|
||||||
#include "nsSVGTextFrame.h"
|
#include "nsSVGTextFrame.h"
|
||||||
|
#include "nsSubDocumentFrame.h"
|
||||||
|
|
||||||
namespace dom = mozilla::dom;
|
namespace dom = mozilla::dom;
|
||||||
|
|
||||||
@ -485,6 +486,11 @@ public:
|
|||||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||||
nsRenderingContext* aCtx);
|
nsRenderingContext* aCtx);
|
||||||
|
|
||||||
|
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion);
|
||||||
|
|
||||||
NS_DISPLAY_DECL_NAME("SVGOuterSVG", TYPE_SVG_OUTER_SVG)
|
NS_DISPLAY_DECL_NAME("SVGOuterSVG", TYPE_SVG_OUTER_SVG)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -555,21 +561,13 @@ nsDisplayOuterSVG::Paint(nsDisplayListBuilder* aBuilder,
|
|||||||
// odd document is probably no worse than printing horribly for all
|
// odd document is probably no worse than printing horribly for all
|
||||||
// documents. Better to fix things so we don't need fallback.
|
// documents. Better to fix things so we don't need fallback.
|
||||||
nsIFrame* ancestor = frame;
|
nsIFrame* ancestor = frame;
|
||||||
PRUint32 flags = 0;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(ancestor);
|
nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(ancestor);
|
||||||
if (!next)
|
if (!next)
|
||||||
break;
|
break;
|
||||||
if (ancestor->GetParent() != next) {
|
|
||||||
// We're crossing a document boundary. Logically, the invalidation is
|
|
||||||
// being triggered by a subdocument of the root document. This will
|
|
||||||
// prevent an untrusted root document being told about invalidation
|
|
||||||
// that happened because a child was using SVG...
|
|
||||||
flags |= nsIFrame::INVALIDATE_CROSS_DOC;
|
|
||||||
}
|
|
||||||
ancestor = next;
|
ancestor = next;
|
||||||
}
|
}
|
||||||
ancestor->InvalidateWithFlags(nsRect(nsPoint(0, 0), ancestor->GetSize()), flags);
|
ancestor->InvalidateFrame();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -581,6 +579,39 @@ nsDisplayOuterSVG::Paint(nsDisplayListBuilder* aBuilder,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PLDHashOperator CheckForeignObjectInvalidatedArea(nsPtrHashKey<nsSVGForeignObjectFrame>* aEntry, void* aData)
|
||||||
|
{
|
||||||
|
nsRegion* region = static_cast<nsRegion*>(aData);
|
||||||
|
region->Or(*region, aEntry->GetKey()->GetInvalidRegion());
|
||||||
|
return PL_DHASH_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRegion
|
||||||
|
nsSVGOuterSVGFrame::FindInvalidatedForeignObjectFrameChildren(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
nsRegion result;
|
||||||
|
if (mForeignObjectHash.Count()) {
|
||||||
|
mForeignObjectHash.EnumerateEntries(CheckForeignObjectInvalidatedArea, &result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDisplayOuterSVG::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion)
|
||||||
|
{
|
||||||
|
nsSVGOuterSVGFrame *frame = static_cast<nsSVGOuterSVGFrame*>(mFrame);
|
||||||
|
frame->InvalidateSVG(frame->FindInvalidatedForeignObjectFrameChildren(frame));
|
||||||
|
|
||||||
|
nsRegion result = frame->GetInvalidRegion();
|
||||||
|
result.MoveBy(ToReferenceFrame());
|
||||||
|
frame->ClearInvalidRegion();
|
||||||
|
|
||||||
|
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
|
||||||
|
aInvalidRegion->Or(*aInvalidRegion, result);
|
||||||
|
}
|
||||||
|
|
||||||
// helper
|
// helper
|
||||||
static inline bool
|
static inline bool
|
||||||
DependsOnIntrinsicSize(const nsIFrame* aEmbeddingFrame)
|
DependsOnIntrinsicSize(const nsIFrame* aEmbeddingFrame)
|
||||||
|
@ -136,6 +136,25 @@ public:
|
|||||||
return mCallingUpdateBounds;
|
return mCallingUpdateBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InvalidateSVG(const nsRegion& aRegion)
|
||||||
|
{
|
||||||
|
if (!aRegion.IsEmpty()) {
|
||||||
|
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
||||||
|
InvalidateFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearInvalidRegion() { mInvalidRegion.SetEmpty(); }
|
||||||
|
|
||||||
|
const nsRegion& GetInvalidRegion() {
|
||||||
|
if (!IsInvalid()) {
|
||||||
|
mInvalidRegion.SetEmpty();
|
||||||
|
}
|
||||||
|
return mInvalidRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRegion FindInvalidatedForeignObjectFrameChildren(nsIFrame* aFrame);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool mCallingUpdateBounds;
|
bool mCallingUpdateBounds;
|
||||||
@ -156,10 +175,12 @@ protected:
|
|||||||
// A hash-set containing our nsSVGForeignObjectFrame descendants. Note we use
|
// A hash-set containing our nsSVGForeignObjectFrame descendants. Note we use
|
||||||
// a hash-set to avoid the O(N^2) behavior we'd get tearing down an SVG frame
|
// a hash-set to avoid the O(N^2) behavior we'd get tearing down an SVG frame
|
||||||
// subtree if we were to use a list (see bug 381285 comment 20).
|
// subtree if we were to use a list (see bug 381285 comment 20).
|
||||||
nsTHashtable<nsVoidPtrHashKey> mForeignObjectHash;
|
nsTHashtable<nsPtrHashKey<nsSVGForeignObjectFrame> > mForeignObjectHash;
|
||||||
|
|
||||||
nsAutoPtr<gfxMatrix> mCanvasTM;
|
nsAutoPtr<gfxMatrix> mCanvasTM;
|
||||||
|
|
||||||
|
nsRegion mInvalidRegion;
|
||||||
|
|
||||||
float mFullZoom;
|
float mFullZoom;
|
||||||
|
|
||||||
bool mViewportInitialized;
|
bool mViewportInitialized;
|
||||||
|
@ -705,8 +705,7 @@ nsSVGUtils::InvalidateBounds(nsIFrame *aFrame, bool aDuringUpdate,
|
|||||||
"SVG frames must always have an nsSVGOuterSVGFrame ancestor!");
|
"SVG frames must always have an nsSVGOuterSVGFrame ancestor!");
|
||||||
invalidArea.MoveBy(aFrame->GetContentRect().TopLeft() - aFrame->GetPosition());
|
invalidArea.MoveBy(aFrame->GetContentRect().TopLeft() - aFrame->GetPosition());
|
||||||
|
|
||||||
static_cast<nsSVGOuterSVGFrame*>(aFrame)->InvalidateWithFlags(invalidArea,
|
static_cast<nsSVGOuterSVGFrame*>(aFrame)->InvalidateSVG(invalidArea);
|
||||||
aFlags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -559,11 +559,6 @@ void nsTableCellFrame::VerticallyAlignChild(nscoord aMaxAscent)
|
|||||||
// if the content is larger than the cell height align from top
|
// if the content is larger than the cell height align from top
|
||||||
kidYTop = NS_MAX(0, kidYTop);
|
kidYTop = NS_MAX(0, kidYTop);
|
||||||
|
|
||||||
if (kidYTop != kidRect.y) {
|
|
||||||
// Invalidate at the old position first
|
|
||||||
firstKid->InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
|
|
||||||
firstKid->SetPosition(nsPoint(kidRect.x, kidYTop));
|
firstKid->SetPosition(nsPoint(kidRect.x, kidYTop));
|
||||||
nsHTMLReflowMetrics desiredSize;
|
nsHTMLReflowMetrics desiredSize;
|
||||||
desiredSize.width = mRect.width;
|
desiredSize.width = mRect.width;
|
||||||
@ -578,9 +573,6 @@ void nsTableCellFrame::VerticallyAlignChild(nscoord aMaxAscent)
|
|||||||
// Make sure any child views are correctly positioned. We know the inner table
|
// Make sure any child views are correctly positioned. We know the inner table
|
||||||
// cell won't have a view
|
// cell won't have a view
|
||||||
nsContainerFrame::PositionChildViews(firstKid);
|
nsContainerFrame::PositionChildViews(firstKid);
|
||||||
|
|
||||||
// Invalidate new overflow rect
|
|
||||||
firstKid->InvalidateFrameSubtree();
|
|
||||||
}
|
}
|
||||||
if (HasView()) {
|
if (HasView()) {
|
||||||
nsContainerFrame::SyncFrameViewAfterReflow(PresContext(), this,
|
nsContainerFrame::SyncFrameViewAfterReflow(PresContext(), this,
|
||||||
@ -871,9 +863,6 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsPoint kidOrigin(leftInset, topInset);
|
nsPoint kidOrigin(leftInset, topInset);
|
||||||
nsRect origRect = firstKid->GetRect();
|
|
||||||
nsRect origVisualOverflow = firstKid->GetVisualOverflowRect();
|
|
||||||
bool firstReflow = (firstKid->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
|
||||||
|
|
||||||
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
|
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
|
||||||
kidOrigin.x, kidOrigin.y, NS_FRAME_INVALIDATE_ON_MOVE, aStatus);
|
kidOrigin.x, kidOrigin.y, NS_FRAME_INVALIDATE_ON_MOVE, aStatus);
|
||||||
@ -884,11 +873,6 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
printf("Set table cell incomplete %p\n", static_cast<void*>(this));
|
printf("Set table cell incomplete %p\n", static_cast<void*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXXbz is this invalidate actually needed, really?
|
|
||||||
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
|
|
||||||
InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DebugCheckChildSize(firstKid, kidSize, availSize);
|
DebugCheckChildSize(firstKid, kidSize, availSize);
|
||||||
#endif
|
#endif
|
||||||
@ -908,9 +892,6 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
FinishReflowChild(firstKid, aPresContext, &kidReflowState, kidSize,
|
FinishReflowChild(firstKid, aPresContext, &kidReflowState, kidSize,
|
||||||
kidOrigin.x, kidOrigin.y, 0);
|
kidOrigin.x, kidOrigin.y, 0);
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(firstKid, origRect, origVisualOverflow,
|
|
||||||
firstReflow);
|
|
||||||
|
|
||||||
// first, compute the height which can be set w/o being restricted by aMaxSize.height
|
// first, compute the height which can be set w/o being restricted by aMaxSize.height
|
||||||
nscoord cellHeight = kidSize.height;
|
nscoord cellHeight = kidSize.height;
|
||||||
|
|
||||||
@ -943,12 +924,6 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If our parent is in initial reflow, it'll handle invalidating our
|
|
||||||
// entire overflow rect.
|
|
||||||
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
|
||||||
CheckInvalidateSizeChange(aDesiredSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remember the desired size for this reflow
|
// remember the desired size for this reflow
|
||||||
SetDesiredSize(aDesiredSize);
|
SetDesiredSize(aDesiredSize);
|
||||||
|
|
||||||
|
@ -209,6 +209,13 @@ public:
|
|||||||
nsPoint aPt);
|
nsPoint aPt);
|
||||||
|
|
||||||
virtual bool UpdateOverflow();
|
virtual bool UpdateOverflow();
|
||||||
|
|
||||||
|
virtual void InvalidateFrame(PRUint32 aFlags = 0)
|
||||||
|
{
|
||||||
|
nsIFrame::InvalidateFrame(aFlags);
|
||||||
|
nsTableFrame *tableFrame = nsTableFrame::GetTableFrame(this);
|
||||||
|
tableFrame->InvalidateFrame(aFlags | INVALIDATE_DONT_SCHEDULE_PAINT);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** implement abstract method on nsContainerFrame */
|
/** implement abstract method on nsContainerFrame */
|
||||||
|
@ -188,3 +188,11 @@ nsTableColFrame::GetSplittableType() const
|
|||||||
return NS_FRAME_NOT_SPLITTABLE;
|
return NS_FRAME_NOT_SPLITTABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTableColFrame::InvalidateFrame(PRUint32 aFlags)
|
||||||
|
{
|
||||||
|
nsIFrame::InvalidateFrame(aFlags);
|
||||||
|
nsTableFrame *tableFrame = nsTableFrame::GetTableFrame(this);
|
||||||
|
tableFrame->InvalidateFrame(aFlags | INVALIDATE_DONT_SCHEDULE_PAINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -262,6 +262,8 @@ public:
|
|||||||
nscoord GetFinalWidth() {
|
nscoord GetFinalWidth() {
|
||||||
return mFinalWidth;
|
return mFinalWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void InvalidateFrame(PRUint32 aFlags = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -72,6 +72,8 @@ nsTableColGroupFrame::AddColsToTable(PRInt32 aFirstColIndex,
|
|||||||
{
|
{
|
||||||
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
|
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
|
||||||
|
|
||||||
|
tableFrame->InvalidateFrameSubtree();
|
||||||
|
|
||||||
// set the col indices of the col frames and and add col info to the table
|
// set the col indices of the col frames and and add col info to the table
|
||||||
PRInt32 colIndex = aFirstColIndex;
|
PRInt32 colIndex = aFirstColIndex;
|
||||||
nsFrameList::Enumerator e(aCols);
|
nsFrameList::Enumerator e(aCols);
|
||||||
@ -459,6 +461,14 @@ nsTableColGroupFrame::GetType() const
|
|||||||
{
|
{
|
||||||
return nsGkAtoms::tableColGroupFrame;
|
return nsGkAtoms::tableColGroupFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTableColGroupFrame::InvalidateFrame(PRUint32 aFlags)
|
||||||
|
{
|
||||||
|
nsIFrame::InvalidateFrame(aFlags);
|
||||||
|
nsTableFrame *tableFrame = nsTableFrame::GetTableFrame(this);
|
||||||
|
tableFrame->InvalidateFrame(aFlags | INVALIDATE_DONT_SCHEDULE_PAINT);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -195,6 +195,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetContinuousBCBorderWidth(PRUint8 aForSide,
|
void SetContinuousBCBorderWidth(PRUint8 aForSide,
|
||||||
BCPixelSize aPixelValue);
|
BCPixelSize aPixelValue);
|
||||||
|
|
||||||
|
virtual void InvalidateFrame(PRUint32 aFlags = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsTableColGroupFrame(nsStyleContext* aContext);
|
nsTableColGroupFrame(nsStyleContext* aContext);
|
||||||
|
|
||||||
|
@ -1211,10 +1211,7 @@ AnyTablePartHasBorderOrBackground(nsIFrame* aStart, nsIFrame* aEnd)
|
|||||||
for (nsIFrame* f = aStart; f != aEnd; f = f->GetNextSibling()) {
|
for (nsIFrame* f = aStart; f != aEnd; f = f->GetNextSibling()) {
|
||||||
NS_ASSERTION(IsFrameAllowedInTable(f->GetType()), "unexpected frame type");
|
NS_ASSERTION(IsFrameAllowedInTable(f->GetType()), "unexpected frame type");
|
||||||
|
|
||||||
if (f->GetStyleVisibility()->IsVisible() &&
|
if (FrameHasBorderOrBackground(f))
|
||||||
(!f->GetStyleBackground()->IsTransparent() ||
|
|
||||||
f->GetStyleDisplay()->mAppearance ||
|
|
||||||
f->GetStyleBorder()->HasBorder()))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
nsTableCellFrame *cellFrame = do_QueryFrame(f);
|
nsTableCellFrame *cellFrame = do_QueryFrame(f);
|
||||||
@ -1394,10 +1391,7 @@ nsTableFrame::ProcessRowInserted(nscoord aNewHeight)
|
|||||||
if (rowFrame->IsFirstInserted()) {
|
if (rowFrame->IsFirstInserted()) {
|
||||||
rowFrame->SetFirstInserted(false);
|
rowFrame->SetFirstInserted(false);
|
||||||
// damage the table from the 1st row inserted to the end of the table
|
// damage the table from the 1st row inserted to the end of the table
|
||||||
nscoord damageY = rgFrame->GetPosition().y + rowFrame->GetPosition().y;
|
InvalidateFrame();
|
||||||
nsRect damageRect(0, damageY, GetSize().width, aNewHeight - damageY);
|
|
||||||
|
|
||||||
Invalidate(damageRect);
|
|
||||||
// XXXbz didn't we do this up front? Why do we need to do it again?
|
// XXXbz didn't we do this up front? Why do we need to do it again?
|
||||||
SetRowInserted(false);
|
SetRowInserted(false);
|
||||||
return; // found it, so leave
|
return; // found it, so leave
|
||||||
@ -1812,13 +1806,6 @@ NS_METHOD nsTableFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
}
|
}
|
||||||
aDesiredSize.mOverflowAreas.UnionAllWith(tableRect);
|
aDesiredSize.mOverflowAreas.UnionAllWith(tableRect);
|
||||||
|
|
||||||
if (GetStateBits() & NS_FRAME_FIRST_REFLOW) {
|
|
||||||
// Fulfill the promise InvalidateFrame makes.
|
|
||||||
Invalidate(aDesiredSize.VisualOverflow());
|
|
||||||
} else {
|
|
||||||
CheckInvalidateSizeChange(aDesiredSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
FinishAndStoreOverflow(&aDesiredSize);
|
FinishAndStoreOverflow(&aDesiredSize);
|
||||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||||
return rv;
|
return rv;
|
||||||
@ -2502,16 +2489,10 @@ void nsTableFrame::PlaceChild(nsTableReflowState& aReflowState,
|
|||||||
const nsRect& aOriginalKidRect,
|
const nsRect& aOriginalKidRect,
|
||||||
const nsRect& aOriginalKidVisualOverflow)
|
const nsRect& aOriginalKidVisualOverflow)
|
||||||
{
|
{
|
||||||
bool isFirstReflow =
|
|
||||||
(aKidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
|
||||||
|
|
||||||
// Place and size the child
|
// Place and size the child
|
||||||
FinishReflowChild(aKidFrame, PresContext(), nsnull, aKidDesiredSize,
|
FinishReflowChild(aKidFrame, PresContext(), nsnull, aKidDesiredSize,
|
||||||
aReflowState.x, aReflowState.y, 0);
|
aReflowState.x, aReflowState.y, 0);
|
||||||
|
|
||||||
InvalidateFrame(aKidFrame, aOriginalKidRect, aOriginalKidVisualOverflow,
|
|
||||||
isFirstReflow);
|
|
||||||
|
|
||||||
// Adjust the running y-offset
|
// Adjust the running y-offset
|
||||||
aReflowState.y += aKidDesiredSize.height;
|
aReflowState.y += aKidDesiredSize.height;
|
||||||
|
|
||||||
@ -2946,13 +2927,9 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
|||||||
aReflowState.y += cellSpacingY;
|
aReflowState.y += cellSpacingY;
|
||||||
nsRect kidRect = kidFrame->GetRect();
|
nsRect kidRect = kidFrame->GetRect();
|
||||||
if (kidRect.y != aReflowState.y) {
|
if (kidRect.y != aReflowState.y) {
|
||||||
// invalidate the old position
|
|
||||||
kidFrame->InvalidateFrameSubtree();
|
|
||||||
kidRect.y = aReflowState.y;
|
kidRect.y = aReflowState.y;
|
||||||
kidFrame->SetRect(kidRect); // move to the new position
|
kidFrame->SetRect(kidRect); // move to the new position
|
||||||
RePositionViews(kidFrame);
|
RePositionViews(kidFrame);
|
||||||
// invalidate the new position
|
|
||||||
kidFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
}
|
||||||
aReflowState.y += kidRect.height;
|
aReflowState.y += kidRect.height;
|
||||||
|
|
||||||
@ -3126,17 +3103,13 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
|||||||
amountUsedByRG += amountForRow;
|
amountUsedByRG += amountForRow;
|
||||||
//rowFrame->DidResize();
|
//rowFrame->DidResize();
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
|
|
||||||
rgFrame->InvalidateRectDifference(oldRowRect, rowRect);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (amountUsed > 0 && yOriginRow != rowRect.y &&
|
if (amountUsed > 0 && yOriginRow != rowRect.y &&
|
||||||
!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
||||||
rowFrame->InvalidateFrameSubtree();
|
|
||||||
rowFrame->SetPosition(nsPoint(rowRect.x, yOriginRow));
|
rowFrame->SetPosition(nsPoint(rowRect.x, yOriginRow));
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
rowFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
}
|
||||||
yOriginRow += rowRect.height + cellSpacingY;
|
yOriginRow += rowRect.height + cellSpacingY;
|
||||||
yEndRG += rowRect.height + cellSpacingY;
|
yEndRG += rowRect.height + cellSpacingY;
|
||||||
@ -3144,10 +3117,6 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
|||||||
rowFrame = rowFrame->GetNextRow();
|
rowFrame = rowFrame->GetNextRow();
|
||||||
}
|
}
|
||||||
if (amountUsed > 0) {
|
if (amountUsed > 0) {
|
||||||
if (rgRect.y != yOriginRG) {
|
|
||||||
rgFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRect origRgRect = rgRect;
|
nsRect origRgRect = rgRect;
|
||||||
nsRect origRgVisualOverflow = rgFrame->GetVisualOverflowRect();
|
nsRect origRgVisualOverflow = rgFrame->GetVisualOverflowRect();
|
||||||
|
|
||||||
@ -3155,17 +3124,12 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
|||||||
rgRect.height += amountUsedByRG;
|
rgRect.height += amountUsedByRG;
|
||||||
|
|
||||||
rgFrame->SetRect(rgRect);
|
rgFrame->SetRect(rgRect);
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(rgFrame, origRgRect,
|
|
||||||
origRgVisualOverflow, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (amountUsed > 0 && yOriginRG != rgRect.y) {
|
else if (amountUsed > 0 && yOriginRG != rgRect.y) {
|
||||||
rgFrame->InvalidateFrameSubtree();
|
|
||||||
rgFrame->SetPosition(nsPoint(rgRect.x, yOriginRG));
|
rgFrame->SetPosition(nsPoint(rgRect.x, yOriginRG));
|
||||||
// Make sure child views are properly positioned
|
// Make sure child views are properly positioned
|
||||||
nsTableFrame::RePositionViews(rgFrame);
|
nsTableFrame::RePositionViews(rgFrame);
|
||||||
rgFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
}
|
||||||
yOriginRG = yEndRG;
|
yOriginRG = yEndRG;
|
||||||
}
|
}
|
||||||
@ -3273,10 +3237,6 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
|||||||
? aAmount - amountUsed : NSToCoordRound(((float)(heightToDistribute)) * ratio);
|
? aAmount - amountUsed : NSToCoordRound(((float)(heightToDistribute)) * ratio);
|
||||||
amountForRow = NS_MIN(amountForRow, aAmount - amountUsed);
|
amountForRow = NS_MIN(amountForRow, aAmount - amountUsed);
|
||||||
|
|
||||||
if (yOriginRow != rowRect.y) {
|
|
||||||
rowFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the row height
|
// update the row height
|
||||||
nsRect newRowRect(rowRect.x, yOriginRow, rowRect.width,
|
nsRect newRowRect(rowRect.x, yOriginRow, rowRect.width,
|
||||||
rowRect.height + amountForRow);
|
rowRect.height + amountForRow);
|
||||||
@ -3290,16 +3250,11 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
|||||||
NS_ASSERTION((amountUsed <= aAmount), "invalid row allocation");
|
NS_ASSERTION((amountUsed <= aAmount), "invalid row allocation");
|
||||||
//rowFrame->DidResize();
|
//rowFrame->DidResize();
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(rowFrame, rowRect, rowVisualOverflow,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (amountUsed > 0 && yOriginRow != rowRect.y) {
|
if (amountUsed > 0 && yOriginRow != rowRect.y) {
|
||||||
rowFrame->InvalidateFrameSubtree();
|
|
||||||
rowFrame->SetPosition(nsPoint(rowRect.x, yOriginRow));
|
rowFrame->SetPosition(nsPoint(rowRect.x, yOriginRow));
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
rowFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
}
|
||||||
yOriginRow += rowRect.height + cellSpacingY;
|
yOriginRow += rowRect.height + cellSpacingY;
|
||||||
yEndRG += rowRect.height + cellSpacingY;
|
yEndRG += rowRect.height + cellSpacingY;
|
||||||
@ -3307,24 +3262,15 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
|||||||
rowFrame = rowFrame->GetNextRow();
|
rowFrame = rowFrame->GetNextRow();
|
||||||
}
|
}
|
||||||
if (amountUsed > 0) {
|
if (amountUsed > 0) {
|
||||||
if (rgRect.y != yOriginRG) {
|
|
||||||
rgFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
|
||||||
|
|
||||||
rgFrame->SetRect(nsRect(rgRect.x, yOriginRG, rgRect.width,
|
rgFrame->SetRect(nsRect(rgRect.x, yOriginRG, rgRect.width,
|
||||||
rgRect.height + amountUsedByRG));
|
rgRect.height + amountUsedByRG));
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(rgFrame, rgRect, rgVisualOverflow,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
// Make sure child views are properly positioned
|
// Make sure child views are properly positioned
|
||||||
}
|
}
|
||||||
else if (amountUsed > 0 && yOriginRG != rgRect.y) {
|
else if (amountUsed > 0 && yOriginRG != rgRect.y) {
|
||||||
rgFrame->InvalidateFrameSubtree();
|
|
||||||
rgFrame->SetPosition(nsPoint(rgRect.x, yOriginRG));
|
rgFrame->SetPosition(nsPoint(rgRect.x, yOriginRG));
|
||||||
// Make sure child views are properly positioned
|
// Make sure child views are properly positioned
|
||||||
nsTableFrame::RePositionViews(rgFrame);
|
nsTableFrame::RePositionViews(rgFrame);
|
||||||
rgFrame->InvalidateFrameSubtree();
|
|
||||||
}
|
}
|
||||||
yOriginRG = yEndRG;
|
yOriginRG = yEndRG;
|
||||||
}
|
}
|
||||||
@ -7236,43 +7182,3 @@ bool nsTableFrame::RowIsSpannedInto(PRInt32 aRowIndex, PRInt32 aNumEffCols)
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
|
||||||
void
|
|
||||||
nsTableFrame::InvalidateFrame(nsIFrame* aFrame,
|
|
||||||
const nsRect& aOrigRect,
|
|
||||||
const nsRect& aOrigVisualOverflow,
|
|
||||||
bool aIsFirstReflow)
|
|
||||||
{
|
|
||||||
nsIFrame* parent = aFrame->GetParent();
|
|
||||||
NS_ASSERTION(parent, "What happened here?");
|
|
||||||
|
|
||||||
if (parent->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
|
|
||||||
// Don't bother; we'll invalidate the parent's overflow rect when
|
|
||||||
// we finish reflowing it.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The part that looks at both the rect and the overflow rect is a
|
|
||||||
// bit of a hack. See nsBlockFrame::ReflowLine for an eloquent
|
|
||||||
// description of its hackishness.
|
|
||||||
nsRect visualOverflow = aFrame->GetVisualOverflowRect();
|
|
||||||
if (aIsFirstReflow ||
|
|
||||||
aOrigRect.TopLeft() != aFrame->GetPosition() ||
|
|
||||||
aOrigVisualOverflow.TopLeft() != visualOverflow.TopLeft()) {
|
|
||||||
// Invalidate the old and new overflow rects. Note that if the
|
|
||||||
// frame moved, we can't just use aOrigVisualOverflow, since it's in
|
|
||||||
// coordinates relative to the old position. So invalidate via
|
|
||||||
// aFrame's parent, and reposition that overflow rect to the right
|
|
||||||
// place.
|
|
||||||
// XXXbz this doesn't handle outlines, does it?
|
|
||||||
aFrame->Invalidate(visualOverflow);
|
|
||||||
parent->Invalidate(aOrigVisualOverflow + aOrigRect.TopLeft());
|
|
||||||
} else {
|
|
||||||
nsRect rect = aFrame->GetRect();
|
|
||||||
aFrame->CheckInvalidateSizeChange(aOrigRect, aOrigVisualOverflow,
|
|
||||||
rect.Size());
|
|
||||||
aFrame->InvalidateRectDifference(aOrigVisualOverflow, visualOverflow);
|
|
||||||
parent->InvalidateRectDifference(aOrigRect, rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -33,6 +33,13 @@ static inline bool IS_TABLE_CELL(nsIAtom* frameType) {
|
|||||||
nsGkAtoms::bcTableCellFrame == frameType;
|
nsGkAtoms::bcTableCellFrame == frameType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool FrameHasBorderOrBackground(nsIFrame* f) {
|
||||||
|
return (f->GetStyleVisibility()->IsVisible() &&
|
||||||
|
(!f->GetStyleBackground()->IsTransparent() ||
|
||||||
|
f->GetStyleDisplay()->mAppearance ||
|
||||||
|
f->GetStyleBorder()->HasBorder()));
|
||||||
|
}
|
||||||
|
|
||||||
class nsDisplayTableItem : public nsDisplayItem
|
class nsDisplayTableItem : public nsDisplayItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -457,23 +464,6 @@ public:
|
|||||||
bool HasCellSpanningPctCol() const;
|
bool HasCellSpanningPctCol() const;
|
||||||
void SetHasCellSpanningPctCol(bool aValue);
|
void SetHasCellSpanningPctCol(bool aValue);
|
||||||
|
|
||||||
/**
|
|
||||||
* To be called on a frame by its parent after setting its size/position and
|
|
||||||
* calling DidReflow (possibly via FinishReflowChild()). This can also be
|
|
||||||
* used for child frames which are not being reflowed but did have their size
|
|
||||||
* or position changed.
|
|
||||||
*
|
|
||||||
* @param aFrame The frame to invalidate
|
|
||||||
* @param aOrigRect The original rect of aFrame (before the change).
|
|
||||||
* @param aOrigVisualOverflow The original overflow rect of aFrame.
|
|
||||||
* @param aIsFirstReflow True if the size/position change is due to the
|
|
||||||
* first reflow of aFrame.
|
|
||||||
*/
|
|
||||||
static void InvalidateFrame(nsIFrame* aFrame,
|
|
||||||
const nsRect& aOrigRect,
|
|
||||||
const nsRect& aOrigVisualOverflow,
|
|
||||||
bool aIsFirstReflow);
|
|
||||||
|
|
||||||
virtual bool UpdateOverflow();
|
virtual bool UpdateOverflow();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -916,21 +916,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
nsHTMLReflowState *innerRS =
|
nsHTMLReflowState *innerRS =
|
||||||
static_cast<nsHTMLReflowState*>((void*) innerRSSpace);
|
static_cast<nsHTMLReflowState*>((void*) innerRSSpace);
|
||||||
|
|
||||||
nsRect origInnerRect = InnerTableFrame()->GetRect();
|
|
||||||
nsRect origInnerVisualOverflow = InnerTableFrame()->GetVisualOverflowRect();
|
|
||||||
bool innerFirstReflow =
|
|
||||||
(InnerTableFrame()->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
|
||||||
nsRect origCaptionRect;
|
|
||||||
nsRect origCaptionVisualOverflow;
|
|
||||||
bool captionFirstReflow;
|
|
||||||
if (mCaptionFrames.NotEmpty()) {
|
|
||||||
origCaptionRect = mCaptionFrames.FirstChild()->GetRect();
|
|
||||||
origCaptionVisualOverflow =
|
|
||||||
mCaptionFrames.FirstChild()->GetVisualOverflowRect();
|
|
||||||
captionFirstReflow =
|
|
||||||
(mCaptionFrames.FirstChild()->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ComputeAutoSize has to match this logic.
|
// ComputeAutoSize has to match this logic.
|
||||||
if (captionSide == NO_SIDE) {
|
if (captionSide == NO_SIDE) {
|
||||||
// We don't have a caption.
|
// We don't have a caption.
|
||||||
@ -1052,14 +1037,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
innerOrigin.x, innerOrigin.y, 0);
|
innerOrigin.x, innerOrigin.y, 0);
|
||||||
innerRS->~nsHTMLReflowState();
|
innerRS->~nsHTMLReflowState();
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(InnerTableFrame(), origInnerRect,
|
|
||||||
origInnerVisualOverflow, innerFirstReflow);
|
|
||||||
if (mCaptionFrames.NotEmpty()) {
|
|
||||||
nsTableFrame::InvalidateFrame(mCaptionFrames.FirstChild(), origCaptionRect,
|
|
||||||
origCaptionVisualOverflow,
|
|
||||||
captionFirstReflow);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, captionMargin);
|
UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, captionMargin);
|
||||||
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aOuterRS, aStatus);
|
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aOuterRS, aStatus);
|
||||||
|
|
||||||
|
@ -333,13 +333,9 @@ nsTableRowFrame::DidResize()
|
|||||||
|
|
||||||
// resize the cell's height
|
// resize the cell's height
|
||||||
nsRect cellRect = cellFrame->GetRect();
|
nsRect cellRect = cellFrame->GetRect();
|
||||||
nsRect cellVisualOverflow = cellFrame->GetVisualOverflowRect();
|
|
||||||
if (cellRect.height != cellHeight)
|
if (cellRect.height != cellHeight)
|
||||||
{
|
{
|
||||||
cellFrame->SetSize(nsSize(cellRect.width, cellHeight));
|
cellFrame->SetSize(nsSize(cellRect.width, cellHeight));
|
||||||
nsTableFrame::InvalidateFrame(cellFrame, cellRect,
|
|
||||||
cellVisualOverflow,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// realign cell content based on the new height. We might be able to
|
// realign cell content based on the new height. We might be able to
|
||||||
@ -814,9 +810,6 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
// Reflow the child frame
|
// Reflow the child frame
|
||||||
nsRect kidRect = kidFrame->GetRect();
|
nsRect kidRect = kidFrame->GetRect();
|
||||||
nsRect kidVisualOverflow = kidFrame->GetVisualOverflowRect();
|
|
||||||
bool firstReflow =
|
|
||||||
(kidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
|
||||||
|
|
||||||
if (doReflowChild) {
|
if (doReflowChild) {
|
||||||
// Calculate the available width for the table cell using the known column widths
|
// Calculate the available width for the table cell using the known column widths
|
||||||
@ -905,9 +898,6 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
|
|||||||
desiredSize.width = availCellWidth;
|
desiredSize.width = availCellWidth;
|
||||||
|
|
||||||
FinishReflowChild(kidFrame, aPresContext, nsnull, desiredSize, x, 0, 0);
|
FinishReflowChild(kidFrame, aPresContext, nsnull, desiredSize, x, 0, 0);
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(kidFrame, kidRect, kidVisualOverflow,
|
|
||||||
firstReflow);
|
|
||||||
|
|
||||||
x += desiredSize.width;
|
x += desiredSize.width;
|
||||||
}
|
}
|
||||||
@ -1002,12 +992,6 @@ nsTableRowFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
// just set our width to what was available. The table will calculate the width and not use our value.
|
// just set our width to what was available. The table will calculate the width and not use our value.
|
||||||
aDesiredSize.width = aReflowState.availableWidth;
|
aDesiredSize.width = aReflowState.availableWidth;
|
||||||
|
|
||||||
// If our parent is in initial reflow, it'll handle invalidating our
|
|
||||||
// entire overflow rect.
|
|
||||||
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
|
||||||
CheckInvalidateSizeChange(aDesiredSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -1054,11 +1038,6 @@ nsTableRowFrame::ReflowCellFrame(nsPresContext* aPresContext,
|
|||||||
aCellFrame->VerticallyAlignChild(mMaxCellAscent);
|
aCellFrame->VerticallyAlignChild(mMaxCellAscent);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(aCellFrame, cellRect,
|
|
||||||
cellVisualOverflow,
|
|
||||||
(aCellFrame->GetStateBits() &
|
|
||||||
NS_FRAME_FIRST_REFLOW) != 0);
|
|
||||||
|
|
||||||
aCellFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
|
aCellFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
|
||||||
|
|
||||||
return desiredSize.height;
|
return desiredSize.height;
|
||||||
@ -1084,8 +1063,6 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsRect rowRect = GetRect();
|
nsRect rowRect = GetRect();
|
||||||
nsRect oldRect = rowRect;
|
|
||||||
nsRect oldVisualOverflow = GetVisualOverflowRect();
|
|
||||||
|
|
||||||
rowRect.y -= aRowOffset;
|
rowRect.y -= aRowOffset;
|
||||||
rowRect.width = aWidth;
|
rowRect.width = aWidth;
|
||||||
@ -1105,7 +1082,7 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
|
|||||||
// need to invalidate if our row is not moving, because the cell might
|
// need to invalidate if our row is not moving, because the cell might
|
||||||
// span out of this row, so invalidating our row rect won't do enough.
|
// span out of this row, so invalidating our row rect won't do enough.
|
||||||
if (aRowOffset == 0) {
|
if (aRowOffset == 0) {
|
||||||
Invalidate(cRect);
|
InvalidateFrame();
|
||||||
}
|
}
|
||||||
cRect.height = 0;
|
cRect.height = 0;
|
||||||
cellFrame->SetRect(cRect);
|
cellFrame->SetRect(cRect);
|
||||||
@ -1214,12 +1191,6 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
|
|||||||
nsSize(cRect.width, cRect.height));
|
nsSize(cRect.width, cRect.height));
|
||||||
nsTableFrame::RePositionViews(cellFrame);
|
nsTableFrame::RePositionViews(cellFrame);
|
||||||
ConsiderChildOverflow(overflow, cellFrame);
|
ConsiderChildOverflow(overflow, cellFrame);
|
||||||
|
|
||||||
if (aRowOffset == 0) {
|
|
||||||
nsTableFrame::InvalidateFrame(cellFrame, oldCellRect,
|
|
||||||
oldCellVisualOverflow,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
kidFrame = iter.Next(); // Get the next child
|
kidFrame = iter.Next(); // Get the next child
|
||||||
}
|
}
|
||||||
@ -1230,7 +1201,6 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
|
|||||||
FinishAndStoreOverflow(overflow, nsSize(rowRect.width, rowRect.height));
|
FinishAndStoreOverflow(overflow, nsSize(rowRect.width, rowRect.height));
|
||||||
|
|
||||||
nsTableFrame::RePositionViews(this);
|
nsTableFrame::RePositionViews(this);
|
||||||
nsTableFrame::InvalidateFrame(this, oldRect, oldVisualOverflow, false);
|
|
||||||
return shift;
|
return shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1356,6 +1326,14 @@ void nsTableRowFrame::InitHasCellWithStyleHeight(nsTableFrame* aTableFrame)
|
|||||||
}
|
}
|
||||||
RemoveStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
|
RemoveStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTableRowFrame::InvalidateFrame(PRUint32 aFlags)
|
||||||
|
{
|
||||||
|
nsIFrame::InvalidateFrame(aFlags);
|
||||||
|
nsTableFrame *tableFrame = nsTableFrame::GetTableFrame(this);
|
||||||
|
tableFrame->InvalidateFrame(aFlags | INVALIDATE_DONT_SCHEDULE_PAINT);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----- global methods ----- */
|
/* ----- global methods ----- */
|
||||||
|
|
||||||
|
@ -223,6 +223,8 @@ public:
|
|||||||
void SetContinuousBCBorderWidth(PRUint8 aForSide,
|
void SetContinuousBCBorderWidth(PRUint8 aForSide,
|
||||||
BCPixelSize aPixelValue);
|
BCPixelSize aPixelValue);
|
||||||
|
|
||||||
|
virtual void InvalidateFrame(PRUint32 aFlags = 0);
|
||||||
|
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
virtual already_AddRefed<Accessible> CreateAccessible();
|
virtual already_AddRefed<Accessible> CreateAccessible();
|
||||||
#endif
|
#endif
|
||||||
|
@ -254,16 +254,10 @@ nsTableRowGroupFrame::PlaceChild(nsPresContext* aPresContext,
|
|||||||
const nsRect& aOriginalKidRect,
|
const nsRect& aOriginalKidRect,
|
||||||
const nsRect& aOriginalKidVisualOverflow)
|
const nsRect& aOriginalKidVisualOverflow)
|
||||||
{
|
{
|
||||||
bool isFirstReflow =
|
|
||||||
(aKidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
|
||||||
|
|
||||||
// Place and size the child
|
// Place and size the child
|
||||||
FinishReflowChild(aKidFrame, aPresContext, nsnull, aDesiredSize, 0,
|
FinishReflowChild(aKidFrame, aPresContext, nsnull, aDesiredSize, 0,
|
||||||
aReflowState.y, 0);
|
aReflowState.y, 0);
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(aKidFrame, aOriginalKidRect,
|
|
||||||
aOriginalKidVisualOverflow, isFirstReflow);
|
|
||||||
|
|
||||||
// Adjust the running y-offset
|
// Adjust the running y-offset
|
||||||
aReflowState.y += aDesiredSize.height;
|
aReflowState.y += aDesiredSize.height;
|
||||||
|
|
||||||
@ -396,15 +390,7 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext,
|
|||||||
// differently, repaint the entire row
|
// differently, repaint the entire row
|
||||||
nsRect kidRect(0, aReflowState.y,
|
nsRect kidRect(0, aReflowState.y,
|
||||||
desiredSize.width, desiredSize.height);
|
desiredSize.width, desiredSize.height);
|
||||||
Invalidate(kidRect);
|
InvalidateFrame();
|
||||||
|
|
||||||
// Invalidate the area we're offseting. Note that we only
|
|
||||||
// repaint within our existing frame bounds.
|
|
||||||
if (kidRect.YMost() < mRect.height) {
|
|
||||||
nsRect dirtyRect(0, kidRect.YMost(),
|
|
||||||
mRect.width, mRect.height - kidRect.YMost());
|
|
||||||
Invalidate(dirtyRect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (oldKidRect.height != desiredSize.height)
|
else if (oldKidRect.height != desiredSize.height)
|
||||||
needToCalcRowHeights = true;
|
needToCalcRowHeights = true;
|
||||||
@ -449,11 +435,7 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext,
|
|||||||
else if (needToCalcRowHeights) {
|
else if (needToCalcRowHeights) {
|
||||||
CalculateRowHeights(aPresContext, aDesiredSize, aReflowState.reflowState);
|
CalculateRowHeights(aPresContext, aDesiredSize, aReflowState.reflowState);
|
||||||
if (!reflowAllKids) {
|
if (!reflowAllKids) {
|
||||||
// Because we don't know what changed repaint everything.
|
InvalidateFrame();
|
||||||
// XXX We should change CalculateRowHeights() to return the bounding
|
|
||||||
// rect of what changed. Or whether anything moved or changed size...
|
|
||||||
nsRect dirtyRect(0, 0, mRect.width, mRect.height);
|
|
||||||
Invalidate(dirtyRect);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,7 +743,6 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext,
|
|||||||
// update the rows with their (potentially) new heights
|
// update the rows with their (potentially) new heights
|
||||||
for (rowFrame = startRowFrame, rowIndex = 0; rowFrame; rowFrame = rowFrame->GetNextRow(), rowIndex++) {
|
for (rowFrame = startRowFrame, rowIndex = 0; rowFrame; rowFrame = rowFrame->GetNextRow(), rowIndex++) {
|
||||||
nsRect rowBounds = rowFrame->GetRect();
|
nsRect rowBounds = rowFrame->GetRect();
|
||||||
nsRect rowVisualOverflow = rowFrame->GetVisualOverflowRect();
|
|
||||||
|
|
||||||
bool movedFrame = (rowBounds.y != yOrigin);
|
bool movedFrame = (rowBounds.y != yOrigin);
|
||||||
nscoord rowHeight = (rowInfo[rowIndex].height > 0) ? rowInfo[rowIndex].height : 0;
|
nscoord rowHeight = (rowInfo[rowIndex].height > 0) ? rowInfo[rowIndex].height : 0;
|
||||||
@ -774,9 +755,6 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
rowFrame->SetRect(nsRect(rowBounds.x, yOrigin, rowBounds.width,
|
rowFrame->SetRect(nsRect(rowBounds.x, yOrigin, rowBounds.width,
|
||||||
rowHeight));
|
rowHeight));
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(rowFrame, rowBounds, rowVisualOverflow,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
if (movedFrame) {
|
if (movedFrame) {
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
@ -820,8 +798,6 @@ nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aYTotalOffset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsRect groupRect = GetRect();
|
nsRect groupRect = GetRect();
|
||||||
nsRect oldGroupRect = groupRect;
|
|
||||||
nsRect oldGroupVisualOverflow = GetVisualOverflowRect();
|
|
||||||
|
|
||||||
groupRect.height -= yGroupOffset;
|
groupRect.height -= yGroupOffset;
|
||||||
if (didCollapse) {
|
if (didCollapse) {
|
||||||
@ -840,9 +816,6 @@ nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aYTotalOffset,
|
|||||||
overflow.UnionAllWith(nsRect(0, 0, groupRect.width, groupRect.height));
|
overflow.UnionAllWith(nsRect(0, 0, groupRect.width, groupRect.height));
|
||||||
FinishAndStoreOverflow(overflow, nsSize(groupRect.width, groupRect.height));
|
FinishAndStoreOverflow(overflow, nsSize(groupRect.width, groupRect.height));
|
||||||
nsTableFrame::RePositionViews(this);
|
nsTableFrame::RePositionViews(this);
|
||||||
nsTableFrame::InvalidateFrame(this, oldGroupRect, oldGroupVisualOverflow,
|
|
||||||
false);
|
|
||||||
|
|
||||||
return yGroupOffset;
|
return yGroupOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1079,10 +1052,6 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
|
|||||||
rowReflowState.mFlags.mIsTopOfPage = isTopOfPage; // set top of page
|
rowReflowState.mFlags.mIsTopOfPage = isTopOfPage; // set top of page
|
||||||
nsHTMLReflowMetrics rowMetrics;
|
nsHTMLReflowMetrics rowMetrics;
|
||||||
|
|
||||||
// Get the old size before we reflow.
|
|
||||||
nsRect oldRowRect = rowFrame->GetRect();
|
|
||||||
nsRect oldRowVisualOverflow = rowFrame->GetVisualOverflowRect();
|
|
||||||
|
|
||||||
// Reflow the cell with the constrained height. A cell with rowspan >1 will get this
|
// Reflow the cell with the constrained height. A cell with rowspan >1 will get this
|
||||||
// reflow later during SplitSpanningCells.
|
// reflow later during SplitSpanningCells.
|
||||||
rv = ReflowChild(rowFrame, aPresContext, rowMetrics, rowReflowState,
|
rv = ReflowChild(rowFrame, aPresContext, rowMetrics, rowReflowState,
|
||||||
@ -1092,10 +1061,6 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
|
|||||||
rowFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
|
rowFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
|
||||||
rowFrame->DidResize();
|
rowFrame->DidResize();
|
||||||
|
|
||||||
nsTableFrame::InvalidateFrame(rowFrame, oldRowRect,
|
|
||||||
oldRowVisualOverflow,
|
|
||||||
false);
|
|
||||||
|
|
||||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||||
// The row frame is incomplete and all of the rowspan 1 cells' block frames split
|
// The row frame is incomplete and all of the rowspan 1 cells' block frames split
|
||||||
if ((rowMetrics.height <= rowReflowState.availableHeight) || isTopOfPage) {
|
if ((rowMetrics.height <= rowReflowState.availableHeight) || isTopOfPage) {
|
||||||
@ -1323,12 +1288,6 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
aDesiredSize.UnionOverflowAreasWithDesiredBounds();
|
aDesiredSize.UnionOverflowAreasWithDesiredBounds();
|
||||||
|
|
||||||
// If our parent is in initial reflow, it'll handle invalidating our
|
|
||||||
// entire overflow rect.
|
|
||||||
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
|
||||||
CheckInvalidateSizeChange(aDesiredSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
FinishAndStoreOverflow(&aDesiredSize);
|
FinishAndStoreOverflow(&aDesiredSize);
|
||||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||||
return rv;
|
return rv;
|
||||||
@ -1880,3 +1839,11 @@ nsTableRowGroupFrame::FrameCursorData::AppendFrame(nsIFrame* aFrame)
|
|||||||
mOverflowBelow = NS_MAX(mOverflowBelow, overflowBelow);
|
mOverflowBelow = NS_MAX(mOverflowBelow, overflowBelow);
|
||||||
return mFrames.AppendElement(aFrame) != nsnull;
|
return mFrames.AppendElement(aFrame) != nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTableRowGroupFrame::InvalidateFrame(PRUint32 aFlags)
|
||||||
|
{
|
||||||
|
nsIFrame::InvalidateFrame(aFlags);
|
||||||
|
nsTableFrame *tableFrame = nsTableFrame::GetTableFrame(this);
|
||||||
|
tableFrame->InvalidateFrame(aFlags | INVALIDATE_DONT_SCHEDULE_PAINT);
|
||||||
|
}
|
||||||
|
@ -323,6 +323,8 @@ public:
|
|||||||
FrameCursorData* SetupRowCursor();
|
FrameCursorData* SetupRowCursor();
|
||||||
|
|
||||||
virtual nsILineIterator* GetLineIterator() { return this; }
|
virtual nsILineIterator* GetLineIterator() { return this; }
|
||||||
|
|
||||||
|
virtual void InvalidateFrame(PRUint32 aFlags = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsTableRowGroupFrame(nsStyleContext* aContext);
|
nsTableRowGroupFrame(nsStyleContext* aContext);
|
||||||
|
@ -584,22 +584,14 @@ nsBox::SyncLayout(nsBoxLayoutState& aState)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsIFrame::Redraw(nsBoxLayoutState& aState,
|
nsIFrame::Redraw(nsBoxLayoutState& aState)
|
||||||
const nsRect* aDamageRect)
|
|
||||||
{
|
{
|
||||||
if (aState.PaintingDisabled())
|
if (aState.PaintingDisabled())
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsRect damageRect(0,0,0,0);
|
|
||||||
if (aDamageRect)
|
|
||||||
damageRect = *aDamageRect;
|
|
||||||
else
|
|
||||||
damageRect = GetVisualOverflowRect();
|
|
||||||
|
|
||||||
Invalidate(damageRect);
|
|
||||||
// nsStackLayout, at least, expects us to repaint descendants even
|
// nsStackLayout, at least, expects us to repaint descendants even
|
||||||
// if a damage rect is provided
|
// if a damage rect is provided
|
||||||
FrameLayerBuilder::InvalidateThebesLayersInSubtree(this);
|
InvalidateFrameSubtree();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ nsDeckFrame::IndexChanged()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// redraw
|
// redraw
|
||||||
InvalidateOverflowRect();
|
InvalidateFrame();
|
||||||
|
|
||||||
// hide the currently showing box
|
// hide the currently showing box
|
||||||
nsIBox* currentBox = GetSelectedBox();
|
nsIBox* currentBox = GetSelectedBox();
|
||||||
|
@ -596,6 +596,10 @@ NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIRequest *aRequest,
|
|||||||
imgIContainer *aContainer,
|
imgIContainer *aContainer,
|
||||||
const nsIntRect *aDirtyRect)
|
const nsIntRect *aDirtyRect)
|
||||||
{
|
{
|
||||||
|
if ((0 == mRect.width) || (0 == mRect.height)) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsBoxLayoutState state(PresContext());
|
nsBoxLayoutState state(PresContext());
|
||||||
this->Redraw(state);
|
this->Redraw(state);
|
||||||
|
|
||||||
|
@ -198,9 +198,7 @@ nsListBoxLayout::LayoutInternal(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||||||
// before them then redraw everything under the inserted rows. The inserted
|
// before them then redraw everything under the inserted rows. The inserted
|
||||||
// rows will automatically be redrawn because the were marked dirty on insertion.
|
// rows will automatically be redrawn because the were marked dirty on insertion.
|
||||||
if (redrawStart > -1) {
|
if (redrawStart > -1) {
|
||||||
nsRect bounds(aBox->GetRect());
|
aBox->Redraw(aState);
|
||||||
nsRect tempRect(0,redrawStart,bounds.width, bounds.height - redrawStart);
|
|
||||||
aBox->Redraw(aState, &tempRect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -170,6 +170,8 @@ nsMenuPopupFrame::Init(nsIContent* aContent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddStateBits(NS_FRAME_IN_POPUP);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,14 +807,6 @@ nsMenuPopupFrame::HidePopup(bool aDeselectMenu, nsPopupState aNewState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsMenuPopupFrame::InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
InvalidateRoot(aDamageRect + nsPoint(aX, aY), aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsMenuPopupFrame::GetLayoutFlags(PRUint32& aFlags)
|
nsMenuPopupFrame::GetLayoutFlags(PRUint32& aFlags)
|
||||||
{
|
{
|
||||||
|
@ -157,10 +157,6 @@ public:
|
|||||||
|
|
||||||
virtual void DestroyFrom(nsIFrame* aDestructRoot);
|
virtual void DestroyFrom(nsIFrame* aDestructRoot);
|
||||||
|
|
||||||
virtual void InvalidateInternal(const nsRect& aDamageRect,
|
|
||||||
nscoord aX, nscoord aY, nsIFrame* aForChild,
|
|
||||||
PRUint32 aFlags);
|
|
||||||
|
|
||||||
// returns true if the popup is a panel with the noautohide attribute set to
|
// returns true if the popup is a panel with the noautohide attribute set to
|
||||||
// true. These panels do not roll up automatically.
|
// true. These panels do not roll up automatically.
|
||||||
bool IsNoAutoHide() const;
|
bool IsNoAutoHide() const;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user