Bug 1408312 - Part 3: Replace nsCSSParser/nsRuleNode usage for color computation in Servo styled documents. r=xidorn draft
authorCameron McCormack <cam@mcc.id.au>
Mon, 16 Oct 2017 09:06:39 +0800
changeset 681164 0fd4e9a3b62c668ab0a6925e70006646a3273e62
parent 681163 decfb82dfa419b5a57edb9e2f1d4cd04ed7d5599
child 736107 5fdb5487894ab4ba1e07f521fe60392702e1e492
push id84782
push userbmo:cam@mcc.id.au
push dateTue, 17 Oct 2017 03:35:29 +0000
reviewersxidorn
bugs1408312
milestone58.0a1
Bug 1408312 - Part 3: Replace nsCSSParser/nsRuleNode usage for color computation in Servo styled documents. r=xidorn MozReview-Commit-ID: LuB0izWz7nk
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/DocumentRendererChild.cpp
layout/base/nsPresContext.cpp
layout/inspector/inDOMUtils.cpp
testing/web-platform/meta/2dcontext/fill-and-stroke-styles/2d.gradient.object.current.html.ini
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -122,16 +122,17 @@
 #include "nsDeviceContext.h"
 #include "nsFontMetrics.h"
 #include "Units.h"
 #include "CanvasUtils.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/StyleSetHandle.h"
 #include "mozilla/StyleSetHandleInlines.h"
 #include "mozilla/layers/CanvasClient.h"
+#include "mozilla/ServoCSSParser.h"
 
 #undef free // apparently defined by some windows header, clashing with a free()
             // method in SkTypes.h
 #include "SkiaGLGlue.h"
 #ifdef USE_SKIA
 #include "SurfaceTypes.h"
 #include "GLBlitHelper.h"
 #include "ScopedGLHelpers.h"
