Bug 655877 - Part 27: Ignore text-shadow in SVG text frames. r=roc
authorCameron McCormack <cam@mcc.id.au>
Wed, 08 Aug 2012 21:37:13 +1000
changeset 101819 dd0e5c7393472a39e416da7f54acd9c8258d4e2d
parent 101818 a90b2757ccc2e3cdb0b234da04c438366fb92bff
child 101820 e45aca2a5d8781f9557aa6139311aa1ce37b5dc3
push id994
push userttaubert@mozilla.com
push dateThu, 09 Aug 2012 18:49:12 +0000
treeherderfx-team@4770bca01046 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs655877
milestone17.0a1
Bug 655877 - Part 27: Ignore text-shadow in SVG text frames. r=roc
layout/base/nsLayoutUtils.cpp
layout/generic/nsTextFrameThebes.cpp
layout/style/nsStyleStruct.h
layout/style/nsStyleStructInlines.h
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -71,16 +71,17 @@
 #include "nsTextFrame.h"
 #include "nsFontFaceList.h"
 #include "nsFontInflationData.h"
 #include "CompositorParent.h"
 #include "nsSVGUtils.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGForeignObjectFrame.h"
 #include "nsSVGOuterSVGFrame.h"
+#include "nsStyleStructInlines.h"
 
 #include "mozilla/Preferences.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #endif
 
 #include "sampler.h"
