Bug 403524: Remove the standards-mode text-decoration code and use the quirks-mode code in all modes. r=dbaron
authorVitor Menezes <vmenezes@mozilla.com>
Wed, 03 Aug 2011 11:30:58 -0700
changeset 73781 83b2648ee44243cf158a9a98c5aad384e613dd7d
parent 73780 db9466903986bcf2c3aa42a8b9112661a4e8be95
child 73782 941c6bc7d7280719d25516f699130aa9d4f080a3
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersdbaron
bugs403524
milestone8.0a1
Bug 403524: Remove the standards-mode text-decoration code and use the quirks-mode code in all modes. r=dbaron
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsHTMLContainerFrame.cpp
layout/generic/nsHTMLContainerFrame.h
layout/generic/nsTextFrameThebes.cpp
layout/mathml/nsMathMLContainerFrame.cpp
layout/reftests/text-decoration/reftest.list
layout/reftests/text-decoration/text-decoration-zorder-1-ref.html
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6098,80 +6098,16 @@ nsBlockFrame::IsVisibleInSelection(nsISe
     return PR_TRUE;
 
   nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mContent));
   PRBool visible;
   nsresult rv = aSelection->ContainsNode(node, PR_TRUE, &visible);
   return NS_SUCCEEDED(rv) && visible;
 }
 
