From 4e96b6eb1b809598bdb3c313f07bb3d1edb377f8 Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Thu, 20 Aug 2009 14:52:47 -0700 Subject: [PATCH] Bug 507067: Fix GetAnimVal and GetBaseVal's handling of em/ex/etc. units inside display:none elements by using nsComputedDOMStyle's method for resolving style contexts for such elements. r=dbaron --- content/svg/content/test/Makefile.in | 1 + .../content/test/test_animLengthUnits.xhtml | 124 ++++++++++++++++++ layout/style/nsComputedDOMStyle.cpp | 39 ++++++ layout/style/nsComputedDOMStyle.h | 7 + layout/svg/base/src/nsSVGUtils.cpp | 55 ++++++-- layout/svg/base/src/nsSVGUtils.h | 3 + 6 files changed, 217 insertions(+), 12 deletions(-) create mode 100644 content/svg/content/test/test_animLengthUnits.xhtml diff --git a/content/svg/content/test/Makefile.in b/content/svg/content/test/Makefile.in index 133c2a7a2a0a..cd73cd058f3b 100644 --- a/content/svg/content/test/Makefile.in +++ b/content/svg/content/test/Makefile.in @@ -45,6 +45,7 @@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk _TEST_FILES = \ + test_animLengthUnits.xhtml \ test_bbox.xhtml \ bbox-helper.svg \ bounds-helper.svg \ diff --git a/content/svg/content/test/test_animLengthUnits.xhtml b/content/svg/content/test/test_animLengthUnits.xhtml new file mode 100644 index 000000000000..f584bdfe4296 --- /dev/null +++ b/content/svg/content/test/test_animLengthUnits.xhtml @@ -0,0 +1,124 @@ + + + + Test for units of SVG animated lengths + + + + + +Mozilla Bug 507067 +

