Bug 1352406 - Back out changeset eecb0af8a88f (bug 418833). a=lizzard
authorMike Conley <mconley@mozilla.com>
Fri, 31 Mar 2017 09:47:57 -0400
changeset 379430 9e2440ee6715204e88c7ae709a96ef7e1f707bdc
parent 379429 52a40cd84b9a2a7d75d8ecdb97802851c5f94594
child 379431 c8a0dd29b2bb48f68c04090639f99888c187c027
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslizzard
bugs1352406, 418833
milestone53.0
Bug 1352406 - Back out changeset eecb0af8a88f (bug 418833). a=lizzard MozReview-Commit-ID: BEyRfEmwjZY
layout/forms/nsGfxCheckboxControlFrame.cpp
layout/forms/nsGfxCheckboxControlFrame.h
layout/forms/nsGfxRadioControlFrame.cpp
layout/forms/nsGfxRadioControlFrame.h
layout/style/jar.mn
layout/style/res/checkmark.svg
layout/style/res/forms.css
layout/style/res/indeterminate-checkmark.svg
layout/style/res/radio.svg
--- a/layout/forms/nsGfxCheckboxControlFrame.cpp
+++ b/layout/forms/nsGfxCheckboxControlFrame.cpp
@@ -13,16 +13,72 @@
 #include "nsRenderingContext.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsDisplayList.h"
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
+static void
+PaintCheckMark(nsIFrame* aFrame,
+               DrawTarget* aDrawTarget,
+               const nsRect& aDirtyRect,
+               nsPoint aPt)
+{
+  nsRect rect(aPt, aFrame->GetSize());
+  rect.Deflate(aFrame->GetUsedBorderAndPadding());
+
+  // Points come from the coordinates on a 7X7 unit box centered at 0,0
+  const int32_t checkPolygonX[] = { -3, -1,  3,  3, -1, -3 };
+  const int32_t checkPolygonY[] = { -1,  1, -3, -1,  3,  1 };
+  const int32_t checkNumPoints = sizeof(checkPolygonX) / sizeof(int32_t);
+  const int32_t checkSize      = 9; // 2 units of padding on either side
+                                    // of the 7x7 unit checkmark
+
+  // Scale the checkmark based on the smallest dimension
+  nscoord paintScale = std::min(rect.width, rect.height) / checkSize;
+  nsPoint paintCenter(rect.x + rect.width  / 2,
+                      rect.y + rect.height / 2);
+
+  RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
+  nsPoint p = paintCenter + nsPoint(checkPolygonX[0] * paintScale,
+                                    checkPolygonY[0] * paintScale);
+
+  int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
+  builder->MoveTo(NSPointToPoint(p, appUnitsPerDevPixel));
+  for (int32_t polyIndex = 1; polyIndex < checkNumPoints; polyIndex++) {
+    p = paintCenter + nsPoint(checkPolygonX[polyIndex] * paintScale,
+                              checkPolygonY[polyIndex] * paintScale);
+    builder->LineTo(NSPointToPoint(p, appUnitsPerDevPixel));
+  }
+  RefPtr<Path> path = builder->Finish();
+  aDrawTarget->Fill(path,
+                    ColorPattern(ToDeviceColor(aFrame->StyleColor()->mColor)));
+}
+
+static void
+PaintIndeterminateMark(nsIFrame* aFrame,
+                       DrawTarget* aDrawTarget,
+                       const nsRect& aDirtyRect,
+                       nsPoint aPt)
+{
+  int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
+
+  nsRect rect(aPt, aFrame->GetSize());
+  rect.Deflate(aFrame->GetUsedBorderAndPadding());
+  rect.y += (rect.height - rect.height/4) / 2;
+  rect.height /= 4;
+
+  Rect devPxRect = NSRectToSnappedRect(rect, appUnitsPerDevPixel, *aDrawTarget);
+
+  aDrawTarget->FillRect(
+    devPxRect, ColorPattern(ToDeviceColor(aFrame->StyleColor()->mColor)));
+}
+
 //------------------------------------------------------------
 nsIFrame*
 NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell,
                               nsStyleContext* aContext)
 {
   return new (aPresShell) nsGfxCheckboxControlFrame(aContext);
 }
 
@@ -44,16 +100,39 @@ nsGfxCheckboxControlFrame::~nsGfxCheckbo
 a11y::AccType
 nsGfxCheckboxControlFrame::AccessibleType()
 {
   return a11y::eHTMLCheckboxType;
 }
 #endif
 
 //------------------------------------------------------------
