Bug 1258636 part 2 - Use struct to pass params for nsTextFrame::PaintDecorationLine. draft
authorXidorn Quan <quanxunzhen@gmail.com>
Tue, 22 Mar 2016 17:42:18 +0800
changeset 343664 2ff5be7628583858c410dde5fe8de3254e8bed88
parent 343663 37f2aac69f6582a42f949b6559ac532b6c467875
child 516812 6f88b3d3d4f29be869d9502b8e82b8c1044dd08d
push id13666
push userxquan@mozilla.com
push dateWed, 23 Mar 2016 01:42:44 +0000
bugs1258636
milestone48.0a1
Bug 1258636 part 2 - Use struct to pass params for nsTextFrame::PaintDecorationLine. MozReview-Commit-ID: CICgNSPRrLM
layout/generic/nsTextFrame.cpp
layout/generic/nsTextFrame.h
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -5461,54 +5461,52 @@ nsTextFrame::ComputeSelectionUnderlineHe
       return ceil(fontSize / 20);
     }
     default:
       NS_WARNING("Requested underline style is not valid");
       return aFontMetrics.underlineSize;
   }
 }
 
+enum class DecorationType
+{
+  Normal, Selection
+};
+struct nsTextFrame::PaintDecorationLineParams
+  : nsCSSRendering::DecorationRectParams
+{
+  gfxContext* context = nullptr;
+  LayoutDeviceRect dirtyRect;
+  Point pt;
+  const nscolor* overrideColor = nullptr;
+  nscolor color = NS_RGBA(0, 0, 0, 0);
+  gfxFloat icoordInFrame = 0.0f;
+  DecorationType decorationType = DecorationType::Normal;
+  DrawPathCallbacks* callbacks = nullptr;
+};
+
 void
