WillReflow/DidReflow changes and changes to the way view positioning

and sizing works
This commit is contained in:
troy%netscape.com 1999-11-19 15:33:29 +00:00
Родитель 78aeabf09d
Коммит 597b5f236b
84 изменённых файлов: 2020 добавлений и 783 удалений

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

@ -992,10 +992,21 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
nsHTMLReflowState reflowState(*mPresContext, rootFrame, nsHTMLReflowState reflowState(*mPresContext, rootFrame,
eReflowReason_Initial, rcx, maxSize); eReflowReason_Initial, rcx, maxSize);
nsIView* view;
rootFrame->WillReflow(*mPresContext);
rootFrame->GetView(mPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
}
rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status); rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status);
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height); rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height)); mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height));
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
nsnull);
}
rootFrame->DidReflow(*mPresContext, NS_FRAME_REFLOW_FINISHED);
#ifdef NS_DEBUG #ifdef NS_DEBUG
if (nsIFrameDebug::GetVerifyTreeEnable()) { if (nsIFrameDebug::GetVerifyTreeEnable()) {
@ -1077,9 +1088,20 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
nsHTMLReflowState reflowState(*mPresContext, rootFrame, nsHTMLReflowState reflowState(*mPresContext, rootFrame,
eReflowReason_Resize, rcx, maxSize); eReflowReason_Resize, rcx, maxSize);
nsIView* view;
rootFrame->WillReflow(*mPresContext);
rootFrame->GetView(mPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
}
rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status); rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status);
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height); rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
nsnull);
}
rootFrame->DidReflow(*mPresContext, NS_FRAME_REFLOW_FINISHED);
#ifdef NS_DEBUG #ifdef NS_DEBUG
if (nsIFrameDebug::GetVerifyTreeEnable()) { if (nsIFrameDebug::GetVerifyTreeEnable()) {
nsIFrameDebug* frameDebug; nsIFrameDebug* frameDebug;
@ -1262,9 +1284,21 @@ PresShell::StyleChangeReflow()
// XXX We should be using eReflowReason_StyleChange // XXX We should be using eReflowReason_StyleChange
nsHTMLReflowState reflowState(*mPresContext, rootFrame, nsHTMLReflowState reflowState(*mPresContext, rootFrame,
eReflowReason_Resize, rcx, maxSize); eReflowReason_Resize, rcx, maxSize);
nsIView* view;
rootFrame->WillReflow(*mPresContext);
rootFrame->GetView(mPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
}
rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status); rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status);
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height); rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height));
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
nsnull);
}
rootFrame->DidReflow(*mPresContext, NS_FRAME_REFLOW_FINISHED);
#ifdef NS_DEBUG #ifdef NS_DEBUG
if (nsIFrameDebug::GetVerifyTreeEnable()) { if (nsIFrameDebug::GetVerifyTreeEnable()) {
nsIFrameDebug* frameDebug; nsIFrameDebug* frameDebug;

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

@ -32,6 +32,23 @@
#include "nsStyleCoord.h" #include "nsStyleCoord.h"
#include "nsHTMLReflowState.h" #include "nsHTMLReflowState.h"
/**
* New rules of reflow:
* 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order
* (no separate pass over the tree)
* 2. it's the parent frame's responsibility to size/position the child's view (not
* the child frame's responsibility as it is today) during reflow (and before
* sending the DidReflow() notification)
* 3. positioning of child frames (and their views) is done on the way down the tree,
* and sizing of child frames (and their views) on the way back up
* 4. if you move a frame (outside of the reflow process, or after reflowing it),
* then you must make sure that its view (or its child frame's views) are re-positioned
* as well. It's reasonable to not position the view until after all reflowing the
* entire line, for example, but the frame should still be positioned and sized (and
* the view sized) during the reflow (i.e., before sending the DidReflow() notification)
* 5. the view system handles moving of widgets, i.e., it's not our problem
*/
class nsIAtom; class nsIAtom;
class nsIContent; class nsIContent;
class nsIPresContext; class nsIPresContext;
@ -545,6 +562,9 @@ public:
* Bounding rect of the frame. The values are in twips, and the origin is * Bounding rect of the frame. The values are in twips, and the origin is
* relative to the upper-left of the geometric parent. The size includes the * relative to the upper-left of the geometric parent. The size includes the
* content area, borders, and padding. * content area, borders, and padding.
*
* Note: moving or sizing the frame does not affect the view's size or
* position.
*/ */
NS_IMETHOD GetRect(nsRect& aRect) const = 0; NS_IMETHOD GetRect(nsRect& aRect) const = 0;
NS_IMETHOD GetOrigin(nsPoint& aPoint) const = 0; NS_IMETHOD GetOrigin(nsPoint& aPoint) const = 0;

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

@ -424,14 +424,13 @@ nsComboboxControlFrame::ReflowComboChildFrame(nsIFrame* aFrame,
kidReflowState.mComputedHeight = aAvailableHeight; kidReflowState.mComputedHeight = aAvailableHeight;
// Reflow child // Reflow child
nsresult rv = ReflowChild(aFrame, aPresContext, aDesiredSize, kidReflowState, aStatus);
// Set the child's width and height to it's desired size
nsRect rect; nsRect rect;
aFrame->GetRect(rect); aFrame->GetRect(rect);
rect.width = aDesiredSize.width; nsresult rv = ReflowChild(aFrame, aPresContext, aDesiredSize, kidReflowState,
rect.height = aDesiredSize.height; rect.x, rect.y, 0, aStatus);
aFrame->SetRect(&aPresContext, rect);
// Set the child's width and height to it's desired size
FinishReflowChild(aFrame, aPresContext, aDesiredSize, rect.x, rect.y, 0);
return rv; return rv;
} }

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

@ -318,7 +318,8 @@ nsFieldSetFrame::Reflow(nsIPresContext& aPresContext,
legendReflowState.mComputedWidth = NS_INTRINSICSIZE; legendReflowState.mComputedWidth = NS_INTRINSICSIZE;
legendReflowState.mComputedHeight = NS_INTRINSICSIZE; legendReflowState.mComputedHeight = NS_INTRINSICSIZE;
ReflowChild(mLegendFrame, aPresContext, aDesiredSize, legendReflowState, aStatus); ReflowChild(mLegendFrame, aPresContext, aDesiredSize, legendReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
// get the legend's margin // get the legend's margin
nsIStyleContext* legendSC = nsnull; nsIStyleContext* legendSC = nsnull;
@ -355,19 +356,22 @@ nsFieldSetFrame::Reflow(nsIPresContext& aPresContext,
availSize.width = mLegendRect.width; availSize.width = mLegendRect.width;
} }
// Tell the legend we're done with the reflow. We'll size and place it later on
mLegendFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
// Try to reflow the area frame into the available space. // Try to reflow the area frame into the available space.
nsHTMLReflowState contentReflowState(aPresContext, aReflowState, nsHTMLReflowState contentReflowState(aPresContext, aReflowState,
mContentFrame, availSize); mContentFrame, availSize);
ReflowChild(mContentFrame, aPresContext, aDesiredSize, contentReflowState, aStatus); ReflowChild(mContentFrame, aPresContext, aDesiredSize, contentReflowState,
borderPadding.left, borderPadding.top + mLegendSpace, 0, aStatus);
// set the rect. make sure we add the margin back in. // set the rect. make sure we add the margin back in.
nsRect contentRect(borderPadding.left,borderPadding.top + mLegendSpace,aDesiredSize.width ,aDesiredSize.height); nsRect contentRect(borderPadding.left,borderPadding.top + mLegendSpace,aDesiredSize.width ,aDesiredSize.height);
// Place the content area frame. // Place the content area frame.
mContentFrame->SetRect(&aPresContext, contentRect); FinishReflowChild(mContentFrame, aPresContext, aDesiredSize, contentRect.x, contentRect.y, 0);
if (mLegendFrame) if (mLegendFrame)
{ {

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

@ -516,6 +516,9 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext& aPresContext,
// the view also breaks the outline code. For some reason you can not reset // the view also breaks the outline code. For some reason you can not reset
// the clip rect to draw outside you bounds if you have a view. And you need to // the clip rect to draw outside you bounds if you have a view. And you need to
// because the outline must be drawn outside of our bounds according to CSS. -EDV // because the outline must be drawn outside of our bounds according to CSS. -EDV
// XXX If you do decide you need a view, then create it in the Init() function
// and not here...
#if 0 #if 0
if (!mDidInit) { if (!mDidInit) {
// create our view, we need a view to grab the mouse // create our view, we need a view to grab the mouse
@ -596,11 +599,15 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext& aPresContext,
} }
} }
ReflowChild(firstKid, aPresContext, aDesiredSize, reflowState, aStatus); ReflowChild(firstKid, aPresContext, aDesiredSize, reflowState,
focusPadding.left + aReflowState.mComputedBorderPadding.left,
focusPadding.top + aReflowState.mComputedBorderPadding.top,
0, aStatus);
// Place the child // Place the child
nsRect rect = nsRect(focusPadding.left + aReflowState.mComputedBorderPadding.left, focusPadding.top + aReflowState.mComputedBorderPadding.top, aDesiredSize.width, aDesiredSize.height); FinishReflowChild(firstKid, aPresContext, aDesiredSize,
firstKid->SetRect(&aPresContext, rect); focusPadding.left + aReflowState.mComputedBorderPadding.left,
focusPadding.top + aReflowState.mComputedBorderPadding.top, 0);
#if 0 // old way #if 0 // old way
// if computed use the computed values. // if computed use the computed values.

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

@ -70,6 +70,12 @@ public:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD Init(nsIPresContext& aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD Reflow(nsIPresContext& aPresContext, NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
@ -202,15 +208,16 @@ nsrefcnt nsImageControlFrame::Release(void)
return 1; return 1;
} }
NS_METHOD NS_IMETHODIMP
nsImageControlFrame::Reflow(nsIPresContext& aPresContext, nsImageControlFrame::Init(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsIContent* aContent,
const nsHTMLReflowState& aReflowState, nsIFrame* aParent,
nsReflowStatus& aStatus) nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{ {
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { // call our base class
// add ourself as an nsIFormControlFrame nsresult rv = nsImageControlFrameSuper::Init(aPresContext, aContent, aParent,
nsFormFrame::AddFormControlFrame(aPresContext, *this); aContext, aPrevInFlow);
// create our view, we need a view to grab the mouse // create our view, we need a view to grab the mouse
nsIView* view; nsIView* view;
@ -227,7 +234,7 @@ nsImageControlFrame::Reflow(nsIPresContext& aPresContext,
GetParentWithView(&aPresContext, &parWithView); GetParentWithView(&aPresContext, &parWithView);
parWithView->GetView(&aPresContext, &parView); parWithView->GetView(&aPresContext, &parView);
// the view's size is not know yet, but its size will be kept in synch with our frame. // the view's size is not know yet, but its size will be kept in synch with our frame.
nsRect boundBox(0, 0, 500, 500); nsRect boundBox(0, 0, 0, 0);
result = view->Init(viewMan, boundBox, parView, nsnull); result = view->Init(viewMan, boundBox, parView, nsnull);
view->SetContentTransparency(PR_TRUE); view->SetContentTransparency(PR_TRUE);
viewMan->InsertChild(parView, view, 0); viewMan->InsertChild(parView, view, 0);
@ -237,6 +244,19 @@ nsImageControlFrame::Reflow(nsIPresContext& aPresContext,
// set the opacity // set the opacity
viewMan->SetViewOpacity(view, color->mOpacity); viewMan->SetViewOpacity(view, color->mOpacity);
} }
return NS_OK;
}
NS_METHOD
nsImageControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
// add ourself as an nsIFormControlFrame
nsFormFrame::AddFormControlFrame(aPresContext, *this);
} }
return nsImageControlFrameSuper::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); return nsImageControlFrameSuper::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
} }

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

@ -260,8 +260,6 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
NS_NOTYETIMPLEMENTED("percentage border"); NS_NOTYETIMPLEMENTED("percentage border");
} }
aKidFrame->WillReflow(aPresContext);
nsSize availSize(aReflowState.mComputedWidth, NS_UNCONSTRAINEDSIZE); nsSize availSize(aReflowState.mComputedWidth, NS_UNCONSTRAINEDSIZE);
nsHTMLReflowMetrics kidDesiredSize(nsnull); nsHTMLReflowMetrics kidDesiredSize(nsnull);
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame,
@ -274,6 +272,19 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
kidReflowState.reason = eReflowReason_Initial; kidReflowState.reason = eReflowReason_Initial;
} }
// XXX TROY
// Send the WillReflow() notification and position the frame
aKidFrame->WillReflow(aPresContext);
aKidFrame->MoveTo(&aPresContext,
border.left + kidReflowState.mComputedOffsets.left + kidReflowState.mComputedMargin.left,
border.top + kidReflowState.mComputedOffsets.top + kidReflowState.mComputedMargin.top);
// Position its view
nsIView* kidView;
aKidFrame->GetView(&aPresContext, &kidView);
nsContainerFrame::PositionFrameView(&aPresContext, aKidFrame, kidView);
// Do the reflow
rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus); rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus);
// Because we don't know the size of a replaced element until after we reflow // Because we don't know the size of a replaced element until after we reflow
@ -368,6 +379,11 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
kidDesiredSize.width, kidDesiredSize.height); kidDesiredSize.width, kidDesiredSize.height);
aKidFrame->SetRect(&aPresContext, rect); aKidFrame->SetRect(&aPresContext, rect);
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, aKidFrame, kidView,
&kidDesiredSize.mCombinedArea);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
return rv; return rv;
} }

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

@ -328,57 +328,6 @@ nsAreaFrame::GetFrameType(nsIAtom** aType) const
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsAreaFrame::DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus)
{
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
// If we should position our view, and we have child frames that stick
// outside our box, then we need to size our view large enough to include
// those child frames
if ((mState & NS_FRAME_SYNC_FRAME_AND_VIEW) &&
(mState & NS_FRAME_OUTSIDE_CHILDREN)) {
nsIView* view;
const nsStyleDisplay* display = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
GetView(&aPresContext, &view);
if (view && (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow)) {
// Don't let our base class position the view since we're doing it
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
// Set the view's bit that indicates that it has transparent content
nsIViewManager* vm;
view->GetViewManager(vm);
vm->SetViewContentTransparency(view, PR_TRUE);
// Position and size view relative to its parent, not relative to our
// parent frame (our parent frame may not have a view).
nsIView* parentWithView;
nsPoint origin;
// XXX We need to handle the case where child frames stick out on the
// left and top edges as well...
GetOffsetFromView(&aPresContext, origin, &parentWithView);
vm->ResizeView(view, mCombinedArea.XMost(), mCombinedArea.YMost());
vm->MoveViewTo(view, origin.x, origin.y);
NS_RELEASE(vm);
// Call our base class
nsresult rv = nsBlockFrame::DidReflow(aPresContext, aStatus);
// Set the flag again...
mState |= NS_FRAME_SYNC_FRAME_AND_VIEW;
return rv;
}
}
}
return nsBlockFrame::DidReflow(aPresContext, aStatus);
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Diagnostics // Diagnostics

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