+ +
+
+
+ + diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 26cb90c16573..65afe82bfe4c 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -354,7 +354,35 @@ nsComputedDOMStyle::GetStyleContextForContent(nsIContent* aContent, NS_ASSERTION(aContent->IsNodeOfType(nsINode::eELEMENT), "aContent must be an element"); if (!aPseudo) { + // If there's no pres shell, get it from the content + if (!aPresShell) { + aPresShell = GetPresShellForContent(aContent); + if (!aPresShell) + return nsnull; + } + aPresShell->FlushPendingNotifications(Flush_Style); + } + + return GetStyleContextForContentNoFlush(aContent, aPseudo, aPresShell); +} + +/* static */ +already_AddRefed +nsComputedDOMStyle::GetStyleContextForContentNoFlush(nsIContent* aContent, + nsIAtom* aPseudo, + nsIPresShell* aPresShell) +{ + NS_ABORT_IF_FALSE(aContent, "NULL content node"); + + // If there's no pres shell, get it from the content + if (!aPresShell) { + aPresShell = GetPresShellForContent(aContent); + if (!aPresShell) + return nsnull; + } + + if (!aPseudo) { nsIFrame* frame = aPresShell->GetPrimaryFrameFor(aContent); if (frame) { nsStyleContext* result = GetStyleContextForFrame(frame); @@ -390,6 +418,17 @@ nsComputedDOMStyle::GetStyleContextForContent(nsIContent* aContent, return styleSet->ResolveStyleFor(aContent, parentContext); } +/* static */ +nsIPresShell* +nsComputedDOMStyle::GetPresShellForContent(nsIContent* aContent) +{ + nsIDocument* currentDoc = aContent->GetCurrentDoc(); + if (!currentDoc) + return nsnull; + + return currentDoc->GetPrimaryShell(); +} + NS_IMETHODIMP nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName, nsIDOMCSSValue** aReturn) diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index d10f7b09c7a0..8b82e064f4b9 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -86,6 +86,13 @@ public: GetStyleContextForContent(nsIContent* aContent, nsIAtom* aPseudo, nsIPresShell* aPresShell); + static already_AddRefed + GetStyleContextForContentNoFlush(nsIContent* aContent, nsIAtom* aPseudo, + nsIPresShell* aPresShell); + + static nsIPresShell* + GetPresShellForContent(nsIContent* aContent); + private: void AssertFlushedPendingReflows() { NS_ASSERTION(mFlushedPendingReflows, diff --git a/layout/svg/base/src/nsSVGUtils.cpp b/layout/svg/base/src/nsSVGUtils.cpp index d1254f8a7785..27f7f586aa81 100644 --- a/layout/svg/base/src/nsSVGUtils.cpp +++ b/layout/svg/base/src/nsSVGUtils.cpp @@ -85,6 +85,7 @@ #include "nsSVGIntegrationUtils.h" #include "nsSVGFilterPaintCallback.h" #include "nsSVGGeometryFrame.h" +#include "nsComputedDOMStyle.h" gfxASurface *nsSVGUtils::mThebesComputationalSurface = nsnull; @@ -267,39 +268,69 @@ nsSVGUtils::GetParentElement(nsIContent *aContent) float nsSVGUtils::GetFontSize(nsIContent *aContent) { - nsIFrame* frame = GetFrameForContent(aContent); - if (!frame) { - NS_WARNING("no frame in GetFontSize()"); + nsRefPtr styleContext = + nsComputedDOMStyle::GetStyleContextForContentNoFlush(aContent, nsnull, + nsnull); + if (!styleContext) { + NS_WARNING("Couldn't get style context for content in GetFontStyle"); return 1.0f; } - return GetFontSize(frame); + return GetFontSize(styleContext); } float nsSVGUtils::GetFontSize(nsIFrame *aFrame) { - return nsPresContext::AppUnitsToFloatCSSPixels(aFrame->GetStyleFont()->mSize) / - aFrame->PresContext()->TextZoom(); + NS_ABORT_IF_FALSE(aFrame, "NULL frame in GetFontSize"); + return GetFontSize(aFrame->GetStyleContext()); +} + +float +nsSVGUtils::GetFontSize(nsStyleContext *aStyleContext) +{ + NS_ABORT_IF_FALSE(aStyleContext, "NULL style context in GetFontSize"); + + nsPresContext *presContext = aStyleContext->PresContext(); + NS_ABORT_IF_FALSE(presContext, "NULL pres context in GetFontSize"); + + nscoord fontSize = aStyleContext->GetStyleFont()->mSize; + return nsPresContext::AppUnitsToFloatCSSPixels(fontSize) / + presContext->TextZoom(); } float nsSVGUtils::GetFontXHeight(nsIContent *aContent) { - nsIFrame* frame = GetFrameForContent(aContent); - if (!frame) { - NS_WARNING("no frame in GetFontXHeight()"); + nsRefPtr styleContext = + nsComputedDOMStyle::GetStyleContextForContentNoFlush(aContent, nsnull, + nsnull); + if (!styleContext) { + NS_WARNING("Couldn't get style context for content in GetFontStyle"); return 1.0f; } - return GetFontXHeight(frame); + return GetFontXHeight(styleContext); } float nsSVGUtils::GetFontXHeight(nsIFrame *aFrame) { + NS_ABORT_IF_FALSE(aFrame, "NULL frame in GetFontXHeight"); + return GetFontXHeight(aFrame->GetStyleContext()); +} + +float +nsSVGUtils::GetFontXHeight(nsStyleContext *aStyleContext) +{ + NS_ABORT_IF_FALSE(aStyleContext, "NULL style context in GetFontXHeight"); + + nsPresContext *presContext = aStyleContext->PresContext(); + NS_ABORT_IF_FALSE(presContext, "NULL pres context in GetFontXHeight"); + nsCOMPtr fontMetrics; - nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fontMetrics)); + nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext, + getter_AddRefs(fontMetrics)); if (!fontMetrics) { NS_WARNING("no FontMetrics in GetFontXHeight()"); @@ -309,7 +340,7 @@ nsSVGUtils::GetFontXHeight(nsIFrame *aFrame) nscoord xHeight; fontMetrics->GetXHeight(xHeight); return nsPresContext::AppUnitsToFloatCSSPixels(xHeight) / - aFrame->PresContext()->TextZoom(); + presContext->TextZoom(); } void diff --git a/layout/svg/base/src/nsSVGUtils.h b/layout/svg/base/src/nsSVGUtils.h index a56ee7d96321..83ba5f558ade 100644 --- a/layout/svg/base/src/nsSVGUtils.h +++ b/layout/svg/base/src/nsSVGUtils.h @@ -53,6 +53,7 @@ class nsIDocument; class nsPresContext; class nsIContent; +class nsStyleContext; class nsStyleCoord; class nsFrameList; class nsIFrame; @@ -203,11 +204,13 @@ public: */ static float GetFontSize(nsIContent *aContent); static float GetFontSize(nsIFrame *aFrame); + static float GetFontSize(nsStyleContext *aStyleContext); /* * Get an x-height of of an nsIContent */ static float GetFontXHeight(nsIContent *aContent); static float GetFontXHeight(nsIFrame *aFrame); + static float GetFontXHeight(nsStyleContext *aStyleContext); /* * Converts image data from premultipled to unpremultiplied alpha