-/* virtual */ void
-nsBlockFrame::PaintTextDecorationLine(
-                gfxContext* aCtx, 
-                const nsPoint& aPt,
-                nsLineBox* aLine,
-                nscolor aColor, 
-                PRUint8 aStyle,
-                gfxFloat aOffset, 
-                gfxFloat aAscent, 
-                gfxFloat aSize,
-                const nsCharClipDisplayItem::ClipEdges& aClipEdges,
-                const PRUint8 aDecoration) 
-{
-  NS_ASSERTION(!aLine->IsBlock(), "Why did we ask for decorations on a block?");
-
-  nscoord start = aLine->mBounds.x;
-  nscoord width = aLine->mBounds.width;
-
-  AdjustForTextIndent(aLine, start, width);
-  nscoord x = start + aPt.x;
-  aClipEdges.Intersect(&x, &width);
-
-  // Only paint if we have a positive width
-  if (width > 0) {
-    gfxPoint pt(PresContext()->AppUnitsToGfxUnits(x),
-                PresContext()->AppUnitsToGfxUnits(aLine->mBounds.y + aPt.y));
-    gfxSize size(PresContext()->AppUnitsToGfxUnits(width), aSize);
-    nsCSSRendering::PaintDecorationLine(
-      aCtx, aColor, pt, size,
-      PresContext()->AppUnitsToGfxUnits(aLine->GetAscent()),
-      aOffset, aDecoration, aStyle);
-  }
-}
-
-/*virtual*/ void
-nsBlockFrame::AdjustForTextIndent(const nsLineBox* aLine,
-                                  nscoord& start,
-                                  nscoord& width)
-{
-  if (!GetPrevContinuation() && aLine == begin_lines().get() &&
-      (GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR)) {
-    // Adjust for the text-indent.  See similar code in
-    // nsLineLayout::BeginLineReflow.
-    const nsStyleCoord &textIndent = GetStyleText()->mTextIndent;
-    nscoord pctBasis = 0;
-    if (textIndent.HasPercent()) {
-      // Only work out the percentage basis if we need to.
-      // It's a percentage of the containing block width.
-      nsIFrame* containingBlock =
-        nsHTMLReflowState::GetContainingBlockFor(this);
-      NS_ASSERTION(containingBlock, "Must have containing block!");
-      pctBasis = containingBlock->GetContentRect().width;
-    }
-    nscoord indent = nsRuleNode::ComputeCoordPercentCalc(textIndent, pctBasis);
-
-    // Adjust the start position and the width of the decoration by the
-    // value of the indent.  Note that indent can be negative; that's OK.
-    // It'll just increase the width (which can also happen to be
-    // negative!).
-    start += indent;
-    width -= indent;
-  }
-}
-
 #ifdef DEBUG
 static void DebugOutputDrawLine(PRInt32 aDepth, nsLineBox* aLine, PRBool aDrawn) {
   if (nsBlockFrame::gNoisyDamageRepair) {
     nsFrame::IndentBy(stdout, aDepth+1);
     nsRect lineArea = aLine->GetVisualOverflowArea();
     printf("%s line=%p bounds=%d,%d,%d,%d ca=%d,%d,%d,%d\n",
            aDrawn ? "draw" : "skip",
            static_cast<void*>(aLine),
@@ -6209,23 +6145,16 @@ DisplayLine(nsDisplayListBuilder* aBuild
   PRBool lineMayHaveTextOverflow = aTextOverflow && lineInline;
   if (!intersect && !aBuilder->ShouldDescendIntoFrame(aFrame) &&
       !lineMayHaveTextOverflow)
     return NS_OK;
 
   nsDisplayListCollection collection;
   nsresult rv;
   nsDisplayList aboveTextDecorations;
-  if (lineInline) {
-    // Display the text-decoration for the hypothetical anonymous inline box
-    // that wraps these inlines
-    rv = aFrame->DisplayTextDecorations(aBuilder, collection.Content(),
-                                        &aboveTextDecorations, aLine);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
 
   // Block-level child backgrounds go on the blockBorderBackgrounds list ...
   // Inline-level child backgrounds go on the regular child content list.
   nsDisplayListSet childLists(collection,
     lineInline ? collection.Content() : collection.BlockBorderBackgrounds());
   nsIFrame* kid = aLine->mFirstChild;
   PRInt32 n = aLine->GetChildCount();
   while (--n >= 0) {
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -356,35 +356,16 @@ protected:
     return aPresContext->StyleSet()->
       ProbePseudoElementStyle(mContent->AsElement(),
                               nsCSSPseudoElements::ePseudo_firstLetter,
                               mStyleContext);
   }
 #endif
 #endif
 
-  /*
-   * Overides member function of nsHTMLContainerFrame. Needed to handle the 
-   * lines in a nsBlockFrame properly.
-   */
-  virtual void PaintTextDecorationLine(gfxContext* aCtx,
-                                       const nsPoint& aPt,
-                                       nsLineBox* aLine,
-                                       nscolor aColor,
-                                       PRUint8 aStyle,
-                                       gfxFloat aOffset,
-                                       gfxFloat aAscent,
-                                       gfxFloat aSize,
-                                       const nsCharClipDisplayItem::ClipEdges& aClipEdges,
-                                       const PRUint8 aDecoration);
-
-  virtual void AdjustForTextIndent(const nsLineBox* aLine,
-                                   nscoord& start,
-                                   nscoord& width);
-
   void TryAllLines(nsLineList::iterator* aIterator,
                    nsLineList::iterator* aStartIterator,
                    nsLineList::iterator* aEndIterator,
                    PRBool* aInOverflowLines);
 
   void SetFlags(nsFrameState aFlags) {
     mState &= ~NS_BLOCK_FLAGS_MASK;
     mState |= aFlags;
--- a/layout/generic/nsHTMLContainerFrame.cpp
+++ b/layout/generic/nsHTMLContainerFrame.cpp
@@ -63,557 +63,28 @@
 #include "gfxFont.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsDisplayList.h"
 #include "nsBlockFrame.h"
 #include "nsLineBox.h"
 #include "nsDisplayList.h"
 #include "nsCSSRendering.h"
 
-class nsDisplayTextDecoration : public nsCharClipDisplayItem {
-public:
-  nsDisplayTextDecoration(nsDisplayListBuilder* aBuilder,
-                          nsHTMLContainerFrame* aFrame, PRUint8 aDecoration,
-                          nscolor aColor, PRUint8 aStyle, nsLineBox* aLine)
-    : nsCharClipDisplayItem(aBuilder, aFrame), mLine(aLine), mColor(aColor),
-      mDecoration(aDecoration), mStyle(aStyle) {
-    MOZ_COUNT_CTOR(nsDisplayTextDecoration);
-  }
-#ifdef NS_BUILD_REFCNT_LOGGING
-  virtual ~nsDisplayTextDecoration() {
-    MOZ_COUNT_DTOR(nsDisplayTextDecoration);
-  }
-#endif
-
-  virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
-  NS_DISPLAY_DECL_NAME("TextDecoration", TYPE_TEXT_DECORATION)
-
-  virtual PRUint32 GetPerFrameKey()
-  {
-    return TYPE_TEXT_DECORATION | (mDecoration << TYPE_BITS);
-  }
-
-private:
-  nsLineBox* mLine;
-  nscolor    mColor;
-  PRUint8    mDecoration;
-  PRUint8    mStyle;
-};
-
-void
-nsDisplayTextDecoration::Paint(nsDisplayListBuilder* aBuilder,
-                               nsRenderingContext* aCtx)
-{
-  nsRefPtr<nsFontMetrics> fm;
-  nsLayoutUtils::GetFontMetricsForFrame(mFrame, getter_AddRefs(fm));
-  gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
-  gfxFont* firstFont = fontGroup->GetFontAt(0);
-  if (!firstFont)
-    return; // OOM
-  const gfxFont::Metrics& metrics = firstFont->GetMetrics();
-
-  gfxFloat ascent;
-  // The ascent of first-letter frame's text may not be the same as the ascent
-  // of the font metrics. Because that may use the tight box of the actual
-  // glyph.
-  if (mFrame->GetType() == nsGkAtoms::letterFrame) {
-    // Note that nsFirstLetterFrame::GetFirstLetterBaseline() returns
-    // |border-top + padding-top + ascent|. But we only need the ascent value.
-    // Because they will be added in PaintTextDecorationLine.
-    nsFirstLetterFrame* letterFrame = static_cast<nsFirstLetterFrame*>(mFrame);
-    nscoord tmp = letterFrame->GetFirstLetterBaseline();
-    tmp -= letterFrame->GetUsedBorderAndPadding().top;
-    ascent = letterFrame->PresContext()->AppUnitsToGfxUnits(tmp);
-  } else {
-    ascent = metrics.maxAscent;
-  }
-
-  nsPoint pt = ToReferenceFrame();
-  nsHTMLContainerFrame* f = static_cast<nsHTMLContainerFrame*>(mFrame);
-  if (mDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE) {
-    gfxFloat underlineOffset = fontGroup->GetUnderlineOffset();
-    f->PaintTextDecorationLine(aCtx->ThebesContext(), pt, mLine, mColor,
-                               mStyle, underlineOffset, ascent,
-                               metrics.underlineSize, Edges(), mDecoration);
-  } else if (mDecoration == NS_STYLE_TEXT_DECORATION_LINE_OVERLINE) {
-    f->PaintTextDecorationLine(aCtx->ThebesContext(), pt, mLine, mColor,
-                               mStyle, metrics.maxAscent, ascent,
-                               metrics.underlineSize, Edges(), mDecoration);
-  } else {
-    f->PaintTextDecorationLine(aCtx->ThebesContext(), pt, mLine, mColor,
-                               mStyle, metrics.strikeoutOffset, ascent,
-                               metrics.strikeoutSize, Edges(), mDecoration);
-  }
-}
-
-nsRect
-nsDisplayTextDecoration::GetBounds(nsDisplayListBuilder* aBuilder)
-{
-  return mFrame->GetVisualOverflowRect() + ToReferenceFrame();
-}
-
-class nsDisplayTextShadow : public nsCharClipDisplayItem {
-public:
-  nsDisplayTextShadow(nsDisplayListBuilder* aBuilder,
-                      nsHTMLContainerFrame* aFrame,
-                      const PRUint8 aDecoration, PRUint8 aUnderlineStyle,
-                      PRUint8 aOverlineStyle, PRUint8 aStrikeThroughStyle,
-                      nsLineBox* aLine)
-    : nsCharClipDisplayItem(aBuilder, aFrame), mLine(aLine),
-      mDecorationFlags(aDecoration), mUnderlineStyle(aUnderlineStyle),
-      mOverlineStyle(aOverlineStyle), mStrikeThroughStyle(aStrikeThroughStyle) {
-    MOZ_COUNT_CTOR(nsDisplayTextShadow);
-  }
-  virtual ~nsDisplayTextShadow() {
-    MOZ_COUNT_DTOR(nsDisplayTextShadow);
-  }
-
-  virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
-  NS_DISPLAY_DECL_NAME("TextShadowContainer", TYPE_TEXT_SHADOW)
-private:
-  nsLineBox*    mLine;
-  PRUint8       mDecorationFlags;
-  PRUint8       mUnderlineStyle;
-  PRUint8       mOverlineStyle;
-  PRUint8       mStrikeThroughStyle;
-};
-
-void
-nsDisplayTextShadow::Paint(nsDisplayListBuilder* aBuilder,
-                           nsRenderingContext* aCtx)
-{
-  nsRefPtr<nsFontMetrics> fm;
-  nsLayoutUtils::GetFontMetricsForFrame(mFrame, getter_AddRefs(fm));
-  gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
-  gfxFont* firstFont = fontGroup->GetFontAt(0);
-  if (!firstFont)
-    return; // OOM
-
-  const gfxFont::Metrics& metrics = firstFont->GetMetrics();
-  gfxFloat underlineOffset = fontGroup->GetUnderlineOffset();
-
-  nsHTMLContainerFrame* f = static_cast<nsHTMLContainerFrame*>(mFrame);
-  nsPresContext* presContext = mFrame->PresContext();
-  gfxContext* thebesCtx = aCtx->ThebesContext();
-
-  gfxFloat ascent;
-  gfxFloat lineWidth;
-  nscoord start;
-  if (mLine) {
-    // Block frames give us an nsLineBox, so we must use that
-    nscoord width = mLine->mBounds.width;
-    start = mLine->mBounds.x;
-    f->AdjustForTextIndent(mLine, start, width);
-    if (width <= 0)
-      return;
-
-    lineWidth = presContext->AppUnitsToGfxUnits(width);
-    ascent = presContext->AppUnitsToGfxUnits(mLine->GetAscent());
-  } else {
-    // For inline frames, we must use the frame's geometry
-    lineWidth = presContext->AppUnitsToGfxUnits(mFrame->GetContentRect().width);
-
-    // The ascent of :first-letter frame's text may not be the same as the ascent
-    // of the font metrics, because it may use the tight box of the actual
-    // glyph.
-    if (mFrame->GetType() == nsGkAtoms::letterFrame) {
-      // Note that nsFirstLetterFrame::GetFirstLetterBaseline() returns
-      // |border-top + padding-top + ascent|. But we only need the ascent value,
-      // because those will be added in PaintTextDecorationLine.
-      nsFirstLetterFrame* letterFrame = static_cast<nsFirstLetterFrame*>(mFrame);
-      nscoord tmp = letterFrame->GetFirstLetterBaseline();
-      tmp -= letterFrame->GetUsedBorderAndPadding().top;
-      ascent = presContext->AppUnitsToGfxUnits(tmp);
-    } else {
-      ascent = metrics.maxAscent;
-    }
-  }
-
-  nsCSSShadowArray* shadowList = mFrame->GetStyleText()->mTextShadow;
-  NS_ABORT_IF_FALSE(shadowList,
-                    "Why did we make a display list item if we have no shadows?");
-
-  // Get the rects for each text decoration line, so we know how big we
-  // can make each shadow's surface
-  nsRect underlineRect;
-  nsRect overlineRect;
-  nsRect lineThroughRect;
-  if (mDecorationFlags & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE) {
-    gfxSize size(lineWidth, metrics.underlineSize);
-    underlineRect = nsCSSRendering::GetTextDecorationRect(presContext, size,
-                       ascent, underlineOffset,
-                       NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
-                       mUnderlineStyle);
-  }
-  if (mDecorationFlags & NS_STYLE_TEXT_DECORATION_LINE_OVERLINE) {
-    gfxSize size(lineWidth, metrics.underlineSize);
-    overlineRect = nsCSSRendering::GetTextDecorationRect(presContext, size,
-                       ascent, metrics.maxAscent,
-                       NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, mOverlineStyle);
-  }
-  if (mDecorationFlags & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) {
-    gfxSize size(lineWidth, metrics.strikeoutSize);
-    lineThroughRect = nsCSSRendering::GetTextDecorationRect(presContext, size,
-                       ascent, metrics.strikeoutOffset,
-                       NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH,
-                       mStrikeThroughStyle);
-  }
-
-  for (PRUint32 i = shadowList->Length(); i > 0; --i) {
-    nsCSSShadowItem* shadow = shadowList->ShadowAt(i - 1);
-
-    nscolor shadowColor =
-      shadow->mHasColor ? shadow->mColor : mFrame->GetStyleColor()->mColor;
-
-    nsPoint pt = ToReferenceFrame() +
-      nsPoint(shadow->mXOffset, shadow->mYOffset);
-    nsPoint linePt;
-    if (mLine) {
-      linePt = nsPoint(start + pt.x, mLine->mBounds.y + pt.y);
-    } else {
-      linePt = mFrame->GetContentRect().TopLeft() - mFrame->GetPosition() + pt;
-    }
-
-    nsRect shadowRect(0, 0, 0, 0);
-    if (mDecorationFlags & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE) {
-      shadowRect.UnionRect(shadowRect, underlineRect + linePt);
-    }
-    if (mDecorationFlags & NS_STYLE_TEXT_DECORATION_LINE_OVERLINE) {
-      shadowRect.UnionRect(shadowRect, overlineRect + linePt);
-    }
-    if (mDecorationFlags & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) {
-      shadowRect.UnionRect(shadowRect, lineThroughRect + linePt);
-    }
-
-    gfxContextAutoSaveRestore save(thebesCtx);
-    thebesCtx->NewPath();
-    thebesCtx->SetColor(gfxRGBA(shadowColor));
-
-    // Create our shadow surface, then paint the text decorations onto it
-    nsContextBoxBlur contextBoxBlur;
-    gfxContext* shadowCtx = contextBoxBlur.Init(shadowRect, 0, shadow->mRadius,
-                                                presContext->AppUnitsPerDevPixel(),
-                                                thebesCtx, mVisibleRect, nsnull);
-    if (!shadowCtx) {
-      continue;
-    }
-
-    const nsCharClipDisplayItem::ClipEdges clipEdges = this->Edges();
-    if (mDecorationFlags & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE) {
-      f->PaintTextDecorationLine(shadowCtx, pt, mLine, shadowColor,
-                                 mUnderlineStyle, underlineOffset, ascent,
-                                 metrics.underlineSize, clipEdges,
-                                 NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE);
-    }
-    if (mDecorationFlags & NS_STYLE_TEXT_DECORATION_LINE_OVERLINE) {
-      f->PaintTextDecorationLine(shadowCtx, pt, mLine, shadowColor,
-                                 mOverlineStyle, metrics.maxAscent, ascent,
-                                 metrics.underlineSize, clipEdges,
-                                 NS_STYLE_TEXT_DECORATION_LINE_OVERLINE);
-    }
-    if (mDecorationFlags & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) {
-      f->PaintTextDecorationLine(shadowCtx, pt, mLine, shadowColor,
-                                 mStrikeThroughStyle, metrics.strikeoutOffset,
-                                 ascent, metrics.strikeoutSize, clipEdges,
-                                 NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH);
-    }
-
-    contextBoxBlur.DoPaint();
-  }
-}
-
-nsRect
-nsDisplayTextShadow::GetBounds(nsDisplayListBuilder* aBuilder)
-{
-  // Shadows are always painted in the overflow rect
-  return mFrame->GetVisualOverflowRect() + ToReferenceFrame();
-}
-
-nsresult
-nsHTMLContainerFrame::DisplayTextDecorations(nsDisplayListBuilder* aBuilder,
-                                             nsDisplayList* aBelowTextDecorations,
-                                             nsDisplayList* aAboveTextDecorations,
-                                             nsLineBox* aLine)
-{
-  if (eCompatibility_NavQuirks == PresContext()->CompatibilityMode())
-    return NS_OK;
-  if (!IsVisibleForPainting(aBuilder))
-    return NS_OK;
-
-  // Hide text decorations if we're currently hiding @font-face fallback text
-  nsRefPtr<nsFontMetrics> fm;
-  nsresult rv = nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (fm->GetThebesFontGroup()->ShouldSkipDrawing())
-    return NS_OK;
-
-  // Do standards mode painting of 'text-decoration's: under+overline
-  // behind children, line-through in front.  For Quirks mode, see
-  // nsTextFrame::PaintTextDecorations.  (See bug 1777.)
-  nscolor underColor, overColor, strikeColor;
-  PRUint8 underStyle, overStyle, strikeStyle;
-  PRUint8 decorations = NS_STYLE_TEXT_DECORATION_LINE_NONE;
-  GetTextDecorations(PresContext(), aLine != nsnull, decorations, underColor, 
-                     overColor, strikeColor, underStyle, overStyle,
-                     strikeStyle);
-
-  if (decorations == NS_STYLE_TEXT_DECORATION_LINE_NONE) {
-    return NS_OK;
-  }
-
-  // The text-shadow spec says that any text decorations must also have a
-  // shadow applied to them. So draw the shadows as part of the display
-  // list, underneath the text and all decorations.
-  if (GetStyleText()->mTextShadow) {
-    rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)
-      nsDisplayTextShadow(aBuilder, this, decorations, underStyle, overStyle,
-                          strikeStyle, aLine));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  if ((decorations & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE) &&
-      underStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
-    rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)
-      nsDisplayTextDecoration(aBuilder, this,
-                              NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
-                              underColor, underStyle, aLine));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  if ((decorations & NS_STYLE_TEXT_DECORATION_LINE_OVERLINE) &&
-      overStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
-    rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder)
-      nsDisplayTextDecoration(aBuilder, this,
-                              NS_STYLE_TEXT_DECORATION_LINE_OVERLINE,
-                              overColor, overStyle, aLine));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  if ((decorations & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) &&
-      strikeStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
-    rv = aAboveTextDecorations->AppendNewToTop(new (aBuilder)
-      nsDisplayTextDecoration(aBuilder, this,
-                              NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH,
-                              strikeColor, strikeStyle, aLine));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  return NS_OK;
-}
-
-nsresult
-nsHTMLContainerFrame::DisplayTextDecorationsAndChildren(
-    nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect,
-    const nsDisplayListSet& aLists)
-{
-  nsDisplayList aboveChildrenDecorations;
-  nsresult rv = DisplayTextDecorations(aBuilder, aLists.Content(),
-      &aboveChildrenDecorations, nsnull);
-  NS_ENSURE_SUCCESS(rv, rv);
-  
-  rv = BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists,
-                                           DISPLAY_CHILD_INLINE);
-  NS_ENSURE_SUCCESS(rv, rv);
-  
-  aLists.Content()->AppendToTop(&aboveChildrenDecorations);
-  return NS_OK;
-}
-
 NS_IMETHODIMP
 nsHTMLContainerFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                        const nsRect&           aDirtyRect,
                                        const nsDisplayListSet& aLists) {
   nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return DisplayTextDecorationsAndChildren(aBuilder, aDirtyRect, aLists);
-}
-
-static PRBool 
-HasTextFrameDescendantOrInFlow(nsIFrame* aFrame);
-
-/*virtual*/ void
-nsHTMLContainerFrame::PaintTextDecorationLine(
-                   gfxContext* aCtx, 
-                   const nsPoint& aPt,
-                   nsLineBox* aLine,
-                   nscolor aColor, 
-                   PRUint8 aStyle,
-                   gfxFloat aOffset, 
-                   gfxFloat aAscent, 
-                   gfxFloat aSize,
-                   const nsCharClipDisplayItem::ClipEdges& aClipEdges,
-                   const PRUint8 aDecoration) 
-{
-  NS_ASSERTION(!aLine, "Should not have passed a linebox to a non-block frame");
-  nsMargin bp = GetUsedBorderAndPadding();
-  PRIntn skip = GetSkipSides();
-  NS_FOR_CSS_SIDES(side) {
-    if (skip & (1 << side)) {
-      bp.Side(side) = 0;
-    }
-  }
-  nscoord x = aPt.x + bp.left;
-  nscoord innerWidth = mRect.width - bp.left - bp.right;
-  aClipEdges.Intersect(&x, &innerWidth);
-  gfxPoint pt(PresContext()->AppUnitsToGfxUnits(x),
-              PresContext()->AppUnitsToGfxUnits(bp.top + aPt.y));
-  gfxSize size(PresContext()->AppUnitsToGfxUnits(innerWidth), aSize);
-  nsCSSRendering::PaintDecorationLine(aCtx, aColor, pt, size, aAscent, aOffset,
-                                      aDecoration, aStyle);
-}
-
-/*virtual*/ void
-nsHTMLContainerFrame::AdjustForTextIndent(const nsLineBox* aLine,
-                                          nscoord& start,
-                                          nscoord& width)
-{
-  // This function is not for us.
-  // It allows nsBlockFrame to adjust the width/X position of its
-  // shadowed decorations if a text-indent rule is in effect.
-}
-
-void
-nsHTMLContainerFrame::GetTextDecorations(nsPresContext* aPresContext, 
-                                         PRBool aIsBlock,
-                                         PRUint8& aDecorations,
-                                         nscolor& aUnderColor, 
-                                         nscolor& aOverColor, 
-                                         nscolor& aStrikeColor,
-                                         PRUint8& aUnderStyle,
-                                         PRUint8& aOverStyle,
-                                         PRUint8& aStrikeStyle)
-{
-  aDecorations = NS_STYLE_TEXT_DECORATION_LINE_NONE;
-  if (!mStyleContext->HasTextDecorationLines()) {
-    // This is a necessary, but not sufficient, condition for text
-    // decorations.
-    return; 
-  }
-
-  if (!aIsBlock) {
-    const nsStyleTextReset* styleTextReset = this->GetStyleTextReset();
-    aDecorations = styleTextReset->mTextDecorationLine &
-                   NS_STYLE_TEXT_DECORATION_LINE_LINES_MASK;
-    if (aDecorations) {
-      nscolor color =
-        this->GetVisitedDependentColor(eCSSProperty_text_decoration_color);
-      aUnderColor = aOverColor = aStrikeColor = color;
-      aUnderStyle = aOverStyle = aStrikeStyle =
-        styleTextReset->GetDecorationStyle();
-    }
-  }
-  else {
-    // We want to ignore a text-decoration from an ancestor frame that
-    // is redundant with one from a descendant frame.  This isn't just
-    // an optimization; the descendant frame's color specification
-    // must win.  At any point in the loop below, this variable
-    // indicates which decorations we are still paying attention to;
-    // it starts set to all possible decorations.
-    PRUint8 decorMask = NS_STYLE_TEXT_DECORATION_LINE_LINES_MASK;
+  rv = BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists,
+                                           DISPLAY_CHILD_INLINE);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-    // walk tree
-    for (nsIFrame* frame = this; frame; frame = frame->GetParent()) {
-      const nsStyleTextReset* styleTextReset = frame->GetStyleTextReset();
-      PRUint8 decors = styleTextReset->mTextDecorationLine & decorMask;
-      if (decors) {
-        // A *new* text-decoration is found.
-        nscolor color = frame->GetVisitedDependentColor(
-                                 eCSSProperty_text_decoration_color);
-        PRUint8 style = styleTextReset->GetDecorationStyle();
-
-        if (NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE & decors) {
-          aUnderColor = color;
-          aUnderStyle = style;
-          decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
-          aDecorations |= NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
-        }
-        if (NS_STYLE_TEXT_DECORATION_LINE_OVERLINE & decors) {
-          aOverColor = color;
-          aOverStyle = style;
-          decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
-          aDecorations |= NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
-        }
-        if (NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH & decors) {
-          aStrikeColor = color;
-          aStrikeStyle = style;
-          decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
-          aDecorations |= NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
-        }
-      }
-      // If all possible decorations have now been specified, no
-      // further ancestor frames can affect the rendering.
-      if (!decorMask) {
-        break;
-      }
-
-      // CSS2.1 16.3.1 specifies that this property is not always
-      // inherited from ancestor boxes (frames in our terminology):
-      //
-      //      When specified on an inline element, [the
-      //      text-decoration property] affects all the boxes
-      //      generated by that element; for all other elements, the
-      //      decorations are propagated to an anonymous inline box
-      //      that wraps all the in-flow inline children of the
-      //      element, and to any block-level in-flow descendants. It
-      //      is not, however, further propagated to floating and
-      //      absolutely positioned descendants, nor to the contents
-      //      of 'inline-table' and 'inline-block' descendants.
-      //
-      // So do not look at the ancestor frame if this frame is any of
-      // the above.  This check is at the bottom of the loop because
-      // even if it's true we still want to look at decorations on the
-      // frame itself.
-      const nsStyleDisplay* styleDisplay = frame->GetStyleDisplay();
-      if (styleDisplay->IsFloating() ||
-          styleDisplay->IsAbsolutelyPositioned() ||
-          styleDisplay->IsInlineOutside()) {
-        break;
-      }
-    }
-  }
-  
-  if (aDecorations) {
-    // If this frame contains no text, we're required to ignore this property
-    if (!HasTextFrameDescendantOrInFlow(this)) {
-      aDecorations = NS_STYLE_TEXT_DECORATION_LINE_NONE;
-    }
-  }
-}
-
-static PRBool 
-HasTextFrameDescendant(nsIFrame* aParent)
-{
-  for (nsIFrame* kid = aParent->GetFirstChild(nsnull); kid;
-       kid = kid->GetNextSibling())
-  {
-    if (kid->GetType() == nsGkAtoms::textFrame) {
-      // This is only a candidate. We need to determine if this text
-      // frame is empty, as in containing only (non-pre) whitespace.
-      // See bug 20163.
-      if (!kid->IsEmpty()) {
-        return PR_TRUE;
-      }
-    }
-    if (HasTextFrameDescendant(kid)) {
-      return PR_TRUE;
-    }
-  }
-  return PR_FALSE;
-}
-
-static PRBool 
-HasTextFrameDescendantOrInFlow(nsIFrame* aFrame)
-{
-  for (nsIFrame *f = aFrame->GetFirstInFlow(); f; f = f->GetNextInFlow()) {
-    if (HasTextFrameDescendant(f))
-      return PR_TRUE;
-  }
-  return PR_FALSE;
+  return NS_OK;
 }
 
 /*
  * Create a next-in-flow for aFrame. Will return the newly created
  * frame in aNextInFlowResult <b>if and only if</b> a new frame is
  * created; otherwise nsnull is returned in aNextInFlowResult.
  */
 nsresult
--- a/layout/generic/nsHTMLContainerFrame.h
+++ b/layout/generic/nsHTMLContainerFrame.h
@@ -61,18 +61,16 @@ class nsLineBox;
 #ifdef DEBUG
 #define CRAZY_W (1000000*60)
 #define CRAZY_H CRAZY_W
 
 #define CRAZY_WIDTH(_x) (((_x) < -CRAZY_W) || ((_x) > CRAZY_W))
 #define CRAZY_HEIGHT(_y) (((_y) < -CRAZY_H) || ((_y) > CRAZY_H))
 #endif
 
-class nsDisplayTextDecoration;
-
 // Base class for html container frames that provides common
 // functionality.
 class nsHTMLContainerFrame : public nsContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   /**
    * Helper method to create next-in-flows if necessary. If aFrame
@@ -94,109 +92,14 @@ public:
   /**
    * Displays the standard border, background and outline for the frame
    * and calls DisplayTextDecorationsAndChildren. This is suitable for
    * inline frames or frames that behave like inlines.
    */
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
-                              
-  nsresult DisplayTextDecorations(nsDisplayListBuilder* aBuilder,
-                                  nsDisplayList* aBelowTextDecorations,
-                                  nsDisplayList* aAboveTextDecorations,
-                                  nsLineBox* aLine);
 
 protected:
   nsHTMLContainerFrame(nsStyleContext *aContext) : nsContainerFrame(aContext) {}
-
-  /**
-   * Displays the below-children decorations, then the children, then
-   * the above-children decorations, with the decorations going in the
-   * Content() list. This is suitable for inline elements and elements
-   * that behave like inline elements (e.g. MathML containers).
-   */
-  nsresult DisplayTextDecorationsAndChildren(nsDisplayListBuilder* aBuilder, 
-                                             const nsRect& aDirtyRect,
-                                             const nsDisplayListSet& aLists);
-
-  /**
-   * Fetch the text decorations for this frame. 
-   *  @param aIsBlock      whether |this| is a block frame or no.
-   *  @param aDecorations  mask with all decorations. 
-   *                         See bug 1777 and 20163 to understand how a
-   *                         frame can end up with several decorations.
-   *  @param aUnderColor   The color of underline if the appropriate bit 
-   *                         in aDecoration is set. It is undefined otherwise.
-   *  @param aOverColor    The color of overline if the appropriate bit 
-   *                         in aDecoration is set. It is undefined otherwise.
-   *  @param aStrikeColor  The color of strike-through if the appropriate bit 
-   *                         in aDecoration is set. It is undefined otherwise.
-   *  @param aUnderStyle   The style of underline if the appropriate bit
-   *                         in aDecoration is set. It is undefined otherwise.
-   *                         The style is one of
-   *                         NS_STYLE_TEXT_DECORATION_STYLE_* consts.
-   *  @param aOverStyle    The style of overline if the appropriate bit
-   *                         in aDecoration is set. It is undefined otherwise.
-   *                         The style is one of
-   *                         NS_STYLE_TEXT_DECORATION_STYLE_* consts.
-   *  @param aStrikeStyle  The style of strike-through if the appropriate bit
-   *                         in aDecoration is set. It is undefined otherwise.
-   *                         The style is one of
-   *                         NS_STYLE_TEXT_DECORATION_STYLE_* consts.
-   *  NOTE: This function assigns NS_STYLE_TEXT_DECORATION_LINE_NONE to
-   *        aDecorations for text-less frames.  See bug 20163 for
-   *        details.
-   *  NOTE: The results of color and style for each lines were not initialized
-   *        if the line wasn't included in aDecorations.
-   */
-  void GetTextDecorations(nsPresContext* aPresContext, 
-                          PRBool aIsBlock,
-                          PRUint8& aDecorations, 
-                          nscolor& aUnderColor, 
-                          nscolor& aOverColor, 
-                          nscolor& aStrikeColor,
-                          PRUint8& aUnderStyle,
-                          PRUint8& aOverStyle,
-                          PRUint8& aStrikeStyle);
-
-  /** 
-   * Function that does the actual drawing of the textdecoration. 
-   *   input:
-   *    @param aCtx               the Thebes graphics context to draw on
-   *    @param aLine              the line, or nsnull if this is an inline frame
-   *    @param aColor             the color of the text-decoration
-   *    @param aStyle             the style of the text-decoration, i.e., one of
-   *                                NS_STYLE_TEXT_DECORATION_STYLE_* consts.
-   *    @param aAscent            ascent of the font from which the
-   *                                text-decoration was derived. 
-   *    @param aOffset            distance *above* baseline where the
-   *                                text-decoration should be drawn,
-   *                                i.e. negative offsets draws *below*
-   *                                the baseline.
-   *    @param aSize              the thickness of the line
-   *    @param aClipEdges         clip edges from the display item
-   *    @param aDecoration        which line will be painted i.e.,
-   *                              NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE or
-   *                              NS_STYLE_TEXT_DECORATION_LINE_OVERLINE or
-   *                              NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH.
-   */
-  virtual void PaintTextDecorationLine(
-                 gfxContext* aCtx,
-                 const nsPoint& aPt,
-                 nsLineBox* aLine,
-                 nscolor aColor,
-                 PRUint8 aStyle,
-                 gfxFloat aOffset,
-                 gfxFloat aAscent,
-                 gfxFloat aSize,
-                 const nsCharClipDisplayItem::ClipEdges& aClipEdges,
-                 const PRUint8 aDecoration);
-
-  virtual void AdjustForTextIndent(const nsLineBox* aLine,
-                                   nscoord& start,
-                                   nscoord& width);
-
-  friend class nsDisplayTextDecoration;
-  friend class nsDisplayTextShadow;
 };
 
 #endif /* nsHTMLContainerFrame_h___ */
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -4259,25 +4259,17 @@ FillClippedRect(gfxContext* aCtx, nsPres
   aCtx->SetColor(gfxRGBA(aColor));
   aCtx->Fill();
 }
 
 void
 nsTextFrame::GetTextDecorations(nsPresContext* aPresContext,
                                 nsTextFrame::TextDecorations& aDecorations)
 {
-  // Quirks mode text decoration are rendered by children; see bug 1777
-  // In non-quirks mode, nsHTMLContainer::Paint and nsBlockFrame::Paint
-  // does the painting of text decorations.
-  // FIXME Bug 403524: We'd like to unify standards-mode and quirks-mode
-  // text-decoration drawing, using what's currently the quirks mode
-  // codepath.  But for now this code is only used for quirks mode.
   const nsCompatibility compatMode = aPresContext->CompatibilityMode();
-  if (compatMode != eCompatibility_NavQuirks)
-    return;
 
   PRBool useOverride = PR_FALSE;
   nscolor overrideColor;
 
   // frameTopOffset represents the offset to f's top from our baseline in our
   // coordinate space
   // baselineOffset represents the offset from our baseline to f's baseline or
   // the nearest block's baseline, in our coordinate space, whichever is closest
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -663,17 +663,18 @@ nsMathMLContainerFrame::BuildDisplayList
 
     return aLists.Content()->AppendNewToTop(
         new (aBuilder) nsDisplayMathMLError(aBuilder, this));
   }
 
   nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = DisplayTextDecorationsAndChildren(aBuilder, aDirtyRect, aLists);
