зеркало из https://github.com/mozilla/gecko-dev.git
Bug 951904 - SVGTextFrame should always be reflowed even if it is inside a nonactive child of switch element r=longsonr
SVGTextFrame is special, it should always be reflowed to get the correct metrics. Differential Revision: https://phabricator.services.mozilla.com/D22841 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
d931e71177
Коммит
76cd3244f4
|
@ -0,0 +1,34 @@
|
|||
<body onload="go()">
|
||||
<svg>
|
||||
<switch>
|
||||
<text id="a">Bonjour</text>
|
||||
<text id="b">Hello</text>
|
||||
<a><text id="c">Hello</text></a>
|
||||
<g>
|
||||
<mask>
|
||||
<text>Lundi</text>
|
||||
</mask>
|
||||
</g>
|
||||
<switch>
|
||||
<text id="d">Au revoir</text>
|
||||
<g>
|
||||
<mask>
|
||||
<text>Mercredi</text>
|
||||
</mask>
|
||||
</g>
|
||||
<text id="e">Goodbye</text>
|
||||
<a><text id="f">Goodbye</text></a>
|
||||
</switch>
|
||||
</switch>
|
||||
</svg>
|
||||
</body>
|
||||
<script>
|
||||
function go() {
|
||||
a.getComputedTextLength();
|
||||
b.getComputedTextLength();
|
||||
c.getComputedTextLength();
|
||||
d.getComputedTextLength();
|
||||
e.getComputedTextLength();
|
||||
f.getComputedTextLength();
|
||||
}
|
||||
</script>
|
|
@ -182,6 +182,7 @@ load 898951-1.svg
|
|||
load 913990.html
|
||||
load 919371-1.xhtml
|
||||
load 950324-1.svg
|
||||
load 951904-1.html
|
||||
load 952270-1.svg
|
||||
load 963086-1.svg
|
||||
load 974746-1.svg
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "nsSVGGFrame.h"
|
||||
#include "mozilla/dom/SVGSwitchElement.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "SVGTextFrame.h"
|
||||
#include "nsSVGContainerFrame.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
@ -51,6 +53,8 @@ class nsSVGSwitchFrame final : public nsSVGGFrame {
|
|||
|
||||
private:
|
||||
nsIFrame* GetActiveChildFrame();
|
||||
void ReflowAllSVGTextFramesInsideNonActiveChildren(nsIFrame* aActiveChild);
|
||||
static void AlwaysReflowSVGTextFrameDoForOneKid(nsIFrame* aKid);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -135,6 +139,47 @@ nsIFrame* nsSVGSwitchFrame::GetFrameForPoint(const gfxPoint& aPoint) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void nsSVGSwitchFrame::AlwaysReflowSVGTextFrameDoForOneKid(nsIFrame* aKid) {
|
||||
if (!NS_SUBTREE_DIRTY(aKid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutFrameType type = aKid->Type();
|
||||
if (type == LayoutFrameType::SVGText) {
|
||||
MOZ_ASSERT(!aKid->HasAnyStateBits(NS_FRAME_IS_NONDISPLAY),
|
||||
"A non-display SVGTextFrame directly contained in a display "
|
||||
"container?");
|
||||
static_cast<SVGTextFrame*>(aKid)->ReflowSVG();
|
||||
} else if (aKid->IsFrameOfType(nsIFrame::eSVG | nsIFrame::eSVGContainer) ||
|
||||
type == LayoutFrameType::SVGForeignObject ||
|
||||
!aKid->IsFrameOfType(nsIFrame::eSVG)) {
|
||||
if (!aKid->HasAnyStateBits(NS_FRAME_IS_NONDISPLAY)) {
|
||||
for (nsIFrame* kid : aKid->PrincipalChildList()) {
|
||||
AlwaysReflowSVGTextFrameDoForOneKid(kid);
|
||||
}
|
||||
} else {
|
||||
// This child is in a nondisplay context, something like:
|
||||
// <switch>
|
||||
// ...
|
||||
// <g><mask><text></text></mask></g>
|
||||
// </switch>
|
||||
// We should not call ReflowSVG on it.
|
||||
nsSVGContainerFrame::ReflowSVGNonDisplayText(aKid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsSVGSwitchFrame::ReflowAllSVGTextFramesInsideNonActiveChildren(
|
||||
nsIFrame* aActiveChild) {
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) {
|
||||
if (aActiveChild == kid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AlwaysReflowSVGTextFrameDoForOneKid(kid);
|
||||
}
|
||||
}
|
||||
|
||||
void nsSVGSwitchFrame::ReflowSVG() {
|
||||
NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this),
|
||||
"This call is probably a wasteful mistake");
|
||||
|
@ -165,6 +210,8 @@ void nsSVGSwitchFrame::ReflowSVG() {
|
|||
nsOverflowAreas overflowRects;
|
||||
|
||||
nsIFrame* child = GetActiveChildFrame();
|
||||
ReflowAllSVGTextFramesInsideNonActiveChildren(child);
|
||||
|
||||
nsSVGDisplayableFrame* svgChild = do_QueryFrame(child);
|
||||
if (svgChild) {
|
||||
MOZ_ASSERT(!(child->GetStateBits() & NS_FRAME_IS_NONDISPLAY),
|
||||
|
|
Загрузка…
Ссылка в новой задаче