@ -82,9 +82,6 @@ public:
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus); nsReflowStatus& aStatus);
NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus);
/** /**
* Get the "type" of the frame * Get the "type" of the frame
* *

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

@ -2809,6 +2809,20 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
return NS_OK; return NS_OK;
} }
static void
PlaceFrameView(nsIPresContext* aPresContext,
nsIFrame* aFrame)
{
nsIView* view;
aFrame->GetView(aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aFrame, view, nsnull);
} else {
nsContainerFrame::PositionChildViews(aPresContext, aFrame);
}
}
void void
nsBlockFrame::SlideLine(nsBlockReflowState& aState, nsBlockFrame::SlideLine(nsBlockReflowState& aState,
nsLineBox* aLine, nscoord aDY) nsLineBox* aLine, nscoord aDY)
@ -2830,6 +2844,9 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
// If the child has any floaters that impact the space-manager, // If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager // place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when // again (they were removed by the space-manager's frame when
@ -2851,16 +2868,21 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
} }
} }
else { else {
if (aDY) { // Adjust the Y coordinate of the frames in the line.
// Adjust the Y coordinate of the frames in the line // Note: we need to re-position views even if aDY is 0, because
// one of our parent frames may have moved and so the view's position
// relative to its parent may have changed
nsRect r; nsRect r;
PRInt32 n = aLine->GetChildCount(); PRInt32 n = aLine->GetChildCount();
while (--n >= 0) { while (--n >= 0) {
if (aDY) {
kid->GetRect(r); kid->GetRect(r);
r.y += aDY; r.y += aDY;
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
kid->GetNextSibling(&kid);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
kid->GetNextSibling(&kid);
} }
} }
} }
@ -4161,6 +4183,16 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
nsLineBox* aLine, nsLineBox* aLine,
const nsSize& aMaxElementSize) const nsSize& aMaxElementSize)
{ {
// If it's inline elements, then make sure the views are correctly
// positioned and sized
if (aLine->IsInline()) {
nsIFrame* frame = aLine->mFirstChild;
for (PRInt32 i = 0; i < aLine->GetChildCount(); i++) {
::PlaceFrameView(aState.mPresContext, frame);
frame->GetNextSibling(&frame);
}
}
// Update max-element-size // Update max-element-size
if (aState.mComputeMaxElementSize) { if (aState.mComputeMaxElementSize) {
aState.UpdateMaxElementSize(aMaxElementSize); aState.UpdateMaxElementSize(aMaxElementSize);
@ -6087,7 +6119,6 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
nsReflowStatus status; nsReflowStatus status;
mBullet->WillReflow(*aState.mPresContext); mBullet->WillReflow(*aState.mPresContext);
mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status); mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status);
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
// Place the bullet now; use its right margin to distance it // Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line // from the rest of the frames in the line
@ -6098,6 +6129,7 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
const nsMargin& bp = aState.BorderPadding(); const nsMargin& bp = aState.BorderPadding();
nscoord y = bp.top; nscoord y = bp.top;
mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height)); mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height));
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
} }
//XXX get rid of this -- its slow //XXX get rid of this -- its slow

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

@ -226,6 +226,14 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
// Let frame know that we are reflowing it // Let frame know that we are reflowing it
aFrame->WillReflow(*mPresContext); aFrame->WillReflow(*mPresContext);
// Position it and its view (if it has one)
aFrame->MoveTo(mPresContext, mX, mY);
nsIView* view;
aFrame->GetView(mPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(mPresContext, aFrame, view);
}
#ifdef DEBUG #ifdef DEBUG
mMetrics.width = nscoord(0xdeadbeef); mMetrics.width = nscoord(0xdeadbeef);
mMetrics.height = nscoord(0xdeadbeef); mMetrics.height = nscoord(0xdeadbeef);
@ -417,7 +425,9 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
// Empty blocks do not have anything special done to them and they // Empty blocks do not have anything special done to them and they
// always fit. Note: don't force the width to 0 // always fit. Note: don't force the width to 0
nsRect r(x, y, mMetrics.width, 0); nsRect r(x, y, mMetrics.width, 0);
mFrame->SetRect(mPresContext, r);
// Now place the frame and complete the reflow process
nsContainerFrame::FinishReflowChild(mFrame, *mPresContext, mMetrics, x, y, 0);
aInFlowBounds = r; aInFlowBounds = r;
// Retain combined area information in case we contain a floater // Retain combined area information in case we contain a floater
@ -544,8 +554,8 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
aCombinedRect.width = mMetrics.mCombinedArea.width; aCombinedRect.width = mMetrics.mCombinedArea.width;
aCombinedRect.height = mMetrics.mCombinedArea.height; aCombinedRect.height = mMetrics.mCombinedArea.height;
// Now place the frame // Now place the frame and complete the reflow process
mFrame->SetRect(mPresContext, nsRect(x, y, mMetrics.width, mMetrics.height)); nsContainerFrame::FinishReflowChild(mFrame, *mPresContext, mMetrics, x, y, 0);
// XXX obsolete, i believe... // XXX obsolete, i believe...
#if 0 #if 0
@ -591,6 +601,9 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
} }
} }
else { else {
// Send the DidReflow() notification, but don't bother placing
// the frame
mFrame->DidReflow(*mPresContext, NS_FRAME_REFLOW_FINISHED);
fits = PR_FALSE; fits = PR_FALSE;
} }
} }

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

@ -2809,6 +2809,20 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
return NS_OK; return NS_OK;
} }
static void
PlaceFrameView(nsIPresContext* aPresContext,
nsIFrame* aFrame)
{
nsIView* view;
aFrame->GetView(aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aFrame, view, nsnull);
} else {
nsContainerFrame::PositionChildViews(aPresContext, aFrame);
}
}
void void
nsBlockFrame::SlideLine(nsBlockReflowState& aState, nsBlockFrame::SlideLine(nsBlockReflowState& aState,
nsLineBox* aLine, nscoord aDY) nsLineBox* aLine, nscoord aDY)
@ -2830,6 +2844,9 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
// If the child has any floaters that impact the space-manager, // If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager // place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when // again (they were removed by the space-manager's frame when
@ -2851,16 +2868,21 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
} }
} }
else { else {
if (aDY) { // Adjust the Y coordinate of the frames in the line.
// Adjust the Y coordinate of the frames in the line // Note: we need to re-position views even if aDY is 0, because
// one of our parent frames may have moved and so the view's position
// relative to its parent may have changed
nsRect r; nsRect r;
PRInt32 n = aLine->GetChildCount(); PRInt32 n = aLine->GetChildCount();
while (--n >= 0) { while (--n >= 0) {
if (aDY) {
kid->GetRect(r); kid->GetRect(r);
r.y += aDY; r.y += aDY;
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
kid->GetNextSibling(&kid);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
kid->GetNextSibling(&kid);
} }
} }
} }
@ -4161,6 +4183,16 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
nsLineBox* aLine, nsLineBox* aLine,
const nsSize& aMaxElementSize) const nsSize& aMaxElementSize)
{ {
// If it's inline elements, then make sure the views are correctly
// positioned and sized
if (aLine->IsInline()) {
nsIFrame* frame = aLine->mFirstChild;
for (PRInt32 i = 0; i < aLine->GetChildCount(); i++) {
::PlaceFrameView(aState.mPresContext, frame);
frame->GetNextSibling(&frame);
}
}
// Update max-element-size // Update max-element-size
if (aState.mComputeMaxElementSize) { if (aState.mComputeMaxElementSize) {
aState.UpdateMaxElementSize(aMaxElementSize); aState.UpdateMaxElementSize(aMaxElementSize);
@ -6087,7 +6119,6 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
nsReflowStatus status; nsReflowStatus status;
mBullet->WillReflow(*aState.mPresContext); mBullet->WillReflow(*aState.mPresContext);
mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status); mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status);
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
// Place the bullet now; use its right margin to distance it // Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line // from the rest of the frames in the line
@ -6098,6 +6129,7 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
const nsMargin& bp = aState.BorderPadding(); const nsMargin& bp = aState.BorderPadding();
nscoord y = bp.top; nscoord y = bp.top;
mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height)); mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height));
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
} }
//XXX get rid of this -- its slow //XXX get rid of this -- its slow

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

@ -2809,6 +2809,20 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
return NS_OK; return NS_OK;
} }
static void
PlaceFrameView(nsIPresContext* aPresContext,
nsIFrame* aFrame)
{
nsIView* view;
aFrame->GetView(aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aFrame, view, nsnull);
} else {
nsContainerFrame::PositionChildViews(aPresContext, aFrame);
}
}
void void
nsBlockFrame::SlideLine(nsBlockReflowState& aState, nsBlockFrame::SlideLine(nsBlockReflowState& aState,
nsLineBox* aLine, nscoord aDY) nsLineBox* aLine, nscoord aDY)
@ -2830,6 +2844,9 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
// If the child has any floaters that impact the space-manager, // If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager // place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when // again (they were removed by the space-manager's frame when
@ -2851,16 +2868,21 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
} }
} }
else { else {
if (aDY) { // Adjust the Y coordinate of the frames in the line.
// Adjust the Y coordinate of the frames in the line // Note: we need to re-position views even if aDY is 0, because
// one of our parent frames may have moved and so the view's position
// relative to its parent may have changed
nsRect r; nsRect r;
PRInt32 n = aLine->GetChildCount(); PRInt32 n = aLine->GetChildCount();
while (--n >= 0) { while (--n >= 0) {
if (aDY) {
kid->GetRect(r); kid->GetRect(r);
r.y += aDY; r.y += aDY;
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
kid->GetNextSibling(&kid);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
kid->GetNextSibling(&kid);
} }
} }
} }
@ -4161,6 +4183,16 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
nsLineBox* aLine, nsLineBox* aLine,
const nsSize& aMaxElementSize) const nsSize& aMaxElementSize)
{ {
// If it's inline elements, then make sure the views are correctly
// positioned and sized
if (aLine->IsInline()) {
nsIFrame* frame = aLine->mFirstChild;
for (PRInt32 i = 0; i < aLine->GetChildCount(); i++) {
::PlaceFrameView(aState.mPresContext, frame);
frame->GetNextSibling(&frame);
}
}
// Update max-element-size // Update max-element-size
if (aState.mComputeMaxElementSize) { if (aState.mComputeMaxElementSize) {
aState.UpdateMaxElementSize(aMaxElementSize); aState.UpdateMaxElementSize(aMaxElementSize);
@ -6087,7 +6119,6 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
nsReflowStatus status; nsReflowStatus status;
mBullet->WillReflow(*aState.mPresContext); mBullet->WillReflow(*aState.mPresContext);
mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status); mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status);
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
// Place the bullet now; use its right margin to distance it // Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line // from the rest of the frames in the line
@ -6098,6 +6129,7 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
const nsMargin& bp = aState.BorderPadding(); const nsMargin& bp = aState.BorderPadding();
nscoord y = bp.top; nscoord y = bp.top;
mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height)); mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height));
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
} }
//XXX get rid of this -- its slow //XXX get rid of this -- its slow

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

@ -39,6 +39,7 @@
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsLayoutAtoms.h" #include "nsLayoutAtoms.h"
#include "nsIViewManager.h"
#ifdef NS_DEBUG #ifdef NS_DEBUG
#undef NOISY #undef NOISY
@ -107,6 +108,8 @@ nsContainerFrame::DidReflow(nsIPresContext& aPresContext,
// the NS_FRAME_IN_REFLOW bit // the NS_FRAME_IN_REFLOW bit
nsresult result = nsFrame::DidReflow(aPresContext, aStatus); nsresult result = nsFrame::DidReflow(aPresContext, aStatus);
// XXX TROY
#if 0
if (NS_FRAME_REFLOW_FINISHED == aStatus) { if (NS_FRAME_REFLOW_FINISHED == aStatus) {
// Apply DidReflow to each and every list that this frame implements // Apply DidReflow to each and every list that this frame implements
nsIAtom* listName = nsnull; nsIAtom* listName = nsnull;
@ -122,6 +125,7 @@ nsContainerFrame::DidReflow(nsIPresContext& aPresContext,
GetAdditionalChildListName(listIndex++, &listName); GetAdditionalChildListName(listIndex++, &listName);
} while(nsnull != listName); } while(nsnull != listName);
} }
#endif
NS_FRAME_TRACE_OUT("nsContainerFrame::DidReflow"); NS_FRAME_TRACE_OUT("nsContainerFrame::DidReflow");
return result; return result;
@ -372,17 +376,194 @@ nsContainerFrame::ReplaceFrame(nsIPresContext& aPresContext,
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Helper member functions // Helper member functions
void
nsContainerFrame::PositionFrameView(nsIPresContext* aPresContext,
nsIFrame* aKidFrame,
nsIView* aView)
{
if (aView) {
// Position view relative to its parent, not relative to aKidFrame's
// frame which may not have a view
nsIView* containingView;
nsPoint origin;
nsIView* parentView;
aView->GetParent(parentView);
aKidFrame->GetOffsetFromView(aPresContext, origin, &containingView);
if (containingView == parentView) {
nsIViewManager *vm;
aView->GetViewManager(vm);
vm->MoveViewTo(aView, origin.x, origin.y);
NS_RELEASE(vm);
}
}
}
void
nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIView* aView,
nsRect* aCombinedArea,
PRUint32 aFlags)
{
if (aView) {
nsIViewManager *vm;
nsFrameState kidState;
nsSize frameSize;
aView->GetViewManager(vm);
aFrame->GetFrameState(&kidState);
aFrame->GetSize(frameSize);
// Make sure the view is sized and positioned correctly
if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW)) {
nsIView* containingView;
nsPoint origin;
nsIView* parentView;
aView->GetParent(parentView);
aFrame->GetOffsetFromView(aPresContext, origin, &containingView);
if (containingView == parentView) {
vm->MoveViewTo(aView, origin.x, origin.y);
}
}
if (0 == (aFlags & NS_FRAME_NO_SIZE_VIEW)) {
// If the frame has child frames that stick outside the content
// area, then size the view large enough to include those child
// frames
if ((kidState & NS_FRAME_OUTSIDE_CHILDREN) && aCombinedArea) {
vm->ResizeView(aView, aCombinedArea->XMost(), aCombinedArea->YMost());
} else {
vm->ResizeView(aView, frameSize.width, frameSize.height);
}
}
const nsStyleColor* color;
const nsStyleDisplay* display;
aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&)color);
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display);
// Set the view's opacity
vm->SetViewOpacity(aView, color->mOpacity);
// See if the view should be hidden or visible
PRBool viewIsVisible = PR_TRUE;
PRBool viewHasTransparentContent = (color->mBackgroundFlags &
NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT;
if (NS_STYLE_VISIBILITY_COLLAPSE == display->mVisible) {
viewIsVisible = PR_FALSE;
}
else if (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible) {
// If it has a widget, hide the view because the widget can't deal with it
nsIWidget* widget = nsnull;
aView->GetWidget(widget);
if (widget) {
viewIsVisible = PR_FALSE;
NS_RELEASE(widget);
}
else {
// If it's a scroll frame, then hide the view. This means that
// child elements can't override their parent's visibility, but
// it's not practical to leave it visible in all cases because
// the scrollbars will be showing
nsIAtom* frameType;
aFrame->GetFrameType(&frameType);
if (frameType == nsLayoutAtoms::scrollFrame) {
viewIsVisible = PR_FALSE;
} else {
// If we're a container element, then leave the view visible, but
// mark it as having transparent content. The reason we need to
// do this is that child elements can override their parent's
// hidden visibility and be visible anyway
nsIFrame* firstChild;
aFrame->FirstChild(nsnull, &firstChild);
if (firstChild) {
// Not a left frame, so the view needs to be visible, but marked
// as having transparent content
viewHasTransparentContent = PR_TRUE;
} else {
// Leaf frame so go ahead and hide the view
viewIsVisible = PR_FALSE;
}
}
NS_IF_RELEASE(frameType);
}
}
// If the frame has visible content that overflows the content area, then we
// need the view marked as having transparent content
if (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow) {
if (kidState & NS_FRAME_OUTSIDE_CHILDREN) {
viewHasTransparentContent = PR_TRUE;
}
}
// Make sure visibility is correct
vm->SetViewVisibility(aView, viewIsVisible ? nsViewVisibility_kShow :
nsViewVisibility_kHide);
// Make sure content transparency is correct
if (viewIsVisible) {
vm->SetViewContentTransparency(aView, viewHasTransparentContent);
}
// Clip applies to block-level and replaced elements with overflow
// set to other than 'visible'
if (display->IsBlockLevel()) {
if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) {
nscoord left, top, right, bottom;
// Start with the 'auto' values and then factor in user
// specified values
left = top = 0;
right = frameSize.width;
bottom = frameSize.height;
if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) {
top += display->mClip.top;
}
if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) {
right -= display->mClip.right;
}
if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) {
bottom -= display->mClip.bottom;
}
if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) {
left += display->mClip.left;
}
aView->SetClip(left, top, right, bottom);
} else {
// Make sure no clip is set
aView->SetClip(0, 0, 0, 0);
}
}
NS_RELEASE(vm);
}
}
/** /**
* Queries the child frame for the nsIHTMLReflow interface and if it's * Invokes the WillReflow() function, positions the frame and its view (if
* supported invokes the WillReflow() and Reflow() member functions. If * requested), and then calls Reflow(). If the reflow succeeds and the child
* the reflow succeeds and the child frame is complete, deletes any * frame is complete, deletes any next-in-flows using DeleteChildsNextInFlow()
* next-in-flows using DeleteChildsNextInFlow()
*/ */
nsresult nsresult
nsContainerFrame::ReflowChild(nsIFrame* aKidFrame, nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext, nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nscoord aX,
nscoord aY,
PRUint32 aFlags,
nsReflowStatus& aStatus) nsReflowStatus& aStatus)
{ {
NS_PRECONDITION(aReflowState.frame == aKidFrame, "bad reflow state"); NS_PRECONDITION(aReflowState.frame == aKidFrame, "bad reflow state");
@ -399,8 +580,23 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
#endif #endif
#endif #endif
// Send the WillReflow notification, and reflow the child frame // Send the WillReflow() notification, and position the child frame
// and its view if requested
aKidFrame->WillReflow(aPresContext); aKidFrame->WillReflow(aPresContext);
if (0 == (aFlags & NS_FRAME_NO_MOVE_FRAME)) {
aKidFrame->MoveTo(&aPresContext, aX, aY);
}
if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW)) {
nsIView* view;
aKidFrame->GetView(&aPresContext, &view);
if (view) {
PositionFrameView(&aPresContext, aKidFrame, view);
}
}
// Reflow the child frame
result = aKidFrame->Reflow(aPresContext, aDesiredSize, aReflowState, result = aKidFrame->Reflow(aPresContext, aDesiredSize, aReflowState,
aStatus); aStatus);
@ -441,6 +637,97 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
return result; return result;
} }
void
nsContainerFrame::PositionChildViews(nsIPresContext* aPresContext,
nsIFrame* aFrame)
{
nsIAtom* childListName = nsnull;
PRInt32 childListIndex = 0;
do {
// Recursively walk aFrame's child frames
nsIFrame* childFrame;
aFrame->FirstChild(childListName, &childFrame);
while (childFrame) {
nsIView* view;
// See if the child frame has a view
childFrame->GetView(aPresContext, &view);
if (view) {
// Position the view. Because any child views are relative to their
// parent, there's no need to recurse
PositionFrameView(aPresContext, childFrame, view);
} else {
// Recursively examine its child frames
PositionChildViews(aPresContext, childFrame);
}
// Get the next sibling child frame
childFrame->GetNextSibling(&childFrame);
}
NS_IF_RELEASE(childListName);
aFrame->GetAdditionalChildListName(childListIndex++, &childListName);
} while (childListName);
}
/**
* The second half of frame reflow. Does the following:
* - sets the frame's bounds
* - sizes and positions (if requested) the frame's view. If the frame's final
* position differs from the current position and the frame itself does not
* have a view, then any child frames with views are positioned so they stay
* in sync
* - sets the view's visibility, opacity, content transparency, and clip
* - invoked the DidReflow() function
*
* Flags:
* NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this
* case. Also implies NS_FRAME_NO_MOVE_VIEW
* NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
* don't want to automatically sync the frame and view
* NS_FRAME_NO_SIZE_VIEW - don't size the frame's view
* NS_FRAME_NO_MOVE_CHILD_VIEWS - don't move child views. This is for the case
* where the frame's new position differs from its current position and the
* frame itself doesn't have a view, so moving the frame would cause any child
* views to be out of sync
*/
nsresult
nsContainerFrame::FinishReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
PRUint32 aFlags)
{
nsPoint curOrigin;
nsRect bounds(aX, aY, aDesiredSize.width, aDesiredSize.height);
aKidFrame->GetOrigin(curOrigin);
aKidFrame->SetRect(&aPresContext, bounds);
nsIView* view;
aKidFrame->GetView(&aPresContext, &view);
if (view) {
// Make sure the frame's view is properly sized and positioned and has
// things like opacity correct
SyncFrameViewAfterReflow(&aPresContext, aKidFrame, view,
&aDesiredSize.mCombinedArea,
aFlags);
} else if (0 == (aFlags & NS_FRAME_NO_MOVE_CHILD_VIEWS)) {
// If the frame has moved, then we need to make sure any child views are
// correctly positioned
if ((curOrigin.x != aX) || (curOrigin.y != aY)) {
PositionChildViews(&aPresContext, aKidFrame);
}
}
return aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
}
/** /**
* Remove and delete aChild's next-in-flow(s). Updates the sibling and flow * Remove and delete aChild's next-in-flow(s). Updates the sibling and flow
* pointers * pointers

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

@ -25,6 +25,13 @@
#include "nsSplittableFrame.h" #include "nsSplittableFrame.h"
#include "nsFrameList.h" #include "nsFrameList.h"
// Option flags for ReflowChild() and FinishReflowChild()
// member functions
#define NS_FRAME_NO_MOVE_VIEW 0x0001
#define NS_FRAME_NO_MOVE_FRAME (0x0002 | NS_FRAME_NO_MOVE_VIEW)
#define NS_FRAME_NO_SIZE_VIEW 0x0004
#define NS_FRAME_NO_MOVE_CHILD_VIEWS 0x0008
/** /**
* Implementation of a container frame. * Implementation of a container frame.
*/ */
@ -67,6 +74,82 @@ public:
return tmp.GetLength(); return tmp.GetLength();
} }
// Positions the frame's view based on the frame's origin
static void PositionFrameView(nsIPresContext* aPresContext,
nsIFrame* aKidFrame,
nsIView* aView);
// Sets several view attributes:
// - if requested sizes the frame's view based on the current size and origin.
// Takes into account the combined area and (if overflow is visible) whether
// the frame has children that extend outside
// - opacity
// - visibility
// - content transparency
// - clip
//
// Flags:
// NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
// don't want to automatically sync the frame and view
// NS_FRAME_NO_MOVE_VIEW - don't move the frame. aX and aY are ignored in this
// case. Also implies NS_FRAME_NO_MOVE_VIEW
static void SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIView* aView,
nsRect* aCombinedArea,
PRUint32 aFlags = 0);
/**
* Invokes the WillReflow() function, positions the frame and its view (if
* requested), and then calls Reflow(). If the reflow succeeds and the child
* frame is complete, deletes any next-in-flows using DeleteChildsNextInFlow()
*
* Flags:
* NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
* don't want to automatically sync the frame and view
* NS_FRAME_NO_MOVE_VIEW - don't move the frame. aX and aY are ignored in this
* case. Also implies NS_FRAME_NO_MOVE_VIEW
*/
nsresult ReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nscoord aX,
nscoord aY,
PRUint32 aFlags,
nsReflowStatus& aStatus);
/**
* The second half of frame reflow. Does the following:
* - sets the frame's bounds
* - sizes and positions (if requested) the frame's view. If the frame's final
* position differs from the current position and the frame itself does not
* have a view, then any child frames with views are positioned so they stay
* in sync
* - sets the view's visibility, opacity, content transparency, and clip
* - invoked the DidReflow() function
*
* Flags:
* NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this
* case. Also implies NS_FRAME_NO_MOVE_VIEW
* NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
* don't want to automatically sync the frame and view
* NS_FRAME_NO_SIZE_VIEW - don't size the frame's view
* NS_FRAME_NO_MOVE_CHILD_VIEWS - don't move child views. This is for the case
* where the frame's new position differs from its current position and the
* frame itself doesn't have a view, so moving the frame would cause any child
* views to be out of sync
*/
static nsresult FinishReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
PRUint32 aFlags);
static void PositionChildViews(nsIPresContext* aPresContext,
nsIFrame* aFrame);
protected: protected:
nsContainerFrame(); nsContainerFrame();
~nsContainerFrame(); ~nsContainerFrame();
@ -87,18 +170,6 @@ protected:
nsIFrame* aFrame, nsIFrame* aFrame,
nsFramePaintLayer aWhichLayer); nsFramePaintLayer aWhichLayer);
/**
* Queries the child frame for the nsIHTMLReflow interface and if it's
* supported invokes the WillReflow() and Reflow() member functions. If
* the reflow succeeds and the child frame is complete, deletes any
* next-in-flows using DeleteChildsNextInFlow()
*/
nsresult ReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** /**
* Get the frames on the overflow list * Get the frames on the overflow list
*/ */

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

@ -247,6 +247,7 @@ nsFirstLetterFrame::Reflow(nsIPresContext& aPresContext,
// Place and size the child and update the output metrics // Place and size the child and update the output metrics
kid->MoveTo(&aPresContext, bp.left, bp.top); kid->MoveTo(&aPresContext, bp.left, bp.top);
kid->SizeTo(&aPresContext, aMetrics.width, aMetrics.height); kid->SizeTo(&aPresContext, aMetrics.width, aMetrics.height);
kid->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
aMetrics.width += lr; aMetrics.width += lr;
aMetrics.height += tb; aMetrics.height += tb;
aMetrics.ascent += bp.top; aMetrics.ascent += bp.top;

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

@ -507,6 +507,8 @@ NS_IMETHODIMP nsFrame::MoveTo(nsIPresContext* aPresContext, nscoord aX, nscoord
mRect.x = aX; mRect.x = aX;
mRect.y = aY; mRect.y = aY;
// XXX TROY
#if 0
nsIView* view; nsIView* view;
GetView(aPresContext, &view); GetView(aPresContext, &view);
if (view) { if (view) {
@ -526,6 +528,7 @@ NS_IMETHODIMP nsFrame::MoveTo(nsIPresContext* aPresContext, nscoord aX, nscoord
NS_RELEASE(vm); NS_RELEASE(vm);
} }
} }
#endif
return NS_OK; return NS_OK;
} }
@ -535,6 +538,8 @@ NS_IMETHODIMP nsFrame::SizeTo(nsIPresContext* aPresContext, nscoord aWidth, nsco
mRect.width = aWidth; mRect.width = aWidth;
mRect.height = aHeight; mRect.height = aHeight;
// XXX TROY
#if 0
// Let the view know // Let the view know
nsIView* view; nsIView* view;
GetView(aPresContext, &view); GetView(aPresContext, &view);
@ -551,6 +556,7 @@ NS_IMETHODIMP nsFrame::SizeTo(nsIPresContext* aPresContext, nscoord aWidth, nsco
NS_RELEASE(vm); NS_RELEASE(vm);
} }
} }
#endif
return NS_OK; return NS_OK;
} }
@ -1266,6 +1272,8 @@ nsFrame::DidReflow(nsIPresContext& aPresContext,
if (NS_FRAME_REFLOW_FINISHED == aStatus) { if (NS_FRAME_REFLOW_FINISHED == aStatus) {
mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY); mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY);
// XXX TROY
#if 0
// Make sure the view is sized and positioned correctly and it's // Make sure the view is sized and positioned correctly and it's
// visibility, opacity, content transparency, and clip are correct // visibility, opacity, content transparency, and clip are correct
nsIView* view; nsIView* view;
@ -1390,6 +1398,7 @@ nsFrame::DidReflow(nsIPresContext& aPresContext,
} }
NS_RELEASE(vm); NS_RELEASE(vm);
} }
#endif
} }
return NS_OK; return NS_OK;
} }

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

@ -360,12 +360,12 @@ nsHTMLFrameOuterFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics kidMetrics(aDesiredSize.maxElementSize); nsHTMLReflowMetrics kidMetrics(aDesiredSize.maxElementSize);
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstChild, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstChild,
innerSize); innerSize);
ReflowChild(firstChild, aPresContext, kidMetrics, kidReflowState, aStatus); ReflowChild(firstChild, aPresContext, kidMetrics, kidReflowState,
offset.x, offset.y, 0, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
// Place and size the child // Place and size the child
nsRect rect(offset.x, offset.y, innerSize.width, innerSize.height); FinishReflowChild(firstChild, aPresContext, kidMetrics, offset.x, offset.y, 0);
firstChild->SetRect(&aPresContext, rect);
// XXX what should the max-element-size of an iframe be? Shouldn't // XXX what should the max-element-size of an iframe be? Shouldn't
// iframe's normally shrink wrap around their content when they // iframe's normally shrink wrap around their content when they

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

@ -234,6 +234,9 @@ nsresult nsHTMLFramesetFrame::QueryInterface(const nsIID& aIID,
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr); return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
} }
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLFramesetFrame::Init(nsIPresContext& aPresContext, nsHTMLFramesetFrame::Init(nsIPresContext& aPresContext,
nsIContent* aContent, nsIContent* aContent,
@ -258,6 +261,25 @@ nsHTMLFramesetFrame::Init(nsIPresContext& aPresContext,
break; break;
} }
} }
// create the view. a view is needed since it needs to be a mouse grabber
nsIView* view;
nsresult result = nsComponentManager::CreateInstance(kViewCID, nsnull, kIViewIID,
(void **)&view);
nsCOMPtr<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
nsCOMPtr<nsIViewManager> viewMan;
presShell->GetViewManager(getter_AddRefs(viewMan));
nsIFrame* parWithView;
nsIView *parView;
GetParentWithView(&aPresContext, &parWithView);
parWithView->GetView(&aPresContext, &parView);
nsRect boundBox(0, 0, 0, 0);
result = view->Init(viewMan, boundBox, parView, nsnull);
viewMan->InsertChild(parView, view, 0);
SetView(&aPresContext, view);
return rv; return rv;
} }
@ -785,13 +807,14 @@ nsHTMLFramesetFrame::ReflowPlaceChild(nsIFrame* aChild,
metrics.height= aSize.height; metrics.height= aSize.height;
nsReflowStatus status; nsReflowStatus status;
ReflowChild(aChild, aPresContext, metrics, reflowState, status); ReflowChild(aChild, aPresContext, metrics, reflowState, aOffset.x,
aOffset.y, 0, status);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status");
// Place and size the child // Place and size the child
nsRect rect(aOffset.x, aOffset.y, aSize.width, aSize.height); metrics.width = aSize.width;
aChild->SetRect(&aPresContext, rect); metrics.height = aSize.height;
aChild->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED); // this call is needed FinishReflowChild(aChild, aPresContext, metrics, aOffset.x, aOffset.y, 0);
} }
static static
@ -902,10 +925,6 @@ nscolor nsHTMLFramesetFrame::GetBorderColor(nsIContent* aContent)
#define FRAME 1 #define FRAME 1
#define BLANK 2 #define BLANK 2
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLFramesetFrame::Reflow(nsIPresContext& aPresContext, nsHTMLFramesetFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
@ -918,25 +937,6 @@ nsHTMLFramesetFrame::Reflow(nsIPresContext& aPresContext,
PRBool firstTime = (0 == mNumRows); PRBool firstTime = (0 == mNumRows);
if (firstTime) { if (firstTime) {
// create the view. a view is needed since it needs to be a mouse grabber
nsIView* view;
nsresult result = nsComponentManager::CreateInstance(kViewCID, nsnull, kIViewIID,
(void **)&view);
nsCOMPtr<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
nsCOMPtr<nsIViewManager> viewMan;
presShell->GetViewManager(getter_AddRefs(viewMan));
nsIFrame* parWithView;
nsIView *parView;
GetParentWithView(&aPresContext, &parWithView);
parWithView->GetView(&aPresContext, &parView);
nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height);
result = view->Init(viewMan, boundBox, parView, nsnull);
viewMan->InsertChild(parView, view, 0);
SetView(&aPresContext, view);
// parse the rows= cols= data // parse the rows= cols= data
ParseRowCol(nsHTMLAtoms::rows, mNumRows, &mRowSpecs); ParseRowCol(nsHTMLAtoms::rows, mNumRows, &mRowSpecs);
ParseRowCol(nsHTMLAtoms::cols, mNumCols, &mColSpecs); ParseRowCol(nsHTMLAtoms::cols, mNumCols, &mColSpecs);

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

@ -1206,7 +1206,8 @@ nsGfxScrollFrameInner::ReflowFrame( nsIPresContext& aPresContext,
childReflowState.mComputedHeight -= childReflowState.mComputedBorderPadding.top + childReflowState.mComputedBorderPadding.bottom; childReflowState.mComputedHeight -= childReflowState.mComputedBorderPadding.top + childReflowState.mComputedBorderPadding.bottom;
*/ */
mOuter->ReflowChild(aFrame, aPresContext, aDesiredSize, childReflowState, aStatus); mOuter->ReflowChild(aFrame, aPresContext, aDesiredSize, childReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
// if the frame size change then mark the flag // if the frame size change then mark the flag
@ -1214,6 +1215,7 @@ nsGfxScrollFrameInner::ReflowFrame( nsIPresContext& aPresContext,
aFrame->SizeTo(&aPresContext, aDesiredSize.width, aDesiredSize.height); aFrame->SizeTo(&aPresContext, aDesiredSize.width, aDesiredSize.height);
aResized = PR_TRUE; aResized = PR_TRUE;
} }
aFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// add the margin back in // add the margin back in
aDesiredSize.width += margin.left + margin.right; aDesiredSize.width += margin.left + margin.right;
@ -1467,13 +1469,29 @@ nsGfxScrollFrameInner::LayoutChildren(nsIPresContext& aPresContext,
const nsMargin& border = aReflowState.mComputedBorderPadding; const nsMargin& border = aReflowState.mComputedBorderPadding;
// Place scroll area // Place scroll area
nsIView* view;
mScrollAreaFrame->MoveTo(&aPresContext, border.left, border.top); mScrollAreaFrame->MoveTo(&aPresContext, border.left, border.top);
mScrollAreaFrame->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, mScrollAreaFrame,
view, nsnull);
}
// place vertical scrollbar // place vertical scrollbar
mVScrollbarFrame->MoveTo(&aPresContext, border.left + scrollAreaSize.width, border.top); mVScrollbarFrame->MoveTo(&aPresContext, border.left + scrollAreaSize.width, border.top);
mVScrollbarFrame->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, mVScrollbarFrame,
view, nsnull);
}
// place horizontal scrollbar // place horizontal scrollbar
mHScrollbarFrame->MoveTo(&aPresContext, border.left, border.top + scrollAreaSize.height); mHScrollbarFrame->MoveTo(&aPresContext, border.left, border.top + scrollAreaSize.height);
mHScrollbarFrame->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, mHScrollbarFrame,
view, nsnull);
}
// Compute our desired size // Compute our desired size
// ---------- compute width ----------- // ---------- compute width -----------

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

@ -324,7 +324,8 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
// Reflow the frame // Reflow the frame
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState, ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
aStatus); kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top,
0, aStatus);
// The document element's background should cover the entire canvas, so // The document element's background should cover the entire canvas, so
// take into account the combined area and any space taken up by // take into account the combined area and any space taken up by
@ -385,10 +386,10 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
} }
} }
// Position and size the child frame // Complete the reflow and position and size the child frame
nsRect rect(kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top, nsRect rect(kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top,
kidDesiredSize.width, kidDesiredSize.height); kidDesiredSize.width, kidDesiredSize.height);
kidFrame->SetRect(&aPresContext, rect); FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, rect.x, rect.y, 0);
// If the child frame was just inserted, then we're responsible for making sure // If the child frame was just inserted, then we're responsible for making sure
// it repaints // it repaints

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