+  rv = BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists,
+                                           DISPLAY_CHILD_INLINE);
   NS_ENSURE_SUCCESS(rv, rv);
 
 #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
   // for visual debug
   // ----------------
   // if you want to see your bounding box, make sure to properly fill
   // your mBoundingMetrics and mReference point, and set
   // mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS
--- a/layout/reftests/text-decoration/reftest.list
+++ b/layout/reftests/text-decoration/reftest.list
@@ -75,22 +75,22 @@ fails == underline-block-propagation-2-q
 == underline-block-standards.html underline-block-standards-ref.html
 != underline-block-standards.html underline-block-standards-notref.html
 == underline-inline-block-standards.html underline-inline-block-standards-ref.html
 != underline-inline-block-standards.html underline-inline-block-standards-notref.html
 == underline-table-caption-standards.html underline-table-caption-standards-ref.html
 != underline-table-caption-standards.html underline-table-caption-standards-notref.html
 == underline-table-cell-standards.html underline-table-cell-standards-ref.html
 != underline-table-cell-standards.html underline-table-cell-standards-notref.html
-fails == underline-block-propagation-standards.html underline-block-propagation-standards-ref.html # bug that decoration is drawn through non-text child (bug 428599)
+== underline-block-propagation-standards.html underline-block-propagation-standards-ref.html
 fails-if(Android) fails-if(d2d) == underline-block-propagation-2-standards.html underline-block-propagation-2-standards-ref.html # bug 585684
 == text-decoration-zorder-1-standards.html text-decoration-zorder-1-ref.html