-nsTextFrame::PaintDecorationLine(gfxContext* const aCtx,
-                                 const LayoutDeviceRect& aDirtyRect,
-                                 nscolor aColor,
-                                 const nscolor* aOverrideColor,
-                                 const Point& aPt,
-                                 gfxFloat aICoordInFrame,
-                                 const Size& aLineSize,
-                                 gfxFloat aAscent,
-                                 gfxFloat aOffset,
-                                 uint8_t aDecoration,
-                                 uint8_t aStyle,
-                                 DecorationType aDecorationType,
-                                 DrawPathCallbacks* aCallbacks,
-                                 bool aVertical,
-                                 gfxFloat aDescentLimit /* = -1.0 */)
+nsTextFrame::PaintDecorationLine(const PaintDecorationLineParams& aParams)
 {
   nsCSSRendering::PaintDecorationLineParams params;
-  params.dirtyRect = aDirtyRect.ToUnknownRect();
-  params.pt = aPt;
-  params.color = aOverrideColor ? *aOverrideColor : aColor;
-  params.icoordInFrame = Float(aICoordInFrame);
-  params.lineSize = aLineSize;
-  params.ascent = aAscent;
-  params.offset = aOffset;
-  params.decoration = aDecoration;
-  params.style = aStyle;
-  params.vertical = aVertical;
-  params.descentLimit = aDescentLimit;
-  if (aCallbacks) {
+  static_cast<nsCSSRendering::DecorationRectParams&>(params) = aParams;
+  params.dirtyRect = aParams.dirtyRect.ToUnknownRect();
+  params.pt = aParams.pt;
+  params.color = aParams.overrideColor ? *aParams.overrideColor : aParams.color;
+  params.icoordInFrame = Float(aParams.icoordInFrame);
+  if (aParams.callbacks) {
     Rect path = nsCSSRendering::DecorationLineToPath(params);
-    if (aDecorationType == eNormalDecoration) {
-      aCallbacks->PaintDecorationLine(path, params.color);
+    if (aParams.decorationType == DecorationType::Normal) {
+      aParams.callbacks->PaintDecorationLine(path, params.color);
     } else {
-      aCallbacks->PaintSelectionDecorationLine(path, params.color);
+      aParams.callbacks->PaintSelectionDecorationLine(path, params.color);
     }
   } else {
-    nsCSSRendering::PaintDecorationLine(this, *aCtx->GetDrawTarget(), params);
+    nsCSSRendering::PaintDecorationLine(
+      this, *aParams.context->GetDrawTarget(), params);
   }
 }
 
 /**
  * This, plus SelectionTypesWithDecorations, encapsulates all knowledge about
  * drawing text decoration for selections.
  */
 void
@@ -5522,35 +5520,42 @@ nsTextFrame::DrawSelectionDecorations(gf
                                       gfxFloat aWidth,
                                       gfxFloat aAscent,
                                       const gfxFont::Metrics& aFontMetrics,
                                       DrawPathCallbacks* aCallbacks,
                                       bool aVertical,
                                       gfxFloat aDecorationOffsetDir,
                                       uint8_t aDecoration)
 {
-  Point pt(aPt);
-  Size size(aWidth,
-            ComputeSelectionUnderlineHeight(aTextPaintStyle.PresContext(),
-                                            aFontMetrics, aType));
-  gfxFloat descentLimit =
+  PaintDecorationLineParams params;
+  params.context = aContext;
+  params.dirtyRect = aDirtyRect;
+  params.pt = aPt;
+  params.lineSize = Size(
+      aWidth, ComputeSelectionUnderlineHeight(aTextPaintStyle.PresContext(),
+                                              aFontMetrics, aType));
+  params.ascent = aAscent;
+  gfxFloat offset = aDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE ?
+                      aFontMetrics.underlineOffset : aFontMetrics.maxAscent;
+  params.offset = offset * aDecorationOffsetDir;
+  params.decoration = aDecoration;
+  params.decorationType = DecorationType::Selection;
+  params.callbacks = aCallbacks;
+  params.vertical = aVertical;
+  params.descentLimit =
     ComputeDescentLimitForSelectionUnderline(aTextPaintStyle.PresContext(),
                                              aFontMetrics);
 
   float relativeSize;
-  uint8_t style;
-  nscolor color;
   int32_t index =
     nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(aType);
   bool weDefineSelectionUnderline =
-    aTextPaintStyle.GetSelectionUnderlineForPaint(index, &color,
-                                                  &relativeSize, &style);
-
-  gfxFloat offset = aDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE ?
-                      aFontMetrics.underlineOffset : aFontMetrics.maxAscent;
+    aTextPaintStyle.GetSelectionUnderlineForPaint(index, &params.color,
+                                                  &relativeSize, &params.style);
+
 
   switch (aType) {
     case nsISelectionController::SELECTION_IME_RAWINPUT:
     case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
     case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
     case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT: {
       // IME decoration lines should not be drawn on the both ends, i.e., we
       // need to cut both edges of the decoration lines.  Because same style
@@ -5560,50 +5565,50 @@ nsTextFrame::DrawSelectionDecorations(gf
       //  X: underline
       //
       //     IME selection #1        IME selection #2      IME selection #3
       //  |                     |                      |                    
       //  | XXXXXXXXXXXXXXXXXXX | XXXXXXXXXXXXXXXXXXXX | XXXXXXXXXXXXXXXXXXX
       //  +---------------------+----------------------+--------------------
       //   ^                   ^ ^                    ^ ^
       //  gap                  gap                    gap
-      pt.x += 1.0;
-      size.width -= 2.0;
+      params.pt.x += 1.0;
+      params.lineSize.width -= 2.0;
       if (aRangeStyle.IsDefined()) {
         // If IME defines the style, that should override our definition.
         if (aRangeStyle.IsLineStyleDefined()) {
           if (aRangeStyle.mLineStyle == TextRangeStyle::LINESTYLE_NONE) {
             return;
           }
-          style = aRangeStyle.mLineStyle;
+          params.style = aRangeStyle.mLineStyle;
           relativeSize = aRangeStyle.mIsBoldLine ? 2.0f : 1.0f;
         } else if (!weDefineSelectionUnderline) {
           // There is no underline style definition.
           return;
         }
         // If underline color is defined and that doesn't depend on the
         // foreground color, we should use the color directly.
         if (aRangeStyle.IsUnderlineColorDefined() &&
             (!aRangeStyle.IsForegroundColorDefined() ||
              aRangeStyle.mUnderlineColor != aRangeStyle.mForegroundColor)) {
-          color = aRangeStyle.mUnderlineColor;
+          params.color = aRangeStyle.mUnderlineColor;
         }
         // If foreground color or background color is defined, the both colors
         // are computed by GetSelectionTextColors().  Then, we should use its
         // foreground color always.  The color should have sufficient contrast
         // with the background color.
         else if (aRangeStyle.IsForegroundColorDefined() ||
                  aRangeStyle.IsBackgroundColorDefined()) {
           nscolor bg;
           GetSelectionTextColors(aType, aTextPaintStyle, aRangeStyle,
-                                 &color, &bg);
+                                 &params.color, &bg);
         }
         // Otherwise, use the foreground color of the frame.
         else {
-          color = aTextPaintStyle.GetTextColor();
+          params.color = aTextPaintStyle.GetTextColor();
         }
       } else if (!weDefineSelectionUnderline) {
         // IME doesn't specify the selection style and we don't define selection
         // underline.
         return;
       }
       break;
     }
@@ -5623,21 +5628,20 @@ nsTextFrame::DrawSelectionDecorations(gf
       offset = metrics.strikeoutOffset + 0.5;
       aDecoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
       break;
     }
     default:
       NS_WARNING("Requested selection decorations when there aren't any");
       return;
   }
-  size.height *= relativeSize;
-  PaintDecorationLine(aContext, aDirtyRect, color, nullptr, pt,
-    (aVertical ? (pt.y - aPt.y) : (pt.x - aPt.x)) + aICoordInFrame,
-    size, aAscent, offset * aDecorationOffsetDir, aDecoration, style,
-    eSelectionDecoration, aCallbacks, aVertical, descentLimit);
+  params.lineSize.height *= relativeSize;
+  params.icoordInFrame = (aVertical ? params.pt.y - aPt.y
+                                    : params.pt.x - aPt.x) + aICoordInFrame;
+  PaintDecorationLine(params);
 }
 
 /* static */
 bool
 nsTextFrame::GetSelectionTextColors(SelectionType aType,
                                     nsTextPaintStyle& aTextPaintStyle,
                                     const TextRangeStyle &aRangeStyle,
                                     nscolor* aForeground,
@@ -6641,24 +6645,18 @@ nsTextFrame::DrawTextRunAndDecorations(R
     nscoord measure = verticalRun ? frameSize.height : frameSize.width;
 
     if (verticalRun) {
       aParams.clipEdges->Intersect(&y, &measure);
     } else {
       aParams.clipEdges->Intersect(&x, &measure);
     }
 
-    // decPt is the physical point where the decoration is to be drawn,
-    // relative to the frame; one of its coordinates will be updated below.
-    Point decPt(x / app, y / app);
-    Float& bCoord = verticalRun ? decPt.x : decPt.y;
-
     // decSize is a textrun-relative size, so its 'width' field is actually
     // the run-relative measure, and 'height' will be the line thickness
-    Size decSize(measure / app, 0);
     gfxFloat ascent = gfxFloat(mAscent) / app;
 
     // The starting edge of the frame in block direction
     gfxFloat frameBStart = verticalRun ? aParams.framePt.x : aParams.framePt.y;
 
     // In vertical-rl mode, block coordinates are measured from the right,
     // so we need to adjust here.
     const WritingMode wm = GetWritingMode();
@@ -6669,59 +6667,72 @@ nsTextFrame::DrawTextRunAndDecorations(R
 
     nscoord inflationMinFontSize =
       nsLayoutUtils::InflationMinFontSizeFor(this);
 
     // The decoration-line offsets need to be reversed for sideways-lr mode,
     // so we will multiply the values from metrics by this factor.
     gfxFloat decorationOffsetDir = mTextRun->IsSidewaysLeft() ? -1.0 : 1.0;
 
+    PaintDecorationLineParams params;
+    params.context = aParams.context;
+    params.dirtyRect = aParams.dirtyRect;
+    params.overrideColor = aParams.decorationOverrideColor;
+    params.callbacks = aParams.callbacks;
+    // pt is the physical point where the decoration is to be drawn,
+    // relative to the frame; one of its coordinates will be updated below.
+    params.pt = Point(x / app, y / app);
+    Float& bCoord = verticalRun ? params.pt.x : params.pt.y;
+    params.lineSize = Size(measure / app, 0);
+    params.ascent = ascent;
+    params.vertical = verticalRun;
+
     // Underlines
     for (uint32_t i = aDecorations.mUnderlines.Length(); i-- > 0; ) {
       const LineDecoration& dec = aDecorations.mUnderlines[i];
       if (dec.mStyle == NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
         continue;
       }
 
       float inflation =
         GetInflationForTextDecorations(dec.mFrame, inflationMinFontSize);
       const gfxFont::Metrics metrics =
         GetFirstFontMetrics(GetFontGroupForFrame(dec.mFrame, inflation),
                             useVerticalMetrics);
 
-      decSize.height = metrics.underlineSize;
+      params.lineSize.height = metrics.underlineSize;
       bCoord = (frameBStart - dec.mBaselineOffset) / app;
 
-      PaintDecorationLine(aParams.context, aParams.dirtyRect, dec.mColor,
-        aParams.decorationOverrideColor, decPt, 0.0, decSize, ascent,
-        decorationOffsetDir * metrics.underlineOffset,
-        NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
-        dec.mStyle, eNormalDecoration, aParams.callbacks, verticalRun);
+      params.color = dec.mColor;
+      params.offset = decorationOffsetDir * metrics.underlineOffset;
+      params.decoration = NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
+      params.style = dec.mStyle;
+      PaintDecorationLine(params);
     }
     // Overlines
     for (uint32_t i = aDecorations.mOverlines.Length(); i-- > 0; ) {
       const LineDecoration& dec = aDecorations.mOverlines[i];
       if (dec.mStyle == NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
         continue;
       }
 
       float inflation =
         GetInflationForTextDecorations(dec.mFrame, inflationMinFontSize);
       const gfxFont::Metrics metrics =
         GetFirstFontMetrics(GetFontGroupForFrame(dec.mFrame, inflation),
                             useVerticalMetrics);
 
-      decSize.height = metrics.underlineSize;
+      params.lineSize.height = metrics.underlineSize;
       bCoord = (frameBStart - dec.mBaselineOffset) / app;
 
-      PaintDecorationLine(aParams.context, aParams.dirtyRect, dec.mColor,
-        aParams.decorationOverrideColor, decPt, 0.0, decSize, ascent,
-        decorationOffsetDir * metrics.maxAscent,
-        NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, dec.mStyle,
-        eNormalDecoration, aParams.callbacks, verticalRun);
+      params.color = dec.mColor;
+      params.offset = decorationOffsetDir * metrics.maxAscent;
+      params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
+      params.style = dec.mStyle;
+      PaintDecorationLine(params);
     }
 
     // CSS 2.1 mandates that text be painted after over/underlines, and *then*
     // line-throughs
     DrawTextRun(aRange, aTextBaselinePt, aParams);
 
     // Emphasis marks
     DrawEmphasisMarks(aParams.context, wm, aTextBaselinePt, aRange,
@@ -6735,24 +6746,24 @@ nsTextFrame::DrawTextRunAndDecorations(R
       }
 
       float inflation =
         GetInflationForTextDecorations(dec.mFrame, inflationMinFontSize);
       const gfxFont::Metrics metrics =
         GetFirstFontMetrics(GetFontGroupForFrame(dec.mFrame, inflation),
                             useVerticalMetrics);
 
-      decSize.height = metrics.strikeoutSize;
+      params.lineSize.height = metrics.strikeoutSize;
       bCoord = (frameBStart - dec.mBaselineOffset) / app;
 
-      PaintDecorationLine(aParams.context, aParams.dirtyRect, dec.mColor,
-        aParams.decorationOverrideColor, decPt, 0.0, decSize, ascent,
-        decorationOffsetDir * metrics.strikeoutOffset,
-        NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH,
-        dec.mStyle, eNormalDecoration, aParams.callbacks, verticalRun);
+      params.color = dec.mColor;
+      params.offset = decorationOffsetDir * metrics.strikeoutOffset;
+      params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
+      params.style = dec.mStyle;
+      PaintDecorationLine(params);
     }
 }
 
 void
 nsTextFrame::DrawText(Range aRange, const gfxPoint& aTextBaselinePt,
                       const DrawTextParams& aParams)
 {
   TextDecorations decorations;
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -741,36 +741,19 @@ protected:
                                 gfxFloat aICoordInFrame,
                                 gfxFloat aWidth,
                                 gfxFloat aAscent,
                                 const gfxFont::Metrics& aFontMetrics,
                                 DrawPathCallbacks* aCallbacks,
                                 bool aVertical,
                                 gfxFloat aDecorationOffsetDir,
                                 uint8_t aDecoration);
-  enum DecorationType
-  {
-    eNormalDecoration,
-    eSelectionDecoration
-  };
-  void PaintDecorationLine(gfxContext* const aCtx,
-                           const LayoutDeviceRect& aDirtyRect,
-                           nscolor aColor,
-                           const nscolor* aOverrideColor,
-                           const Point& aPt,
-                           gfxFloat aICoordInFrame,
-                           const Size& aLineSize,
-                           gfxFloat aAscent,
-                           gfxFloat aOffset,
-                           uint8_t aDecoration,
-                           uint8_t aStyle,
-                           DecorationType aDecorationType,
-                           DrawPathCallbacks* aCallbacks,
-                           bool aVertical,
-                           gfxFloat aDescentLimit = -1.0);
+
+  struct PaintDecorationLineParams;
+  void PaintDecorationLine(const PaintDecorationLineParams& aParams);
   /**
    * ComputeDescentLimitForSelectionUnderline() computes the most far position
    * where we can put selection underline.
    *
    * @return The maximum underline offset from the baseline (positive value
    *         means that the underline can put below the baseline).
    */
   gfxFloat ComputeDescentLimitForSelectionUnderline(