+void
+nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
+                                            const nsRect&           aDirtyRect,
+                                            const nsDisplayListSet& aLists)
+{
+  nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
+  
+  // Get current checked state through content model.
+  if ((!IsChecked() && !IsIndeterminate()) || !IsVisibleForPainting(aBuilder))
+    return;   // we're not checked or not visible, nothing to paint.
+    
+  if (IsThemed())
+    return; // No need to paint the checkmark. The theme will do it.
+
+  aLists.Content()->AppendNewToTop(new (aBuilder)
+    nsDisplayGeneric(aBuilder, this,
+                     IsIndeterminate()
+                     ? PaintIndeterminateMark : PaintCheckMark,
+                     "CheckedCheckbox",
+                     nsDisplayItem::TYPE_CHECKED_CHECKBOX));
+}
+
+//------------------------------------------------------------
 bool
 nsGfxCheckboxControlFrame::IsChecked()
 {
   nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
   bool retval = false;
   elem->GetChecked(&retval);
   return retval;
 }
--- a/layout/forms/nsGfxCheckboxControlFrame.h
+++ b/layout/forms/nsGfxCheckboxControlFrame.h
@@ -17,16 +17,20 @@ public:
   virtual ~nsGfxCheckboxControlFrame();
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override {
     return MakeFrameName(NS_LITERAL_STRING("CheckboxControl"), aResult);
   }
 #endif
 
+  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
+                                const nsRect&           aDirtyRect,
+                                const nsDisplayListSet& aLists) override;
+
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() override;
 #endif
 
 protected:
 
   bool IsChecked();
   bool IsIndeterminate();
--- a/layout/forms/nsGfxRadioControlFrame.cpp
+++ b/layout/forms/nsGfxRadioControlFrame.cpp
@@ -35,8 +35,59 @@ nsGfxRadioControlFrame::~nsGfxRadioContr
 
 #ifdef ACCESSIBILITY
 a11y::AccType
 nsGfxRadioControlFrame::AccessibleType()
 {
   return a11y::eHTMLRadioButtonType;
 }
 #endif
+
+//--------------------------------------------------------------
+// Draw the dot for a non-native radio button in the checked state.
+static void
+PaintCheckedRadioButton(nsIFrame* aFrame,
+                        DrawTarget* aDrawTarget,
+                        const nsRect& aDirtyRect,
+                        nsPoint aPt)
+{
+  // The dot is an ellipse 2px on all sides smaller than the content-box,
+  // drawn in the foreground color.
+  nsRect rect(aPt, aFrame->GetSize());
+  rect.Deflate(aFrame->GetUsedBorderAndPadding());
+  rect.Deflate(nsPresContext::CSSPixelsToAppUnits(2),
+               nsPresContext::CSSPixelsToAppUnits(2));
+
+  Rect devPxRect =
+    ToRect(nsLayoutUtils::RectToGfxRect(rect,
+                                        aFrame->PresContext()->AppUnitsPerDevPixel()));
+
+  ColorPattern color(ToDeviceColor(aFrame->StyleColor()->mColor));
+
+  RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
+  AppendEllipseToPath(builder, devPxRect.Center(), devPxRect.Size());
+  RefPtr<Path> ellipse = builder->Finish();
+  aDrawTarget->Fill(ellipse, color);
+}
+
+void
+nsGfxRadioControlFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
+                                         const nsRect&           aDirtyRect,
+                                         const nsDisplayListSet& aLists)
+{
+  nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
+
+  if (!IsVisibleForPainting(aBuilder))
+    return;
+  
+  if (IsThemed())
+    return; // The theme will paint the check, if any.
+
+  bool checked = true;
+  GetCurrentCheckState(&checked); // Get check state from the content model
+  if (!checked)
+    return;
+    
+  aLists.Content()->AppendNewToTop(new (aBuilder)
+    nsDisplayGeneric(aBuilder, this, PaintCheckedRadioButton,
+                     "CheckedRadioButton",
+                     nsDisplayItem::TYPE_CHECKED_RADIOBUTTON));
+}
--- a/layout/forms/nsGfxRadioControlFrame.h
+++ b/layout/forms/nsGfxRadioControlFrame.h
@@ -18,11 +18,15 @@ public:
   explicit nsGfxRadioControlFrame(nsStyleContext* aContext);
   ~nsGfxRadioControlFrame();
 
   NS_DECL_FRAMEARENA_HELPERS
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() override;
 #endif
+
+  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
+                                const nsRect&           aDirtyRect,
+                                const nsDisplayListSet& aLists) override;
 };
 
 #endif