@ -30,6 +30,7 @@
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
#include "nsHTMLIIDs.h" #include "nsHTMLIIDs.h"
#include "nsFrame.h" #include "nsFrame.h"
#include "nsContainerFrame.h"
static NS_DEFINE_IID(kIReflowCommandIID, NS_IREFLOWCOMMAND_IID); static NS_DEFINE_IID(kIReflowCommandIID, NS_IREFLOWCOMMAND_IID);
@ -133,8 +134,20 @@ NS_IMETHODIMP nsHTMLReflowCommand::Dispatch(nsIPresContext& aPresContext,
nsHTMLReflowState reflowState(aPresContext, root, *this, nsHTMLReflowState reflowState(aPresContext, root, *this,
&aRendContext, aMaxSize); &aRendContext, aMaxSize);
nsReflowStatus status; nsReflowStatus status;
nsIView* view;
root->WillReflow(aPresContext);
root->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(&aPresContext, root, view);
}
root->Reflow(aPresContext, aDesiredSize, reflowState, status); root->Reflow(aPresContext, aDesiredSize, reflowState, status);
root->SizeTo(&aPresContext, aDesiredSize.width, aDesiredSize.height);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, root, view,
nsnull);
}
root->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
return NS_OK; return NS_OK;

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

@ -32,6 +32,23 @@
#include "nsStyleCoord.h" #include "nsStyleCoord.h"
#include "nsHTMLReflowState.h" #include "nsHTMLReflowState.h"
/**
* New rules of reflow:
* 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order
* (no separate pass over the tree)
* 2. it's the parent frame's responsibility to size/position the child's view (not
* the child frame's responsibility as it is today) during reflow (and before
* sending the DidReflow() notification)
* 3. positioning of child frames (and their views) is done on the way down the tree,
* and sizing of child frames (and their views) on the way back up
* 4. if you move a frame (outside of the reflow process, or after reflowing it),
* then you must make sure that its view (or its child frame's views) are re-positioned
* as well. It's reasonable to not position the view until after all reflowing the
* entire line, for example, but the frame should still be positioned and sized (and
* the view sized) during the reflow (i.e., before sending the DidReflow() notification)
* 5. the view system handles moving of widgets, i.e., it's not our problem
*/
class nsIAtom; class nsIAtom;
class nsIContent; class nsIContent;
class nsIPresContext; class nsIPresContext;
@ -545,6 +562,9 @@ public:
* Bounding rect of the frame. The values are in twips, and the origin is * Bounding rect of the frame. The values are in twips, and the origin is
* relative to the upper-left of the geometric parent. The size includes the * relative to the upper-left of the geometric parent. The size includes the
* content area, borders, and padding. * content area, borders, and padding.
*
* Note: moving or sizing the frame does not affect the view's size or
* position.
*/ */
NS_IMETHOD GetRect(nsRect& aRect) const = 0; NS_IMETHOD GetRect(nsRect& aRect) const = 0;
NS_IMETHOD GetOrigin(nsPoint& aPoint) const = 0; NS_IMETHOD GetOrigin(nsPoint& aPoint) const = 0;

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

@ -35,6 +35,8 @@
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIHTMLDocument.h" #include "nsIHTMLDocument.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#ifdef DEBUG #ifdef DEBUG
#undef NOISY_HORIZONTAL_ALIGN #undef NOISY_HORIZONTAL_ALIGN
@ -918,7 +920,9 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
// new starting x,y coordinates for the frame. // new starting x,y coordinates for the frame.
ApplyLeftMargin(pfd, reflowState); ApplyLeftMargin(pfd, reflowState);
// Let frame know that are reflowing it // Let frame know that are reflowing it. Note that we don't bother
// positioning the frame yet, because we're probably going to end up
// moving it when we do the vertical alignment
nscoord x = pfd->mBounds.x; nscoord x = pfd->mBounds.x;
nscoord y = pfd->mBounds.y; nscoord y = pfd->mBounds.y;
@ -1072,14 +1076,21 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
pfd->mMaxElementSize = *metrics.maxElementSize; pfd->mMaxElementSize = *metrics.maxElementSize;
} }
// Now that frame has been reflowed at least one time make sure that // Size the frame and size its view (if it has one)
// the NS_FRAME_FIRST_REFLOW bit is cleared so that never give it an aFrame->SizeTo(&mPresContext, metrics.width, metrics.height);
// initial reflow reason again. nsIView* view;
if (eReflowReason_Initial == reason) { aFrame->GetView(&mPresContext, &view);
aFrame->GetFrameState(&state); if (view) {
aFrame->SetFrameState(state & ~NS_FRAME_FIRST_REFLOW); nsIViewManager *vm;
view->GetViewManager(vm);
vm->ResizeView(view, metrics.width, metrics.height);
NS_RELEASE(vm);
} }
// Tell the frame that we're done reflowing it
aFrame->DidReflow(mPresContext, NS_FRAME_REFLOW_FINISHED);
if (aMetrics) { if (aMetrics) {
*aMetrics = metrics; *aMetrics = metrics;
} }

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

@ -1037,10 +1037,8 @@ nsObjectFrame::HandleImage(nsIPresContext& aPresContext,
} }
} }
ReflowChild(child, aPresContext, kidDesiredSize, kidReflowState, status); ReflowChild(child, aPresContext, kidDesiredSize, kidReflowState, 0, 0, 0, status);
FinishReflowChild(child, aPresContext, kidDesiredSize, 0, 0, 0);
nsRect rect(0, 0, kidDesiredSize.width, kidDesiredSize.height);
child->SetRect(&aPresContext, rect);
aMetrics.width = kidDesiredSize.width; aMetrics.width = kidDesiredSize.width;
aMetrics.height = kidDesiredSize.height; aMetrics.height = kidDesiredSize.height;

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

@ -80,7 +80,7 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext& aPresContext,
kidReflowState.isTopOfPage = PR_TRUE; kidReflowState.isTopOfPage = PR_TRUE;
ReflowChild(mFrames.FirstChild(), aPresContext, aDesiredSize, ReflowChild(mFrames.FirstChild(), aPresContext, aDesiredSize,
kidReflowState, aStatus); kidReflowState, 0, 0, 0, aStatus);
// Place and size the child. Make sure the child is at least as // Place and size the child. Make sure the child is at least as
// tall as our max size (the containing window) // tall as our max size (the containing window)
@ -88,8 +88,8 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.height = aReflowState.availableHeight; aDesiredSize.height = aReflowState.availableHeight;
} }
nsRect rect(0, 0, aDesiredSize.width, aDesiredSize.height); FinishReflowChild(mFrames.FirstChild(), aPresContext, aDesiredSize,
mFrames.FirstChild()->SetRect(&aPresContext, rect); 0, 0, 0);
} else { } else {
// Do we have any children? // Do we have any children?
@ -122,7 +122,7 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext& aPresContext,
kidReflowState.isTopOfPage = PR_TRUE; kidReflowState.isTopOfPage = PR_TRUE;
// Get the child's desired size // Get the child's desired size
ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, aStatus); ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
// Make sure the child is at least as tall as our max size (the containing window) // Make sure the child is at least as tall as our max size (the containing window)
if (aDesiredSize.height < aReflowState.availableHeight) { if (aDesiredSize.height < aReflowState.availableHeight) {
@ -130,10 +130,7 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext& aPresContext,
} }
// Place and size the child // Place and size the child
nsRect rect(0, 0, aDesiredSize.width, aDesiredSize.height); FinishReflowChild(frame, aPresContext, aDesiredSize, 0, 0, 0);
frame->SetRect(&aPresContext, rect);
// XXX Should we be sending the DidReflow?
frame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// Is the frame complete? // Is the frame complete?
if (NS_FRAME_IS_COMPLETE(aStatus)) { if (NS_FRAME_IS_COMPLETE(aStatus)) {

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

@ -126,12 +126,11 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext& aPresConte
// Dispatch the reflow command to our child frame. Allow it to be as high // Dispatch the reflow command to our child frame. Allow it to be as high
// as it wants // as it wants
ReflowChild(nextFrame, aPresContext, kidSize, kidReflowState, status); ReflowChild(nextFrame, aPresContext, kidSize, kidReflowState, aX, aY, 0, status);
// Place and size the page. If the page is narrower than our max width, then // Place and size the page. If the page is narrower than our max width, then
// center it horizontally // center it horizontally
nsRect rect(aX, aY, kidSize.width, kidSize.height); FinishReflowChild(nextFrame, aPresContext, kidSize, aX, aY, 0);
nextFrame->SetRect(&aPresContext, rect);
aY += kidSize.height + PAGE_SPACING_TWIPS; aY += kidSize.height + PAGE_SPACING_TWIPS;
// Check if the page is complete... // Check if the page is complete...
@ -169,8 +168,9 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext& aPresConte
// Place and size the page. If the page is narrower than our // Place and size the page. If the page is narrower than our
// max width then center it horizontally // max width then center it horizontally
ReflowChild(kidFrame, aPresContext, childSize, childReflowState, ReflowChild(kidFrame, aPresContext, childSize, childReflowState,
status); aX, aY, 0, status);
kidFrame->SetRect(&aPresContext, nsRect(aX, aY, childSize.width, childSize.height));
FinishReflowChild(kidFrame, aPresContext, childSize, aX, aY, 0);
aY += childSize.height; aY += childSize.height;
// Leave a slight gap between the pages // Leave a slight gap between the pages
@ -242,8 +242,9 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext& aPresContext,
// Place and size the page. If the page is narrower than our // Place and size the page. If the page is narrower than our
// max width then center it horizontally // max width then center it horizontally
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, status); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, x, y, 0, status);
kidFrame->SetRect(&aPresContext, nsRect(x, y, kidSize.width, kidSize.height));
FinishReflowChild(kidFrame, aPresContext, kidSize, x, y, 0);
y += kidSize.height; y += kidSize.height;
// Leave a slight gap between the pages // Leave a slight gap between the pages

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

@ -332,8 +332,6 @@ ViewportFrame::ReflowFixedFrame(nsIPresContext& aPresContext,
// Reflow the frame // Reflow the frame
nsresult rv; nsresult rv;
aKidFrame->WillReflow(aPresContext);
nsHTMLReflowMetrics kidDesiredSize(nsnull); nsHTMLReflowMetrics kidDesiredSize(nsnull);
nsSize availSize(aReflowState.availableWidth, NS_UNCONSTRAINEDSIZE); nsSize availSize(aReflowState.availableWidth, NS_UNCONSTRAINEDSIZE);
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame,
@ -345,6 +343,18 @@ ViewportFrame::ReflowFixedFrame(nsIPresContext& aPresContext,
kidReflowState.reason = eReflowReason_Initial; kidReflowState.reason = eReflowReason_Initial;
} }
// Send the WillReflow() notification and position the frame
aKidFrame->WillReflow(aPresContext);
aKidFrame->MoveTo(&aPresContext,
kidReflowState.mComputedOffsets.left + kidReflowState.mComputedMargin.left,
kidReflowState.mComputedOffsets.top + kidReflowState.mComputedMargin.top);
// Position its view
nsIView* kidView;
aKidFrame->GetView(&aPresContext, &kidView);
nsContainerFrame::PositionFrameView(&aPresContext, aKidFrame, kidView);
// Do the reflow
rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus); rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus);
// XXX If the child had a fixed height, then make sure it respected it... // XXX If the child had a fixed height, then make sure it respected it...
@ -361,8 +371,12 @@ ViewportFrame::ReflowFixedFrame(nsIPresContext& aPresContext,
kidReflowState.mComputedOffsets.top + kidReflowState.mComputedMargin.top, kidReflowState.mComputedOffsets.top + kidReflowState.mComputedMargin.top,
kidDesiredSize.width, kidDesiredSize.height); kidDesiredSize.width, kidDesiredSize.height);
aKidFrame->SetRect(&aPresContext, rect); aKidFrame->SetRect(&aPresContext, rect);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, aKidFrame, kidView,
&kidDesiredSize.mCombinedArea);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
return rv; return rv;
} }
@ -509,15 +523,9 @@ ViewportFrame::Reflow(nsIPresContext& aPresContext,
// Reflow the frame // Reflow the frame
kidReflowState.mComputedHeight = aReflowState.availableHeight; kidReflowState.mComputedHeight = aReflowState.availableHeight;
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState, ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
aStatus); 0, 0, 0, aStatus);
nsRect rect(0, 0, kidDesiredSize.width, kidDesiredSize.height); FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, 0, 0, 0);
kidFrame->SetRect(&aPresContext, rect);
kidRect = rect;
// XXX We should resolve the details of who/when DidReflow()
// notifications are sent...
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
// If it's a 'initial', 'resize', or 'style change' reflow command (anything // If it's a 'initial', 'resize', or 'style change' reflow command (anything

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

@ -260,8 +260,6 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
NS_NOTYETIMPLEMENTED("percentage border"); NS_NOTYETIMPLEMENTED("percentage border");
} }
aKidFrame->WillReflow(aPresContext);
nsSize availSize(aReflowState.mComputedWidth, NS_UNCONSTRAINEDSIZE); nsSize availSize(aReflowState.mComputedWidth, NS_UNCONSTRAINEDSIZE);
nsHTMLReflowMetrics kidDesiredSize(nsnull); nsHTMLReflowMetrics kidDesiredSize(nsnull);
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame,
@ -274,6 +272,19 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
kidReflowState.reason = eReflowReason_Initial; kidReflowState.reason = eReflowReason_Initial;
} }
// XXX TROY
// Send the WillReflow() notification and position the frame
aKidFrame->WillReflow(aPresContext);
aKidFrame->MoveTo(&aPresContext,
border.left + kidReflowState.mComputedOffsets.left + kidReflowState.mComputedMargin.left,
border.top + kidReflowState.mComputedOffsets.top + kidReflowState.mComputedMargin.top);
// Position its view
nsIView* kidView;
aKidFrame->GetView(&aPresContext, &kidView);
nsContainerFrame::PositionFrameView(&aPresContext, aKidFrame, kidView);
// Do the reflow
rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus); rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus);
// Because we don't know the size of a replaced element until after we reflow // Because we don't know the size of a replaced element until after we reflow
@ -368,6 +379,11 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
kidDesiredSize.width, kidDesiredSize.height); kidDesiredSize.width, kidDesiredSize.height);
aKidFrame->SetRect(&aPresContext, rect); aKidFrame->SetRect(&aPresContext, rect);
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, aKidFrame, kidView,
&kidDesiredSize.mCombinedArea);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
return rv; return rv;
} }

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

@ -328,57 +328,6 @@ nsAreaFrame::GetFrameType(nsIAtom** aType) const
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsAreaFrame::DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus)
{
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
// If we should position our view, and we have child frames that stick
// outside our box, then we need to size our view large enough to include
// those child frames
if ((mState & NS_FRAME_SYNC_FRAME_AND_VIEW) &&
(mState & NS_FRAME_OUTSIDE_CHILDREN)) {
nsIView* view;
const nsStyleDisplay* display = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
GetView(&aPresContext, &view);
if (view && (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow)) {
// Don't let our base class position the view since we're doing it
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
// Set the view's bit that indicates that it has transparent content
nsIViewManager* vm;
view->GetViewManager(vm);
vm->SetViewContentTransparency(view, PR_TRUE);
// Position and size view relative to its parent, not relative to our
// parent frame (our parent frame may not have a view).
nsIView* parentWithView;
nsPoint origin;
// XXX We need to handle the case where child frames stick out on the
// left and top edges as well...
GetOffsetFromView(&aPresContext, origin, &parentWithView);
vm->ResizeView(view, mCombinedArea.XMost(), mCombinedArea.YMost());
vm->MoveViewTo(view, origin.x, origin.y);
NS_RELEASE(vm);
// Call our base class
nsresult rv = nsBlockFrame::DidReflow(aPresContext, aStatus);
// Set the flag again...
mState |= NS_FRAME_SYNC_FRAME_AND_VIEW;
return rv;
}
}
}
return nsBlockFrame::DidReflow(aPresContext, aStatus);
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Diagnostics // Diagnostics

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