@@ -2113,17 +2114,17 @@ nsLayoutUtils::GetAllInFlowPaddingRectsU
 }
 
 nsRect
 nsLayoutUtils::GetTextShadowRectsUnion(const nsRect& aTextAndDecorationsRect,
                                        nsIFrame* aFrame,
                                        PRUint32 aFlags)
 {
   const nsStyleText* textStyle = aFrame->GetStyleText();
-  if (!textStyle->mTextShadow)
+  if (!textStyle->HasTextShadow(aFrame))
     return aTextAndDecorationsRect;
 
   nsRect resultRect = aTextAndDecorationsRect;
   PRInt32 A2D = aFrame->PresContext()->AppUnitsPerDevPixel();
   for (PRUint32 i = 0; i < textStyle->mTextShadow->Length(); ++i) {
     nsCSSShadowItem* shadow = textStyle->mTextShadow->ShadowAt(i);
     nsMargin blur = nsContextBoxBlur::GetBlurRadiusMargin(shadow->mRadius, A2D);
     if ((aFlags & EXCLUDE_BLUR_SHADOWS) && blur != nsMargin(0, 0, 0, 0))
@@ -3219,17 +3220,17 @@ nsLayoutUtils::PaintTextShadow(const nsI
                                nsRenderingContext* aContext,
                                const nsRect& aTextRect,
                                const nsRect& aDirtyRect,
                                const nscolor& aForegroundColor,
                                TextShadowCallback aCallback,
                                void* aCallbackData)
 {
   const nsStyleText* textStyle = aFrame->GetStyleText();
-  if (!textStyle->mTextShadow)
+  if (!textStyle->HasTextShadow(aFrame))
     return;
 
   // Text shadow happens with the last value being painted at the back,
   // ie. it is painted first.
   gfxContext* aDestCtx = aContext->ThebesContext();
   for (PRUint32 i = textStyle->mTextShadow->Length(); i > 0; --i) {
     nsCSSShadowItem* shadowDetails = textStyle->mTextShadow->ShadowAt(i - 1);
     nsPoint shadowOffset(shadowDetails->mXOffset,
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -5070,20 +5070,24 @@ static bool GetSelectionTextColors(Selec
 }
 
 /**
  * This sets *aShadow to the appropriate shadow, if any, for the given
  * type of selection. Returns true if *aShadow was set.
  * If text-shadow was not specified, *aShadow is left untouched
  * (NOT reset to null), and the function returns false.
  */
-static bool GetSelectionTextShadow(SelectionType aType,
+static bool GetSelectionTextShadow(nsIFrame* aFrame,
+                                   SelectionType aType,
                                    nsTextPaintStyle& aTextPaintStyle,
                                    nsCSSShadowArray** aShadow)
 {
+  if (aFrame->IsSVGText()) {
+    return false;
+  }
   switch (aType) {
     case nsISelectionController::SELECTION_NORMAL:
       return aTextPaintStyle.GetSelectionShadow(aShadow);
     default:
       return false;
   }
 }
 
@@ -5369,18 +5373,18 @@ nsTextFrame::PaintTextWithSelectionColor
                                  &type, &rangeStyle)) {
     nscolor foreground, background;
     GetSelectionTextColors(type, aTextPaintStyle, rangeStyle,
                            &foreground, &background);
     gfxPoint textBaselinePt(aFramePt.x + xOffset, aTextBaselinePt.y);
 
     // Determine what shadow, if any, to draw - either from textStyle
     // or from the ::-moz-selection pseudo-class if specified there
-    nsCSSShadowArray *shadow = textStyle->mTextShadow;
-    GetSelectionTextShadow(type, aTextPaintStyle, &shadow);
+    nsCSSShadowArray *shadow = textStyle->GetTextShadow(this);
+    GetSelectionTextShadow(this, type, aTextPaintStyle, &shadow);
 
     // Draw shadows, if any
     if (shadow) {
       gfxTextRun::Metrics shadowMetrics =
         mTextRun->MeasureText(offset, length, gfxFont::LOOSE_INK_EXTENTS,
                               nullptr, &aProvider);
       if (GetStateBits() & TEXT_HYPHEN_BREAK) {
         AddHyphenToMetrics(this, mTextRun, &shadowMetrics,
@@ -5737,17 +5741,17 @@ nsTextFrame::PaintText(nsRenderingContex
                                textPaintStyle, clipEdges, aCallbacks)) {
       return;
     }
   }
 
   nscolor foregroundColor = textPaintStyle.GetTextColor();
   if (!aCallbacks) {
     const nsStyleText* textStyle = GetStyleText();
-    if (textStyle->mTextShadow) {
+    if (textStyle->HasTextShadow(this)) {
       // Text shadow happens with the last value being painted at the back,
       // ie. it is painted first.
       gfxTextRun::Metrics shadowMetrics = 
         mTextRun->MeasureText(startOffset, maxLength, gfxFont::LOOSE_INK_EXTENTS,
                               nullptr, &provider);
       for (PRUint32 i = textStyle->mTextShadow->Length(); i > 0; --i) {
         PaintOneShadow(startOffset, maxLength,
                        textStyle->mTextShadow->ShadowAt(i - 1), &provider,
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1319,16 +1319,20 @@ struct nsStyleText {
     return mWhiteSpace == NS_STYLE_WHITESPACE_NORMAL ||
            mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
            mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
   }
 
   bool WordCanWrap() const {
     return WhiteSpaceCanWrap() && mWordWrap == NS_STYLE_WORDWRAP_BREAK_WORD;
   }
+
+  // These are defined in nsStyleStructInlines.h.
+  inline bool HasTextShadow(const nsIFrame* aFrame) const;
+  inline nsCSSShadowArray* GetTextShadow(const nsIFrame* aFrame) const;
 };
 
 struct nsStyleVisibility {
   nsStyleVisibility(nsPresContext* aPresContext);
   nsStyleVisibility(const nsStyleVisibility& aVisibility);
   ~nsStyleVisibility() {
     MOZ_COUNT_DTOR(nsStyleVisibility);
   }
--- a/layout/style/nsStyleStructInlines.h
+++ b/layout/style/nsStyleStructInlines.h
@@ -51,16 +51,31 @@ nsStyleBorder::GetSubImage(PRUint8 aInde
 {
   imgIContainer* subImage = nullptr;
   if (aIndex < mSubImages.Count())
     subImage = mSubImages[aIndex];
   return subImage;
 }
 
 bool
+nsStyleText::HasTextShadow(const nsIFrame* aFrame) const
+{
+  return mTextShadow && !aFrame->IsSVGText();
+}
+
+nsCSSShadowArray*
+nsStyleText::GetTextShadow(const nsIFrame* aFrame) const
+{
+  if (aFrame->IsSVGText()) {
+    return nullptr;
+  }
+  return mTextShadow;
+}
+
+bool
 nsStyleDisplay::IsBlockInside(const nsIFrame* aFrame) const
 {
   if (aFrame->GetStateBits() & NS_FRAME_IS_SVG_TEXT) {
     return aFrame->GetType() == nsGkAtoms::blockFrame;
   }
   return IsBlockInsideStyle();
 }