--- a/layout/style/jar.mn
+++ b/layout/style/jar.mn
@@ -26,13 +26,10 @@ toolkit.jar:
    res/accessiblecaret-tilt-left@1x.png      (res/accessiblecaret-tilt-left@1x.png)
    res/accessiblecaret-tilt-left@1.5x.png    (res/accessiblecaret-tilt-left@1.5x.png)
    res/accessiblecaret-tilt-left@2x.png      (res/accessiblecaret-tilt-left@2x.png)
    res/accessiblecaret-tilt-left@2.25x.png   (res/accessiblecaret-tilt-left@2.25x.png)
    res/accessiblecaret-tilt-right@1x.png     (res/accessiblecaret-tilt-right@1x.png)
    res/accessiblecaret-tilt-right@1.5x.png   (res/accessiblecaret-tilt-right@1.5x.png)
    res/accessiblecaret-tilt-right@2x.png     (res/accessiblecaret-tilt-right@2x.png)
    res/accessiblecaret-tilt-right@2.25x.png  (res/accessiblecaret-tilt-right@2.25x.png)
-   res/checkmark.svg                         (res/checkmark.svg)
-   res/indeterminate-checkmark.svg           (res/indeterminate-checkmark.svg)
-   res/radio.svg                             (res/radio.svg)
 
 % resource gre-resources %res/
deleted file mode 100644
--- a/layout/style/res/checkmark.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 10 10" width="10" height="10">
-    <style type="text/css">
-        path { fill: -moz-FieldText; }
-        #disabled:target { fill: GrayText; }
-    </style>
-    <path id="disabled" d="M 2 4 L 4 6 L 8 2 L 8 4 L 4 8 L 2 6 Z"/>
-</svg>
--- a/layout/style/res/forms.css
+++ b/layout/style/res/forms.css
@@ -574,80 +574,52 @@ input[type="checkbox"] {
 input[type="radio"],
 input[type="checkbox"] {
   box-sizing: border-box;
   inline-size: 13px;
   block-size: 13px;
   cursor: default;
   padding: 0 !important;
   -moz-binding: none;
-  border: 2px inset ThreeDLightShadow;
-  background-repeat: no-repeat;
-  background-position: center;
+  /* same colors as |input| rule, but |!important| this time. */
+  background-color: -moz-Field ! important;
+  color: -moz-FieldText ! important;
+  border: 2px inset ThreeDLightShadow ! important;
 }
 
 input[type="radio"]:disabled,
 input[type="radio"]:disabled:active,
 input[type="radio"]:disabled:hover,
 input[type="radio"]:disabled:hover:active,
 input[type="checkbox"]:disabled,
 input[type="checkbox"]:disabled:active,
 input[type="checkbox"]:disabled:hover,
 input[type="checkbox"]:disabled:hover:active {
   padding: 1px;
-  border: 1px inset ThreeDShadow;
+  border: 1px inset ThreeDShadow ! important;
+  /* same as above, but !important */
+  color: GrayText ! important;
+  background-color: ThreeDFace ! important;
   cursor: inherit;
 }
 
 % On Mac, the native theme takes care of this.
 % See nsNativeThemeCocoa::ThemeDrawsFocusForWidget.
 %ifndef XP_MACOSX
 input[type="checkbox"]:-moz-focusring,
 input[type="radio"]:-moz-focusring {
   /* Don't specify the outline-color, we should always use initial value. */
   outline: 1px dotted;
 }
 %endif
 
 input[type="checkbox"]:hover:active,
 input[type="radio"]:hover:active {
-  background-color: ThreeDFace;
-  border-style: inset;
-}
-
-input[type="radio"] {
-  background-size: calc(100% - 4px) calc(100% - 4px);
-}
-
-input[type="radio"]:checked {
-  background-image: url(radio.svg);
-}
-
-input[type="radio"]:disabled:checked {
-  background-image: url(radio.svg#disabled);
-}
-
-input[type="checkbox"] {
-  background-size: 100% 100%;
-}
-
-input[type="checkbox"]:checked {
-  background-image: url(checkmark.svg);
-}
-
-input[type="checkbox"]:disabled:checked {
-  background-image: url(checkmark.svg#disabled);
-}
-
-input[type="checkbox"]:indeterminate {
-  background-image: url(indeterminate-checkmark.svg);
-}
-
-input[type="checkbox"]:indeterminate:disabled {
-  background-image: url(indeterminate-checkmark.svg#disabled);
+  background-color: ThreeDFace ! important;
+  border-style: inset !important;
 }
 
 input[type="search"] {
   box-sizing: border-box;
 }
 
 /* buttons */
 
deleted file mode 100644
--- a/layout/style/res/indeterminate-checkmark.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 5 5" width="5" height="5">
-    <style type="text/css">
-        rect { fill: -moz-FieldText; }
-        #disabled:target { fill: GrayText; }
-    </style>
-    <rect id="disabled" x="0" y="2" width="5" height="1"/>
-</svg>
deleted file mode 100644
--- a/layout/style/res/radio.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 20 20" width="20" height="20">
-    <style type="text/css">
-        circle { fill: -moz-FieldText; }
-        #disabled:target { fill: GrayText; }
-    </style>
-    <circle id="disabled" cx="10" cy="10" r="10"/>
-</svg>