From 441ad600ab6017e3bc1e686fc7df8a04f781513c Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Mon, 11 Feb 2013 17:22:18 +1100 Subject: [PATCH] Bug 655877 - Part 42a: Handle SVG text frame pref changes gracefully. r=bz,longsonr --- .../svg/content/src/SVGTextContentElement.cpp | 23 ++++--- .../svg/content/src/SVGTextContentElement.h | 1 + layout/base/nsCSSFrameConstructor.cpp | 65 ++++++++++--------- layout/svg/nsSVGUtils.cpp | 2 +- 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/content/svg/content/src/SVGTextContentElement.cpp b/content/svg/content/src/SVGTextContentElement.cpp index c8daecbf9ae..9f2765b6d61 100644 --- a/content/svg/content/src/SVGTextContentElement.cpp +++ b/content/svg/content/src/SVGTextContentElement.cpp @@ -34,12 +34,19 @@ SVGTextContentElement::GetSVGTextFrame() return nullptr; } +bool +SVGTextContentElement::FrameIsSVGText() +{ + nsIFrame* frame = GetPrimaryFrame(Flush_Layout); + return frame && frame->IsSVGText(); +} + //---------------------------------------------------------------------- int32_t SVGTextContentElement::GetNumberOfChars() { - if (NS_SVGTextCSSFramesEnabled()) { + if (FrameIsSVGText()) { nsSVGTextFrame2* textFrame = GetSVGTextFrame(); return textFrame ? textFrame->GetNumberOfChars(this) : 0; } else { @@ -51,7 +58,7 @@ SVGTextContentElement::GetNumberOfChars() float SVGTextContentElement::GetComputedTextLength() { - if (NS_SVGTextCSSFramesEnabled()) { + if (FrameIsSVGText()) { nsSVGTextFrame2* textFrame = GetSVGTextFrame(); return textFrame ? textFrame->GetComputedTextLength(this) : 0.0f; } else { @@ -63,7 +70,7 @@ SVGTextContentElement::GetComputedTextLength() float SVGTextContentElement::GetSubStringLength(uint32_t charnum, uint32_t nchars, ErrorResult& rv) { - if (NS_SVGTextCSSFramesEnabled()) { + if (FrameIsSVGText()) { nsSVGTextFrame2* textFrame = GetSVGTextFrame(); if (!textFrame) return 0.0f; @@ -100,7 +107,7 @@ already_AddRefed SVGTextContentElement::GetStartPositionOfChar(uint32_t charnum, ErrorResult& rv) { nsCOMPtr point; - if (NS_SVGTextCSSFramesEnabled()) { + if (FrameIsSVGText()) { nsSVGTextFrame2* textFrame = GetSVGTextFrame(); if (!textFrame) { rv.Throw(NS_ERROR_FAILURE); @@ -125,7 +132,7 @@ already_AddRefed SVGTextContentElement::GetEndPositionOfChar(uint32_t charnum, ErrorResult& rv) { nsCOMPtr point; - if (NS_SVGTextCSSFramesEnabled()) { + if (FrameIsSVGText()) { nsSVGTextFrame2* textFrame = GetSVGTextFrame(); if (!textFrame) { rv.Throw(NS_ERROR_FAILURE); @@ -150,7 +157,7 @@ already_AddRefed SVGTextContentElement::GetExtentOfChar(uint32_t charnum, ErrorResult& rv) { nsCOMPtr rect; - if (NS_SVGTextCSSFramesEnabled()) { + if (FrameIsSVGText()) { nsSVGTextFrame2* textFrame = GetSVGTextFrame(); if (!textFrame) { @@ -176,7 +183,7 @@ float SVGTextContentElement::GetRotationOfChar(uint32_t charnum, ErrorResult& rv) { float rotation; - if (NS_SVGTextCSSFramesEnabled()) { + if (FrameIsSVGText()) { nsSVGTextFrame2* textFrame = GetSVGTextFrame(); if (!textFrame) { @@ -201,7 +208,7 @@ SVGTextContentElement::GetRotationOfChar(uint32_t charnum, ErrorResult& rv) int32_t SVGTextContentElement::GetCharNumAtPosition(nsISVGPoint& aPoint) { - if (NS_SVGTextCSSFramesEnabled()) { + if (FrameIsSVGText()) { nsSVGTextFrame2* textFrame = GetSVGTextFrame(); return textFrame ? textFrame->GetCharNumAtPosition(this, &aPoint) : -1; } else { diff --git a/content/svg/content/src/SVGTextContentElement.h b/content/svg/content/src/SVGTextContentElement.h index ad3f5189bcc..21e3ab9e295 100644 --- a/content/svg/content/src/SVGTextContentElement.h +++ b/content/svg/content/src/SVGTextContentElement.h @@ -41,6 +41,7 @@ protected: nsSVGTextContainerFrame* GetTextContainerFrame(); nsSVGTextFrame2* GetSVGTextFrame(); + bool FrameIsSVGText(); }; } // namespace dom diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 77c9cc71806..1620a6ddfc9 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -4939,41 +4939,42 @@ nsCSSFrameConstructor::FindSVGData(Element* aElement, // Special cases for text/tspan/textPath, because the kind of frame // they get depends on the parent frame. We ignore 'a' elements when // determining the parent, however. - if (NS_SVGTextCSSFramesEnabled()) { - if (aIsWithinSVGText) { - // We don't use ConstructInline because we want different behavior - // for generated content. - static const FrameConstructionData sTSpanData = - FCDATA_DECL(FCDATA_DISALLOW_OUT_OF_FLOW | - FCDATA_SKIP_ABSPOS_PUSH | - FCDATA_DISALLOW_GENERATED_CONTENT | - FCDATA_IS_LINE_PARTICIPANT | - FCDATA_IS_INLINE | - FCDATA_USE_CHILD_ITEMS, - NS_NewInlineFrame); - if (aTag == nsGkAtoms::textPath) { - if (aAllowsTextPathChild) { - return &sTSpanData; - } - } else if (aTag == nsGkAtoms::tspan || - aTag == nsGkAtoms::altGlyph || - aTag == nsGkAtoms::a) { + if (aIsWithinSVGText) { + // If aIsWithinSVGText is true, then we know that the "SVG text uses + // CSS frames" pref was true when this SVG fragment was first constructed. + + // We don't use ConstructInline because we want different behavior + // for generated content. + static const FrameConstructionData sTSpanData = + FCDATA_DECL(FCDATA_DISALLOW_OUT_OF_FLOW | + FCDATA_SKIP_ABSPOS_PUSH | + FCDATA_DISALLOW_GENERATED_CONTENT | + FCDATA_IS_LINE_PARTICIPANT | + FCDATA_IS_INLINE | + FCDATA_USE_CHILD_ITEMS, + NS_NewInlineFrame); + if (aTag == nsGkAtoms::textPath) { + if (aAllowsTextPathChild) { return &sTSpanData; } + } else if (aTag == nsGkAtoms::tspan || + aTag == nsGkAtoms::altGlyph || + aTag == nsGkAtoms::a) { + return &sTSpanData; + } + return &sSuppressData; + } else if (NS_SVGTextCSSFramesEnabled()) { + if (aTag == nsGkAtoms::text) { + static const FrameConstructionData sTextData = + FCDATA_WITH_WRAPPING_BLOCK(FCDATA_DISALLOW_OUT_OF_FLOW | + FCDATA_ALLOW_BLOCK_STYLES, + NS_NewSVGTextFrame2, + nsCSSAnonBoxes::mozSVGText); + return &sTextData; + } else if (aTag == nsGkAtoms::tspan || + aTag == nsGkAtoms::altGlyph || + aTag == nsGkAtoms::textPath) { return &sSuppressData; - } else { - if (aTag == nsGkAtoms::text) { - static const FrameConstructionData sTextData = - FCDATA_WITH_WRAPPING_BLOCK(FCDATA_DISALLOW_OUT_OF_FLOW | - FCDATA_ALLOW_BLOCK_STYLES, - NS_NewSVGTextFrame2, - nsCSSAnonBoxes::mozSVGText); - return &sTextData; - } else if (aTag == nsGkAtoms::tspan || - aTag == nsGkAtoms::altGlyph || - aTag == nsGkAtoms::textPath) { - return &sSuppressData; - } } } else { nsIFrame *ancestorFrame = diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 14706e66f12..c36e0a05114 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -1217,7 +1217,7 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, uint32_t aFlags) // filter to text. When one of these facilities is applied to text // the bounding box is the entire text element in all // cases. - if (NS_SVGTextCSSFramesEnabled()) { + if (aFrame->IsSVGText()) { nsIFrame* ancestor = GetFirstNonAAncestorFrame(aFrame); if (ancestor && ancestor->IsSVGText()) { while (ancestor->GetType() != nsGkAtoms::svgTextFrame2) {