Bug 1324700 - Add a function which is equivalent to GetFontStyleContext() for servo. r?heycam draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Sat, 15 Apr 2017 07:37:35 +0900
changeset 563189 fa32ddcb26af8aa79b8550479e4c2992831f53e3
parent 563188 6d0100ac6b70a469674f175bdedc593d5542049a
child 563190 97b9c7c16b78703602c97f55b030739e6fbfef67
push id54220
push userhikezoe@mozilla.com
push dateSat, 15 Apr 2017 04:25:00 +0000
reviewersheycam
bugs1324700
milestone55.0a1
Bug 1324700 - Add a function which is equivalent to GetFontStyleContext() for servo. r?heycam MozReview-Commit-ID: K4KvPk4fJTb
dom/canvas/CanvasRenderingContext2D.cpp
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -21,16 +21,17 @@
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFrame.h"
 #include "nsError.h"
 
 #include "nsCSSParser.h"
+#include "nsCSSPseudoElements.h"
 #include "mozilla/css/StyleRule.h"
 #include "mozilla/css/Declaration.h"
 #include "nsComputedDOMStyle.h"
 #include "nsStyleSet.h"
 
 #include "nsPrintfCString.h"
 
 #include "nsReadableUtils.h"
@@ -2835,16 +2836,87 @@ CreateDeclarationForServo(nsCSSPropertyI
                                            false,
                                            data,
                                            LengthParsingMode::Default);
   }
 
   return servoDeclarations.forget();
 }
 
+static already_AddRefed<RawServoDeclarationBlock>
+CreateFontDeclarationForServo(const nsAString& aFont,
+                              nsIDocument* aDocument)
+{
+  return CreateDeclarationForServo(eCSSProperty_font, aFont, aDocument);
+}
+
+static already_AddRefed<ServoComputedValues>
+GetFontStyleForServo(Element* aElement, const nsAString& aFont,
+                     nsIPresShell* aPresShell,
+                     nsAString& aOutUsedFont,
+                     ErrorResult& aError)
+{
+  MOZ_ASSERT(aPresShell->StyleSet()->IsServo());
+
+  RefPtr<RawServoDeclarationBlock> declarations =
+    CreateFontDeclarationForServo(aFont, aPresShell->GetDocument());
+  if (!declarations) {
+    // We got a syntax error.  The spec says this value must be ignored.
+    return nullptr;
+  }
+
+  // In addition to unparseable values, the spec says we need to reject
+  // 'inherit' and 'initial'. The easiest way to check for this is to look
+  // at font-size-adjust, which the font shorthand resets to 'none'.
+  if (Servo_DeclarationBlock_HasCSSWideKeyword(declarations,
+                                               eCSSProperty_font_size_adjust)) {
+    return nullptr;
+  }
+
+  ServoStyleSet* styleSet = aPresShell->StyleSet()->AsServo();
+
+  RefPtr<ServoComputedValues> parentStyle;
+  // have to get a parent style context for inherit-like relative
+  // values (2em, bolder, etc.)
+  if (aElement && aElement->IsInUncomposedDoc()) {
+    // Inherit from the canvas element.
+    aPresShell->FlushPendingNotifications(FlushType::Style);
+    // We need to use ResolveTransientServoStyle, which involves traversal,
+    // instead of ResolveServoStyle() because we need up-to-date style even if
+    // the canvas element is display:none.
+    parentStyle = styleSet->ResolveTransientServoStyle(aElement, nullptr);
+  } else {
+    RefPtr<RawServoDeclarationBlock> declarations =
+      CreateFontDeclarationForServo(NS_LITERAL_STRING("10px sans-serif"),
+                                    aPresShell->GetDocument());
+    MOZ_ASSERT(declarations);
+
+    parentStyle = aPresShell->StyleSet()->AsServo()->
+      ResolveForDeclarations(nullptr, declarations);
+  }
+
+  MOZ_RELEASE_ASSERT(parentStyle, "Should have a valid parent style");
+
+  MOZ_ASSERT(!aPresShell->IsDestroying(),
+             "GetFontParentStyleContext should have returned an error if the presshell is being destroyed.");
+
+  RefPtr<ServoComputedValues> sc =
+    styleSet->ResolveForDeclarations(parentStyle, declarations);
+
+  // The font getter is required to be reserialized based on what we
+  // parsed (including having line-height removed).  (Older drafts of
+  // the spec required font sizes be converted to pixels, but that no
+  // longer seems to be required.)
+  Servo_DeclarationBlock_SerializeOneValue(declarations,
+                                           eCSSProperty_font,
+                                           &aOutUsedFont);
+
+  return sc.forget();
+}
+
 static already_AddRefed<Declaration>
 CreateFilterDeclaration(const nsAString& aFilter,
                         nsINode* aNode,
                         bool* aOutFilterChanged)
 {
   bool dummy;
   return CreateDeclaration(aNode,
     eCSSProperty_filter, aFilter, aOutFilterChanged,