@ -82,9 +82,6 @@ public:
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus); nsReflowStatus& aStatus);
NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus);
/** /**
* Get the "type" of the frame * Get the "type" of the frame
* *

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

@ -2809,6 +2809,20 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
return NS_OK; return NS_OK;
} }
static void
PlaceFrameView(nsIPresContext* aPresContext,
nsIFrame* aFrame)
{
nsIView* view;
aFrame->GetView(aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aFrame, view, nsnull);
} else {
nsContainerFrame::PositionChildViews(aPresContext, aFrame);
}
}
void void
nsBlockFrame::SlideLine(nsBlockReflowState& aState, nsBlockFrame::SlideLine(nsBlockReflowState& aState,
nsLineBox* aLine, nscoord aDY) nsLineBox* aLine, nscoord aDY)
@ -2830,6 +2844,9 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
// If the child has any floaters that impact the space-manager, // If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager // place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when // again (they were removed by the space-manager's frame when
@ -2851,16 +2868,21 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
} }
} }
else { else {
if (aDY) { // Adjust the Y coordinate of the frames in the line.
// Adjust the Y coordinate of the frames in the line // Note: we need to re-position views even if aDY is 0, because
// one of our parent frames may have moved and so the view's position
// relative to its parent may have changed
nsRect r; nsRect r;
PRInt32 n = aLine->GetChildCount(); PRInt32 n = aLine->GetChildCount();
while (--n >= 0) { while (--n >= 0) {
if (aDY) {
kid->GetRect(r); kid->GetRect(r);
r.y += aDY; r.y += aDY;
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
kid->GetNextSibling(&kid);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
kid->GetNextSibling(&kid);
} }
} }
} }
@ -4161,6 +4183,16 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
nsLineBox* aLine, nsLineBox* aLine,
const nsSize& aMaxElementSize) const nsSize& aMaxElementSize)
{ {
// If it's inline elements, then make sure the views are correctly
// positioned and sized
if (aLine->IsInline()) {
nsIFrame* frame = aLine->mFirstChild;
for (PRInt32 i = 0; i < aLine->GetChildCount(); i++) {
::PlaceFrameView(aState.mPresContext, frame);
frame->GetNextSibling(&frame);
}
}
// Update max-element-size // Update max-element-size
if (aState.mComputeMaxElementSize) { if (aState.mComputeMaxElementSize) {
aState.UpdateMaxElementSize(aMaxElementSize); aState.UpdateMaxElementSize(aMaxElementSize);
@ -6087,7 +6119,6 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
nsReflowStatus status; nsReflowStatus status;
mBullet->WillReflow(*aState.mPresContext); mBullet->WillReflow(*aState.mPresContext);
mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status); mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status);
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
// Place the bullet now; use its right margin to distance it // Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line // from the rest of the frames in the line
@ -6098,6 +6129,7 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
const nsMargin& bp = aState.BorderPadding(); const nsMargin& bp = aState.BorderPadding();
nscoord y = bp.top; nscoord y = bp.top;
mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height)); mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height));
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
} }
//XXX get rid of this -- its slow //XXX get rid of this -- its slow

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

@ -226,6 +226,14 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
// Let frame know that we are reflowing it // Let frame know that we are reflowing it
aFrame->WillReflow(*mPresContext); aFrame->WillReflow(*mPresContext);
// Position it and its view (if it has one)
aFrame->MoveTo(mPresContext, mX, mY);
nsIView* view;
aFrame->GetView(mPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(mPresContext, aFrame, view);
}
#ifdef DEBUG #ifdef DEBUG
mMetrics.width = nscoord(0xdeadbeef); mMetrics.width = nscoord(0xdeadbeef);
mMetrics.height = nscoord(0xdeadbeef); mMetrics.height = nscoord(0xdeadbeef);
@ -417,7 +425,9 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
// Empty blocks do not have anything special done to them and they // Empty blocks do not have anything special done to them and they
// always fit. Note: don't force the width to 0 // always fit. Note: don't force the width to 0
nsRect r(x, y, mMetrics.width, 0); nsRect r(x, y, mMetrics.width, 0);
mFrame->SetRect(mPresContext, r);
// Now place the frame and complete the reflow process
nsContainerFrame::FinishReflowChild(mFrame, *mPresContext, mMetrics, x, y, 0);
aInFlowBounds = r; aInFlowBounds = r;
// Retain combined area information in case we contain a floater // Retain combined area information in case we contain a floater
@ -544,8 +554,8 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
aCombinedRect.width = mMetrics.mCombinedArea.width; aCombinedRect.width = mMetrics.mCombinedArea.width;
aCombinedRect.height = mMetrics.mCombinedArea.height; aCombinedRect.height = mMetrics.mCombinedArea.height;
// Now place the frame // Now place the frame and complete the reflow process
mFrame->SetRect(mPresContext, nsRect(x, y, mMetrics.width, mMetrics.height)); nsContainerFrame::FinishReflowChild(mFrame, *mPresContext, mMetrics, x, y, 0);
// XXX obsolete, i believe... // XXX obsolete, i believe...
#if 0 #if 0
@ -591,6 +601,9 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
} }
} }
else { else {
// Send the DidReflow() notification, but don't bother placing
// the frame
mFrame->DidReflow(*mPresContext, NS_FRAME_REFLOW_FINISHED);
fits = PR_FALSE; fits = PR_FALSE;
} }
} }

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

@ -2809,6 +2809,20 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
return NS_OK; return NS_OK;
} }
static void
PlaceFrameView(nsIPresContext* aPresContext,
nsIFrame* aFrame)
{
nsIView* view;
aFrame->GetView(aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aFrame, view, nsnull);
} else {
nsContainerFrame::PositionChildViews(aPresContext, aFrame);
}
}
void void
nsBlockFrame::SlideLine(nsBlockReflowState& aState, nsBlockFrame::SlideLine(nsBlockReflowState& aState,
nsLineBox* aLine, nscoord aDY) nsLineBox* aLine, nscoord aDY)
@ -2830,6 +2844,9 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
// If the child has any floaters that impact the space-manager, // If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager // place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when // again (they were removed by the space-manager's frame when
@ -2851,16 +2868,21 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
} }
} }
else { else {
if (aDY) { // Adjust the Y coordinate of the frames in the line.
// Adjust the Y coordinate of the frames in the line // Note: we need to re-position views even if aDY is 0, because
// one of our parent frames may have moved and so the view's position
// relative to its parent may have changed
nsRect r; nsRect r;
PRInt32 n = aLine->GetChildCount(); PRInt32 n = aLine->GetChildCount();
while (--n >= 0) { while (--n >= 0) {
if (aDY) {
kid->GetRect(r); kid->GetRect(r);
r.y += aDY; r.y += aDY;
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
kid->GetNextSibling(&kid);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
kid->GetNextSibling(&kid);
} }
} }
} }
@ -4161,6 +4183,16 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
nsLineBox* aLine, nsLineBox* aLine,
const nsSize& aMaxElementSize) const nsSize& aMaxElementSize)
{ {
// If it's inline elements, then make sure the views are correctly
// positioned and sized
if (aLine->IsInline()) {
nsIFrame* frame = aLine->mFirstChild;
for (PRInt32 i = 0; i < aLine->GetChildCount(); i++) {
::PlaceFrameView(aState.mPresContext, frame);
frame->GetNextSibling(&frame);
}
}
// Update max-element-size // Update max-element-size
if (aState.mComputeMaxElementSize) { if (aState.mComputeMaxElementSize) {
aState.UpdateMaxElementSize(aMaxElementSize); aState.UpdateMaxElementSize(aMaxElementSize);
@ -6087,7 +6119,6 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
nsReflowStatus status; nsReflowStatus status;
mBullet->WillReflow(*aState.mPresContext); mBullet->WillReflow(*aState.mPresContext);
mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status); mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status);
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
// Place the bullet now; use its right margin to distance it // Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line // from the rest of the frames in the line
@ -6098,6 +6129,7 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
const nsMargin& bp = aState.BorderPadding(); const nsMargin& bp = aState.BorderPadding();
nscoord y = bp.top; nscoord y = bp.top;
mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height)); mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height));
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
} }
//XXX get rid of this -- its slow //XXX get rid of this -- its slow

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

@ -2809,6 +2809,20 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
return NS_OK; return NS_OK;
} }
static void
PlaceFrameView(nsIPresContext* aPresContext,
nsIFrame* aFrame)
{
nsIView* view;
aFrame->GetView(aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aFrame, view, nsnull);
} else {
nsContainerFrame::PositionChildViews(aPresContext, aFrame);
}
}
void void
nsBlockFrame::SlideLine(nsBlockReflowState& aState, nsBlockFrame::SlideLine(nsBlockReflowState& aState,
nsLineBox* aLine, nscoord aDY) nsLineBox* aLine, nscoord aDY)
@ -2830,6 +2844,9 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
// If the child has any floaters that impact the space-manager, // If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager // place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when // again (they were removed by the space-manager's frame when
@ -2851,16 +2868,21 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
} }
} }
else { else {
if (aDY) { // Adjust the Y coordinate of the frames in the line.
// Adjust the Y coordinate of the frames in the line // Note: we need to re-position views even if aDY is 0, because
// one of our parent frames may have moved and so the view's position
// relative to its parent may have changed
nsRect r; nsRect r;
PRInt32 n = aLine->GetChildCount(); PRInt32 n = aLine->GetChildCount();
while (--n >= 0) { while (--n >= 0) {
if (aDY) {
kid->GetRect(r); kid->GetRect(r);
r.y += aDY; r.y += aDY;
kid->SetRect(aState.mPresContext, r); kid->SetRect(aState.mPresContext, r);
kid->GetNextSibling(&kid);
} }
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
kid->GetNextSibling(&kid);
} }
} }
} }
@ -4161,6 +4183,16 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
nsLineBox* aLine, nsLineBox* aLine,
const nsSize& aMaxElementSize) const nsSize& aMaxElementSize)
{ {
// If it's inline elements, then make sure the views are correctly
// positioned and sized
if (aLine->IsInline()) {
nsIFrame* frame = aLine->mFirstChild;
for (PRInt32 i = 0; i < aLine->GetChildCount(); i++) {
::PlaceFrameView(aState.mPresContext, frame);
frame->GetNextSibling(&frame);
}
}
// Update max-element-size // Update max-element-size
if (aState.mComputeMaxElementSize) { if (aState.mComputeMaxElementSize) {
aState.UpdateMaxElementSize(aMaxElementSize); aState.UpdateMaxElementSize(aMaxElementSize);
@ -6087,7 +6119,6 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
nsReflowStatus status; nsReflowStatus status;
mBullet->WillReflow(*aState.mPresContext); mBullet->WillReflow(*aState.mPresContext);
mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status); mBullet->Reflow(*aState.mPresContext, aMetrics, reflowState, status);
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
// Place the bullet now; use its right margin to distance it // Place the bullet now; use its right margin to distance it
// from the rest of the frames in the line // from the rest of the frames in the line
@ -6098,6 +6129,7 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
const nsMargin& bp = aState.BorderPadding(); const nsMargin& bp = aState.BorderPadding();
nscoord y = bp.top; nscoord y = bp.top;
mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height)); mBullet->SetRect(aState.mPresContext, nsRect(x, y, aMetrics.width, aMetrics.height));
mBullet->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
} }
//XXX get rid of this -- its slow //XXX get rid of this -- its slow

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

@ -39,6 +39,7 @@
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsLayoutAtoms.h" #include "nsLayoutAtoms.h"
#include "nsIViewManager.h"
#ifdef NS_DEBUG #ifdef NS_DEBUG
#undef NOISY #undef NOISY
@ -107,6 +108,8 @@ nsContainerFrame::DidReflow(nsIPresContext& aPresContext,
// the NS_FRAME_IN_REFLOW bit // the NS_FRAME_IN_REFLOW bit
nsresult result = nsFrame::DidReflow(aPresContext, aStatus); nsresult result = nsFrame::DidReflow(aPresContext, aStatus);
// XXX TROY
#if 0
if (NS_FRAME_REFLOW_FINISHED == aStatus) { if (NS_FRAME_REFLOW_FINISHED == aStatus) {
// Apply DidReflow to each and every list that this frame implements // Apply DidReflow to each and every list that this frame implements
nsIAtom* listName = nsnull; nsIAtom* listName = nsnull;
@ -122,6 +125,7 @@ nsContainerFrame::DidReflow(nsIPresContext& aPresContext,
GetAdditionalChildListName(listIndex++, &listName); GetAdditionalChildListName(listIndex++, &listName);
} while(nsnull != listName); } while(nsnull != listName);
} }
#endif
NS_FRAME_TRACE_OUT("nsContainerFrame::DidReflow"); NS_FRAME_TRACE_OUT("nsContainerFrame::DidReflow");
return result; return result;
@ -372,17 +376,194 @@ nsContainerFrame::ReplaceFrame(nsIPresContext& aPresContext,
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Helper member functions // Helper member functions
void
nsContainerFrame::PositionFrameView(nsIPresContext* aPresContext,
nsIFrame* aKidFrame,
nsIView* aView)
{
if (aView) {
// Position view relative to its parent, not relative to aKidFrame's
// frame which may not have a view
nsIView* containingView;
nsPoint origin;
nsIView* parentView;
aView->GetParent(parentView);
aKidFrame->GetOffsetFromView(aPresContext, origin, &containingView);
if (containingView == parentView) {
nsIViewManager *vm;
aView->GetViewManager(vm);
vm->MoveViewTo(aView, origin.x, origin.y);
NS_RELEASE(vm);
}
}
}
void
nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIView* aView,
nsRect* aCombinedArea,
PRUint32 aFlags)
{
if (aView) {
nsIViewManager *vm;
nsFrameState kidState;
nsSize frameSize;
aView->GetViewManager(vm);
aFrame->GetFrameState(&kidState);
aFrame->GetSize(frameSize);
// Make sure the view is sized and positioned correctly
if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW)) {
nsIView* containingView;
nsPoint origin;
nsIView* parentView;
aView->GetParent(parentView);
aFrame->GetOffsetFromView(aPresContext, origin, &containingView);
if (containingView == parentView) {
vm->MoveViewTo(aView, origin.x, origin.y);
}
}
if (0 == (aFlags & NS_FRAME_NO_SIZE_VIEW)) {
// If the frame has child frames that stick outside the content
// area, then size the view large enough to include those child
// frames
if ((kidState & NS_FRAME_OUTSIDE_CHILDREN) && aCombinedArea) {
vm->ResizeView(aView, aCombinedArea->XMost(), aCombinedArea->YMost());
} else {
vm->ResizeView(aView, frameSize.width, frameSize.height);
}
}
const nsStyleColor* color;
const nsStyleDisplay* display;
aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&)color);
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display);
// Set the view's opacity
vm->SetViewOpacity(aView, color->mOpacity);
// See if the view should be hidden or visible
PRBool viewIsVisible = PR_TRUE;
PRBool viewHasTransparentContent = (color->mBackgroundFlags &
NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT;
if (NS_STYLE_VISIBILITY_COLLAPSE == display->mVisible) {
viewIsVisible = PR_FALSE;
}
else if (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible) {
// If it has a widget, hide the view because the widget can't deal with it
nsIWidget* widget = nsnull;
aView->GetWidget(widget);
if (widget) {
viewIsVisible = PR_FALSE;
NS_RELEASE(widget);
}
else {
// If it's a scroll frame, then hide the view. This means that
// child elements can't override their parent's visibility, but
// it's not practical to leave it visible in all cases because
// the scrollbars will be showing
nsIAtom* frameType;
aFrame->GetFrameType(&frameType);
if (frameType == nsLayoutAtoms::scrollFrame) {
viewIsVisible = PR_FALSE;
} else {
// If we're a container element, then leave the view visible, but
// mark it as having transparent content. The reason we need to
// do this is that child elements can override their parent's
// hidden visibility and be visible anyway
nsIFrame* firstChild;
aFrame->FirstChild(nsnull, &firstChild);
if (firstChild) {
// Not a left frame, so the view needs to be visible, but marked
// as having transparent content
viewHasTransparentContent = PR_TRUE;
} else {
// Leaf frame so go ahead and hide the view
viewIsVisible = PR_FALSE;
}
}
NS_IF_RELEASE(frameType);
}
}
// If the frame has visible content that overflows the content area, then we
// need the view marked as having transparent content
if (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow) {
if (kidState & NS_FRAME_OUTSIDE_CHILDREN) {
viewHasTransparentContent = PR_TRUE;
}
}
// Make sure visibility is correct
vm->SetViewVisibility(aView, viewIsVisible ? nsViewVisibility_kShow :
nsViewVisibility_kHide);
// Make sure content transparency is correct
if (viewIsVisible) {
vm->SetViewContentTransparency(aView, viewHasTransparentContent);
}
// Clip applies to block-level and replaced elements with overflow
// set to other than 'visible'
if (display->IsBlockLevel()) {
if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) {
nscoord left, top, right, bottom;
// Start with the 'auto' values and then factor in user
// specified values
left = top = 0;
right = frameSize.width;
bottom = frameSize.height;
if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) {
top += display->mClip.top;
}
if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) {
right -= display->mClip.right;
}
if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) {
bottom -= display->mClip.bottom;
}
if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) {
left += display->mClip.left;
}
aView->SetClip(left, top, right, bottom);
} else {
// Make sure no clip is set
aView->SetClip(0, 0, 0, 0);
}
}
NS_RELEASE(vm);
}
}
/** /**
* Queries the child frame for the nsIHTMLReflow interface and if it's * Invokes the WillReflow() function, positions the frame and its view (if
* supported invokes the WillReflow() and Reflow() member functions. If * requested), and then calls Reflow(). If the reflow succeeds and the child
* the reflow succeeds and the child frame is complete, deletes any * frame is complete, deletes any next-in-flows using DeleteChildsNextInFlow()
* next-in-flows using DeleteChildsNextInFlow()
*/ */
nsresult nsresult
nsContainerFrame::ReflowChild(nsIFrame* aKidFrame, nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext, nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nscoord aX,
nscoord aY,
PRUint32 aFlags,
nsReflowStatus& aStatus) nsReflowStatus& aStatus)
{ {
NS_PRECONDITION(aReflowState.frame == aKidFrame, "bad reflow state"); NS_PRECONDITION(aReflowState.frame == aKidFrame, "bad reflow state");
@ -399,8 +580,23 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
#endif #endif
#endif #endif
// Send the WillReflow notification, and reflow the child frame // Send the WillReflow() notification, and position the child frame
// and its view if requested
aKidFrame->WillReflow(aPresContext); aKidFrame->WillReflow(aPresContext);
if (0 == (aFlags & NS_FRAME_NO_MOVE_FRAME)) {
aKidFrame->MoveTo(&aPresContext, aX, aY);
}
if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW)) {
nsIView* view;
aKidFrame->GetView(&aPresContext, &view);
if (view) {
PositionFrameView(&aPresContext, aKidFrame, view);
}
}
// Reflow the child frame
result = aKidFrame->Reflow(aPresContext, aDesiredSize, aReflowState, result = aKidFrame->Reflow(aPresContext, aDesiredSize, aReflowState,
aStatus); aStatus);
@ -441,6 +637,97 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
return result; return result;
} }
void
nsContainerFrame::PositionChildViews(nsIPresContext* aPresContext,
nsIFrame* aFrame)
{
nsIAtom* childListName = nsnull;
PRInt32 childListIndex = 0;
do {
// Recursively walk aFrame's child frames
nsIFrame* childFrame;
aFrame->FirstChild(childListName, &childFrame);
while (childFrame) {
nsIView* view;
// See if the child frame has a view
childFrame->GetView(aPresContext, &view);
if (view) {
// Position the view. Because any child views are relative to their
// parent, there's no need to recurse
PositionFrameView(aPresContext, childFrame, view);
} else {
// Recursively examine its child frames
PositionChildViews(aPresContext, childFrame);
}
// Get the next sibling child frame
childFrame->GetNextSibling(&childFrame);
}
NS_IF_RELEASE(childListName);
aFrame->GetAdditionalChildListName(childListIndex++, &childListName);
} while (childListName);
}
/**
* The second half of frame reflow. Does the following:
* - sets the frame's bounds
* - sizes and positions (if requested) the frame's view. If the frame's final
* position differs from the current position and the frame itself does not
* have a view, then any child frames with views are positioned so they stay
* in sync
* - sets the view's visibility, opacity, content transparency, and clip
* - invoked the DidReflow() function
*
* Flags:
* NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this
* case. Also implies NS_FRAME_NO_MOVE_VIEW
* NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
* don't want to automatically sync the frame and view
* NS_FRAME_NO_SIZE_VIEW - don't size the frame's view
* NS_FRAME_NO_MOVE_CHILD_VIEWS - don't move child views. This is for the case
* where the frame's new position differs from its current position and the
* frame itself doesn't have a view, so moving the frame would cause any child
* views to be out of sync
*/
nsresult
nsContainerFrame::FinishReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
PRUint32 aFlags)
{
nsPoint curOrigin;
nsRect bounds(aX, aY, aDesiredSize.width, aDesiredSize.height);
aKidFrame->GetOrigin(curOrigin);
aKidFrame->SetRect(&aPresContext, bounds);
nsIView* view;
aKidFrame->GetView(&aPresContext, &view);
if (view) {
// Make sure the frame's view is properly sized and positioned and has
// things like opacity correct
SyncFrameViewAfterReflow(&aPresContext, aKidFrame, view,
&aDesiredSize.mCombinedArea,
aFlags);
} else if (0 == (aFlags & NS_FRAME_NO_MOVE_CHILD_VIEWS)) {
// If the frame has moved, then we need to make sure any child views are
// correctly positioned
if ((curOrigin.x != aX) || (curOrigin.y != aY)) {
PositionChildViews(&aPresContext, aKidFrame);
}
}
return aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
}
/** /**
* Remove and delete aChild's next-in-flow(s). Updates the sibling and flow * Remove and delete aChild's next-in-flow(s). Updates the sibling and flow
* pointers * pointers

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

@ -25,6 +25,13 @@
#include "nsSplittableFrame.h" #include "nsSplittableFrame.h"
#include "nsFrameList.h" #include "nsFrameList.h"
// Option flags for ReflowChild() and FinishReflowChild()
// member functions
#define NS_FRAME_NO_MOVE_VIEW 0x0001
#define NS_FRAME_NO_MOVE_FRAME (0x0002 | NS_FRAME_NO_MOVE_VIEW)
#define NS_FRAME_NO_SIZE_VIEW 0x0004
#define NS_FRAME_NO_MOVE_CHILD_VIEWS 0x0008
/** /**
* Implementation of a container frame. * Implementation of a container frame.
*/ */
@ -67,6 +74,82 @@ public:
return tmp.GetLength(); return tmp.GetLength();
} }
// Positions the frame's view based on the frame's origin
static void PositionFrameView(nsIPresContext* aPresContext,
nsIFrame* aKidFrame,
nsIView* aView);
// Sets several view attributes:
// - if requested sizes the frame's view based on the current size and origin.
// Takes into account the combined area and (if overflow is visible) whether
// the frame has children that extend outside
// - opacity
// - visibility
// - content transparency
// - clip
//
// Flags:
// NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
// don't want to automatically sync the frame and view
// NS_FRAME_NO_MOVE_VIEW - don't move the frame. aX and aY are ignored in this
// case. Also implies NS_FRAME_NO_MOVE_VIEW
static void SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIView* aView,
nsRect* aCombinedArea,
PRUint32 aFlags = 0);
/**
* Invokes the WillReflow() function, positions the frame and its view (if
* requested), and then calls Reflow(). If the reflow succeeds and the child
* frame is complete, deletes any next-in-flows using DeleteChildsNextInFlow()
*
* Flags:
* NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
* don't want to automatically sync the frame and view
* NS_FRAME_NO_MOVE_VIEW - don't move the frame. aX and aY are ignored in this
* case. Also implies NS_FRAME_NO_MOVE_VIEW
*/
nsresult ReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nscoord aX,
nscoord aY,
PRUint32 aFlags,
nsReflowStatus& aStatus);
/**
* The second half of frame reflow. Does the following:
* - sets the frame's bounds
* - sizes and positions (if requested) the frame's view. If the frame's final
* position differs from the current position and the frame itself does not
* have a view, then any child frames with views are positioned so they stay
* in sync
* - sets the view's visibility, opacity, content transparency, and clip
* - invoked the DidReflow() function
*
* Flags:
* NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this
* case. Also implies NS_FRAME_NO_MOVE_VIEW
* NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you
* don't want to automatically sync the frame and view
* NS_FRAME_NO_SIZE_VIEW - don't size the frame's view
* NS_FRAME_NO_MOVE_CHILD_VIEWS - don't move child views. This is for the case
* where the frame's new position differs from its current position and the
* frame itself doesn't have a view, so moving the frame would cause any child
* views to be out of sync
*/
static nsresult FinishReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
PRUint32 aFlags);
static void PositionChildViews(nsIPresContext* aPresContext,
nsIFrame* aFrame);
protected: protected:
nsContainerFrame(); nsContainerFrame();
~nsContainerFrame(); ~nsContainerFrame();
@ -87,18 +170,6 @@ protected:
nsIFrame* aFrame, nsIFrame* aFrame,
nsFramePaintLayer aWhichLayer); nsFramePaintLayer aWhichLayer);
/**
* Queries the child frame for the nsIHTMLReflow interface and if it's
* supported invokes the WillReflow() and Reflow() member functions. If
* the reflow succeeds and the child frame is complete, deletes any
* next-in-flows using DeleteChildsNextInFlow()
*/
nsresult ReflowChild(nsIFrame* aKidFrame,
nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** /**
* Get the frames on the overflow list * Get the frames on the overflow list
*/ */

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

@ -247,6 +247,7 @@ nsFirstLetterFrame::Reflow(nsIPresContext& aPresContext,
// Place and size the child and update the output metrics // Place and size the child and update the output metrics
kid->MoveTo(&aPresContext, bp.left, bp.top); kid->MoveTo(&aPresContext, bp.left, bp.top);
kid->SizeTo(&aPresContext, aMetrics.width, aMetrics.height); kid->SizeTo(&aPresContext, aMetrics.width, aMetrics.height);
kid->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
aMetrics.width += lr; aMetrics.width += lr;
aMetrics.height += tb; aMetrics.height += tb;
aMetrics.ascent += bp.top; aMetrics.ascent += bp.top;

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

@ -507,6 +507,8 @@ NS_IMETHODIMP nsFrame::MoveTo(nsIPresContext* aPresContext, nscoord aX, nscoord
mRect.x = aX; mRect.x = aX;
mRect.y = aY; mRect.y = aY;
// XXX TROY
#if 0
nsIView* view; nsIView* view;
GetView(aPresContext, &view); GetView(aPresContext, &view);
if (view) { if (view) {
@ -526,6 +528,7 @@ NS_IMETHODIMP nsFrame::MoveTo(nsIPresContext* aPresContext, nscoord aX, nscoord
NS_RELEASE(vm); NS_RELEASE(vm);
} }
} }
#endif
return NS_OK; return NS_OK;
} }
@ -535,6 +538,8 @@ NS_IMETHODIMP nsFrame::SizeTo(nsIPresContext* aPresContext, nscoord aWidth, nsco
mRect.width = aWidth; mRect.width = aWidth;
mRect.height = aHeight; mRect.height = aHeight;
// XXX TROY
#if 0
// Let the view know // Let the view know
nsIView* view; nsIView* view;
GetView(aPresContext, &view); GetView(aPresContext, &view);
@ -551,6 +556,7 @@ NS_IMETHODIMP nsFrame::SizeTo(nsIPresContext* aPresContext, nscoord aWidth, nsco
NS_RELEASE(vm); NS_RELEASE(vm);
} }
} }
#endif
return NS_OK; return NS_OK;
} }
@ -1266,6 +1272,8 @@ nsFrame::DidReflow(nsIPresContext& aPresContext,
if (NS_FRAME_REFLOW_FINISHED == aStatus) { if (NS_FRAME_REFLOW_FINISHED == aStatus) {
mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY); mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY);
// XXX TROY
#if 0
// Make sure the view is sized and positioned correctly and it's // Make sure the view is sized and positioned correctly and it's
// visibility, opacity, content transparency, and clip are correct // visibility, opacity, content transparency, and clip are correct
nsIView* view; nsIView* view;
@ -1390,6 +1398,7 @@ nsFrame::DidReflow(nsIPresContext& aPresContext,
} }
NS_RELEASE(vm); NS_RELEASE(vm);
} }
#endif
} }
return NS_OK; return NS_OK;
} }

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

@ -1206,7 +1206,8 @@ nsGfxScrollFrameInner::ReflowFrame( nsIPresContext& aPresContext,
childReflowState.mComputedHeight -= childReflowState.mComputedBorderPadding.top + childReflowState.mComputedBorderPadding.bottom; childReflowState.mComputedHeight -= childReflowState.mComputedBorderPadding.top + childReflowState.mComputedBorderPadding.bottom;
*/ */
mOuter->ReflowChild(aFrame, aPresContext, aDesiredSize, childReflowState, aStatus); mOuter->ReflowChild(aFrame, aPresContext, aDesiredSize, childReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
// if the frame size change then mark the flag // if the frame size change then mark the flag
@ -1214,6 +1215,7 @@ nsGfxScrollFrameInner::ReflowFrame( nsIPresContext& aPresContext,
aFrame->SizeTo(&aPresContext, aDesiredSize.width, aDesiredSize.height); aFrame->SizeTo(&aPresContext, aDesiredSize.width, aDesiredSize.height);
aResized = PR_TRUE; aResized = PR_TRUE;
} }
aFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// add the margin back in // add the margin back in
aDesiredSize.width += margin.left + margin.right; aDesiredSize.width += margin.left + margin.right;
@ -1467,13 +1469,29 @@ nsGfxScrollFrameInner::LayoutChildren(nsIPresContext& aPresContext,
const nsMargin& border = aReflowState.mComputedBorderPadding; const nsMargin& border = aReflowState.mComputedBorderPadding;
// Place scroll area // Place scroll area
nsIView* view;
mScrollAreaFrame->MoveTo(&aPresContext, border.left, border.top); mScrollAreaFrame->MoveTo(&aPresContext, border.left, border.top);
mScrollAreaFrame->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, mScrollAreaFrame,
view, nsnull);
}
// place vertical scrollbar // place vertical scrollbar
mVScrollbarFrame->MoveTo(&aPresContext, border.left + scrollAreaSize.width, border.top); mVScrollbarFrame->MoveTo(&aPresContext, border.left + scrollAreaSize.width, border.top);
mVScrollbarFrame->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, mVScrollbarFrame,
view, nsnull);
}
// place horizontal scrollbar // place horizontal scrollbar
mHScrollbarFrame->MoveTo(&aPresContext, border.left, border.top + scrollAreaSize.height); mHScrollbarFrame->MoveTo(&aPresContext, border.left, border.top + scrollAreaSize.height);
mHScrollbarFrame->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, mHScrollbarFrame,
view, nsnull);
}
// Compute our desired size // Compute our desired size
// ---------- compute width ----------- // ---------- compute width -----------

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

@ -324,7 +324,8 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
// Reflow the frame // Reflow the frame
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState, ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
aStatus); kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top,
0, aStatus);
// The document element's background should cover the entire canvas, so // The document element's background should cover the entire canvas, so
// take into account the combined area and any space taken up by // take into account the combined area and any space taken up by
@ -385,10 +386,10 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
} }
} }
// Position and size the child frame // Complete the reflow and position and size the child frame
nsRect rect(kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top, nsRect rect(kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top,
kidDesiredSize.width, kidDesiredSize.height); kidDesiredSize.width, kidDesiredSize.height);
kidFrame->SetRect(&aPresContext, rect); FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, rect.x, rect.y, 0);
// If the child frame was just inserted, then we're responsible for making sure // If the child frame was just inserted, then we're responsible for making sure
// it repaints // it repaints

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

@ -30,6 +30,7 @@
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
#include "nsHTMLIIDs.h" #include "nsHTMLIIDs.h"
#include "nsFrame.h" #include "nsFrame.h"
#include "nsContainerFrame.h"
static NS_DEFINE_IID(kIReflowCommandIID, NS_IREFLOWCOMMAND_IID); static NS_DEFINE_IID(kIReflowCommandIID, NS_IREFLOWCOMMAND_IID);
@ -133,8 +134,20 @@ NS_IMETHODIMP nsHTMLReflowCommand::Dispatch(nsIPresContext& aPresContext,
nsHTMLReflowState reflowState(aPresContext, root, *this, nsHTMLReflowState reflowState(aPresContext, root, *this,
&aRendContext, aMaxSize); &aRendContext, aMaxSize);
nsReflowStatus status; nsReflowStatus status;
nsIView* view;
root->WillReflow(aPresContext);
root->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(&aPresContext, root, view);
}
root->Reflow(aPresContext, aDesiredSize, reflowState, status); root->Reflow(aPresContext, aDesiredSize, reflowState, status);
root->SizeTo(&aPresContext, aDesiredSize.width, aDesiredSize.height);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, root, view,
nsnull);
}
root->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
return NS_OK; return NS_OK;

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

@ -35,6 +35,8 @@
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIHTMLDocument.h" #include "nsIHTMLDocument.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#ifdef DEBUG #ifdef DEBUG
#undef NOISY_HORIZONTAL_ALIGN #undef NOISY_HORIZONTAL_ALIGN
@ -918,7 +920,9 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
// new starting x,y coordinates for the frame. // new starting x,y coordinates for the frame.
ApplyLeftMargin(pfd, reflowState); ApplyLeftMargin(pfd, reflowState);
// Let frame know that are reflowing it // Let frame know that are reflowing it. Note that we don't bother
// positioning the frame yet, because we're probably going to end up
// moving it when we do the vertical alignment
nscoord x = pfd->mBounds.x; nscoord x = pfd->mBounds.x;
nscoord y = pfd->mBounds.y; nscoord y = pfd->mBounds.y;
@ -1072,14 +1076,21 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
pfd->mMaxElementSize = *metrics.maxElementSize; pfd->mMaxElementSize = *metrics.maxElementSize;
} }
// Now that frame has been reflowed at least one time make sure that // Size the frame and size its view (if it has one)
// the NS_FRAME_FIRST_REFLOW bit is cleared so that never give it an aFrame->SizeTo(&mPresContext, metrics.width, metrics.height);
// initial reflow reason again. nsIView* view;
if (eReflowReason_Initial == reason) { aFrame->GetView(&mPresContext, &view);
aFrame->GetFrameState(&state); if (view) {
aFrame->SetFrameState(state & ~NS_FRAME_FIRST_REFLOW); nsIViewManager *vm;
view->GetViewManager(vm);
vm->ResizeView(view, metrics.width, metrics.height);
NS_RELEASE(vm);
} }
// Tell the frame that we're done reflowing it
aFrame->DidReflow(mPresContext, NS_FRAME_REFLOW_FINISHED);
if (aMetrics) { if (aMetrics) {
*aMetrics = metrics; *aMetrics = metrics;
} }

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

@ -1037,10 +1037,8 @@ nsObjectFrame::HandleImage(nsIPresContext& aPresContext,
} }
} }
ReflowChild(child, aPresContext, kidDesiredSize, kidReflowState, status); ReflowChild(child, aPresContext, kidDesiredSize, kidReflowState, 0, 0, 0, status);
FinishReflowChild(child, aPresContext, kidDesiredSize, 0, 0, 0);
nsRect rect(0, 0, kidDesiredSize.width, kidDesiredSize.height);
child->SetRect(&aPresContext, rect);
aMetrics.width = kidDesiredSize.width; aMetrics.width = kidDesiredSize.width;
aMetrics.height = kidDesiredSize.height; aMetrics.height = kidDesiredSize.height;

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

