mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-05 20:15:58 +00:00
infrastructure to recover overflow area during incremental reflow, bug 197581, r=kin sr=dbaron
This commit is contained in:
parent
799cc4775c
commit
838f8ce8ad
@ -1245,6 +1245,15 @@ public:
|
||||
void* aPropertyValue) = 0;
|
||||
#endif // IBMBIDI
|
||||
|
||||
/** Create or retrieve the previously stored overflow area, if the frame does
|
||||
* not overflow and no creation is required return nsnull.
|
||||
* @param aPresContext PresContext
|
||||
* @param aCreateIfNecessary create a new nsRect for the overflow area
|
||||
* @return pointer to the overflow area rectangle
|
||||
*/
|
||||
virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext,
|
||||
PRBool aCreateIfNecessary = PR_FALSE) = 0;
|
||||
|
||||
/**
|
||||
* Return PR_TRUE if and only if this frame obeys visibility:hidden.
|
||||
* if it does not, then nsContainerFrame will hide its view even though
|
||||
|
@ -156,52 +156,6 @@ nsAbsoluteContainingBlock::ReplaceFrame(nsIFrame* aDelegatingFrame,
|
||||
return result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// Destructor function for the collapse offset frame property
|
||||
static void
|
||||
DestroyRectFunc(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
delete (nsRect*)aPropertyValue;
|
||||
}
|
||||
|
||||
static nsRect*
|
||||
GetOverflowAreaProperty(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
PRBool aCreateIfNecessary = PR_FALSE)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
void* value;
|
||||
|
||||
frameManager->GetFrameProperty(aFrame, nsLayoutAtoms::overflowAreaProperty,
|
||||
0, &value);
|
||||
if (value) {
|
||||
return (nsRect*)value; // the property already exists
|
||||
|
||||
} else if (aCreateIfNecessary) {
|
||||
// The property isn't set yet, so allocate a new rect, set the property,
|
||||
// and return the newly allocated rect
|
||||
nsRect* overflow = new nsRect(0, 0, 0, 0);
|
||||
|
||||
frameManager->SetFrameProperty(aFrame, nsLayoutAtoms::overflowAreaProperty,
|
||||
overflow, DestroyRectFunc);
|
||||
return overflow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
|
||||
nsIPresContext* aPresContext,
|
||||
@ -257,7 +211,7 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
|
||||
kidFrame->GetFrameState(&kidFrameState);
|
||||
if (kidFrameState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
// Get the property
|
||||
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, kidFrame);
|
||||
nsRect* overflowArea = kidFrame->GetOverflowAreaProperty(aPresContext);
|
||||
|
||||
if (overflowArea) {
|
||||
// The overflow area is in the child's coordinate space, so translate
|
||||
@ -291,7 +245,7 @@ nsAbsoluteContainingBlock::CalculateChildBounds(nsIPresContext* aPresContext,
|
||||
f->GetFrameState(&frameState);
|
||||
if (frameState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
// Get the property
|
||||
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, f);
|
||||
nsRect* overflowArea = f->GetOverflowAreaProperty(aPresContext);
|
||||
|
||||
if (overflowArea) {
|
||||
// The overflow area is in the child's coordinate space, so translate
|
||||
@ -550,7 +504,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
|
||||
aKidFrame->GetFrameState(&kidFrameState);
|
||||
if (kidFrameState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
// Get the property (creating a rect struct if necessary)
|
||||
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, aKidFrame, PR_TRUE);
|
||||
nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(aPresContext, PR_TRUE);
|
||||
|
||||
NS_ASSERTION(overflowArea, "should have created rect");
|
||||
if (overflowArea) {
|
||||
|
@ -686,15 +686,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
||||
mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds);
|
||||
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
|
||||
|
||||
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
|
||||
if ((aMetrics.mOverflowArea.x < 0) ||
|
||||
(aMetrics.mOverflowArea.y < 0) ||
|
||||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
|
||||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
} else {
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
StoreOverflow(aPresContext, aMetrics);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -952,6 +944,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
// Compute our final size
|
||||
ComputeFinalSize(aReflowState, state, aMetrics);
|
||||
StoreOverflow(aPresContext, aMetrics);
|
||||
|
||||
// see if verifyReflow is enabled, and if so store off the space manager pointer
|
||||
#ifdef DEBUG
|
||||
@ -1012,17 +1005,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// Factor the absolutely positioned child bounds into the overflow area
|
||||
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
|
||||
|
||||
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
|
||||
if ((aMetrics.mOverflowArea.x < 0) ||
|
||||
(aMetrics.mOverflowArea.y < 0) ||
|
||||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
|
||||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
} else {
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
StoreOverflow(aPresContext, aMetrics);
|
||||
}
|
||||
|
||||
// Clear the space manager pointer in the block reflow state so we
|
||||
// don't waste time translating the coordinate system back on a dead
|
||||
// space manager.
|
||||
@ -1430,18 +1414,6 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
|
||||
}
|
||||
|
||||
ComputeCombinedArea(aReflowState, aMetrics);
|
||||
|
||||
// If the combined area of our children exceeds our bounding box
|
||||
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
|
||||
if ((aMetrics.mOverflowArea.x < 0) ||
|
||||
(aMetrics.mOverflowArea.y < 0) ||
|
||||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
|
||||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
else {
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4549,6 +4549,87 @@ GetIBSpecialSibling(nsIPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Destructor function for the overflow area property
|
||||
static void
|
||||
DestroyRectFunc(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
delete (nsRect*)aPropertyValue;
|
||||
}
|
||||
|
||||
nsRect*
|
||||
nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext,
|
||||
PRBool aCreateIfNecessary)
|
||||
{
|
||||
nsFrameState frameState;
|
||||
GetFrameState(&frameState);
|
||||
if (!((frameState & NS_FRAME_OUTSIDE_CHILDREN) || aCreateIfNecessary)) {
|
||||
return nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
void* value;
|
||||
|
||||
frameManager->GetFrameProperty((nsIFrame*)this, nsLayoutAtoms::overflowAreaProperty,
|
||||
0, &value);
|
||||
if (value) {
|
||||
return (nsRect*)value; // the property already exists
|
||||
|
||||
} else if (aCreateIfNecessary) {
|
||||
// The property isn't set yet, so allocate a new rect, set the property,
|
||||
// and return the newly allocated rect
|
||||
nsRect* overflow = new nsRect(0, 0, 0, 0);
|
||||
|
||||
frameManager->SetFrameProperty((nsIFrame*)this, nsLayoutAtoms::overflowAreaProperty,
|
||||
overflow, DestroyRectFunc);
|
||||
return overflow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrame::StoreOverflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aMetrics)
|
||||
{
|
||||
if ((aMetrics.mOverflowArea.x < 0) ||
|
||||
(aMetrics.mOverflowArea.y < 0) ||
|
||||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
|
||||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
nsRect* overflowArea = GetOverflowAreaProperty(aPresContext, PR_TRUE);
|
||||
NS_ASSERTION(overflowArea, "should have created rect");
|
||||
if (overflowArea) {
|
||||
*overflowArea = aMetrics.mOverflowArea;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
// remove the previously stored overflow area
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
if (frameManager) {
|
||||
frameManager->RemoveFrameProperty((nsIFrame*)this, nsLayoutAtoms::overflowAreaProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrame::DoGetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
@ -5634,6 +5715,16 @@ void nsFrame::DisplayReflowExit(nsIPresContext* aPresContext,
|
||||
DR_state->PrettyUC(aMetrics.mOverflowArea.width, width);
|
||||
DR_state->PrettyUC(aMetrics.mOverflowArea.height, height);
|
||||
printf("o=(%s,%s) %s x %s", x, y, width, height);
|
||||
nsRect* storedOverflow = aFrame->GetOverflowAreaProperty(aPresContext);
|
||||
if (storedOverflow) {
|
||||
if (aMetrics.mOverflowArea != *storedOverflow) {
|
||||
DR_state->PrettyUC(storedOverflow->x, x);
|
||||
DR_state->PrettyUC(storedOverflow->y, y);
|
||||
DR_state->PrettyUC(storedOverflow->width, width);
|
||||
DR_state->PrettyUC(storedOverflow->height, height);
|
||||
printf("sto=(%s,%s) %s x %s", x, y, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
if (DR_state->mDisplayPixelErrors) {
|
||||
|
@ -381,6 +381,17 @@ public:
|
||||
nsresult GetIBSpecialParent(nsIPresContext* aPresContext,
|
||||
nsIFrame** aSpecialParent);
|
||||
|
||||
// Return the previously stored overflow area, if the frame does not
|
||||
// overflow and a creation is not requested it will return nsnull
|
||||
virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext,
|
||||
PRBool aCreateIfNecessary = PR_FALSE);
|
||||
|
||||
// Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area
|
||||
// as a frame property in the frame manager so that it can be retrieved
|
||||
// later without reflowing the frame.
|
||||
void StoreOverflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aMetrics);
|
||||
|
||||
//Mouse Capturing code used by the frames to tell the view to capture all the following events
|
||||
NS_IMETHOD CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
|
||||
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
|
||||
|
@ -1245,6 +1245,15 @@ public:
|
||||
void* aPropertyValue) = 0;
|
||||
#endif // IBMBIDI
|
||||
|
||||
/** Create or retrieve the previously stored overflow area, if the frame does
|
||||
* not overflow and no creation is required return nsnull.
|
||||
* @param aPresContext PresContext
|
||||
* @param aCreateIfNecessary create a new nsRect for the overflow area
|
||||
* @return pointer to the overflow area rectangle
|
||||
*/
|
||||
virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext,
|
||||
PRBool aCreateIfNecessary = PR_FALSE) = 0;
|
||||
|
||||
/**
|
||||
* Return PR_TRUE if and only if this frame obeys visibility:hidden.
|
||||
* if it does not, then nsContainerFrame will hide its view even though
|
||||
|
@ -156,52 +156,6 @@ nsAbsoluteContainingBlock::ReplaceFrame(nsIFrame* aDelegatingFrame,
|
||||
return result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// Destructor function for the collapse offset frame property
|
||||
static void
|
||||
DestroyRectFunc(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
delete (nsRect*)aPropertyValue;
|
||||
}
|
||||
|
||||
static nsRect*
|
||||
GetOverflowAreaProperty(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
PRBool aCreateIfNecessary = PR_FALSE)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
void* value;
|
||||
|
||||
frameManager->GetFrameProperty(aFrame, nsLayoutAtoms::overflowAreaProperty,
|
||||
0, &value);
|
||||
if (value) {
|
||||
return (nsRect*)value; // the property already exists
|
||||
|
||||
} else if (aCreateIfNecessary) {
|
||||
// The property isn't set yet, so allocate a new rect, set the property,
|
||||
// and return the newly allocated rect
|
||||
nsRect* overflow = new nsRect(0, 0, 0, 0);
|
||||
|
||||
frameManager->SetFrameProperty(aFrame, nsLayoutAtoms::overflowAreaProperty,
|
||||
overflow, DestroyRectFunc);
|
||||
return overflow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
|
||||
nsIPresContext* aPresContext,
|
||||
@ -257,7 +211,7 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
|
||||
kidFrame->GetFrameState(&kidFrameState);
|
||||
if (kidFrameState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
// Get the property
|
||||
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, kidFrame);
|
||||
nsRect* overflowArea = kidFrame->GetOverflowAreaProperty(aPresContext);
|
||||
|
||||
if (overflowArea) {
|
||||
// The overflow area is in the child's coordinate space, so translate
|
||||
@ -291,7 +245,7 @@ nsAbsoluteContainingBlock::CalculateChildBounds(nsIPresContext* aPresContext,
|
||||
f->GetFrameState(&frameState);
|
||||
if (frameState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
// Get the property
|
||||
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, f);
|
||||
nsRect* overflowArea = f->GetOverflowAreaProperty(aPresContext);
|
||||
|
||||
if (overflowArea) {
|
||||
// The overflow area is in the child's coordinate space, so translate
|
||||
@ -550,7 +504,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
|
||||
aKidFrame->GetFrameState(&kidFrameState);
|
||||
if (kidFrameState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
// Get the property (creating a rect struct if necessary)
|
||||
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, aKidFrame, PR_TRUE);
|
||||
nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(aPresContext, PR_TRUE);
|
||||
|
||||
NS_ASSERTION(overflowArea, "should have created rect");
|
||||
if (overflowArea) {
|
||||
|
@ -686,15 +686,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
||||
mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds);
|
||||
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
|
||||
|
||||
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
|
||||
if ((aMetrics.mOverflowArea.x < 0) ||
|
||||
(aMetrics.mOverflowArea.y < 0) ||
|
||||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
|
||||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
} else {
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
StoreOverflow(aPresContext, aMetrics);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -952,6 +944,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
// Compute our final size
|
||||
ComputeFinalSize(aReflowState, state, aMetrics);
|
||||
StoreOverflow(aPresContext, aMetrics);
|
||||
|
||||
// see if verifyReflow is enabled, and if so store off the space manager pointer
|
||||
#ifdef DEBUG
|
||||
@ -1012,17 +1005,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// Factor the absolutely positioned child bounds into the overflow area
|
||||
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
|
||||
|
||||
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
|
||||
if ((aMetrics.mOverflowArea.x < 0) ||
|
||||
(aMetrics.mOverflowArea.y < 0) ||
|
||||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
|
||||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
} else {
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
StoreOverflow(aPresContext, aMetrics);
|
||||
}
|
||||
|
||||
// Clear the space manager pointer in the block reflow state so we
|
||||
// don't waste time translating the coordinate system back on a dead
|
||||
// space manager.
|
||||
@ -1430,18 +1414,6 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
|
||||
}
|
||||
|
||||
ComputeCombinedArea(aReflowState, aMetrics);
|
||||
|
||||
// If the combined area of our children exceeds our bounding box
|
||||
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
|
||||
if ((aMetrics.mOverflowArea.x < 0) ||
|
||||
(aMetrics.mOverflowArea.y < 0) ||
|
||||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
|
||||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
else {
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4549,6 +4549,87 @@ GetIBSpecialSibling(nsIPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Destructor function for the overflow area property
|
||||
static void
|
||||
DestroyRectFunc(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
delete (nsRect*)aPropertyValue;
|
||||
}
|
||||
|
||||
nsRect*
|
||||
nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext,
|
||||
PRBool aCreateIfNecessary)
|
||||
{
|
||||
nsFrameState frameState;
|
||||
GetFrameState(&frameState);
|
||||
if (!((frameState & NS_FRAME_OUTSIDE_CHILDREN) || aCreateIfNecessary)) {
|
||||
return nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
void* value;
|
||||
|
||||
frameManager->GetFrameProperty((nsIFrame*)this, nsLayoutAtoms::overflowAreaProperty,
|
||||
0, &value);
|
||||
if (value) {
|
||||
return (nsRect*)value; // the property already exists
|
||||
|
||||
} else if (aCreateIfNecessary) {
|
||||
// The property isn't set yet, so allocate a new rect, set the property,
|
||||
// and return the newly allocated rect
|
||||
nsRect* overflow = new nsRect(0, 0, 0, 0);
|
||||
|
||||
frameManager->SetFrameProperty((nsIFrame*)this, nsLayoutAtoms::overflowAreaProperty,
|
||||
overflow, DestroyRectFunc);
|
||||
return overflow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrame::StoreOverflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aMetrics)
|
||||
{
|
||||
if ((aMetrics.mOverflowArea.x < 0) ||
|
||||
(aMetrics.mOverflowArea.y < 0) ||
|
||||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
|
||||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
nsRect* overflowArea = GetOverflowAreaProperty(aPresContext, PR_TRUE);
|
||||
NS_ASSERTION(overflowArea, "should have created rect");
|
||||
if (overflowArea) {
|
||||
*overflowArea = aMetrics.mOverflowArea;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
// remove the previously stored overflow area
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
if (frameManager) {
|
||||
frameManager->RemoveFrameProperty((nsIFrame*)this, nsLayoutAtoms::overflowAreaProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrame::DoGetParentStyleContextFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
@ -5634,6 +5715,16 @@ void nsFrame::DisplayReflowExit(nsIPresContext* aPresContext,
|
||||
DR_state->PrettyUC(aMetrics.mOverflowArea.width, width);
|
||||
DR_state->PrettyUC(aMetrics.mOverflowArea.height, height);
|
||||
printf("o=(%s,%s) %s x %s", x, y, width, height);
|
||||
nsRect* storedOverflow = aFrame->GetOverflowAreaProperty(aPresContext);
|
||||
if (storedOverflow) {
|
||||
if (aMetrics.mOverflowArea != *storedOverflow) {
|
||||
DR_state->PrettyUC(storedOverflow->x, x);
|
||||
DR_state->PrettyUC(storedOverflow->y, y);
|
||||
DR_state->PrettyUC(storedOverflow->width, width);
|
||||
DR_state->PrettyUC(storedOverflow->height, height);
|
||||
printf("sto=(%s,%s) %s x %s", x, y, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
if (DR_state->mDisplayPixelErrors) {
|
||||
|
@ -381,6 +381,17 @@ public:
|
||||
nsresult GetIBSpecialParent(nsIPresContext* aPresContext,
|
||||
nsIFrame** aSpecialParent);
|
||||
|
||||
// Return the previously stored overflow area, if the frame does not
|
||||
// overflow and a creation is not requested it will return nsnull
|
||||
virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext,
|
||||
PRBool aCreateIfNecessary = PR_FALSE);
|
||||
|
||||
// Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area
|
||||
// as a frame property in the frame manager so that it can be retrieved
|
||||
// later without reflowing the frame.
|
||||
void StoreOverflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aMetrics);
|
||||
|
||||
//Mouse Capturing code used by the frames to tell the view to capture all the following events
|
||||
NS_IMETHOD CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
|
||||
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
|
||||
|
Loading…
Reference in New Issue
Block a user