Fixing bug 369827. Reflow of foreignObject with percentage width/height doesn't work. r=tor@acm.org, sr=dbaron@mozilla.com (this also fixes bug 379615, so changing the reftest manifest to expect the foreignObject tests to pass)

This commit is contained in:
jwatt@jwatt.org 2007-05-05 04:11:07 -07:00
Родитель 07bad8b85e
Коммит 48f0cb4b50
3 изменённых файлов: 31 добавлений и 22 удалений

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

@ -3,9 +3,9 @@
# include bugs/reftest.list
fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == clipPath-basic-01.svg pass.svg
fails == foreignObject-01.svg pass.svg
== foreignObject-01.svg pass.svg
== foreignObject-display-01.svg pass.svg
fails == foreignObject-overflow-01.svg pass.svg
== foreignObject-overflow-01.svg pass.svg
== getElementById-a-element-01.svg pass.svg
== nested-viewBox-01.svg pass.svg
fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == opacity-and-gradient-01.svg pass.svg

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

@ -115,7 +115,7 @@ nsSVGForeignObjectFrame::AttributeChanged(PRInt32 aNameSpaceID,
if (aNameSpaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::height) {
PostChildDirty();
RequestReflow(nsIPresShell::eStyleChange);
UpdateGraphic();
} else if (aAttribute == nsGkAtoms::x ||
aAttribute == nsGkAtoms::y) {
@ -140,26 +140,18 @@ nsSVGForeignObjectFrame::DidSetStyleContext()
/* virtual */ void
nsSVGForeignObjectFrame::MarkIntrinsicWidthsDirty()
{
if (GetStateBits() & NS_FRAME_FIRST_REFLOW)
// If we haven't had an InitialUpdate yet, nothing to do.
return;
// Use the fact that we get a MarkIntrinsicWidthsDirty whenever
// there's a style change that requires reflow to actually cause that
// reflow, since the SVG outer frame doesn't know to reflow us.
nsIFrame* kid = GetFirstChild(nsnull);
if (!kid)
return;
// Since we don't know whether this is because of a style change on an
// ancestor or descendant, mark the kid dirty. If it's a descendant,
// all we need is the NS_FRAME_IS_DIRTY_CHILDREN that our caller is
// going to set, though.
kid->AddStateBits(NS_FRAME_IS_DIRTY);
// all we need is the NS_FRAME_HAS_DIRTY_CHILDREN that our caller is
// going to set, though. (If we could differentiate between a style change on
// an ancestor or descendant, we'd need to add a parameter to RequestReflow
// to pass either NS_FRAME_IS_DIRTY or NS_FRAME_HAS_DIRTY_CHILDREN.)
//
// This is really a style change, except we're already being called
// from MarkIntrinsicWidthsDirty, so say it's a resize to avoid doing
// the same work over again.
PresContext()->PresShell()->FrameNeedsReflow(kid,
nsIPresShell::eResize);
RequestReflow(nsIPresShell::eResize);
}
NS_IMETHODIMP
@ -363,6 +355,11 @@ NS_IMETHODIMP
nsSVGForeignObjectFrame::NotifyCanvasTMChanged(PRBool suppressInvalidation)
{
mCanvasTM = nsnull;
// If our width/height has a percentage value then we need to reflow if the
// width/height of our parent coordinate context changes. Actually we also
// need to reflow if our scale changes since when text is scaled it doesn't
// necessarily change by quite the same amount as the change in scale.
RequestReflow(nsIPresShell::eResize);
UpdateGraphic();
return NS_OK;
}
@ -487,13 +484,18 @@ nsSVGForeignObjectFrame::GetCanvasTM()
//----------------------------------------------------------------------
// Implementation helpers
void nsSVGForeignObjectFrame::PostChildDirty()
void nsSVGForeignObjectFrame::RequestReflow(nsIPresShell::IntrinsicDirty aType)
{
if (GetStateBits() & NS_FRAME_FIRST_REFLOW)
// If we haven't had an InitialUpdate yet, nothing to do.
return;
nsIFrame* kid = GetFirstChild(nsnull);
if (!kid)
return;
PresContext()->PresShell()->
FrameNeedsReflow(kid, nsIPresShell::eStyleChange);
kid->AddStateBits(NS_FRAME_IS_DIRTY);
PresContext()->PresShell()->FrameNeedsReflow(kid, aType);
}
void nsSVGForeignObjectFrame::UpdateGraphic()

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

@ -44,6 +44,7 @@
#include "nsIDOMSVGMatrix.h"
#include "nsIDOMSVGLength.h"
#include "nsRegion.h"
#include "nsIPresShell.h"
typedef nsContainerFrame nsSVGForeignObjectFrameBase;
@ -73,6 +74,12 @@ public:
}
NS_IMETHOD DidSetStyleContext();
/**
* We need to reflow our decendants whenever style changes requiring reflow
* occur on an ancestor. Most SVG doesn't participate in reflow, but we can
* use MarkIntrinsicWidthsDirty to detect when this happens.
*/
virtual void MarkIntrinsicWidthsDirty();
NS_IMETHOD Reflow(nsPresContext* aPresContext,
@ -131,7 +138,7 @@ public:
protected:
// implementation helpers:
void DoReflow();
void PostChildDirty();
void RequestReflow(nsIPresShell::IntrinsicDirty aType);
void UpdateGraphic();
// Get the bounding box relative to the outer SVG element, in user units
void GetBBoxInternal(float* aX, float *aY, float* aWidth, float *aHeight);