@ -80,7 +80,7 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext& aPresContext,
kidReflowState.isTopOfPage = PR_TRUE; kidReflowState.isTopOfPage = PR_TRUE;
ReflowChild(mFrames.FirstChild(), aPresContext, aDesiredSize, ReflowChild(mFrames.FirstChild(), aPresContext, aDesiredSize,
kidReflowState, aStatus); kidReflowState, 0, 0, 0, aStatus);
// Place and size the child. Make sure the child is at least as // Place and size the child. Make sure the child is at least as
// tall as our max size (the containing window) // tall as our max size (the containing window)
@ -88,8 +88,8 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.height = aReflowState.availableHeight; aDesiredSize.height = aReflowState.availableHeight;
} }
nsRect rect(0, 0, aDesiredSize.width, aDesiredSize.height); FinishReflowChild(mFrames.FirstChild(), aPresContext, aDesiredSize,
mFrames.FirstChild()->SetRect(&aPresContext, rect); 0, 0, 0);
} else { } else {
// Do we have any children? // Do we have any children?
@ -122,7 +122,7 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext& aPresContext,
kidReflowState.isTopOfPage = PR_TRUE; kidReflowState.isTopOfPage = PR_TRUE;
// Get the child's desired size // Get the child's desired size
ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, aStatus); ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
// Make sure the child is at least as tall as our max size (the containing window) // Make sure the child is at least as tall as our max size (the containing window)
if (aDesiredSize.height < aReflowState.availableHeight) { if (aDesiredSize.height < aReflowState.availableHeight) {
@ -130,10 +130,7 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext& aPresContext,
} }
// Place and size the child // Place and size the child
nsRect rect(0, 0, aDesiredSize.width, aDesiredSize.height); FinishReflowChild(frame, aPresContext, aDesiredSize, 0, 0, 0);
frame->SetRect(&aPresContext, rect);
// XXX Should we be sending the DidReflow?
frame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// Is the frame complete? // Is the frame complete?
if (NS_FRAME_IS_COMPLETE(aStatus)) { if (NS_FRAME_IS_COMPLETE(aStatus)) {

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

@ -992,10 +992,21 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
nsHTMLReflowState reflowState(*mPresContext, rootFrame, nsHTMLReflowState reflowState(*mPresContext, rootFrame,
eReflowReason_Initial, rcx, maxSize); eReflowReason_Initial, rcx, maxSize);
nsIView* view;
rootFrame->WillReflow(*mPresContext);
rootFrame->GetView(mPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
}
rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status); rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status);
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height); rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height)); mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height));
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
nsnull);
}
rootFrame->DidReflow(*mPresContext, NS_FRAME_REFLOW_FINISHED);
#ifdef NS_DEBUG #ifdef NS_DEBUG
if (nsIFrameDebug::GetVerifyTreeEnable()) { if (nsIFrameDebug::GetVerifyTreeEnable()) {
@ -1077,9 +1088,20 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
nsHTMLReflowState reflowState(*mPresContext, rootFrame, nsHTMLReflowState reflowState(*mPresContext, rootFrame,
eReflowReason_Resize, rcx, maxSize); eReflowReason_Resize, rcx, maxSize);
nsIView* view;
rootFrame->WillReflow(*mPresContext);
rootFrame->GetView(mPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
}
rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status); rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status);
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height); rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
nsnull);
}
rootFrame->DidReflow(*mPresContext, NS_FRAME_REFLOW_FINISHED);
#ifdef NS_DEBUG #ifdef NS_DEBUG
if (nsIFrameDebug::GetVerifyTreeEnable()) { if (nsIFrameDebug::GetVerifyTreeEnable()) {
nsIFrameDebug* frameDebug; nsIFrameDebug* frameDebug;
@ -1262,9 +1284,21 @@ PresShell::StyleChangeReflow()
// XXX We should be using eReflowReason_StyleChange // XXX We should be using eReflowReason_StyleChange
nsHTMLReflowState reflowState(*mPresContext, rootFrame, nsHTMLReflowState reflowState(*mPresContext, rootFrame,
eReflowReason_Resize, rcx, maxSize); eReflowReason_Resize, rcx, maxSize);
nsIView* view;
rootFrame->WillReflow(*mPresContext);
rootFrame->GetView(mPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
}
rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status); rootFrame->Reflow(*mPresContext, desiredSize, reflowState, status);
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height); rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height));
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
nsnull);
}
rootFrame->DidReflow(*mPresContext, NS_FRAME_REFLOW_FINISHED);
#ifdef NS_DEBUG #ifdef NS_DEBUG
if (nsIFrameDebug::GetVerifyTreeEnable()) { if (nsIFrameDebug::GetVerifyTreeEnable()) {
nsIFrameDebug* frameDebug; nsIFrameDebug* frameDebug;

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

@ -164,6 +164,8 @@ nsScrollFrame::DidReflow(nsIPresContext& aPresContext,
// and size and position our view // and size and position our view
rv = nsFrame::DidReflow(aPresContext, aStatus); rv = nsFrame::DidReflow(aPresContext, aStatus);
// XXX TROY
#if 0
// Send the DidReflow notification to the scrolled frame's view // Send the DidReflow notification to the scrolled frame's view
nsIFrame* frame = mFrames.FirstChild(); nsIFrame* frame = mFrames.FirstChild();
@ -179,6 +181,7 @@ nsScrollFrame::DidReflow(nsIPresContext& aPresContext,
scrolledView->GetViewManager(vm); scrolledView->GetViewManager(vm);
vm->ResizeView(scrolledView, size.width, size.height); vm->ResizeView(scrolledView, size.width, size.height);
NS_RELEASE(vm); NS_RELEASE(vm);
#endif
// Have the scrolling view layout // Have the scrolling view layout
nsIScrollableView* scrollingView; nsIScrollableView* scrollingView;
@ -617,7 +620,7 @@ nsScrollFrame::Reflow(nsIPresContext& aPresContext,
kidReflowState.mComputedHeight = theHeight; kidReflowState.mComputedHeight = theHeight;
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState, ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
aStatus); border.left, border.top, NS_FRAME_NO_MOVE_VIEW, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
CalculateChildTotalSize(kidFrame, kidDesiredSize); CalculateChildTotalSize(kidFrame, kidDesiredSize);
@ -683,7 +686,7 @@ nsScrollFrame::Reflow(nsIPresContext& aPresContext,
// Reflow the child frame with a reflow reason of reflow // Reflow the child frame with a reflow reason of reflow
kidReflowState.reason = eReflowReason_Resize; kidReflowState.reason = eReflowReason_Resize;
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState, ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
aStatus); border.left, border.top, NS_FRAME_NO_MOVE_VIEW, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
CalculateChildTotalSize(kidFrame, kidDesiredSize); CalculateChildTotalSize(kidFrame, kidDesiredSize);
} }
@ -711,10 +714,8 @@ nsScrollFrame::Reflow(nsIPresContext& aPresContext,
} }
// Place and size the child. // Place and size the child.
nscoord x = border.left; FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, border.left,
nscoord y = border.top; border.top, NS_FRAME_NO_MOVE_VIEW);
nsRect rect(x, y, kidDesiredSize.width, kidDesiredSize.height);
kidFrame->SetRect(&aPresContext, rect);
// Compute our desired size // Compute our desired size
aDesiredSize.width = scrollAreaSize.width; aDesiredSize.width = scrollAreaSize.width;

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

@ -174,11 +174,11 @@ nsScrollPortFrame::DidReflow(nsIPresContext& aPresContext,
// and size and position our view // and size and position our view
rv = nsFrame::DidReflow(aPresContext, aStatus); rv = nsFrame::DidReflow(aPresContext, aStatus);
// XXX TROY
#if 0
// Send the DidReflow notification to the scrolled frame's view // Send the DidReflow notification to the scrolled frame's view
nsIFrame* frame = mFrames.FirstChild(); nsIFrame* frame = mFrames.FirstChild();
frame->DidReflow(aPresContext, aStatus);
// Size the scrolled frame's view. Leave its position alone // Size the scrolled frame's view. Leave its position alone
nsSize size; nsSize size;
nsRect bounds; nsRect bounds;
@ -203,8 +203,18 @@ nsScrollPortFrame::DidReflow(nsIPresContext& aPresContext,
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) { if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
scrollingView->ComputeScrollOffsets(PR_TRUE); scrollingView->ComputeScrollOffsets(PR_TRUE);
} }
} }
frame->DidReflow(aPresContext, aStatus);
#else
// Have the scrolling view layout
nsIScrollableView* scrollingView;
nsIView* view;
GetView(&aPresContext, &view);
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
scrollingView->ComputeScrollOffsets(PR_TRUE);
}
#endif
} }
return rv; return rv;
@ -440,7 +450,7 @@ nsScrollPortFrame::Reflow(nsIPresContext& aPresContext,
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState, ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
aStatus); border.left, border.top, 0, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
CalculateChildTotalSize(kidFrame, kidDesiredSize); CalculateChildTotalSize(kidFrame, kidDesiredSize);
@ -471,8 +481,7 @@ nsScrollPortFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.height += border.top + border.bottom; aDesiredSize.height += border.top + border.bottom;
nsRect rect(x, y, kidDesiredSize.width, kidDesiredSize.height); FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, x, y, 0);
kidFrame->SetRect(&aPresContext, rect);
//printf("width=%d, height=%d\n", kidDesiredSize.width, kidDesiredSize.height); //printf("width=%d, height=%d\n", kidDesiredSize.width, kidDesiredSize.height);
@ -648,7 +657,8 @@ nsScrollPortFrame::GetChildBoxInfo(nsIPresContext& aPresContext, const nsHTMLRef
nsReflowStatus status = NS_FRAME_COMPLETE; nsReflowStatus status = NS_FRAME_COMPLETE;
ReflowChild(aFrame, aPresContext, kidDesiredSize, kidReflowState, ReflowChild(aFrame, aPresContext, kidDesiredSize, kidReflowState,
status); 0, 0, NS_FRAME_NO_MOVE_FRAME, status);
aFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status");

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

@ -126,12 +126,11 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext& aPresConte
// Dispatch the reflow command to our child frame. Allow it to be as high // Dispatch the reflow command to our child frame. Allow it to be as high
// as it wants // as it wants
ReflowChild(nextFrame, aPresContext, kidSize, kidReflowState, status); ReflowChild(nextFrame, aPresContext, kidSize, kidReflowState, aX, aY, 0, status);
// Place and size the page. If the page is narrower than our max width, then // Place and size the page. If the page is narrower than our max width, then
// center it horizontally // center it horizontally
nsRect rect(aX, aY, kidSize.width, kidSize.height); FinishReflowChild(nextFrame, aPresContext, kidSize, aX, aY, 0);
nextFrame->SetRect(&aPresContext, rect);
aY += kidSize.height + PAGE_SPACING_TWIPS; aY += kidSize.height + PAGE_SPACING_TWIPS;
// Check if the page is complete... // Check if the page is complete...
@ -169,8 +168,9 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext& aPresConte
// Place and size the page. If the page is narrower than our // Place and size the page. If the page is narrower than our
// max width then center it horizontally // max width then center it horizontally
ReflowChild(kidFrame, aPresContext, childSize, childReflowState, ReflowChild(kidFrame, aPresContext, childSize, childReflowState,
status); aX, aY, 0, status);
kidFrame->SetRect(&aPresContext, nsRect(aX, aY, childSize.width, childSize.height));
FinishReflowChild(kidFrame, aPresContext, childSize, aX, aY, 0);
aY += childSize.height; aY += childSize.height;
// Leave a slight gap between the pages // Leave a slight gap between the pages
@ -242,8 +242,9 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext& aPresContext,
// Place and size the page. If the page is narrower than our // Place and size the page. If the page is narrower than our
// max width then center it horizontally // max width then center it horizontally
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, status); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, x, y, 0, status);
kidFrame->SetRect(&aPresContext, nsRect(x, y, kidSize.width, kidSize.height));
FinishReflowChild(kidFrame, aPresContext, kidSize, x, y, 0);
y += kidSize.height; y += kidSize.height;
// Leave a slight gap between the pages // Leave a slight gap between the pages

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

@ -332,8 +332,6 @@ ViewportFrame::ReflowFixedFrame(nsIPresContext& aPresContext,
// Reflow the frame // Reflow the frame
nsresult rv; nsresult rv;
aKidFrame->WillReflow(aPresContext);
nsHTMLReflowMetrics kidDesiredSize(nsnull); nsHTMLReflowMetrics kidDesiredSize(nsnull);
nsSize availSize(aReflowState.availableWidth, NS_UNCONSTRAINEDSIZE); nsSize availSize(aReflowState.availableWidth, NS_UNCONSTRAINEDSIZE);
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame,
@ -345,6 +343,18 @@ ViewportFrame::ReflowFixedFrame(nsIPresContext& aPresContext,
kidReflowState.reason = eReflowReason_Initial; kidReflowState.reason = eReflowReason_Initial;
} }
// Send the WillReflow() notification and position the frame
aKidFrame->WillReflow(aPresContext);
aKidFrame->MoveTo(&aPresContext,
kidReflowState.mComputedOffsets.left + kidReflowState.mComputedMargin.left,
kidReflowState.mComputedOffsets.top + kidReflowState.mComputedMargin.top);
// Position its view
nsIView* kidView;
aKidFrame->GetView(&aPresContext, &kidView);
nsContainerFrame::PositionFrameView(&aPresContext, aKidFrame, kidView);
// Do the reflow
rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus); rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus);
// XXX If the child had a fixed height, then make sure it respected it... // XXX If the child had a fixed height, then make sure it respected it...
@ -361,8 +371,12 @@ ViewportFrame::ReflowFixedFrame(nsIPresContext& aPresContext,
kidReflowState.mComputedOffsets.top + kidReflowState.mComputedMargin.top, kidReflowState.mComputedOffsets.top + kidReflowState.mComputedMargin.top,
kidDesiredSize.width, kidDesiredSize.height); kidDesiredSize.width, kidDesiredSize.height);
aKidFrame->SetRect(&aPresContext, rect); aKidFrame->SetRect(&aPresContext, rect);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, aKidFrame, kidView,
&kidDesiredSize.mCombinedArea);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
return rv; return rv;
} }
@ -509,15 +523,9 @@ ViewportFrame::Reflow(nsIPresContext& aPresContext,
// Reflow the frame // Reflow the frame
kidReflowState.mComputedHeight = aReflowState.availableHeight; kidReflowState.mComputedHeight = aReflowState.availableHeight;
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState, ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
aStatus); 0, 0, 0, aStatus);
nsRect rect(0, 0, kidDesiredSize.width, kidDesiredSize.height); FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, 0, 0, 0);
kidFrame->SetRect(&aPresContext, rect);
kidRect = rect;
// XXX We should resolve the details of who/when DidReflow()
// notifications are sent...
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
// If it's a 'initial', 'resize', or 'style change' reflow command (anything // If it's a 'initial', 'resize', or 'style change' reflow command (anything

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

@ -360,12 +360,12 @@ nsHTMLFrameOuterFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics kidMetrics(aDesiredSize.maxElementSize); nsHTMLReflowMetrics kidMetrics(aDesiredSize.maxElementSize);
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstChild, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstChild,
innerSize); innerSize);
ReflowChild(firstChild, aPresContext, kidMetrics, kidReflowState, aStatus); ReflowChild(firstChild, aPresContext, kidMetrics, kidReflowState,
offset.x, offset.y, 0, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
// Place and size the child // Place and size the child
nsRect rect(offset.x, offset.y, innerSize.width, innerSize.height); FinishReflowChild(firstChild, aPresContext, kidMetrics, offset.x, offset.y, 0);
firstChild->SetRect(&aPresContext, rect);
// XXX what should the max-element-size of an iframe be? Shouldn't // XXX what should the max-element-size of an iframe be? Shouldn't
// iframe's normally shrink wrap around their content when they // iframe's normally shrink wrap around their content when they

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

@ -234,6 +234,9 @@ nsresult nsHTMLFramesetFrame::QueryInterface(const nsIID& aIID,
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr); return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
} }
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLFramesetFrame::Init(nsIPresContext& aPresContext, nsHTMLFramesetFrame::Init(nsIPresContext& aPresContext,
nsIContent* aContent, nsIContent* aContent,
@ -258,6 +261,25 @@ nsHTMLFramesetFrame::Init(nsIPresContext& aPresContext,
break; break;
} }
} }
// create the view. a view is needed since it needs to be a mouse grabber
nsIView* view;
nsresult result = nsComponentManager::CreateInstance(kViewCID, nsnull, kIViewIID,
(void **)&view);
nsCOMPtr<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
nsCOMPtr<nsIViewManager> viewMan;
presShell->GetViewManager(getter_AddRefs(viewMan));
nsIFrame* parWithView;
nsIView *parView;
GetParentWithView(&aPresContext, &parWithView);
parWithView->GetView(&aPresContext, &parView);
nsRect boundBox(0, 0, 0, 0);
result = view->Init(viewMan, boundBox, parView, nsnull);
viewMan->InsertChild(parView, view, 0);
SetView(&aPresContext, view);
return rv; return rv;
} }
@ -785,13 +807,14 @@ nsHTMLFramesetFrame::ReflowPlaceChild(nsIFrame* aChild,
metrics.height= aSize.height; metrics.height= aSize.height;
nsReflowStatus status; nsReflowStatus status;
ReflowChild(aChild, aPresContext, metrics, reflowState, status); ReflowChild(aChild, aPresContext, metrics, reflowState, aOffset.x,
aOffset.y, 0, status);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status");
// Place and size the child // Place and size the child
nsRect rect(aOffset.x, aOffset.y, aSize.width, aSize.height); metrics.width = aSize.width;
aChild->SetRect(&aPresContext, rect); metrics.height = aSize.height;
aChild->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED); // this call is needed FinishReflowChild(aChild, aPresContext, metrics, aOffset.x, aOffset.y, 0);
} }
static static
@ -902,10 +925,6 @@ nscolor nsHTMLFramesetFrame::GetBorderColor(nsIContent* aContent)
#define FRAME 1 #define FRAME 1
#define BLANK 2 #define BLANK 2
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLFramesetFrame::Reflow(nsIPresContext& aPresContext, nsHTMLFramesetFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
@ -918,25 +937,6 @@ nsHTMLFramesetFrame::Reflow(nsIPresContext& aPresContext,
PRBool firstTime = (0 == mNumRows); PRBool firstTime = (0 == mNumRows);
if (firstTime) { if (firstTime) {
// create the view. a view is needed since it needs to be a mouse grabber
nsIView* view;
nsresult result = nsComponentManager::CreateInstance(kViewCID, nsnull, kIViewIID,
(void **)&view);
nsCOMPtr<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
nsCOMPtr<nsIViewManager> viewMan;
presShell->GetViewManager(getter_AddRefs(viewMan));
nsIFrame* parWithView;
nsIView *parView;
GetParentWithView(&aPresContext, &parWithView);
parWithView->GetView(&aPresContext, &parView);
nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height);
result = view->Init(viewMan, boundBox, parView, nsnull);
viewMan->InsertChild(parView, view, 0);
SetView(&aPresContext, view);
// parse the rows= cols= data // parse the rows= cols= data
ParseRowCol(nsHTMLAtoms::rows, mNumRows, &mRowSpecs); ParseRowCol(nsHTMLAtoms::rows, mNumRows, &mRowSpecs);
ParseRowCol(nsHTMLAtoms::cols, mNumCols, &mColSpecs); ParseRowCol(nsHTMLAtoms::cols, mNumCols, &mColSpecs);

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

@ -424,14 +424,13 @@ nsComboboxControlFrame::ReflowComboChildFrame(nsIFrame* aFrame,
kidReflowState.mComputedHeight = aAvailableHeight; kidReflowState.mComputedHeight = aAvailableHeight;
// Reflow child // Reflow child
nsresult rv = ReflowChild(aFrame, aPresContext, aDesiredSize, kidReflowState, aStatus);
// Set the child's width and height to it's desired size
nsRect rect; nsRect rect;
aFrame->GetRect(rect); aFrame->GetRect(rect);
rect.width = aDesiredSize.width; nsresult rv = ReflowChild(aFrame, aPresContext, aDesiredSize, kidReflowState,
rect.height = aDesiredSize.height; rect.x, rect.y, 0, aStatus);
aFrame->SetRect(&aPresContext, rect);
// Set the child's width and height to it's desired size
FinishReflowChild(aFrame, aPresContext, aDesiredSize, rect.x, rect.y, 0);
return rv; return rv;
} }

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

@ -318,7 +318,8 @@ nsFieldSetFrame::Reflow(nsIPresContext& aPresContext,
legendReflowState.mComputedWidth = NS_INTRINSICSIZE; legendReflowState.mComputedWidth = NS_INTRINSICSIZE;
legendReflowState.mComputedHeight = NS_INTRINSICSIZE; legendReflowState.mComputedHeight = NS_INTRINSICSIZE;
ReflowChild(mLegendFrame, aPresContext, aDesiredSize, legendReflowState, aStatus); ReflowChild(mLegendFrame, aPresContext, aDesiredSize, legendReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
// get the legend's margin // get the legend's margin
nsIStyleContext* legendSC = nsnull; nsIStyleContext* legendSC = nsnull;
@ -355,19 +356,22 @@ nsFieldSetFrame::Reflow(nsIPresContext& aPresContext,
availSize.width = mLegendRect.width; availSize.width = mLegendRect.width;
} }
// Tell the legend we're done with the reflow. We'll size and place it later on
mLegendFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
// Try to reflow the area frame into the available space. // Try to reflow the area frame into the available space.
nsHTMLReflowState contentReflowState(aPresContext, aReflowState, nsHTMLReflowState contentReflowState(aPresContext, aReflowState,
mContentFrame, availSize); mContentFrame, availSize);
ReflowChild(mContentFrame, aPresContext, aDesiredSize, contentReflowState, aStatus); ReflowChild(mContentFrame, aPresContext, aDesiredSize, contentReflowState,
borderPadding.left, borderPadding.top + mLegendSpace, 0, aStatus);
// set the rect. make sure we add the margin back in. // set the rect. make sure we add the margin back in.
nsRect contentRect(borderPadding.left,borderPadding.top + mLegendSpace,aDesiredSize.width ,aDesiredSize.height); nsRect contentRect(borderPadding.left,borderPadding.top + mLegendSpace,aDesiredSize.width ,aDesiredSize.height);
// Place the content area frame. // Place the content area frame.
mContentFrame->SetRect(&aPresContext, contentRect); FinishReflowChild(mContentFrame, aPresContext, aDesiredSize, contentRect.x, contentRect.y, 0);
if (mLegendFrame) if (mLegendFrame)
{ {

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

@ -1864,6 +1864,12 @@ nsGfxTextControlFrame::Reflow(nsIPresContext& aPresContext,
// Send the WillReflow notification, and reflow the child frame // Send the WillReflow notification, and reflow the child frame
mDisplayFrame->WillReflow(aPresContext); mDisplayFrame->WillReflow(aPresContext);
mDisplayFrame->MoveTo(&aPresContext, subBounds.x, subBounds.y);
nsIView* view;
mDisplayFrame->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(&aPresContext, mDisplayFrame, view);
}
nsReflowStatus status; nsReflowStatus status;
rv = mDisplayFrame->Reflow(aPresContext, kidSize, kidReflowState, status); rv = mDisplayFrame->Reflow(aPresContext, kidSize, kidReflowState, status);
// notice how status is ignored here // notice how status is ignored here

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

@ -516,6 +516,9 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext& aPresContext,
// the view also breaks the outline code. For some reason you can not reset // the view also breaks the outline code. For some reason you can not reset
// the clip rect to draw outside you bounds if you have a view. And you need to // the clip rect to draw outside you bounds if you have a view. And you need to
// because the outline must be drawn outside of our bounds according to CSS. -EDV // because the outline must be drawn outside of our bounds according to CSS. -EDV
// XXX If you do decide you need a view, then create it in the Init() function
// and not here...
#if 0 #if 0
if (!mDidInit) { if (!mDidInit) {
// create our view, we need a view to grab the mouse // create our view, we need a view to grab the mouse
@ -596,11 +599,15 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext& aPresContext,
} }
} }
ReflowChild(firstKid, aPresContext, aDesiredSize, reflowState, aStatus); ReflowChild(firstKid, aPresContext, aDesiredSize, reflowState,
focusPadding.left + aReflowState.mComputedBorderPadding.left,
focusPadding.top + aReflowState.mComputedBorderPadding.top,
0, aStatus);
// Place the child // Place the child
nsRect rect = nsRect(focusPadding.left + aReflowState.mComputedBorderPadding.left, focusPadding.top + aReflowState.mComputedBorderPadding.top, aDesiredSize.width, aDesiredSize.height); FinishReflowChild(firstKid, aPresContext, aDesiredSize,
firstKid->SetRect(&aPresContext, rect); focusPadding.left + aReflowState.mComputedBorderPadding.left,
focusPadding.top + aReflowState.mComputedBorderPadding.top, 0);
#if 0 // old way #if 0 // old way
// if computed use the computed values. // if computed use the computed values.

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

@ -70,6 +70,12 @@ public:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD Init(nsIPresContext& aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD Reflow(nsIPresContext& aPresContext, NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
@ -202,15 +208,16 @@ nsrefcnt nsImageControlFrame::Release(void)
return 1; return 1;
} }
NS_METHOD NS_IMETHODIMP
nsImageControlFrame::Reflow(nsIPresContext& aPresContext, nsImageControlFrame::Init(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsIContent* aContent,
const nsHTMLReflowState& aReflowState, nsIFrame* aParent,
nsReflowStatus& aStatus) nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{ {
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { // call our base class
// add ourself as an nsIFormControlFrame nsresult rv = nsImageControlFrameSuper::Init(aPresContext, aContent, aParent,
nsFormFrame::AddFormControlFrame(aPresContext, *this); aContext, aPrevInFlow);
// create our view, we need a view to grab the mouse // create our view, we need a view to grab the mouse
nsIView* view; nsIView* view;
@ -227,7 +234,7 @@ nsImageControlFrame::Reflow(nsIPresContext& aPresContext,
GetParentWithView(&aPresContext, &parWithView); GetParentWithView(&aPresContext, &parWithView);
parWithView->GetView(&aPresContext, &parView); parWithView->GetView(&aPresContext, &parView);
// the view's size is not know yet, but its size will be kept in synch with our frame. // the view's size is not know yet, but its size will be kept in synch with our frame.
nsRect boundBox(0, 0, 500, 500); nsRect boundBox(0, 0, 0, 0);
result = view->Init(viewMan, boundBox, parView, nsnull); result = view->Init(viewMan, boundBox, parView, nsnull);
view->SetContentTransparency(PR_TRUE); view->SetContentTransparency(PR_TRUE);
viewMan->InsertChild(parView, view, 0); viewMan->InsertChild(parView, view, 0);
@ -237,6 +244,19 @@ nsImageControlFrame::Reflow(nsIPresContext& aPresContext,
// set the opacity // set the opacity
viewMan->SetViewOpacity(view, color->mOpacity); viewMan->SetViewOpacity(view, color->mOpacity);
} }
return NS_OK;
}
NS_METHOD
nsImageControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
// add ourself as an nsIFormControlFrame
nsFormFrame::AddFormControlFrame(aPresContext, *this);
} }
return nsImageControlFrameSuper::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); return nsImageControlFrameSuper::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
} }

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

