diff --git a/mozilla/layout/svg/base/src/nsSVGForeignObjectFrame.cpp b/mozilla/layout/svg/base/src/nsSVGForeignObjectFrame.cpp index a83dab5e396..4b66881170d 100644 --- a/mozilla/layout/svg/base/src/nsSVGForeignObjectFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGForeignObjectFrame.cpp @@ -85,6 +85,8 @@ NS_NewSVGForeignObjectFrame(nsIPresShell* aPresShell, nsIContent* aContent) nsSVGForeignObjectFrame::nsSVGForeignObjectFrame() : mIsDirty(PR_TRUE), mPropagateTransform(PR_TRUE), mFilter(nsnull) { + AddStateBits(NS_BLOCK_SPACE_MGR | NS_BLOCK_MARGIN_ROOT | + NS_FRAME_REFLOW_ROOT); } nsSVGForeignObjectFrame::~nsSVGForeignObjectFrame() @@ -213,39 +215,30 @@ nsSVGForeignObjectFrame::Reflow(nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { -#ifdef DEBUG - printf("nsSVGForeignObjectFrame(%p)::Reflow\n", this); -#endif - - float twipsPerPx = GetTwipsPerPx(); - - NS_ENSURE_TRUE(mX && mY && mWidth && mHeight, NS_ERROR_FAILURE); + nsHTMLReflowState &reflowState = + NS_CONST_CAST(nsHTMLReflowState&, aReflowState); - float width, height; - mWidth->GetValue(&width); - mHeight->GetValue(&height); + // We could do this in DoReflow, except that we set + // NS_FRAME_REFLOW_ROOT, so we also need to do it when the pres shell + // calls us directly. + reflowState.mComputedHeight = mRect.height; + reflowState.mComputedWidth = mRect.width; - // move our frame to (0, 0), set our size to the untransformed - // width and height. Our frame size and position are meaningless - // given the possibility of non-rectilinear transforms; our size - // is only useful for reflowing our content - SetPosition(nsPoint(0, 0)); - - // create a new reflow state, setting our max size to (width,height): - nsSize availableSpace((nscoord)(width*twipsPerPx), (nscoord)(height*twipsPerPx)); - nsHTMLReflowState sizedReflowState(aPresContext, - aReflowState, - this, - availableSpace); + nsSpaceManager* spaceManager = + new nsSpaceManager(aPresContext->PresShell(), this); + if (!spaceManager) { + NS_ERROR("Could not create space manager"); + return nsnull; + } + reflowState.mSpaceManager = spaceManager; + + nsresult rv = nsSVGForeignObjectFrameBase::Reflow(aPresContext, aDesiredSize, + aReflowState, aStatus); - // XXX Not sure the dirty-state should be cleared here. We should - // re-examine how the reflow is driven from nsSVGOuterSVGFrame. I - // think we're missing a call to DidReflow somewhere ? - mState &= ~NS_FRAME_IS_DIRTY; - - // leverage our base class' reflow function to do all the work: - return nsSVGForeignObjectFrameBase::Reflow(aPresContext, aDesiredSize, - sizedReflowState, aStatus); + reflowState.mSpaceManager = nsnull; + delete spaceManager; + + return rv; } NS_IMETHODIMP @@ -742,24 +735,41 @@ nsSVGForeignObjectFrame::DoReflow() nsIPresShell* presShell = presContext->PresShell(); NS_ASSERTION(presShell, "null presShell"); presShell->CreateRenderingContext(this,getter_AddRefs(renderingContext)); + NS_ENSURE_TRUE(renderingContext, nsnull); - // XXX we always pass this off as an initial reflow. is that a problem? - nsHTMLReflowState reflowState(presContext, this, eReflowReason_Initial, - renderingContext, availableSpace); + float twipsPerPx = GetTwipsPerPx(); + + NS_ENSURE_TRUE(mX && mY && mWidth && mHeight, nsnull); - nsSpaceManager* spaceManager = new nsSpaceManager(presShell, this); - if (!spaceManager) { - NS_ERROR("Could not create space manager"); - return nsnull; - } - reflowState.mSpaceManager = spaceManager; - + float width, height; + mWidth->GetValue(&width); + mHeight->GetValue(&height); + + nsSize size(NSFloatPixelsToTwips(width, twipsPerPx), + NSFloatPixelsToTwips(height, twipsPerPx)); + + // move our frame to (0, 0), set our size to the untransformed + // width and height. Our frame size and position are meaningless + // given the possibility of non-rectilinear transforms; our size + // is only useful for reflowing our content + SetPosition(nsPoint(0, 0)); + SetSize(size); + + // create a new reflow state, setting our max size to (width,height): + // Make up a potentially reasonable but perhaps too destructive reflow + // reason. + nsReflowReason reason = (GetStateBits() & NS_FRAME_FIRST_REFLOW) + ? eReflowReason_Initial + : eReflowReason_StyleChange; + nsHTMLReflowState reflowState(presContext, this, reason, + renderingContext, size); nsHTMLReflowMetrics desiredSize(nsnull); nsReflowStatus status; WillReflow(presContext); Reflow(presContext, desiredSize, reflowState, status); - SetSize(nsSize(desiredSize.width, desiredSize.height)); + NS_ASSERTION(size.width == desiredSize.width && + size.height == desiredSize.height, "unexpected size"); DidReflow(presContext, &reflowState, NS_FRAME_REFLOW_FINISHED); mIsDirty = PR_FALSE; diff --git a/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp b/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp index 1d70fa4fa8e..5bfa914bacc 100644 --- a/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGOuterSVGFrame.cpp @@ -408,45 +408,18 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext* aPresContext, } #endif - // check whether this reflow request is targeted at us or a child - // frame (e.g. a foreignObject): - if (aReflowState.reason == eReflowReason_Incremental) { - nsReflowPath::iterator iter = aReflowState.path->FirstChild(); - nsReflowPath::iterator end = aReflowState.path->EndChildren(); + if (aReflowState.reason == eReflowReason_Incremental && + !aReflowState.path->mReflowCommand) { + // We're not the target of the incremental reflow, so just bail. + // This means that something happened to one of our descendants + // (excluding those inside svg:foreignObject, since + // nsSVGForeignObjectFrame is a reflow root). - for ( ; iter != end; ++iter) { - // The actual target of this reflow is one of our child - // frames. Since SVG as such doesn't use reflow, this will - // probably be the child of a . Some HTML|XUL - // content frames target reflow events at themselves when they - // need to be redrawn in response to e.g. a style change. For - // correct visual updating, we must make sure the reflow - // reaches its intended target. - - // Since it is an svg frame (probably an nsSVGForeignObjectFrame), - // we might as well pass in our aDesiredSize and aReflowState - // objects - they are ignored by svg frames: - nsSize availSpace(0, 0); // XXXwaterson probably wrong! - nsHTMLReflowState state(aPresContext, aReflowState, *iter, availSpace); - (*iter)->Reflow (aPresContext, - aDesiredSize, - state, - aStatus); - - // XXX do we really have to return our metrics although we're - // not affected by the reflow? Is there a way of telling our - // parent that we don't want anything changed? - aDesiredSize.width = mRect.width; - aDesiredSize.height = mRect.height; - aDesiredSize.ascent = aDesiredSize.height; - aDesiredSize.descent = 0; - } - - if (! aReflowState.path->mReflowCommand) { - // We're not the target of the incremental reflow, so just bail. - aStatus = NS_FRAME_COMPLETE; - return NS_OK; - } + // XXXldb If this incremental reflow was the result of a style + // change to something that *contains* a foreignObject, then we're + // dropping the change completely on the floor! + aStatus = NS_FRAME_COMPLETE; + return NS_OK; } // SVG CR 20001102: When the SVG content is embedded inline within diff --git a/mozilla/layout/svg/base/src/svg.css b/mozilla/layout/svg/base/src/svg.css index 9ab7610ae6f..03badf7ab12 100644 --- a/mozilla/layout/svg/base/src/svg.css +++ b/mozilla/layout/svg/base/src/svg.css @@ -62,3 +62,9 @@ switch { svg:not(:root), symbol, image, marker, pattern, foreignObject { overflow: hidden; } + +foreignObject { + margin: 0 ! important; + padding: 0 ! important; + border: none ! important; +}