@@ -740,27 +741,38 @@ CanvasPattern::SetTransform(SVGMatrix& a
 void
 CanvasGradient::AddColorStop(float aOffset, const nsAString& aColorstr, ErrorResult& aRv)
 {
   if (aOffset < 0.0 || aOffset > 1.0) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return;
   }
 
-  nsCSSValue value;
-  nsCSSParser parser;
-  if (!parser.ParseColorString(aColorstr, nullptr, 0, value)) {
-    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return;
-  }
-
   nscolor color;
-  nsCOMPtr<nsIPresShell> presShell = mContext ? mContext->GetPresShell() : nullptr;
-  if (!nsRuleNode::ComputeColor(value, presShell ? presShell->GetPresContext() : nullptr,
-                                nullptr, color)) {
+  bool ok;
+
+  nsIPresShell* shell = mContext ? mContext->GetPresShell() : nullptr;
+  ServoStyleSet* servoStyleSet = shell && shell->StyleSet()
+    ? shell->StyleSet()->GetAsServo()
+    : nullptr;
+
+  if (servoStyleSet) {
+    ok = ServoCSSParser::ComputeColor(servoStyleSet, NS_RGB(0, 0, 0), aColorstr,
+                                      &color);
+  } else {
+    nsCSSValue value;
+    nsCSSParser parser;
+
+    nsPresContext* presContext = shell ? shell->GetPresContext() : nullptr;
+
+    ok = parser.ParseColorString(aColorstr, nullptr, 0, value) &&
+         nsRuleNode::ComputeColor(value, presContext, nullptr, color);
+  }
+
+  if (!ok) {
     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
     return;
   }
 
   mStops = nullptr;
 
   GradientStop newStop;
 
--- a/dom/canvas/DocumentRendererChild.cpp
+++ b/dom/canvas/DocumentRendererChild.cpp
@@ -20,16 +20,17 @@
 #include "nsPresContext.h"
 #include "nsCOMPtr.h"
 #include "nsColor.h"
 #include "nsLayoutUtils.h"
 #include "nsContentUtils.h"
 #include "nsCSSValue.h"
 #include "nsRuleNode.h"
 #include "mozilla/gfx/Matrix.h"
+#include "mozilla/ServoCSSParser.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::ipc;
 
 DocumentRendererChild::DocumentRendererChild()
 {}
 
@@ -54,25 +55,34 @@ DocumentRendererChild::RenderDocument(ns
         nsIDocShell* docshell = window->GetDocShell();
         if (docshell) {
             docshell->GetPresContext(getter_AddRefs(presContext));
         }
     }
     if (!presContext)
         return false;
 
-    nsCSSParser parser;
-    nsCSSValue bgColorValue;
-    if (!parser.ParseColorString(aBGColor, nullptr, 0, bgColorValue)) {
+    nscolor bgColor;
+
+    ServoStyleSet* servoStyleSet = presContext->StyleSet()
+      ? presContext->StyleSet()->GetAsServo()
+      : nullptr;
+
+    if (servoStyleSet) {
+      if (!ServoCSSParser::ComputeColor(servoStyleSet, NS_RGB(0, 0, 0),
+                                        aBGColor, &bgColor)) {
         return false;
-    }
-
-    nscolor bgColor;
-    if (!nsRuleNode::ComputeColor(bgColorValue, presContext, nullptr, bgColor)) {
+      }
+    } else {
+      nsCSSParser parser;
+      nsCSSValue bgColorValue;
+      if (!parser.ParseColorString(aBGColor, nullptr, 0, bgColorValue) ||
+          !nsRuleNode::ComputeColor(bgColorValue, presContext, nullptr, bgColor)) {
         return false;
+      }
     }
 
     // Draw directly into the output array.
     data.SetLength(renderSize.width * renderSize.height * 4);
 
     RefPtr<DrawTarget> dt =
         Factory::CreateDrawTargetForData(gfxPlatform::GetPlatform()->GetSoftwareBackend(),
                                          reinterpret_cast<uint8_t*>(data.BeginWriting()),
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -90,16 +90,17 @@
 #include "nsIImageLoadingContent.h"
 
 #include "nsCSSParser.h"
 #include "nsBidiUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsBidi.h"
 
 #include "mozilla/dom/URL.h"
+#include "mozilla/ServoCSSParser.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 uint8_t gNotifySubDocInvalidationData;
 
@@ -141,27 +142,39 @@ private:
   NotNull<const Encoding*> mCharSet;
 };
 
 } // namespace
 
 nscolor
 nsPresContext::MakeColorPref(const nsString& aColor)
 {
-  nsCSSParser parser;
-  nsCSSValue value;
-  if (!parser.ParseColorString(aColor, nullptr, 0, value)) {
-    // Any better choices?
-    return NS_RGB(0, 0, 0);
+  bool ok;
+  nscolor result;
+
+  ServoStyleSet* servoStyleSet = mShell && mShell->StyleSet()
+    ? mShell->StyleSet()->GetAsServo()
+    : nullptr;
+
+  if (servoStyleSet) {
+    ok = ServoCSSParser::ComputeColor(servoStyleSet, NS_RGB(0, 0, 0), aColor,
+                                      &result);
+  } else {
+    nsCSSParser parser;
+    nsCSSValue value;
+    ok = parser.ParseColorString(aColor, nullptr, 0, value) &&
+         nsRuleNode::ComputeColor(value, this, nullptr, result);
   }
 
-  nscolor color;
-  return nsRuleNode::ComputeColor(value, this, nullptr, color)
-    ? color
-    : NS_RGB(0, 0, 0);
+  if (!ok) {
+    // Any better choices?
+    result = NS_RGB(0, 0, 0);
+  }
+
+  return result;
 }
 
 bool
 nsPresContext::IsDOMPaintEventPending()
 {
   if (mFireAfterPaintEvents) {
     return true;
   }
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -1002,29 +1002,35 @@ inDOMUtils::RgbToColorName(uint8_t aR, u
   aColorName.AssignASCII(color);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 inDOMUtils::ColorToRGBA(const nsAString& aColorString, JSContext* aCx,
                         JS::MutableHandle<JS::Value> aValue)
 {
-  nscolor color = 0;
+  nscolor color = NS_RGB(0, 0, 0);
+
+#ifdef MOZ_STYLO
+  if (!ServoCSSParser::ComputeColor(nullptr, NS_RGB(0, 0, 0), aColorString,
+                                    &color)) {
+    aValue.setNull();
+    return NS_OK;
+  }
+#else
   nsCSSParser cssParser;
   nsCSSValue cssValue;
 
-  bool isColor = cssParser.ParseColorString(aColorString, nullptr, 0,
-                                            cssValue, true);
-
-  if (!isColor) {
+  if (!cssParser.ParseColorString(aColorString, nullptr, 0, cssValue, true)) {
     aValue.setNull();
     return NS_OK;
   }
 
   nsRuleNode::ComputeColor(cssValue, nullptr, nullptr, color);
+#endif
 
   InspectorRGBATuple tuple;
   tuple.mR = NS_GET_R(color);
   tuple.mG = NS_GET_G(color);
   tuple.mB = NS_GET_B(color);
   tuple.mA = nsStyleUtil::ColorComponentToFloat(NS_GET_A(color));
 
   if (!ToJSValue(aCx, tuple, aValue)) {
--- a/testing/web-platform/meta/2dcontext/fill-and-stroke-styles/2d.gradient.object.current.html.ini
+++ b/testing/web-platform/meta/2dcontext/fill-and-stroke-styles/2d.gradient.object.current.html.ini
@@ -1,5 +1,6 @@
 [2d.gradient.object.current.html]
   type: testharness
   [Canvas test: 2d.gradient.object.current]
-    expected: FAIL
+    expected:
+      if not stylo: FAIL