@ -76,6 +76,12 @@ class nsLabelFrame : public nsHTMLContainerFrame
public: public:
nsLabelFrame(); nsLabelFrame();
NS_IMETHOD Init(nsIPresContext& aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD Paint(nsIPresContext& aPresContext, NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext, nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
@ -116,7 +122,6 @@ protected:
PRBool mControlIsInside; PRBool mControlIsInside;
nsIFormControlFrame* mControlFrame; nsIFormControlFrame* mControlFrame;
nsRect mTranslatedRect; nsRect mTranslatedRect;
PRBool mDidInit;
}; };
nsresult nsresult
@ -143,7 +148,6 @@ nsLabelFrame::nsLabelFrame()
mControlIsInside = PR_FALSE; mControlIsInside = PR_FALSE;
mControlFrame = nsnull; mControlFrame = nsnull;
mTranslatedRect = nsRect(0,0,0,0); mTranslatedRect = nsRect(0,0,0,0);
mDidInit = PR_FALSE;
} }
void void
@ -424,14 +428,16 @@ void LabelHack(nsHTMLReflowState& aReflowState, char* aMessage)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsLabelFrame::Reflow(nsIPresContext& aPresContext, nsLabelFrame::Init(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsIContent* aContent,
const nsHTMLReflowState& aReflowState, nsIFrame* aParent,
nsReflowStatus& aStatus) nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{ {
// XXX remove the following when the reflow state is fixed // call our base class
LabelHack((nsHTMLReflowState&)aReflowState, "BUG - label"); nsresult rv = nsHTMLContainerFrame::Init(aPresContext, aContent, aParent,
if (!mDidInit) { aContext, aPrevInFlow);
// create our view, we need a view to grab the mouse // create our view, we need a view to grab the mouse
nsIView* view; nsIView* view;
GetView(&aPresContext, &view); GetView(&aPresContext, &view);
@ -448,15 +454,25 @@ nsLabelFrame::Reflow(nsIPresContext& aPresContext,
GetParentWithView(&aPresContext, &parWithView); GetParentWithView(&aPresContext, &parWithView);
parWithView->GetView(&aPresContext, &parView); parWithView->GetView(&aPresContext, &parView);
// the view's size is not know yet, but its size will be kept in synch with our frame. // the view's size is not know yet, but its size will be kept in synch with our frame.
nsRect boundBox(0, 0, 500, 500); nsRect boundBox(0, 0, 0, 0);
result = view->Init(viewMan, boundBox, parView, nsnull); result = view->Init(viewMan, boundBox, parView, nsnull);
view->SetContentTransparency(PR_TRUE); view->SetContentTransparency(PR_TRUE);
viewMan->InsertChild(parView, view, 0); viewMan->InsertChild(parView, view, 0);
SetView(&aPresContext, view); SetView(&aPresContext, view);
} }
mDidInit = PR_TRUE;
return rv;
} }
NS_IMETHODIMP
nsLabelFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
// XXX remove the following when the reflow state is fixed
LabelHack((nsHTMLReflowState&)aReflowState, "BUG - label");
if (nsnull == mControlFrame) { if (nsnull == mControlFrame) {
// check to see if a form control is referenced via the "for" attribute // check to see if a form control is referenced via the "for" attribute
if (FindForControl(mControlFrame)) { if (FindForControl(mControlFrame)) {
@ -489,11 +505,12 @@ nsLabelFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowState reflowState(aPresContext, aReflowState, firstKid, availSize); nsHTMLReflowState reflowState(aPresContext, aReflowState, firstKid, availSize);
// XXX remove when reflow state is fixed // XXX remove when reflow state is fixed
LabelHack(reflowState, "label's area"); LabelHack(reflowState, "label's area");
ReflowChild(firstKid, aPresContext, aDesiredSize, reflowState, aStatus); ReflowChild(firstKid, aPresContext, aDesiredSize, reflowState,
borderPadding.left, borderPadding.top, 0, aStatus);
// Place the child // Place the child
nsRect rect = nsRect(borderPadding.left, borderPadding.top, aDesiredSize.width, aDesiredSize.height); FinishReflowChild(firstKid, aPresContext, aDesiredSize,
firstKid->SetRect(&aPresContext, rect); borderPadding.left, borderPadding.top, 0);
// add in our border and padding to the size of the child // add in our border and padding to the size of the child
aDesiredSize.width += borderPadding.left + borderPadding.right; aDesiredSize.width += borderPadding.left + borderPadding.right;

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

@ -469,6 +469,11 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext)
kidYTop = (height - childHeight - bottomInset + topInset) / 2; kidYTop = (height - childHeight - bottomInset + topInset) / 2;
} }
firstKid->MoveTo(aPresContext, kidRect.x, kidYTop); firstKid->MoveTo(aPresContext, kidRect.x, kidYTop);
if (kidYTop != kidRect.y) {
// Make sure any child views are correctly positioned. We know the inner table
// cell won't have a view
nsContainerFrame::PositionChildViews(aPresContext, firstKid);
}
} }
PRInt32 nsTableCellFrame::GetRowSpan() PRInt32 nsTableCellFrame::GetRowSpan()
@ -649,8 +654,18 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext& aPresContext,
kidReflowState.reflowCommand = nsnull; kidReflowState.reflowCommand = nsnull;
} }
// Assume the inner child will stay positioned exactly where it is. Later in
// VerticallyAlignChild() we'll move it if it turns out to be wrong. This
// avoids excessive movement and is more stable
nsPoint kidOrigin;
if (eReflowReason_Initial == aReflowState.reason) {
kidOrigin.MoveTo(leftInset, topInset);
} else {
firstKid->GetOrigin(kidOrigin);
}
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl en", firstKid, &kidReflowState, nsnull); if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl en", firstKid, &kidReflowState, nsnull);
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState, aStatus); ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
kidOrigin.x, kidOrigin.y, 0, aStatus);
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl ex", firstKid, nsnull, &kidSize); if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl ex", firstKid, nsnull, &kidSize);
#ifdef NS_DEBUG #ifdef NS_DEBUG
@ -727,8 +742,8 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext& aPresContext,
//////////////////////////////// HACK ////////////////////////////// //////////////////////////////// HACK //////////////////////////////
kidSize.width = PR_MIN(kidSize.width, availSize.width); kidSize.width = PR_MIN(kidSize.width, availSize.width);
///////////////////////////// END HACK ///////////////////////////// ///////////////////////////// END HACK /////////////////////////////
firstKid->SetRect(&aPresContext, nsRect(leftInset, topInset, FinishReflowChild(firstKid, aPresContext, kidSize,
kidSize.width, kidSize.height)); kidOrigin.x, kidOrigin.y, 0);
// Return our size and our result // Return our size and our result

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

@ -343,9 +343,8 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
nsSize(0,0), eReflowReason_Initial); nsSize(0,0), eReflowReason_Initial);
nsReflowStatus status; nsReflowStatus status;
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, status); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, status);
// note that DidReflow is called as the result of some ancestor firing off a DidReflow above me FinishReflowChild(kidFrame, aPresContext, kidSize, 0, 0, 0);
kidFrame->SetRect(&aPresContext, nsRect(0,0,0,0));
} }
aDesiredSize.width=0; aDesiredSize.width=0;
@ -454,7 +453,8 @@ NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext& aPresC
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aNextFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aNextFrame,
nsSize(aReflowState.availableWidth, nsSize(aReflowState.availableWidth,
aReflowState.availableHeight)); aReflowState.availableHeight));
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, aStatus);
aNextFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;

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

