Bug 655877 - Part 42a: Handle SVG text frame pref changes gracefully. r=bz,longsonr

This commit is contained in:
Cameron McCormack 2013-02-11 17:22:18 +11:00
parent a4183f9467
commit 441ad600ab
4 changed files with 50 additions and 41 deletions

View File

@ -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<nsISVGPoint>
SVGTextContentElement::GetStartPositionOfChar(uint32_t charnum, ErrorResult& rv)
{
nsCOMPtr<nsISVGPoint> point;
if (NS_SVGTextCSSFramesEnabled()) {
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
@ -125,7 +132,7 @@ already_AddRefed<nsISVGPoint>
SVGTextContentElement::GetEndPositionOfChar(uint32_t charnum, ErrorResult& rv)
{
nsCOMPtr<nsISVGPoint> point;
if (NS_SVGTextCSSFramesEnabled()) {
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
@ -150,7 +157,7 @@ already_AddRefed<nsIDOMSVGRect>
SVGTextContentElement::GetExtentOfChar(uint32_t charnum, ErrorResult& rv)
{
nsCOMPtr<nsIDOMSVGRect> 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 {

View File

@ -41,6 +41,7 @@ protected:
nsSVGTextContainerFrame* GetTextContainerFrame();
nsSVGTextFrame2* GetSVGTextFrame();
bool FrameIsSVGText();
};
} // namespace dom

View File

@ -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 =

View File

@ -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) {