-== text-decoration-zorder-1-quirks.html text-decoration-zorder-1-ref.html # bug 403524
+== text-decoration-zorder-1-quirks.html text-decoration-zorder-1-ref.html
 == table-quirk-1.html table-quirk-1-ref.html
 == table-quirk-2.html table-quirk-2-ref.html
 == text-decoration-propagation-1-quirks.html text-decoration-propagation-1-quirks-ref.html
-fails == text-decoration-propagation-1-standards.html text-decoration-propagation-1-standards-ref.html
+== text-decoration-propagation-1-standards.html text-decoration-propagation-1-standards-ref.html
 == 641444-1.html 641444-1-ref.html
-== decoration-css21.html decoration-css21-ref.html # bug 403524
+== decoration-css21.html decoration-css21-ref.html
 == decoration-color-override-quirks.html decoration-color-override-quirks-ref.html
 == decoration-color-override-standards.html decoration-color-override-standards-ref.html
 != decoration-color-override-standards-ref.html decoration-color-override-quirks-ref.html
 == decoration-css21-block.html decoration-css21-block-ref.html # bug 403524
--- a/layout/reftests/text-decoration/text-decoration-zorder-1-ref.html
+++ b/layout/reftests/text-decoration/text-decoration-zorder-1-ref.html
@@ -19,17 +19,17 @@
 		font-size: 50px;
 	}
 	
 	p.under { text-decoration: underline; top: 25px; }
 	p.over { text-decoration: overline; top: 125px; }
 	p.through { text-decoration: line-through; top: 225px; }
 
 	p.text { text-decoration: none ! important; }
-	p.line span { visibility: hidden; }
+	p.line span { color: transparent; }
 
 	p.text { color: blue; }
 	p.line { color: fuchsia; }
 
 	</style>
 </head>
 <body>