@ -1388,7 +1388,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
availSize, aReason); availSize, aReason);
// rv intentionally not set here // rv intentionally not set here
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, aStatus);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
continue; continue;
} }
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
@ -1396,10 +1397,10 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
// Note: we don't bother checking here for whether we should clear the // Note: we don't bother checking here for whether we should clear the
// isTopOfPage reflow state flag, because we're dealing with an unconstrained // isTopOfPage reflow state flag, because we're dealing with an unconstrained
// height and it isn't an issue... // height and it isn't an issue...
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, aStatus);
// Place the child since some of its content fit in us. // Place the child since some of its content fit in us.
kidFrame->SetRect(&aPresContext, nsRect(0, 0, kidSize.width, kidSize.height)); FinishReflowChild(kidFrame, aPresContext, kidSize, 0, 0, 0);
if (NS_UNCONSTRAINEDSIZE==kidSize.height) if (NS_UNCONSTRAINEDSIZE==kidSize.height)
y = NS_UNCONSTRAINEDSIZE; y = NS_UNCONSTRAINEDSIZE;
else else
@ -1428,8 +1429,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
{ {
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
availSize, aReason); availSize, aReason);
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, aStatus);
kidFrame->SetRect(&aPresContext, nsRect(0, 0, 0, 0)); FinishReflowChild(kidFrame, aPresContext, kidSize, 0, 0, 0);
} }
} }
} }
@ -2356,22 +2357,23 @@ NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
aNextFrame, aReflowState.availSize); aNextFrame, aReflowState.availSize);
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); nscoord x = aReflowState.mBorderPadding.left;
nscoord y = aReflowState.mBorderPadding.top + aReflowState.y;
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
x, y, 0, aStatus);
// Place the row group frame. Don't use PlaceChild(), because it moves // Place the row group frame. Don't use PlaceChild(), because it moves
// the footer frame as well. We'll adjust the footer frame later on in // the footer frame as well. We'll adjust the footer frame later on in
// AdjustSiblingsAfterReflow() // AdjustSiblingsAfterReflow()
nscoord x = aReflowState.mBorderPadding.left;
nscoord y = aReflowState.mBorderPadding.top + aReflowState.y;
nsRect kidRect(x, y, desiredSize.width, desiredSize.height); nsRect kidRect(x, y, desiredSize.width, desiredSize.height);
aNextFrame->SetRect(&aPresContext, kidRect); FinishReflowChild(aNextFrame, aPresContext, desiredSize, x, y, 0);
// Adjust the running y-offset // Adjust the running y-offset
aReflowState.y += kidRect.height; aReflowState.y += desiredSize.height;
// If our height is constrained, then update the available height // If our height is constrained, then update the available height
if (PR_FALSE == aReflowState.unconstrainedHeight) { if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= kidRect.height; aReflowState.availSize.height -= desiredSize.height;
} }
// Update the max element size // Update the max element size
@ -2462,19 +2464,21 @@ nscoord nsTableFrame::ComputeDesiredWidth(const nsHTMLReflowState& aReflowState)
void nsTableFrame::PlaceChild(nsIPresContext& aPresContext, void nsTableFrame::PlaceChild(nsIPresContext& aPresContext,
InnerTableReflowState& aReflowState, InnerTableReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize) nsSize& aKidMaxElementSize)
{ {
// Place and size the child // Place and size the child
aKidFrame->SetRect(&aPresContext, aKidRect); FinishReflowChild(aKidFrame, aPresContext, aDesiredSize, aX, aY, 0);
// Adjust the running y-offset // Adjust the running y-offset
aReflowState.y += aKidRect.height; aReflowState.y += aDesiredSize.height;
// If our height is constrained, then update the available height // If our height is constrained, then update the available height
if (PR_FALSE == aReflowState.unconstrainedHeight) { if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= aKidRect.height; aReflowState.availSize.height -= aDesiredSize.height;
} }
// If this is a footer row group, remember it // If this is a footer row group, remember it
@ -2500,7 +2504,7 @@ void nsTableFrame::PlaceChild(nsIPresContext& aPresContext,
// Move the footer below the body row group frame // Move the footer below the body row group frame
aReflowState.footerFrame->GetOrigin(origin); aReflowState.footerFrame->GetOrigin(origin);
origin.y += aKidRect.height; origin.y += aDesiredSize.height;
aReflowState.footerFrame->MoveTo(&aPresContext, origin.x, origin.y); aReflowState.footerFrame->MoveTo(&aPresContext, origin.x, origin.y);
} }
@ -2606,7 +2610,8 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
} }
} }
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
x, y, 0, aStatus);
// Did the child fit? // Did the child fit?
if (desiredSize.height > kidAvailSize.height) { if (desiredSize.height > kidAvailSize.height) {
if (aReflowState.firstBodySection && (kidFrame != aReflowState.firstBodySection)) { if (aReflowState.firstBodySection && (kidFrame != aReflowState.firstBodySection)) {
@ -2619,7 +2624,6 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
} }
// Place the child // Place the child
nsRect kidRect (x, y, desiredSize.width, desiredSize.height);
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay)) if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{ {
// we don't want to adjust the maxElementSize if this is an initial reflow // we don't want to adjust the maxElementSize if this is an initial reflow
@ -2627,8 +2631,10 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
nsSize *requestedMaxElementSize = nsnull; nsSize *requestedMaxElementSize = nsnull;
if (eReflowReason_Initial != aReflowState.reflowState.reason) if (eReflowReason_Initial != aReflowState.reflowState.reason)
requestedMaxElementSize = aDesiredSize.maxElementSize; requestedMaxElementSize = aDesiredSize.maxElementSize;
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
requestedMaxElementSize, kidMaxElementSize); x, y, requestedMaxElementSize, kidMaxElementSize);
} else {
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
childCount++; childCount++;
@ -2677,7 +2683,9 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
aReflowState.reflowState, kidFrame, aReflowState.reflowState, kidFrame,
nsSize(0,0), eReflowReason_Resize); nsSize(0,0), eReflowReason_Resize);
nsHTMLReflowMetrics unusedDesiredSize(nsnull); nsHTMLReflowMetrics unusedDesiredSize(nsnull);
ReflowChild(kidFrame, aPresContext, unusedDesiredSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, unusedDesiredSize, kidReflowState,
0, 0, 0, aStatus);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
// Get the next child // Get the next child
@ -2749,7 +2757,8 @@ NS_METHOD nsTableFrame::PullUpChildren(nsIPresContext& aPresContext,
kidFrame, aReflowState.availSize, kidFrame, aReflowState.availSize,
eReflowReason_Resize); eReflowReason_Resize);
rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState,
0, aReflowState.y, 0, aStatus);
// Did the child fit? // Did the child fit?
if ((kidSize.height > aReflowState.availSize.height) && mFrames.NotEmpty()) { if ((kidSize.height > aReflowState.availSize.height) && mFrames.NotEmpty()) {
@ -2760,13 +2769,14 @@ NS_METHOD nsTableFrame::PullUpChildren(nsIPresContext& aPresContext,
break; break;
} }
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
kidRect.y += aReflowState.y;
const nsStyleDisplay *childDisplay; const nsStyleDisplay *childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay)); kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay)) if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{ {
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize, *pKidMaxElementSize); PlaceChild(aPresContext, aReflowState, kidFrame, kidSize, 0,
aReflowState.y, aDesiredSize.maxElementSize, *pKidMaxElementSize);
} else {
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
// Remove the frame from its current parent // Remove the frame from its current parent

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

@ -505,7 +505,9 @@ protected:
void PlaceChild(nsIPresContext& aPresContext, void PlaceChild(nsIPresContext& aPresContext,
InnerTableReflowState& aReflowState, InnerTableReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize); nsSize& aKidMaxElementSize);

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

@ -403,7 +403,10 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext& aPres
nsSize(mRect.width, aReflowState.reflowState.availableHeight), nsSize(mRect.width, aReflowState.reflowState.availableHeight),
aReflowState.reflowState.reason); aReflowState.reflowState.reason);
captionReflowState.reflowCommand = aReflowState.reflowState.reflowCommand; captionReflowState.reflowCommand = aReflowState.reflowState.reflowCommand;
rv = ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState, aStatus);
rv = ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
mCaptionFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -440,7 +443,9 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext& aPres
nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame, nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame,
nsSize(tableWidth, aReflowState.reflowState.availableHeight), nsSize(tableWidth, aReflowState.reflowState.availableHeight),
eReflowReason_Resize); eReflowReason_Resize);
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus); rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
mInnerTableFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -579,7 +584,9 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
nscoord tableMaxWidth = PR_MAX(aReflowState.reflowState.availableWidth, mMinCaptionWidth); nscoord tableMaxWidth = PR_MAX(aReflowState.reflowState.availableWidth, mMinCaptionWidth);
nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame, nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame,
nsSize(tableMaxWidth, aReflowState.reflowState.availableHeight)); nsSize(tableMaxWidth, aReflowState.reflowState.availableHeight));
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus); rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
mInnerTableFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// if there is a caption and the width or height of the inner table changed from a successful reflow, // if there is a caption and the width or height of the inner table changed from a successful reflow,
// then reflow or move the caption as needed // then reflow or move the caption as needed
if ((nsnull != mCaptionFrame) && (PR_TRUE==NS_SUCCEEDED(rv))) { if ((nsnull != mCaptionFrame) && (PR_TRUE==NS_SUCCEEDED(rv))) {
@ -597,6 +604,7 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
// reflow the caption // reflow the caption
mCaptionFrame->WillReflow(aPresContext); mCaptionFrame->WillReflow(aPresContext);
rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus); rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
mCaptionFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
captionWasReflowed = PR_TRUE; captionWasReflowed = PR_TRUE;
if ((oldCaptionRect.height!=captionSize.height) || if ((oldCaptionRect.height!=captionSize.height) ||
(oldCaptionRect.width!=captionSize.width)) { (oldCaptionRect.width!=captionSize.width)) {
@ -694,7 +702,9 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext& aPresConte
nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame, nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame,
nsSize(mMinCaptionWidth, aReflowState.reflowState.availableHeight), nsSize(mMinCaptionWidth, aReflowState.reflowState.availableHeight),
eReflowReason_Resize); eReflowReason_Resize);
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus); rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
mInnerTableFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
else { // set innerSize as if the inner table were reflowed else { // set innerSize as if the inner table were reflowed
innerSize.height = mRect.height; innerSize.height = mRect.height;
@ -868,6 +878,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
mCaptionFrame->WillReflow(aPresContext); mCaptionFrame->WillReflow(aPresContext);
rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus); rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
mCaptionFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
mMinCaptionWidth = maxElementSize.width; mMinCaptionWidth = maxElementSize.width;
} }
} }
@ -896,8 +907,11 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
} }
innerReflowState.mComputedHeight = aReflowState.mComputedHeight; innerReflowState.mComputedHeight = aReflowState.mComputedHeight;
nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize); nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
// XXX To do this efficiently we really need to know where the inner
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus); // table will be placed. In the case of a top caption that means
// reflowing the caption first and getting its desired height...
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState,
0, 0, 0, aStatus);
// Table's max element size is the MAX of the caption's max element size // Table's max element size is the MAX of the caption's max element size
// and the inner table's max element size... // and the inner table's max element size...
@ -910,6 +924,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
// Now that we know the table width we can reflow the caption, and // Now that we know the table width we can reflow the caption, and
// place the caption and the inner table // place the caption and the inner table
nscoord innerY = 0;
if (nsnull != mCaptionFrame) { if (nsnull != mCaptionFrame) {
// Get the caption's margin // Get the caption's margin
nsMargin captionMargin; nsMargin captionMargin;
@ -934,9 +949,8 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
nsRect captionRect(captionMargin.left, captionY, 0, 0); nsRect captionRect(captionMargin.left, captionY, 0, 0);
nsReflowStatus captionStatus; nsReflowStatus captionStatus;
mCaptionFrame->WillReflow(aPresContext); ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState,
mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, captionRect.x, captionRect.y, 0, captionStatus);
captionStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(captionStatus), "unexpected reflow status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(captionStatus), "unexpected reflow status");
// XXX If the height is constrained then we need to check whether the inner // XXX If the height is constrained then we need to check whether the inner
@ -944,10 +958,10 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
// Place the caption // Place the caption
captionRect.SizeTo(captionSize.width, captionSize.height); captionRect.SizeTo(captionSize.width, captionSize.height);
mCaptionFrame->SetRect(&aPresContext, captionRect); FinishReflowChild(mCaptionFrame, aPresContext, captionSize,
captionRect.x, captionRect.y, 0);
// Place the inner table // Place the inner table
nscoord innerY;
if (NS_SIDE_BOTTOM != captionTableStyle->mCaptionSide) { if (NS_SIDE_BOTTOM != captionTableStyle->mCaptionSide) {
// top caption // top caption
innerY = captionRect.YMost() + captionMargin.bottom; innerY = captionRect.YMost() + captionMargin.bottom;
@ -958,16 +972,17 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
innerY = 0; innerY = 0;
state.y = captionRect.YMost() + captionMargin.bottom; state.y = captionRect.YMost() + captionMargin.bottom;
} }
nsRect innerRect(0, innerY, innerSize.width, innerSize.height);
mInnerTableFrame->SetRect(&aPresContext, innerRect);
} }
else { else {
// Place the inner table // Place the inner table at 0
nsRect innerRect(0, 0, innerSize.width, innerSize.height); innerY = 0;
mInnerTableFrame->SetRect(&aPresContext, innerRect);
state.y = innerSize.height; state.y = innerSize.height;
} }
// Finish the inner table reflow
FinishReflowChild(mInnerTableFrame, aPresContext, innerSize,
0, innerY, 0);
} }
// Return our desired rect // Return our desired rect
@ -980,38 +995,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
return rv; return rv;
} }
// Position and size aKidFrame and update our reflow state. The origin of
// aKidRect is relative to the upper-left origin of our frame, and includes
// any left/top margin.
void nsTableOuterFrame::PlaceChild(OuterTableReflowState& aReflowState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize)
{
// Place and size the child
aKidFrame->SetRect(aReflowState.pc, aKidRect);
// Adjust the running y-offset
aReflowState.y += aKidRect.height;
// If our height is constrained then update the available height
if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= aKidRect.height;
}
/* Update the maximum element size, which is the max of:
* the maxElementSize of our first row
* or the maxElementSize of the caption if we include it
*/
if (aKidFrame == mCaptionFrame) {
if (nsnull != aMaxElementSize) {
aMaxElementSize->width = aKidMaxElementSize.width;
aMaxElementSize->height = aKidMaxElementSize.height;
}
}
}
NS_METHOD nsTableOuterFrame::VerifyTree() const NS_METHOD nsTableOuterFrame::VerifyTree() const
{ {
return NS_OK; return NS_OK;

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

@ -137,25 +137,6 @@ protected:
*/ */
PRBool NeedsReflow(const nsHTMLReflowState& aReflowState); PRBool NeedsReflow(const nsHTMLReflowState& aReflowState);
/** position the child frame
* @param aReflowState the state of the reflow process
* @param aKidFrame the frame to place.
* @param aKidRect the computed dimensions of aKidFrame. The origin of aKidRect
* is relative to the upper-left origin of this frame.
* @param aMaxElementSize the table's maxElementSize
* may be nsnull, meaning that we're not computing maxElementSize during this reflow
* set to the caption's maxElementSize, if aKidFrame is the caption
* the tables maxElementSize eventually gets set to the max of
* the value here and the value of the inner table, elsewhere during reflow.
* @param aKidMaxElementSize the maxElementSize of aKidFrame, if available
*/
void PlaceChild(OuterTableReflowState& aReflowState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
/** compute the width available to the table during reflow, based on /** compute the width available to the table during reflow, based on
* the reflow state and the table's style. * the reflow state and the table's style.
* @return the computed width * @return the computed width

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

@ -334,6 +334,9 @@ nsTableRowFrame::DidResize(nsIPresContext& aPresContext,
cellFrame->GetSize(cellFrameSize); cellFrame->GetSize(cellFrameSize);
//if (cellFrameSize.height!=cellHeight) //if (cellFrameSize.height!=cellHeight)
{ {
// XXX If the cell frame has a view, then we need to resize
// it as well. We would like to only do that if the cell's size
// is changing. Why is the 'if' stmt above commented out?
cellFrame->SizeTo(&aPresContext, cellFrameSize.width, cellHeight); cellFrame->SizeTo(&aPresContext, cellFrameSize.width, cellHeight);
// realign cell content based on the new height // realign cell content based on the new height
/*nsHTMLReflowMetrics desiredSize(nsnull); /*nsHTMLReflowMetrics desiredSize(nsnull);
@ -598,15 +601,17 @@ void nsTableRowFrame::FixMinCellHeight(nsTableFrame *aTableFrame)
void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext, void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
RowReflowState& aReflowState, RowReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize* aKidMaxElementSize) nsSize* aKidMaxElementSize)
{ {
// Place and size the child // Complete the reflow
aKidFrame->SetRect(&aPresContext, aKidRect); FinishReflowChild(aKidFrame, aPresContext, aDesiredSize, aX, aY, 0);
// update the running total for the row width // update the running total for the row width
aReflowState.x += aKidRect.width; aReflowState.x += aDesiredSize.width;
// Update the maximum element size // Update the maximum element size
PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan((nsTableCellFrame*)aKidFrame); PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan((nsTableCellFrame*)aKidFrame);
@ -644,14 +649,14 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
#else #else
if (1 == rowSpan) { if (1 == rowSpan) {
// Update maxCellHeight // Update maxCellHeight
if (aKidRect.height > aReflowState.maxCellHeight) if (aDesiredSize.height > aReflowState.maxCellHeight)
aReflowState.maxCellHeight = aKidRect.height; aReflowState.maxCellHeight = aDesiredSize.height;
// Update maxCellVertSpace // Update maxCellVertSpace
nsMargin margin; nsMargin margin;
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK) { if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK) {
nscoord height = aKidRect.height + margin.top + margin.bottom; nscoord height = aDesiredSize.height + margin.top + margin.bottom;
if (height > aReflowState.maxCellVertSpace) if (height > aReflowState.maxCellVertSpace)
aReflowState.maxCellVertSpace = height; aReflowState.maxCellVertSpace = height;
@ -887,7 +892,8 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
kidAvailSize, kidAvailSize,
reason); reason);
nsReflowStatus status; nsReflowStatus status;
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status); rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, status);
#ifdef NS_DEBUG #ifdef NS_DEBUG
if (desiredSize.width > availWidth) if (desiredSize.width > availWidth)
{ {
@ -925,10 +931,8 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
desiredSize.height, availWidth); desiredSize.height, availWidth);
// Place the child // Place the child
nsRect kidRect (aReflowState.x, GetChildMaxTopMargin(), desiredSize.width, PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
desiredSize.height); aReflowState.x, GetChildMaxTopMargin(),
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect,
aDesiredSize.maxElementSize, kidMaxElementSize); aDesiredSize.maxElementSize, kidMaxElementSize);
} }
@ -939,7 +943,8 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
nsSize(0,0), eReflowReason_Resize); nsSize(0,0), eReflowReason_Resize);
nsHTMLReflowMetrics desiredSize(nsnull); nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status; nsReflowStatus status;
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status); ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, status);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
} }
@ -1037,7 +1042,8 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
kidFrame, kidAvailSize, kidFrame, kidAvailSize,
eReflowReason_Initial); eReflowReason_Initial);
rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState,
x + kidMargin.left, kidMargin.top, 0, aStatus);
// the following signals bugs in the content frames. // the following signals bugs in the content frames.
if (kidMaxElementSize.width > kidSize.width) { if (kidMaxElementSize.width > kidSize.width) {
@ -1057,9 +1063,8 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
// Place the child // Place the child
x += kidMargin.left; x += kidMargin.left;
nsRect kidRect(x, kidMargin.top, kidSize.width, kidSize.height); PlaceChild(aPresContext, aReflowState, kidFrame, kidSize, x, kidMargin.top,
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize, aDesiredSize.maxElementSize, &kidMaxElementSize);
&kidMaxElementSize);
x += kidSize.width + kidMargin.right; x += kidSize.width + kidMargin.right;
} }
else else
@ -1067,7 +1072,8 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
kidFrame, nsSize(0,0), eReflowReason_Initial); kidFrame, nsSize(0,0), eReflowReason_Initial);
nsHTMLReflowMetrics desiredSize(nsnull); nsHTMLReflowMetrics desiredSize(nsnull);
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, aStatus);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
if (PR_FALSE==aDoSiblings) if (PR_FALSE==aDoSiblings)
break; break;
@ -1291,7 +1297,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
// Reflow the cell passing it the incremental reflow command. We can't pass // Reflow the cell passing it the incremental reflow command. We can't pass
// in a max width of NS_UNCONSTRAINEDSIZE, because the max width must match // in a max width of NS_UNCONSTRAINEDSIZE, because the max width must match
// the width of the previous reflow... // the width of the previous reflow...
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
//XXX: this is a hack, shouldn't it be the case that a min size is //XXX: this is a hack, shouldn't it be the case that a min size is
// never larger than a desired size? // never larger than a desired size?
@ -1325,7 +1332,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
kidReflowState.reason = eReflowReason_Initial; kidReflowState.reason = eReflowReason_Initial;
kidReflowState.reflowCommand = nsnull; kidReflowState.reflowCommand = nsnull;
kidReflowState.availableWidth = NS_UNCONSTRAINEDSIZE; kidReflowState.availableWidth = NS_UNCONSTRAINEDSIZE;
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
//XXX: this is a hack, shouldn't it be the case that a min size is //XXX: this is a hack, shouldn't it be the case that a min size is
// never larger than a desired size? // never larger than a desired size?
@ -1355,7 +1363,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
// again this time constraining the width back to the column width again // again this time constraining the width back to the column width again
kidReflowState.reason = eReflowReason_Resize; kidReflowState.reason = eReflowReason_Resize;
kidReflowState.availableWidth = cellAvailWidth; kidReflowState.availableWidth = cellAvailWidth;
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
} else { } else {
// The column widths need to be rebalanced, so don't waste time reflowing // The column widths need to be rebalanced, so don't waste time reflowing
@ -1371,10 +1380,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
cellAvailWidth); cellAvailWidth);
// Now place the child // Now place the child
nsRect kidRect (aReflowState.x, GetChildMaxTopMargin(), desiredSize.width, PlaceChild(aPresContext, aReflowState, aNextFrame, desiredSize, aReflowState.x,
desiredSize.height); GetChildMaxTopMargin(), aDesiredSize.maxElementSize, &kidMaxElementSize);
PlaceChild(aPresContext, aReflowState, aNextFrame, kidRect,
aDesiredSize.maxElementSize, &kidMaxElementSize);
SetMaxChildHeight(aReflowState.maxCellHeight); SetMaxChildHeight(aReflowState.maxCellHeight);
@ -1517,9 +1524,11 @@ void nsTableRowFrame::ReflowCellFrame(nsIPresContext& aPresContext,
eReflowReason_Resize); eReflowReason_Resize);
nsHTMLReflowMetrics desiredSize(nsnull); nsHTMLReflowMetrics desiredSize(nsnull);
ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState, aStatus); ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
aCellFrame->SizeTo(&aPresContext, cellSize.width, aAvailableHeight); aCellFrame->SizeTo(&aPresContext, cellSize.width, aAvailableHeight);
aCellFrame->VerticallyAlignChild(&aPresContext); aCellFrame->VerticallyAlignChild(&aPresContext);
aCellFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
/** /**

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

@ -251,7 +251,9 @@ protected:
void PlaceChild(nsIPresContext& aPresContext, void PlaceChild(nsIPresContext& aPresContext,
RowReflowState& aState, RowReflowState& aState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize* aKidMaxElementSize); nsSize* aKidMaxElementSize);

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

@ -342,19 +342,21 @@ nsTableRowGroupFrame::GetFrameForPoint(nsIPresContext* aPresContext,
void nsTableRowGroupFrame::PlaceChild(nsIPresContext& aPresContext, void nsTableRowGroupFrame::PlaceChild(nsIPresContext& aPresContext,
RowGroupReflowState& aReflowState, RowGroupReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize) nsSize& aKidMaxElementSize)
{ {
// Place and size the child // Place and size the child
aKidFrame->SetRect(&aPresContext, aKidRect); FinishReflowChild(aKidFrame, aPresContext, aDesiredSize, aX, aY, 0);
// Adjust the running y-offset // Adjust the running y-offset
aReflowState.y += aKidRect.height; aReflowState.y += aDesiredSize.height;
// If our height is constrained then update the available height // If our height is constrained then update the available height
if (PR_FALSE == aReflowState.unconstrainedHeight) { if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= aKidRect.height; aReflowState.availSize.height -= aDesiredSize.height;
} }
// Update the maximum element size // Update the maximum element size
@ -457,12 +459,13 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
} }
} }
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
0, aReflowState.y, 0, aStatus);
// Place the child // Place the child
nsRect kidRect (0, aReflowState.y, desiredSize.width, desiredSize.height); nsRect kidRect (0, aReflowState.y, desiredSize.width, desiredSize.height);
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize, PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize, 0,
kidMaxElementSize); aReflowState.y, aDesiredSize.maxElementSize, kidMaxElementSize);
/* if the table has collapsing borders, we need to reset the length of the shared vertical borders /* if the table has collapsing borders, we need to reset the length of the shared vertical borders
* for the table and the cells that overlap this row * for the table and the cells that overlap this row
@ -877,8 +880,10 @@ nsTableRowGroupFrame::SplitRowGroup(nsIPresContext& aPresContext,
availSize, eReflowReason_Resize); availSize, eReflowReason_Resize);
nsHTMLReflowMetrics desiredSize(nsnull); nsHTMLReflowMetrics desiredSize(nsnull);
rv = ReflowChild(rowFrame, aPresContext, desiredSize, rowReflowState, aStatus); rv = ReflowChild(rowFrame, aPresContext, desiredSize, rowReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
rowFrame->SizeTo(&aPresContext, desiredSize.width, desiredSize.height); rowFrame->SizeTo(&aPresContext, desiredSize.width, desiredSize.height);
rowFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState); ((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState);
aDesiredSize.height = desiredSize.height; aDesiredSize.height = desiredSize.height;
@ -1507,12 +1512,13 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext& aPresConte
nsSize kidMaxElementSize; nsSize kidMaxElementSize;
nsHTMLReflowMetrics desiredSize(aDesiredSize.maxElementSize ? &kidMaxElementSize : nsnull); nsHTMLReflowMetrics desiredSize(aDesiredSize.maxElementSize ? &kidMaxElementSize : nsnull);
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
0, aReflowState.y, 0, aStatus);
// Place the row frame // Place the row frame
nsRect kidRect(0, aReflowState.y, desiredSize.width, desiredSize.height); nsRect kidRect(0, aReflowState.y, desiredSize.width, desiredSize.height);
PlaceChild(aPresContext, aReflowState, aNextFrame, kidRect, PlaceChild(aPresContext, aReflowState, aNextFrame, desiredSize, 0,
aDesiredSize.maxElementSize, kidMaxElementSize); aReflowState.y, aDesiredSize.maxElementSize, kidMaxElementSize);
// See if the table needs a reflow (e.g., if the column widths have // See if the table needs a reflow (e.g., if the column widths have
// changed). If so, just return and don't bother adjusting the rows // changed). If so, just return and don't bother adjusting the rows

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

@ -205,7 +205,9 @@ protected:
void PlaceChild(nsIPresContext& aPresContext, void PlaceChild(nsIPresContext& aPresContext,
RowGroupReflowState& aReflowState, RowGroupReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize); nsSize& aKidMaxElementSize);

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

@ -469,6 +469,11 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext)
kidYTop = (height - childHeight - bottomInset + topInset) / 2; kidYTop = (height - childHeight - bottomInset + topInset) / 2;
} }
firstKid->MoveTo(aPresContext, kidRect.x, kidYTop); firstKid->MoveTo(aPresContext, kidRect.x, kidYTop);
if (kidYTop != kidRect.y) {
// Make sure any child views are correctly positioned. We know the inner table
// cell won't have a view
nsContainerFrame::PositionChildViews(aPresContext, firstKid);
}
} }
PRInt32 nsTableCellFrame::GetRowSpan() PRInt32 nsTableCellFrame::GetRowSpan()
@ -649,8 +654,18 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext& aPresContext,
kidReflowState.reflowCommand = nsnull; kidReflowState.reflowCommand = nsnull;
} }
// Assume the inner child will stay positioned exactly where it is. Later in
// VerticallyAlignChild() we'll move it if it turns out to be wrong. This
// avoids excessive movement and is more stable
nsPoint kidOrigin;
if (eReflowReason_Initial == aReflowState.reason) {
kidOrigin.MoveTo(leftInset, topInset);
} else {
firstKid->GetOrigin(kidOrigin);
}
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl en", firstKid, &kidReflowState, nsnull); if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl en", firstKid, &kidReflowState, nsnull);
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState, aStatus); ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
kidOrigin.x, kidOrigin.y, 0, aStatus);
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl ex", firstKid, nsnull, &kidSize); if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl ex", firstKid, nsnull, &kidSize);
#ifdef NS_DEBUG #ifdef NS_DEBUG
@ -727,8 +742,8 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext& aPresContext,
//////////////////////////////// HACK ////////////////////////////// //////////////////////////////// HACK //////////////////////////////
kidSize.width = PR_MIN(kidSize.width, availSize.width); kidSize.width = PR_MIN(kidSize.width, availSize.width);
///////////////////////////// END HACK ///////////////////////////// ///////////////////////////// END HACK /////////////////////////////
firstKid->SetRect(&aPresContext, nsRect(leftInset, topInset, FinishReflowChild(firstKid, aPresContext, kidSize,
kidSize.width, kidSize.height)); kidOrigin.x, kidOrigin.y, 0);
// Return our size and our result // Return our size and our result

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

@ -343,9 +343,8 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
nsSize(0,0), eReflowReason_Initial); nsSize(0,0), eReflowReason_Initial);
nsReflowStatus status; nsReflowStatus status;
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, status); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, status);
// note that DidReflow is called as the result of some ancestor firing off a DidReflow above me FinishReflowChild(kidFrame, aPresContext, kidSize, 0, 0, 0);
kidFrame->SetRect(&aPresContext, nsRect(0,0,0,0));
} }
aDesiredSize.width=0; aDesiredSize.width=0;
@ -454,7 +453,8 @@ NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext& aPresC
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aNextFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aNextFrame,
nsSize(aReflowState.availableWidth, nsSize(aReflowState.availableWidth,
aReflowState.availableHeight)); aReflowState.availableHeight));
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, aStatus);
aNextFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;

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

@ -1388,7 +1388,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
availSize, aReason); availSize, aReason);
// rv intentionally not set here // rv intentionally not set here
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, aStatus);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
continue; continue;
} }
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
@ -1396,10 +1397,10 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
// Note: we don't bother checking here for whether we should clear the // Note: we don't bother checking here for whether we should clear the
// isTopOfPage reflow state flag, because we're dealing with an unconstrained // isTopOfPage reflow state flag, because we're dealing with an unconstrained
// height and it isn't an issue... // height and it isn't an issue...
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, aStatus);
// Place the child since some of its content fit in us. // Place the child since some of its content fit in us.
kidFrame->SetRect(&aPresContext, nsRect(0, 0, kidSize.width, kidSize.height)); FinishReflowChild(kidFrame, aPresContext, kidSize, 0, 0, 0);
if (NS_UNCONSTRAINEDSIZE==kidSize.height) if (NS_UNCONSTRAINEDSIZE==kidSize.height)
y = NS_UNCONSTRAINEDSIZE; y = NS_UNCONSTRAINEDSIZE;
else else
@ -1428,8 +1429,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
{ {
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
availSize, aReason); availSize, aReason);
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, aStatus);
kidFrame->SetRect(&aPresContext, nsRect(0, 0, 0, 0)); FinishReflowChild(kidFrame, aPresContext, kidSize, 0, 0, 0);
} }
} }
} }
@ -2356,22 +2357,23 @@ NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
aNextFrame, aReflowState.availSize); aNextFrame, aReflowState.availSize);
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); nscoord x = aReflowState.mBorderPadding.left;
nscoord y = aReflowState.mBorderPadding.top + aReflowState.y;
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
x, y, 0, aStatus);
// Place the row group frame. Don't use PlaceChild(), because it moves // Place the row group frame. Don't use PlaceChild(), because it moves
// the footer frame as well. We'll adjust the footer frame later on in // the footer frame as well. We'll adjust the footer frame later on in
// AdjustSiblingsAfterReflow() // AdjustSiblingsAfterReflow()
nscoord x = aReflowState.mBorderPadding.left;
nscoord y = aReflowState.mBorderPadding.top + aReflowState.y;
nsRect kidRect(x, y, desiredSize.width, desiredSize.height); nsRect kidRect(x, y, desiredSize.width, desiredSize.height);
aNextFrame->SetRect(&aPresContext, kidRect); FinishReflowChild(aNextFrame, aPresContext, desiredSize, x, y, 0);
// Adjust the running y-offset // Adjust the running y-offset
aReflowState.y += kidRect.height; aReflowState.y += desiredSize.height;
// If our height is constrained, then update the available height // If our height is constrained, then update the available height
if (PR_FALSE == aReflowState.unconstrainedHeight) { if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= kidRect.height; aReflowState.availSize.height -= desiredSize.height;
} }
// Update the max element size // Update the max element size
@ -2462,19 +2464,21 @@ nscoord nsTableFrame::ComputeDesiredWidth(const nsHTMLReflowState& aReflowState)
void nsTableFrame::PlaceChild(nsIPresContext& aPresContext, void nsTableFrame::PlaceChild(nsIPresContext& aPresContext,
InnerTableReflowState& aReflowState, InnerTableReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize) nsSize& aKidMaxElementSize)
{ {
// Place and size the child // Place and size the child
aKidFrame->SetRect(&aPresContext, aKidRect); FinishReflowChild(aKidFrame, aPresContext, aDesiredSize, aX, aY, 0);
// Adjust the running y-offset // Adjust the running y-offset
aReflowState.y += aKidRect.height; aReflowState.y += aDesiredSize.height;
// If our height is constrained, then update the available height // If our height is constrained, then update the available height
if (PR_FALSE == aReflowState.unconstrainedHeight) { if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= aKidRect.height; aReflowState.availSize.height -= aDesiredSize.height;
} }
// If this is a footer row group, remember it // If this is a footer row group, remember it
@ -2500,7 +2504,7 @@ void nsTableFrame::PlaceChild(nsIPresContext& aPresContext,
// Move the footer below the body row group frame // Move the footer below the body row group frame
aReflowState.footerFrame->GetOrigin(origin); aReflowState.footerFrame->GetOrigin(origin);
origin.y += aKidRect.height; origin.y += aDesiredSize.height;
aReflowState.footerFrame->MoveTo(&aPresContext, origin.x, origin.y); aReflowState.footerFrame->MoveTo(&aPresContext, origin.x, origin.y);
} }
@ -2606,7 +2610,8 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
} }
} }
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
x, y, 0, aStatus);
// Did the child fit? // Did the child fit?
if (desiredSize.height > kidAvailSize.height) { if (desiredSize.height > kidAvailSize.height) {
if (aReflowState.firstBodySection && (kidFrame != aReflowState.firstBodySection)) { if (aReflowState.firstBodySection && (kidFrame != aReflowState.firstBodySection)) {
@ -2619,7 +2624,6 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
} }
// Place the child // Place the child
nsRect kidRect (x, y, desiredSize.width, desiredSize.height);
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay)) if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{ {
// we don't want to adjust the maxElementSize if this is an initial reflow // we don't want to adjust the maxElementSize if this is an initial reflow
@ -2627,8 +2631,10 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
nsSize *requestedMaxElementSize = nsnull; nsSize *requestedMaxElementSize = nsnull;
if (eReflowReason_Initial != aReflowState.reflowState.reason) if (eReflowReason_Initial != aReflowState.reflowState.reason)
requestedMaxElementSize = aDesiredSize.maxElementSize; requestedMaxElementSize = aDesiredSize.maxElementSize;
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
requestedMaxElementSize, kidMaxElementSize); x, y, requestedMaxElementSize, kidMaxElementSize);
} else {
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
childCount++; childCount++;
@ -2677,7 +2683,9 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
aReflowState.reflowState, kidFrame, aReflowState.reflowState, kidFrame,
nsSize(0,0), eReflowReason_Resize); nsSize(0,0), eReflowReason_Resize);
nsHTMLReflowMetrics unusedDesiredSize(nsnull); nsHTMLReflowMetrics unusedDesiredSize(nsnull);
ReflowChild(kidFrame, aPresContext, unusedDesiredSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, unusedDesiredSize, kidReflowState,
0, 0, 0, aStatus);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
// Get the next child // Get the next child
@ -2749,7 +2757,8 @@ NS_METHOD nsTableFrame::PullUpChildren(nsIPresContext& aPresContext,
kidFrame, aReflowState.availSize, kidFrame, aReflowState.availSize,
eReflowReason_Resize); eReflowReason_Resize);
rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState,
0, aReflowState.y, 0, aStatus);
// Did the child fit? // Did the child fit?
if ((kidSize.height > aReflowState.availSize.height) && mFrames.NotEmpty()) { if ((kidSize.height > aReflowState.availSize.height) && mFrames.NotEmpty()) {
@ -2760,13 +2769,14 @@ NS_METHOD nsTableFrame::PullUpChildren(nsIPresContext& aPresContext,
break; break;
} }
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
kidRect.y += aReflowState.y;
const nsStyleDisplay *childDisplay; const nsStyleDisplay *childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay)); kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay)) if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{ {
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize, *pKidMaxElementSize); PlaceChild(aPresContext, aReflowState, kidFrame, kidSize, 0,
aReflowState.y, aDesiredSize.maxElementSize, *pKidMaxElementSize);
} else {
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
// Remove the frame from its current parent // Remove the frame from its current parent

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

@ -505,7 +505,9 @@ protected:
void PlaceChild(nsIPresContext& aPresContext, void PlaceChild(nsIPresContext& aPresContext,
InnerTableReflowState& aReflowState, InnerTableReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize); nsSize& aKidMaxElementSize);

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

@ -403,7 +403,10 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext& aPres
nsSize(mRect.width, aReflowState.reflowState.availableHeight), nsSize(mRect.width, aReflowState.reflowState.availableHeight),
aReflowState.reflowState.reason); aReflowState.reflowState.reason);
captionReflowState.reflowCommand = aReflowState.reflowState.reflowCommand; captionReflowState.reflowCommand = aReflowState.reflowState.reflowCommand;
rv = ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState, aStatus);
rv = ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
mCaptionFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -440,7 +443,9 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext& aPres
nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame, nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame,
nsSize(tableWidth, aReflowState.reflowState.availableHeight), nsSize(tableWidth, aReflowState.reflowState.availableHeight),
eReflowReason_Resize); eReflowReason_Resize);
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus); rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
mInnerTableFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -579,7 +584,9 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
nscoord tableMaxWidth = PR_MAX(aReflowState.reflowState.availableWidth, mMinCaptionWidth); nscoord tableMaxWidth = PR_MAX(aReflowState.reflowState.availableWidth, mMinCaptionWidth);
nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame, nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame,
nsSize(tableMaxWidth, aReflowState.reflowState.availableHeight)); nsSize(tableMaxWidth, aReflowState.reflowState.availableHeight));
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus); rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
mInnerTableFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// if there is a caption and the width or height of the inner table changed from a successful reflow, // if there is a caption and the width or height of the inner table changed from a successful reflow,
// then reflow or move the caption as needed // then reflow or move the caption as needed
if ((nsnull != mCaptionFrame) && (PR_TRUE==NS_SUCCEEDED(rv))) { if ((nsnull != mCaptionFrame) && (PR_TRUE==NS_SUCCEEDED(rv))) {
@ -597,6 +604,7 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext& aPresCont
// reflow the caption // reflow the caption
mCaptionFrame->WillReflow(aPresContext); mCaptionFrame->WillReflow(aPresContext);
rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus); rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
mCaptionFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
captionWasReflowed = PR_TRUE; captionWasReflowed = PR_TRUE;
if ((oldCaptionRect.height!=captionSize.height) || if ((oldCaptionRect.height!=captionSize.height) ||
(oldCaptionRect.width!=captionSize.width)) { (oldCaptionRect.width!=captionSize.width)) {
@ -694,7 +702,9 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext& aPresConte
nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame, nsHTMLReflowState innerReflowState(aPresContext, aReflowState.reflowState, mInnerTableFrame,
nsSize(mMinCaptionWidth, aReflowState.reflowState.availableHeight), nsSize(mMinCaptionWidth, aReflowState.reflowState.availableHeight),
eReflowReason_Resize); eReflowReason_Resize);
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus); rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
mInnerTableFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
else { // set innerSize as if the inner table were reflowed else { // set innerSize as if the inner table were reflowed
innerSize.height = mRect.height; innerSize.height = mRect.height;
@ -868,6 +878,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
mCaptionFrame->WillReflow(aPresContext); mCaptionFrame->WillReflow(aPresContext);
rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus); rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
mCaptionFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
mMinCaptionWidth = maxElementSize.width; mMinCaptionWidth = maxElementSize.width;
} }
} }
@ -896,8 +907,11 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
} }
innerReflowState.mComputedHeight = aReflowState.mComputedHeight; innerReflowState.mComputedHeight = aReflowState.mComputedHeight;
nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize); nsHTMLReflowMetrics innerSize(aDesiredSize.maxElementSize);
// XXX To do this efficiently we really need to know where the inner
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState, aStatus); // table will be placed. In the case of a top caption that means
// reflowing the caption first and getting its desired height...
rv = ReflowChild(mInnerTableFrame, aPresContext, innerSize, innerReflowState,
0, 0, 0, aStatus);
// Table's max element size is the MAX of the caption's max element size // Table's max element size is the MAX of the caption's max element size
// and the inner table's max element size... // and the inner table's max element size...
@ -910,6 +924,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
// Now that we know the table width we can reflow the caption, and // Now that we know the table width we can reflow the caption, and
// place the caption and the inner table // place the caption and the inner table
nscoord innerY = 0;
if (nsnull != mCaptionFrame) { if (nsnull != mCaptionFrame) {
// Get the caption's margin // Get the caption's margin
nsMargin captionMargin; nsMargin captionMargin;
@ -934,9 +949,8 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
nsRect captionRect(captionMargin.left, captionY, 0, 0); nsRect captionRect(captionMargin.left, captionY, 0, 0);
nsReflowStatus captionStatus; nsReflowStatus captionStatus;
mCaptionFrame->WillReflow(aPresContext); ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState,
mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, captionRect.x, captionRect.y, 0, captionStatus);
captionStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(captionStatus), "unexpected reflow status"); NS_ASSERTION(NS_FRAME_IS_COMPLETE(captionStatus), "unexpected reflow status");
// XXX If the height is constrained then we need to check whether the inner // XXX If the height is constrained then we need to check whether the inner
@ -944,10 +958,10 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
// Place the caption // Place the caption
captionRect.SizeTo(captionSize.width, captionSize.height); captionRect.SizeTo(captionSize.width, captionSize.height);
mCaptionFrame->SetRect(&aPresContext, captionRect); FinishReflowChild(mCaptionFrame, aPresContext, captionSize,
captionRect.x, captionRect.y, 0);
// Place the inner table // Place the inner table
nscoord innerY;
if (NS_SIDE_BOTTOM != captionTableStyle->mCaptionSide) { if (NS_SIDE_BOTTOM != captionTableStyle->mCaptionSide) {
// top caption // top caption
innerY = captionRect.YMost() + captionMargin.bottom; innerY = captionRect.YMost() + captionMargin.bottom;
@ -958,16 +972,17 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
innerY = 0; innerY = 0;
state.y = captionRect.YMost() + captionMargin.bottom; state.y = captionRect.YMost() + captionMargin.bottom;
} }
nsRect innerRect(0, innerY, innerSize.width, innerSize.height);
mInnerTableFrame->SetRect(&aPresContext, innerRect);
} }
else { else {
// Place the inner table // Place the inner table at 0
nsRect innerRect(0, 0, innerSize.width, innerSize.height); innerY = 0;
mInnerTableFrame->SetRect(&aPresContext, innerRect);
state.y = innerSize.height; state.y = innerSize.height;
} }
// Finish the inner table reflow
FinishReflowChild(mInnerTableFrame, aPresContext, innerSize,
0, innerY, 0);
} }
// Return our desired rect // Return our desired rect
@ -980,38 +995,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext,
return rv; return rv;
} }
// Position and size aKidFrame and update our reflow state. The origin of
// aKidRect is relative to the upper-left origin of our frame, and includes
// any left/top margin.
void nsTableOuterFrame::PlaceChild(OuterTableReflowState& aReflowState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize)
{
// Place and size the child
aKidFrame->SetRect(aReflowState.pc, aKidRect);
// Adjust the running y-offset
aReflowState.y += aKidRect.height;
// If our height is constrained then update the available height
if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= aKidRect.height;
}
/* Update the maximum element size, which is the max of:
* the maxElementSize of our first row
* or the maxElementSize of the caption if we include it
*/
if (aKidFrame == mCaptionFrame) {
if (nsnull != aMaxElementSize) {
aMaxElementSize->width = aKidMaxElementSize.width;
aMaxElementSize->height = aKidMaxElementSize.height;
}
}
}
NS_METHOD nsTableOuterFrame::VerifyTree() const NS_METHOD nsTableOuterFrame::VerifyTree() const
{ {
return NS_OK; return NS_OK;

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

@ -137,25 +137,6 @@ protected:
*/ */
PRBool NeedsReflow(const nsHTMLReflowState& aReflowState); PRBool NeedsReflow(const nsHTMLReflowState& aReflowState);
/** position the child frame
* @param aReflowState the state of the reflow process
* @param aKidFrame the frame to place.
* @param aKidRect the computed dimensions of aKidFrame. The origin of aKidRect
* is relative to the upper-left origin of this frame.
* @param aMaxElementSize the table's maxElementSize
* may be nsnull, meaning that we're not computing maxElementSize during this reflow
* set to the caption's maxElementSize, if aKidFrame is the caption
* the tables maxElementSize eventually gets set to the max of
* the value here and the value of the inner table, elsewhere during reflow.
* @param aKidMaxElementSize the maxElementSize of aKidFrame, if available
*/
void PlaceChild(OuterTableReflowState& aReflowState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
/** compute the width available to the table during reflow, based on /** compute the width available to the table during reflow, based on
* the reflow state and the table's style. * the reflow state and the table's style.
* @return the computed width * @return the computed width

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

@ -334,6 +334,9 @@ nsTableRowFrame::DidResize(nsIPresContext& aPresContext,
cellFrame->GetSize(cellFrameSize); cellFrame->GetSize(cellFrameSize);
//if (cellFrameSize.height!=cellHeight) //if (cellFrameSize.height!=cellHeight)
{ {
// XXX If the cell frame has a view, then we need to resize
// it as well. We would like to only do that if the cell's size
// is changing. Why is the 'if' stmt above commented out?
cellFrame->SizeTo(&aPresContext, cellFrameSize.width, cellHeight); cellFrame->SizeTo(&aPresContext, cellFrameSize.width, cellHeight);
// realign cell content based on the new height // realign cell content based on the new height
/*nsHTMLReflowMetrics desiredSize(nsnull); /*nsHTMLReflowMetrics desiredSize(nsnull);
@ -598,15 +601,17 @@ void nsTableRowFrame::FixMinCellHeight(nsTableFrame *aTableFrame)
void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext, void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
RowReflowState& aReflowState, RowReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize* aKidMaxElementSize) nsSize* aKidMaxElementSize)
{ {
// Place and size the child // Complete the reflow
aKidFrame->SetRect(&aPresContext, aKidRect); FinishReflowChild(aKidFrame, aPresContext, aDesiredSize, aX, aY, 0);
// update the running total for the row width // update the running total for the row width
aReflowState.x += aKidRect.width; aReflowState.x += aDesiredSize.width;
// Update the maximum element size // Update the maximum element size
PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan((nsTableCellFrame*)aKidFrame); PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan((nsTableCellFrame*)aKidFrame);
@ -644,14 +649,14 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
#else #else
if (1 == rowSpan) { if (1 == rowSpan) {
// Update maxCellHeight // Update maxCellHeight
if (aKidRect.height > aReflowState.maxCellHeight) if (aDesiredSize.height > aReflowState.maxCellHeight)
aReflowState.maxCellHeight = aKidRect.height; aReflowState.maxCellHeight = aDesiredSize.height;
// Update maxCellVertSpace // Update maxCellVertSpace
nsMargin margin; nsMargin margin;
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK) { if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK) {
nscoord height = aKidRect.height + margin.top + margin.bottom; nscoord height = aDesiredSize.height + margin.top + margin.bottom;
if (height > aReflowState.maxCellVertSpace) if (height > aReflowState.maxCellVertSpace)
aReflowState.maxCellVertSpace = height; aReflowState.maxCellVertSpace = height;
@ -887,7 +892,8 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
kidAvailSize, kidAvailSize,
reason); reason);
nsReflowStatus status; nsReflowStatus status;
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status); rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, status);
#ifdef NS_DEBUG #ifdef NS_DEBUG
if (desiredSize.width > availWidth) if (desiredSize.width > availWidth)
{ {
@ -925,10 +931,8 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
desiredSize.height, availWidth); desiredSize.height, availWidth);
// Place the child // Place the child
nsRect kidRect (aReflowState.x, GetChildMaxTopMargin(), desiredSize.width, PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
desiredSize.height); aReflowState.x, GetChildMaxTopMargin(),
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect,
aDesiredSize.maxElementSize, kidMaxElementSize); aDesiredSize.maxElementSize, kidMaxElementSize);
} }
@ -939,7 +943,8 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
nsSize(0,0), eReflowReason_Resize); nsSize(0,0), eReflowReason_Resize);
nsHTMLReflowMetrics desiredSize(nsnull); nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status; nsReflowStatus status;
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status); ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, status);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
} }
@ -1037,7 +1042,8 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
kidFrame, kidAvailSize, kidFrame, kidAvailSize,
eReflowReason_Initial); eReflowReason_Initial);
rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState,
x + kidMargin.left, kidMargin.top, 0, aStatus);
// the following signals bugs in the content frames. // the following signals bugs in the content frames.
if (kidMaxElementSize.width > kidSize.width) { if (kidMaxElementSize.width > kidSize.width) {
@ -1057,9 +1063,8 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
// Place the child // Place the child
x += kidMargin.left; x += kidMargin.left;
nsRect kidRect(x, kidMargin.top, kidSize.width, kidSize.height); PlaceChild(aPresContext, aReflowState, kidFrame, kidSize, x, kidMargin.top,
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize, aDesiredSize.maxElementSize, &kidMaxElementSize);
&kidMaxElementSize);
x += kidSize.width + kidMargin.right; x += kidSize.width + kidMargin.right;
} }
else else
@ -1067,7 +1072,8 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
kidFrame, nsSize(0,0), eReflowReason_Initial); kidFrame, nsSize(0,0), eReflowReason_Initial);
nsHTMLReflowMetrics desiredSize(nsnull); nsHTMLReflowMetrics desiredSize(nsnull);
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus); ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, aStatus);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
if (PR_FALSE==aDoSiblings) if (PR_FALSE==aDoSiblings)
break; break;
@ -1291,7 +1297,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
// Reflow the cell passing it the incremental reflow command. We can't pass // Reflow the cell passing it the incremental reflow command. We can't pass
// in a max width of NS_UNCONSTRAINEDSIZE, because the max width must match // in a max width of NS_UNCONSTRAINEDSIZE, because the max width must match
// the width of the previous reflow... // the width of the previous reflow...
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
//XXX: this is a hack, shouldn't it be the case that a min size is //XXX: this is a hack, shouldn't it be the case that a min size is
// never larger than a desired size? // never larger than a desired size?
@ -1325,7 +1332,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
kidReflowState.reason = eReflowReason_Initial; kidReflowState.reason = eReflowReason_Initial;
kidReflowState.reflowCommand = nsnull; kidReflowState.reflowCommand = nsnull;
kidReflowState.availableWidth = NS_UNCONSTRAINEDSIZE; kidReflowState.availableWidth = NS_UNCONSTRAINEDSIZE;
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
//XXX: this is a hack, shouldn't it be the case that a min size is //XXX: this is a hack, shouldn't it be the case that a min size is
// never larger than a desired size? // never larger than a desired size?
@ -1355,7 +1363,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
// again this time constraining the width back to the column width again // again this time constraining the width back to the column width again
kidReflowState.reason = eReflowReason_Resize; kidReflowState.reason = eReflowReason_Resize;
kidReflowState.availableWidth = cellAvailWidth; kidReflowState.availableWidth = cellAvailWidth;
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
} else { } else {
// The column widths need to be rebalanced, so don't waste time reflowing // The column widths need to be rebalanced, so don't waste time reflowing
@ -1371,10 +1380,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
cellAvailWidth); cellAvailWidth);
// Now place the child // Now place the child
nsRect kidRect (aReflowState.x, GetChildMaxTopMargin(), desiredSize.width, PlaceChild(aPresContext, aReflowState, aNextFrame, desiredSize, aReflowState.x,
desiredSize.height); GetChildMaxTopMargin(), aDesiredSize.maxElementSize, &kidMaxElementSize);
PlaceChild(aPresContext, aReflowState, aNextFrame, kidRect,
aDesiredSize.maxElementSize, &kidMaxElementSize);
SetMaxChildHeight(aReflowState.maxCellHeight); SetMaxChildHeight(aReflowState.maxCellHeight);
@ -1517,9 +1524,11 @@ void nsTableRowFrame::ReflowCellFrame(nsIPresContext& aPresContext,
eReflowReason_Resize); eReflowReason_Resize);
nsHTMLReflowMetrics desiredSize(nsnull); nsHTMLReflowMetrics desiredSize(nsnull);
ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState, aStatus); ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
aCellFrame->SizeTo(&aPresContext, cellSize.width, aAvailableHeight); aCellFrame->SizeTo(&aPresContext, cellSize.width, aAvailableHeight);
aCellFrame->VerticallyAlignChild(&aPresContext); aCellFrame->VerticallyAlignChild(&aPresContext);
aCellFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
} }
/** /**

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

@ -251,7 +251,9 @@ protected:
void PlaceChild(nsIPresContext& aPresContext, void PlaceChild(nsIPresContext& aPresContext,
RowReflowState& aState, RowReflowState& aState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize* aKidMaxElementSize); nsSize* aKidMaxElementSize);

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

@ -342,19 +342,21 @@ nsTableRowGroupFrame::GetFrameForPoint(nsIPresContext* aPresContext,
void nsTableRowGroupFrame::PlaceChild(nsIPresContext& aPresContext, void nsTableRowGroupFrame::PlaceChild(nsIPresContext& aPresContext,
RowGroupReflowState& aReflowState, RowGroupReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize) nsSize& aKidMaxElementSize)
{ {
// Place and size the child // Place and size the child
aKidFrame->SetRect(&aPresContext, aKidRect); FinishReflowChild(aKidFrame, aPresContext, aDesiredSize, aX, aY, 0);
// Adjust the running y-offset // Adjust the running y-offset
aReflowState.y += aKidRect.height; aReflowState.y += aDesiredSize.height;
// If our height is constrained then update the available height // If our height is constrained then update the available height
if (PR_FALSE == aReflowState.unconstrainedHeight) { if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= aKidRect.height; aReflowState.availSize.height -= aDesiredSize.height;
} }
// Update the maximum element size // Update the maximum element size
@ -457,12 +459,13 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
} }
} }
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
0, aReflowState.y, 0, aStatus);
// Place the child // Place the child
nsRect kidRect (0, aReflowState.y, desiredSize.width, desiredSize.height); nsRect kidRect (0, aReflowState.y, desiredSize.width, desiredSize.height);
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize, PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize, 0,
kidMaxElementSize); aReflowState.y, aDesiredSize.maxElementSize, kidMaxElementSize);
/* if the table has collapsing borders, we need to reset the length of the shared vertical borders /* if the table has collapsing borders, we need to reset the length of the shared vertical borders
* for the table and the cells that overlap this row * for the table and the cells that overlap this row
@ -877,8 +880,10 @@ nsTableRowGroupFrame::SplitRowGroup(nsIPresContext& aPresContext,
availSize, eReflowReason_Resize); availSize, eReflowReason_Resize);
nsHTMLReflowMetrics desiredSize(nsnull); nsHTMLReflowMetrics desiredSize(nsnull);
rv = ReflowChild(rowFrame, aPresContext, desiredSize, rowReflowState, aStatus); rv = ReflowChild(rowFrame, aPresContext, desiredSize, rowReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
rowFrame->SizeTo(&aPresContext, desiredSize.width, desiredSize.height); rowFrame->SizeTo(&aPresContext, desiredSize.width, desiredSize.height);
rowFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState); ((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState);
aDesiredSize.height = desiredSize.height; aDesiredSize.height = desiredSize.height;
@ -1507,12 +1512,13 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext& aPresConte
nsSize kidMaxElementSize; nsSize kidMaxElementSize;
nsHTMLReflowMetrics desiredSize(aDesiredSize.maxElementSize ? &kidMaxElementSize : nsnull); nsHTMLReflowMetrics desiredSize(aDesiredSize.maxElementSize ? &kidMaxElementSize : nsnull);
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
0, aReflowState.y, 0, aStatus);
// Place the row frame // Place the row frame
nsRect kidRect(0, aReflowState.y, desiredSize.width, desiredSize.height); nsRect kidRect(0, aReflowState.y, desiredSize.width, desiredSize.height);
PlaceChild(aPresContext, aReflowState, aNextFrame, kidRect, PlaceChild(aPresContext, aReflowState, aNextFrame, desiredSize, 0,
aDesiredSize.maxElementSize, kidMaxElementSize); aReflowState.y, aDesiredSize.maxElementSize, kidMaxElementSize);
// See if the table needs a reflow (e.g., if the column widths have // See if the table needs a reflow (e.g., if the column widths have
// changed). If so, just return and don't bother adjusting the rows // changed). If so, just return and don't bother adjusting the rows

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

@ -205,7 +205,9 @@ protected:
void PlaceChild(nsIPresContext& aPresContext, void PlaceChild(nsIPresContext& aPresContext,
RowGroupReflowState& aReflowState, RowGroupReflowState& aReflowState,
nsIFrame* aKidFrame, nsIFrame* aKidFrame,
const nsRect& aKidRect, nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize, nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize); nsSize& aKidMaxElementSize);

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

@ -971,10 +971,23 @@ nsBoxFrame::PlaceChildren(nsIPresContext& aPresContext, nsRect& boxRect)
} }
nsRect rect; nsRect rect;
nsIView* view;
childFrame->GetRect(rect); childFrame->GetRect(rect);
rect.x = x; rect.x = x;
rect.y = y; rect.y = y;
childFrame->SetRect(&aPresContext, rect); childFrame->SetRect(&aPresContext, rect);
childFrame->GetView(&aPresContext, &view);
// XXX Because we didn't position the frame or its view when reflowing
// it we must re-position all child views. This isn't optimal, and if
// we knew its final position, it would be better to position the frame
// and its view when doing the reflow...
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, childFrame,
view, nsnull);
} else {
// Re-position any child frame views
nsContainerFrame::PositionChildViews(&aPresContext, childFrame);
}
// add in the right margin // add in the right margin
if (mInner->mHorizontal) if (mInner->mHorizontal)
@ -1131,6 +1144,9 @@ nsBoxFrame::FlowChildAt(nsIFrame* childFrame,
printf("because (%s)\n", ch); printf("because (%s)\n", ch);
#endif #endif
// do the flow // do the flow
// Note that we don't position the frame (or its view) now. If we knew
// where we were going to place the child, then it would be more
// efficient to position it now...
childFrame->WillReflow(aPresContext); childFrame->WillReflow(aPresContext);
childFrame->Reflow(aPresContext, desiredSize, reflowState, aStatus); childFrame->Reflow(aPresContext, desiredSize, reflowState, aStatus);
@ -1183,8 +1199,20 @@ nsBoxFrame::FlowChildAt(nsIFrame* childFrame,
} }
// set the rect // set the rect and size the view (if it has one).. Don't position the view
// and sync its properties (like opacity) until later when we know its final
// position
childFrame->SizeTo(&aPresContext, desiredSize.width, desiredSize.height); childFrame->SizeTo(&aPresContext, desiredSize.width, desiredSize.height);
nsIView* view;
childFrame->GetView(&aPresContext, &view);
if (view) {
nsIViewManager *vm;
view->GetViewManager(vm);
vm->ResizeView(view, desiredSize.width, desiredSize.height);
NS_RELEASE(vm);
}
childFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// Stub out desiredSize.maxElementSize so that when go out of // Stub out desiredSize.maxElementSize so that when go out of
// scope, nothing bad happens! // scope, nothing bad happens!

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

@ -619,14 +619,16 @@ nsMenuFrame::Reflow(nsIPresContext& aPresContext,
if (kidReflowState.reason == eReflowReason_Incremental) if (kidReflowState.reason == eReflowReason_Incremental)
kidReflowState.reason = eReflowReason_Resize; kidReflowState.reason = eReflowReason_Resize;
rv = ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, aStatus);
// Set the child's width and height to its desired size
nsRect rect; nsRect rect;
frame->GetRect(rect); frame->GetRect(rect);
rect.width = aDesiredSize.width; rv = ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState,
rect.height = aDesiredSize.height; rect.x, rect.y, NS_FRAME_NO_MOVE_VIEW, aStatus);
frame->SetRect(&aPresContext, rect);
// Set the child's width and height to its desired size
// Note: don't position or size the view now, we'll do that in the
// DidReflow() function
frame->SizeTo(&aPresContext, aDesiredSize.width, aDesiredSize.height);
frame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// Don't let it affect our size. // Don't let it affect our size.
aDesiredSize.width = w; aDesiredSize.width = w;
@ -652,7 +654,10 @@ nsMenuFrame::DidReflow(nsIPresContext& aPresContext,
mMenuParent->IsMenuBar(onMenuBar); mMenuParent->IsMenuBar(onMenuBar);
menuPopup->SyncViewWithFrame(aPresContext, onMenuBar, this, -1, -1); menuPopup->SyncViewWithFrame(aPresContext, onMenuBar, this, -1, -1);
// XXX TROY
#if 0
menuPopup->DidReflow(aPresContext, aStatus); menuPopup->DidReflow(aPresContext, aStatus);
#endif
} }
return rv; return rv;

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

@ -271,6 +271,8 @@ nsMenuPopupFrame::DidReflow(nsIPresContext& aPresContext,
// wrong place. // wrong place.
nsresult result = NS_OK; /* = nsFrame::DidReflow(aPresContext, aStatus) */ nsresult result = NS_OK; /* = nsFrame::DidReflow(aPresContext, aStatus) */
// XXX TROY
#if 0
if (NS_FRAME_REFLOW_FINISHED == aStatus) { if (NS_FRAME_REFLOW_FINISHED == aStatus) {
// Apply DidReflow to each and every list that this frame implements // Apply DidReflow to each and every list that this frame implements
nsIAtom* listName = nsnull; nsIAtom* listName = nsnull;
@ -286,6 +288,7 @@ nsMenuPopupFrame::DidReflow(nsIPresContext& aPresContext,
GetAdditionalChildListName(listIndex++, &listName); GetAdditionalChildListName(listIndex++, &listName);
} while(nsnull != listName); } while(nsnull != listName);
} }
#endif
NS_FRAME_TRACE_OUT("nsContainerFrame::DidReflow"); NS_FRAME_TRACE_OUT("nsContainerFrame::DidReflow");
return result; return result;

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

@ -225,14 +225,13 @@ nsPopupSetFrame::Reflow(nsIPresContext& aPresContext,
nscoord w = aDesiredSize.width; nscoord w = aDesiredSize.width;
nscoord h = aDesiredSize.height; nscoord h = aDesiredSize.height;
rv = ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, aStatus);
// Set the child's width and height to its desired size
nsRect rect; nsRect rect;
frame->GetRect(rect); frame->GetRect(rect);
rect.width = aDesiredSize.width; rv = ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState,
rect.height = aDesiredSize.height; rect.x, rect.y, 0, aStatus);
frame->SetRect(&aPresContext, rect);
// Set the child's width and height to its desired size
FinishReflowChild(frame, aPresContext, aDesiredSize, rect.x, rect.y, 0);
// Don't let it affect our size. // Don't let it affect our size.
aDesiredSize.width = w; aDesiredSize.width = w;

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

@ -313,7 +313,9 @@ nsSliderFrame::ReflowThumb(nsIPresContext& aPresContext,
if (thumbReflowState.mComputedHeight != NS_INTRINSICSIZE) if (thumbReflowState.mComputedHeight != NS_INTRINSICSIZE)
thumbReflowState.mComputedHeight -= total.top + total.bottom; thumbReflowState.mComputedHeight -= total.top + total.bottom;
ReflowChild(thumbFrame, aPresContext, aDesiredSize, thumbReflowState, aStatus); ReflowChild(thumbFrame, aPresContext, aDesiredSize, thumbReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
thumbFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// add the margin back in // add the margin back in
aDesiredSize.width += margin.left + margin.right; aDesiredSize.width += margin.left + margin.right;
@ -442,7 +444,13 @@ nsSliderFrame::Reflow(nsIPresContext& aPresContext,
else else
thumbRect.y += pos; thumbRect.y += pos;
nsIView* view;
thumbFrame->SetRect(&aPresContext, thumbRect); thumbFrame->SetRect(&aPresContext, thumbRect);
thumbFrame->GetView(&aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(&aPresContext, thumbFrame,
view, nsnull);
}
// add in our border // add in our border
aDesiredSize.width += borderPadding.left + borderPadding.right; aDesiredSize.width += borderPadding.left + borderPadding.right;

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

@ -877,7 +877,8 @@ nsTreeRowGroupFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
kidReflowState.mComputedHeight = mRowGroupHeight; kidReflowState.mComputedHeight = mRowGroupHeight;
nsHTMLReflowMetrics desiredSize(nsnull); nsHTMLReflowMetrics desiredSize(nsnull);
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
nscoord xpos = 0; nscoord xpos = 0;
@ -890,8 +891,7 @@ nsTreeRowGroupFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
} }
// Place the child // Place the child
nsRect kidRect (xpos, 0, desiredSize.width, mRowGroupHeight); FinishReflowChild(aNextFrame, aPresContext, desiredSize, xpos, 0, 0);
mScrollbar->SetRect(&aPresContext, kidRect);
// Return our desired width // Return our desired width
aDesiredSize.width = aReflowState.reflowState.availableWidth; aDesiredSize.width = aReflowState.reflowState.availableWidth;
@ -999,7 +999,8 @@ nsTreeRowGroupFrame::ReflowAfterRowLayout(nsIPresContext& aPresContext,
kidAvailSize, aReason); kidAvailSize, aReason);
kidReflowState.mComputedHeight = mRowGroupHeight; kidReflowState.mComputedHeight = mRowGroupHeight;
rv = ReflowChild(mScrollbar, aPresContext, desiredSize, kidReflowState, aStatus); rv = ReflowChild(mScrollbar, aPresContext, desiredSize, kidReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
@ -1014,8 +1015,7 @@ nsTreeRowGroupFrame::ReflowAfterRowLayout(nsIPresContext& aPresContext,
} }
// Place the child // Place the child
nsRect kidRect (xpos, 0, desiredSize.width, mRowGroupHeight); FinishReflowChild(mScrollbar, aPresContext, desiredSize, xpos, 0, 0);
mScrollbar->SetRect(&aPresContext, kidRect);
} }
return rv; return rv;
} }