Bug 1261552 - Introduce StyleStructContext, and make all style struct constructors take it. r=heycam
authorBobby Holley <bobbyholley@gmail.com>
Wed, 30 Mar 2016 16:30:39 -0700
changeset 347752 767a3ddd89e46554e84b51ee9f80ff1cbd2b91ad
parent 347751 74a65e4f87f0dc77bd550c117442173420fbe2a0
child 347753 c185e1c3be0547634af286920d5a34d6cf3f1bf7
push id14653
push userolivier@olivieryiptong.com
push dateTue, 05 Apr 2016 19:21:01 +0000
reviewersheycam
bugs1261552
milestone48.0a1
Bug 1261552 - Introduce StyleStructContext, and make all style struct constructors take it. r=heycam
layout/style/StyleStructContext.h
layout/style/moz.build
layout/style/nsRuleNode.cpp
layout/style/nsStyleContext.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
new file mode 100644
--- /dev/null
+++ b/layout/style/StyleStructContext.h
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_StyleStructContext_h
+#define mozilla_StyleStructContext_h
+
+#include "CounterStyleManager.h"
+#include "mozilla/LookAndFeel.h"
+#include "nsPresContext.h"
+
+class nsDeviceContext;
+
+/**
+ * Construction context for style structs.
+ *
+ * Certain Gecko style structs have historically taken an nsPresContext
+ * argument in their constructor, which is used to compute various things. This
+ * makes Gecko style structs document-specific (which Servo style structs are
+ * not), and means that the initial values for style-structs cannot be shared
+ * across the entire runtime (as is the case in Servo).
+ *
+ * We'd like to remove this constraint so that Gecko can get the benefits of the
+ * Servo model, and so that Gecko aligns better with the Servo style system when
+ * using it. Unfortunately, this may require a fair amount of work, especially
+ * related to text zoom.
+ *
+ * So as an intermediate step, we define a reduced API set of "things that are
+ * needed when constructing style structs". This just wraps and forwards to an
+ * nsPresContext in the Gecko case, and returns some default not-always-correct
+ * values in the Servo case. We can then focus on reducing this API surface to
+ * zero, at which point this can be removed.
+ *
+ * We don't put the type in namespace mozilla, since we expect it to be
+ * temporary, and the namespacing would clutter up nsStyleStruct.h.
+ */
+#ifdef MOZ_STYLO
+#define SERVO_DEFAULT(default_val) { if (!mPresContext) { return default_val; } }
+#else
+#define SERVO_DEFAULT(default_val) { MOZ_ASSERT(mPresContext); }
+#endif
+class StyleStructContext {
+public:
+  MOZ_IMPLICIT StyleStructContext(nsPresContext* aPresContext)
+    : mPresContext(aPresContext) { MOZ_ASSERT(aPresContext); }
+  static StyleStructContext ServoContext() { return StyleStructContext(); }
+
+  // XXXbholley: Need to make text zoom work with stylo. This probably means
+  // moving the zoom handling out of computed values and into a post-
+  // computation.
+  float TextZoom()
+  {
+    SERVO_DEFAULT(1.0);
+    return mPresContext->TextZoom();
+  }
+
+  const nsFont* GetDefaultFont(uint8_t aFontID)
+  {
+    // NB: The servo case only differ from the default case in terms of which
+    // font pref cache gets used. The distinction is probably unnecessary.
+    SERVO_DEFAULT(mozilla::StaticPresData::Get()->
+                  GetDefaultFont(aFontID, GetLanguageFromCharset()));
+    return mPresContext->GetDefaultFont(aFontID, GetLanguageFromCharset());
+  }
+
+  uint32_t GetBidi()
+  {
+    SERVO_DEFAULT(0);
+    return mPresContext->GetBidi();
+  }
+
+  int32_t AppUnitsPerDevPixel();
+
+  nscoord DevPixelsToAppUnits(int32_t aPixels)
+  {
+    return NSIntPixelsToAppUnits(aPixels, AppUnitsPerDevPixel());
+  }
+
+  typedef mozilla::LookAndFeel LookAndFeel;
+  nscolor DefaultColor()
+  {
+    SERVO_DEFAULT(LookAndFeel::GetColor(LookAndFeel::eColorID_WindowForeground,
+                                        NS_RGB(0x00, 0x00, 0x00)));
+    return mPresContext->DefaultColor();
+  }
+
+  mozilla::CounterStyle* BuildCounterStyle(const nsSubstring& aName)
+  {
+    SERVO_DEFAULT(nullptr);
+    return mPresContext->CounterStyleManager()->BuildCounterStyle(aName);
+  }
+
+  nsIAtom* GetLanguageFromCharset() const
+  {
+    SERVO_DEFAULT(nsGkAtoms::x_western);
+    return mPresContext->GetLanguageFromCharset();
+  }
+
+  already_AddRefed<nsIAtom> GetContentLanguage() const
+  {
+    SERVO_DEFAULT(do_AddRef(nsGkAtoms::x_western));
+    return mPresContext->GetContentLanguage();
+  }
+
+private:
+  nsDeviceContext* DeviceContext()
+  {
+    SERVO_DEFAULT(HackilyFindSomeDeviceContext());
+    return mPresContext->DeviceContext();
+  }
+
+  nsDeviceContext* HackilyFindSomeDeviceContext();
+
+  StyleStructContext() : mPresContext(nullptr) {}
+  nsPresContext* mPresContext;
+};
+
+#undef SERVO_DEFAULT
+
+#endif // mozilla_StyleStructContext_h
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -100,16 +100,17 @@ EXPORTS.mozilla += [
     'StyleContextSource.h',
     'StyleSetHandle.h',
     'StyleSetHandleInlines.h',
     'StyleSheet.h',
     'StyleSheetHandle.h',
     'StyleSheetHandleInlines.h',
     'StyleSheetInfo.h',
     'StyleSheetInlines.h',
+    'StyleStructContext.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'CSS.h',
     'CSSLexer.h',
     'CSSRuleList.h',
     'CSSValue.h',
     'FontFace.h',
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -2446,17 +2446,17 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
       else {
         fontData->mFont.size = fontData->mSize;
       }
       aContext->SetStyle(eStyleStruct_Font, fontData);
       return fontData;
     }
     case eStyleStruct_Display:
     {
-      nsStyleDisplay* disp = new (mPresContext) nsStyleDisplay();
+      nsStyleDisplay* disp = new (mPresContext) nsStyleDisplay(mPresContext);
       aContext->SetStyle(eStyleStruct_Display, disp);
       return disp;
     }
     case eStyleStruct_Visibility:
     {
       nsStyleVisibility* vis = new (mPresContext) nsStyleVisibility(mPresContext);
       aContext->SetStyle(eStyleStruct_Visibility, vis);
       return vis;
@@ -2464,47 +2464,47 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
     case eStyleStruct_Text:
     {
       nsStyleText* text = new (mPresContext) nsStyleText(mPresContext);
       aContext->SetStyle(eStyleStruct_Text, text);
       return text;
     }
     case eStyleStruct_TextReset:
     {
-      nsStyleTextReset* text = new (mPresContext) nsStyleTextReset();
+      nsStyleTextReset* text = new (mPresContext) nsStyleTextReset(mPresContext);
       aContext->SetStyle(eStyleStruct_TextReset, text);
       return text;
     }
     case eStyleStruct_Color:
     {
       nsStyleColor* color = new (mPresContext) nsStyleColor(mPresContext);
       aContext->SetStyle(eStyleStruct_Color, color);
       return color;
     }
     case eStyleStruct_Background:
     {
-      nsStyleBackground* bg = new (mPresContext) nsStyleBackground();
+      nsStyleBackground* bg = new (mPresContext) nsStyleBackground(mPresContext);
       aContext->SetStyle(eStyleStruct_Background, bg);
       return bg;
     }
     case eStyleStruct_Margin:
     {
-      nsStyleMargin* margin = new (mPresContext) nsStyleMargin();
+      nsStyleMargin* margin = new (mPresContext) nsStyleMargin(mPresContext);
       aContext->SetStyle(eStyleStruct_Margin, margin);
       return margin;
     }
     case eStyleStruct_Border:
     {
       nsStyleBorder* border = new (mPresContext) nsStyleBorder(mPresContext);
       aContext->SetStyle(eStyleStruct_Border, border);
       return border;
     }
     case eStyleStruct_Padding:
     {
-      nsStylePadding* padding = new (mPresContext) nsStylePadding();
+      nsStylePadding* padding = new (mPresContext) nsStylePadding(mPresContext);
       aContext->SetStyle(eStyleStruct_Padding, padding);
       return padding;
     }
     case eStyleStruct_Outline:
     {
       nsStyleOutline* outline = new (mPresContext) nsStyleOutline(mPresContext);
       aContext->SetStyle(eStyleStruct_Outline, outline);
       return outline;
@@ -2512,83 +2512,83 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
     case eStyleStruct_List:
     {
       nsStyleList* list = new (mPresContext) nsStyleList(mPresContext);
       aContext->SetStyle(eStyleStruct_List, list);
       return list;
     }
     case eStyleStruct_Position:
     {
-      nsStylePosition* pos = new (mPresContext) nsStylePosition();
+      nsStylePosition* pos = new (mPresContext) nsStylePosition(mPresContext);
       aContext->SetStyle(eStyleStruct_Position, pos);
       return pos;
     }
     case eStyleStruct_Table:
     {
-      nsStyleTable* table = new (mPresContext) nsStyleTable();
+      nsStyleTable* table = new (mPresContext) nsStyleTable(mPresContext);
       aContext->SetStyle(eStyleStruct_Table, table);
       return table;
     }
     case eStyleStruct_TableBorder:
     {
-      nsStyleTableBorder* table = new (mPresContext) nsStyleTableBorder();
+      nsStyleTableBorder* table = new (mPresContext) nsStyleTableBorder(mPresContext);
       aContext->SetStyle(eStyleStruct_TableBorder, table);
       return table;
     }
     case eStyleStruct_Content:
     {
-      nsStyleContent* content = new (mPresContext) nsStyleContent();
+      nsStyleContent* content = new (mPresContext) nsStyleContent(mPresContext);
       aContext->SetStyle(eStyleStruct_Content, content);
       return content;
     }
     case eStyleStruct_Quotes:
     {
-      nsStyleQuotes* quotes = new (mPresContext) nsStyleQuotes();
+      nsStyleQuotes* quotes = new (mPresContext) nsStyleQuotes(mPresContext);
       aContext->SetStyle(eStyleStruct_Quotes, quotes);
       return quotes;
     }
     case eStyleStruct_UserInterface:
     {
-      nsStyleUserInterface* ui = new (mPresContext) nsStyleUserInterface();
+      nsStyleUserInterface* ui = new (mPresContext) nsStyleUserInterface(mPresContext);
       aContext->SetStyle(eStyleStruct_UserInterface, ui);
       return ui;
     }
     case eStyleStruct_UIReset:
     {
-      nsStyleUIReset* ui = new (mPresContext) nsStyleUIReset();
+      nsStyleUIReset* ui = new (mPresContext) nsStyleUIReset(mPresContext);
       aContext->SetStyle(eStyleStruct_UIReset, ui);
       return ui;
     }
     case eStyleStruct_XUL:
     {
-      nsStyleXUL* xul = new (mPresContext) nsStyleXUL();
+      nsStyleXUL* xul = new (mPresContext) nsStyleXUL(mPresContext);
       aContext->SetStyle(eStyleStruct_XUL, xul);
       return xul;
     }
     case eStyleStruct_Column:
     {
       nsStyleColumn* column = new (mPresContext) nsStyleColumn(mPresContext);
       aContext->SetStyle(eStyleStruct_Column, column);
       return column;
     }
     case eStyleStruct_SVG:
     {
-      nsStyleSVG* svg = new (mPresContext) nsStyleSVG();
+      nsStyleSVG* svg = new (mPresContext) nsStyleSVG(mPresContext);
       aContext->SetStyle(eStyleStruct_SVG, svg);
       return svg;
     }
     case eStyleStruct_SVGReset:
     {
-      nsStyleSVGReset* svgReset = new (mPresContext) nsStyleSVGReset();
+      nsStyleSVGReset* svgReset = new (mPresContext) nsStyleSVGReset(mPresContext);
       aContext->SetStyle(eStyleStruct_SVGReset, svgReset);
       return svgReset;
     }
     case eStyleStruct_Variables:
     {
-      nsStyleVariables* vars = new (mPresContext) nsStyleVariables();
+      nsStyleVariables* vars = new (mPresContext) nsStyleVariables(mPresContext);
       aContext->SetStyle(eStyleStruct_Variables, vars);
       return vars;
     }
     default:
       /*
        * unhandled case: nsStyleStructID_Length.
        * last item of nsStyleStructID, to know its length.
        */
@@ -2597,23 +2597,22 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
   }
   return nullptr;
 }
 
 /**
  * Begin an nsRuleNode::Compute*Data function for an inherited struct.
  *
  * @param type_ The nsStyle* type this function computes.
- * @param ctorargs_ The arguments used for the default nsStyle* constructor.
  * @param data_ Variable (declared here) holding the result of this
  *              function.
  * @param parentdata_ Variable (declared here) holding the parent style
  *                    context's data for this struct.
  */
-#define COMPUTE_START_INHERITED(type_, ctorargs_, data_, parentdata_)         \
+#define COMPUTE_START_INHERITED(type_, data_, parentdata_)                    \
   NS_ASSERTION(aRuleDetail != eRuleFullInherited,                             \
                "should not have bothered calling Compute*Data");              \
                                                                               \
   nsStyleContext* parentContext = aContext->GetParent();                      \
                                                                               \
   nsStyle##type_* data_ = nullptr;                                            \
   mozilla::Maybe<nsStyle##type_> maybeFakeParentData;                         \
   const nsStyle##type_* parentdata_ = nullptr;                                \
@@ -2623,58 +2622,57 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
   /* can't call parentContext->Style##type_() since it could recur into */    \
   /* setting the same struct on the same rule node, causing a leak. */        \
   if (aRuleDetail != eRuleFullReset &&                                        \
       (!aStartStruct || (aRuleDetail != eRulePartialReset &&                  \
                          aRuleDetail != eRuleNone))) {                        \
     if (parentContext) {                                                      \
       parentdata_ = parentContext->Style##type_();                            \
     } else {                                                                  \
-      maybeFakeParentData.emplace ctorargs_;                                  \
+      maybeFakeParentData.emplace(mPresContext);                              \
       parentdata_ = maybeFakeParentData.ptr();                                \
     }                                                                         \
   }                                                                           \
   if (eStyleStruct_##type_ == eStyleStruct_Variables)                         \
     /* no need to copy construct an nsStyleVariables, as we will copy */      \
     /* inherited variables (and call SetUncacheable()) in */                  \
     /* ComputeVariablesData */                                                \
-    data_ = new (mPresContext) nsStyle##type_ ctorargs_;                      \
+    data_ = new (mPresContext) nsStyle##type_(mPresContext);                  \
   else if (aStartStruct)                                                      \
     /* We only need to compute the delta between this computed data and */    \
     /* our computed data. */                                                  \
     data_ = new (mPresContext)                                                \
             nsStyle##type_(*static_cast<nsStyle##type_*>(aStartStruct));      \
   else {                                                                      \
     if (aRuleDetail != eRuleFullMixed && aRuleDetail != eRuleFullReset) {     \
       /* No question. We will have to inherit. Go ahead and init */           \
       /* with inherited vals from parent. */                                  \
       conditions.SetUncacheable();                                            \
       if (parentdata_)                                                        \
         data_ = new (mPresContext) nsStyle##type_(*parentdata_);              \
       else                                                                    \
-        data_ = new (mPresContext) nsStyle##type_ ctorargs_;                  \
+        data_ = new (mPresContext) nsStyle##type_(mPresContext);              \
     }                                                                         \
     else                                                                      \
-      data_ = new (mPresContext) nsStyle##type_ ctorargs_;                    \
+      data_ = new (mPresContext) nsStyle##type_(mPresContext);                \
   }                                                                           \
                                                                               \
   if (!parentdata_)                                                           \
     parentdata_ = data_;
 
 /**
  * Begin an nsRuleNode::Compute*Data function for a reset struct.
  *
  * @param type_ The nsStyle* type this function computes.
- * @param ctorargs_ The arguments used for the default nsStyle* constructor.
  * @param data_ Variable (declared here) holding the result of this
  *              function.
  * @param parentdata_ Variable (declared here) holding the parent style
  *                    context's data for this struct.
  */
-#define COMPUTE_START_RESET(type_, ctorargs_, data_, parentdata_)             \
+#define COMPUTE_START_RESET(type_, data_, parentdata_)                        \
   NS_ASSERTION(aRuleDetail != eRuleFullInherited,                             \
                "should not have bothered calling Compute*Data");              \
                                                                               \
   nsStyleContext* parentContext = aContext->GetParent();                      \
   /* Reset structs don't inherit from first-line */                           \
   /* See similar code in WalkRuleTree */                                      \
   while (parentContext &&                                                     \
          parentContext->GetPseudo() == nsCSSPseudoElements::firstLine) {      \
@@ -2683,30 +2681,30 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
                                                                               \
   nsStyle##type_* data_;                                                      \
   if (aStartStruct)                                                           \
     /* We only need to compute the delta between this computed data and */    \
     /* our computed data. */                                                  \
     data_ = new (mPresContext)                                                \
             nsStyle##type_(*static_cast<nsStyle##type_*>(aStartStruct));      \
   else                                                                        \
-    data_ = new (mPresContext) nsStyle##type_ ctorargs_;                      \
+    data_ = new (mPresContext) nsStyle##type_(mPresContext);                  \
                                                                               \
   /* If |conditions.Cacheable()| might be true by the time we're done, we */  \
   /* can't call parentContext->Style##type_() since it could recur into */    \
   /* setting the same struct on the same rule node, causing a leak. */        \
   mozilla::Maybe<nsStyle##type_> maybeFakeParentData;                         \
   const nsStyle##type_* parentdata_ = data_;                                  \
   if (aRuleDetail != eRuleFullReset &&                                        \
       aRuleDetail != eRulePartialReset &&                                     \
       aRuleDetail != eRuleNone) {                                             \
     if (parentContext) {                                                      \
       parentdata_ = parentContext->Style##type_();                            \
     } else {                                                                  \
-      maybeFakeParentData.emplace ctorargs_;                                  \
+      maybeFakeParentData.emplace(mPresContext);                              \
       parentdata_ = maybeFakeParentData.ptr();                                \
     }                                                                         \
   }                                                                           \
   RuleNodeCacheConditions conditions = aConditions;
 
 /**
  * End an nsRuleNode::Compute*Data function for an inherited struct.
  *
@@ -4032,17 +4030,17 @@ nsRuleNode::SetGenericFont(nsPresContext
 const void*
 nsRuleNode::ComputeFontData(void* aStartStruct,
                             const nsRuleData* aRuleData,
                             nsStyleContext* aContext,
                             nsRuleNode* aHighestNode,
                             const RuleDetail aRuleDetail,
                             const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(Font, (mPresContext), font, parentFont)
+  COMPUTE_START_INHERITED(Font, font, parentFont)
 
   // NOTE:  The |aRuleDetail| passed in is a little bit conservative due
   // to the -moz-system-font property.  We really don't need to consider
   // it here in determining whether to cache in the rule tree.  However,
   // we do need to consider it in WalkRuleTree when deciding whether to
   // walk further up the tree.  So this means that when the font struct
   // is fully specified using *longhand* properties (excluding
   // -moz-system-font), we won't cache in the rule tree even though we
@@ -4354,17 +4352,17 @@ struct SetLineHeightCalcOps : public css
 const void*
 nsRuleNode::ComputeTextData(void* aStartStruct,
                             const nsRuleData* aRuleData,
                             nsStyleContext* aContext,
                             nsRuleNode* aHighestNode,
                             const RuleDetail aRuleDetail,
                             const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(Text, (mPresContext), text, parentText)
+  COMPUTE_START_INHERITED(Text, text, parentText)
 
   // tab-size: integer, inherit
   SetDiscrete(*aRuleData->ValueForTabSize(),
               text->mTabSize, conditions,
               SETDSC_INTEGER | SETDSC_UNSET_INHERIT, parentText->mTabSize,
               NS_STYLE_TABSIZE_INITIAL, 0, 0, 0, 0);
 
   // letter-spacing: normal, length, inherit
@@ -4726,17 +4724,17 @@ nsRuleNode::ComputeTextData(void* aStart
 const void*
 nsRuleNode::ComputeTextResetData(void* aStartStruct,
                                  const nsRuleData* aRuleData,
                                  nsStyleContext* aContext,
                                  nsRuleNode* aHighestNode,
                                  const RuleDetail aRuleDetail,
                                  const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(TextReset, (), text, parentText)
+  COMPUTE_START_RESET(TextReset, text, parentText)
 
   // vertical-align: enum, length, percent, calc, inherit
   const nsCSSValue* verticalAlignValue = aRuleData->ValueForVerticalAlign();
   if (!SetCoord(*verticalAlignValue, text->mVerticalAlign,
                 parentText->mVerticalAlign,
                 SETCOORD_LPH | SETCOORD_ENUMERATED | SETCOORD_STORE_CALC,
                 aContext, mPresContext, conditions)) {
     if (eCSSUnit_Initial == verticalAlignValue->GetUnit() ||
@@ -4888,17 +4886,17 @@ nsRuleNode::ComputeTextResetData(void* a
 const void*
 nsRuleNode::ComputeUserInterfaceData(void* aStartStruct,
                                      const nsRuleData* aRuleData,
                                      nsStyleContext* aContext,
                                      nsRuleNode* aHighestNode,
                                      const RuleDetail aRuleDetail,
                                      const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(UserInterface, (), ui, parentUI)
+  COMPUTE_START_INHERITED(UserInterface, ui, parentUI)
 
   // cursor: enum, url, inherit
   const nsCSSValue* cursorValue = aRuleData->ValueForCursor();
   nsCSSUnit cursorUnit = cursorValue->GetUnit();
   if (cursorUnit != eCSSUnit_Null) {
     delete [] ui->mCursorArray;
     ui->mCursorArray = nullptr;
     ui->mCursorArrayLength = 0;
@@ -4983,17 +4981,17 @@ nsRuleNode::ComputeUserInterfaceData(voi
 const void*
 nsRuleNode::ComputeUIResetData(void* aStartStruct,
                                const nsRuleData* aRuleData,
                                nsStyleContext* aContext,
                                nsRuleNode* aHighestNode,
                                const RuleDetail aRuleDetail,
                                const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(UIReset, (), ui, parentUI)
+  COMPUTE_START_RESET(UIReset, ui, parentUI)
 
   // user-select: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForUserSelect(),
               ui->mUserSelect, conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentUI->mUserSelect,
               NS_STYLE_USER_SELECT_AUTO, 0, 0, 0, 0);
 
@@ -5229,17 +5227,17 @@ GetWillChangeBitFieldFromPropFlags(const
 const void*
 nsRuleNode::ComputeDisplayData(void* aStartStruct,
                                const nsRuleData* aRuleData,
                                nsStyleContext* aContext,
                                nsRuleNode* aHighestNode,
                                const RuleDetail aRuleDetail,
                                const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(Display, (), display, parentDisplay)
+  COMPUTE_START_RESET(Display, display, parentDisplay)
 
   // We may have ended up with aStartStruct's values of mDisplay and
   // mFloats, but those may not be correct if our style data overrides
   // its position or float properties.  Reset to mOriginalDisplay and
   // mOriginalFloats; it if turns out we still need the display/floats
   // adjustments we'll do them below.
   display->mDisplay = display->mOriginalDisplay;
   display->mFloats = display->mOriginalFloats;
@@ -6373,18 +6371,17 @@ nsRuleNode::ComputeDisplayData(void* aSt
 const void*
 nsRuleNode::ComputeVisibilityData(void* aStartStruct,
                                   const nsRuleData* aRuleData,
                                   nsStyleContext* aContext,
                                   nsRuleNode* aHighestNode,
                                   const RuleDetail aRuleDetail,
                                   const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(Visibility, (mPresContext),
-                          visibility, parentVisibility)
+  COMPUTE_START_INHERITED(Visibility, visibility, parentVisibility)
 
   // IMPORTANT: No properties in this struct have lengths in them.  We
   // depend on this since CalcLengthWith can call StyleVisibility()
   // to get the language for resolving fonts!
 
   // direction: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForDirection(), visibility->mDirection,
               conditions,
@@ -6473,17 +6470,17 @@ nsRuleNode::ComputeVisibilityData(void* 
 const void*
 nsRuleNode::ComputeColorData(void* aStartStruct,
                              const nsRuleData* aRuleData,
                              nsStyleContext* aContext,
                              nsRuleNode* aHighestNode,
                              const RuleDetail aRuleDetail,
                              const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(Color, (mPresContext), color, parentColor)
+  COMPUTE_START_INHERITED(Color, color, parentColor)
 
   // color: color, string, inherit
   // Special case for currentColor.  According to CSS3, setting color to 'currentColor'
   // should behave as if it is inherited
   const nsCSSValue* colorValue = aRuleData->ValueForColor();
   if ((colorValue->GetUnit() == eCSSUnit_EnumColor &&
        colorValue->GetIntValue() == NS_COLOR_CURRENTCOLOR) ||
       colorValue->GetUnit() == eCSSUnit_Unset) {
@@ -6954,17 +6951,17 @@ FillBackgroundList(AutoTArray< nsStyleIm
 const void*
 nsRuleNode::ComputeBackgroundData(void* aStartStruct,
                                   const nsRuleData* aRuleData,
                                   nsStyleContext* aContext,
                                   nsRuleNode* aHighestNode,
                                   const RuleDetail aRuleDetail,
                                   const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(Background, (), bg, parentBG)
+  COMPUTE_START_RESET(Background, bg, parentBG)
 
   // background-color: color, string, inherit
   const nsCSSValue* backColorValue = aRuleData->ValueForBackgroundColor();
   if (eCSSUnit_Initial == backColorValue->GetUnit() ||
       eCSSUnit_Unset == backColorValue->GetUnit()) {
     bg->mBackgroundColor = NS_RGBA(0, 0, 0, 0);
   } else if (!SetColor(*backColorValue, parentBG->mBackgroundColor,
                        mPresContext, aContext, bg->mBackgroundColor,
@@ -7098,17 +7095,17 @@ nsRuleNode::ComputeBackgroundData(void* 
 const void*
 nsRuleNode::ComputeMarginData(void* aStartStruct,
                               const nsRuleData* aRuleData,
                               nsStyleContext* aContext,
                               nsRuleNode* aHighestNode,
                               const RuleDetail aRuleDetail,
                               const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(Margin, (), margin, parentMargin)
+  COMPUTE_START_RESET(Margin, margin, parentMargin)
 
   // margin: length, percent, calc, inherit
   const nsCSSProperty* subprops =
     nsCSSProps::SubpropertyEntryFor(eCSSProperty_margin);
   nsStyleCoord coord;
   NS_FOR_CSS_SIDES(side) {
     nsStyleCoord parentCoord = parentMargin->mMargin.Get(side);
     if (SetCoord(*aRuleData->ValueFor(subprops[side]),
@@ -7204,17 +7201,17 @@ SetBorderImageSlice(const nsCSSValue& aV
 const void*
 nsRuleNode::ComputeBorderData(void* aStartStruct,
                               const nsRuleData* aRuleData,
                               nsStyleContext* aContext,
                               nsRuleNode* aHighestNode,
                               const RuleDetail aRuleDetail,
                               const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(Border, (mPresContext), border, parentBorder)
+  COMPUTE_START_RESET(Border, border, parentBorder)
 
   // box-decoration-break: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForBoxDecorationBreak(),
               border->mBoxDecorationBreak, conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentBorder->mBoxDecorationBreak,
               NS_STYLE_BOX_DECORATION_BREAK_SLICE, 0, 0, 0, 0);
 
@@ -7547,17 +7544,17 @@ nsRuleNode::ComputeBorderData(void* aSta
 const void*
 nsRuleNode::ComputePaddingData(void* aStartStruct,
                                const nsRuleData* aRuleData,
                                nsStyleContext* aContext,
                                nsRuleNode* aHighestNode,
                                const RuleDetail aRuleDetail,
                                const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(Padding, (), padding, parentPadding)
+  COMPUTE_START_RESET(Padding, padding, parentPadding)
 
   // padding: length, percent, calc, inherit
   const nsCSSProperty* subprops =
     nsCSSProps::SubpropertyEntryFor(eCSSProperty_padding);
   nsStyleCoord coord;
   NS_FOR_CSS_SIDES(side) {
     nsStyleCoord parentCoord = parentPadding->mPadding.Get(side);
     if (SetCoord(*aRuleData->ValueFor(subprops[side]),
@@ -7576,17 +7573,17 @@ nsRuleNode::ComputePaddingData(void* aSt
 const void*
 nsRuleNode::ComputeOutlineData(void* aStartStruct,
                                const nsRuleData* aRuleData,
                                nsStyleContext* aContext,
                                nsRuleNode* aHighestNode,
                                const RuleDetail aRuleDetail,
                                const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(Outline, (mPresContext), outline, parentOutline)
+  COMPUTE_START_RESET(Outline, outline, parentOutline)
 
   // outline-width: length, enum, inherit
   const nsCSSValue* outlineWidthValue = aRuleData->ValueForOutlineWidth();
   if (eCSSUnit_Initial == outlineWidthValue->GetUnit() ||
       eCSSUnit_Unset == outlineWidthValue->GetUnit()) {
     outline->mOutlineWidth =
       nsStyleCoord(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated);
   }
@@ -7687,17 +7684,17 @@ nsRuleNode::ComputeOutlineData(void* aSt
 const void*
 nsRuleNode::ComputeListData(void* aStartStruct,
                             const nsRuleData* aRuleData,
                             nsStyleContext* aContext,
                             nsRuleNode* aHighestNode,
                             const RuleDetail aRuleDetail,
                             const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(List, (mPresContext), list, parentList)
+  COMPUTE_START_INHERITED(List, list, parentList)
 
   // list-style-type: string, none, inherit, initial
   const nsCSSValue* typeValue = aRuleData->ValueForListStyleType();
   switch (typeValue->GetUnit()) {
     case eCSSUnit_Unset:
     case eCSSUnit_Inherit: {
       conditions.SetUncacheable();
       nsString type;
@@ -8144,17 +8141,17 @@ SetGridLine(const nsCSSValue& aValue,
 const void*
 nsRuleNode::ComputePositionData(void* aStartStruct,
                                 const nsRuleData* aRuleData,
                                 nsStyleContext* aContext,
                                 nsRuleNode* aHighestNode,
                                 const RuleDetail aRuleDetail,
                                 const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(Position, (), pos, parentPos)
+  COMPUTE_START_RESET(Position, pos, parentPos)
 
   // box offsets: length, percent, calc, auto, inherit
   static const nsCSSProperty offsetProps[] = {
     eCSSProperty_top,
     eCSSProperty_right,
     eCSSProperty_bottom,
     eCSSProperty_left
   };
@@ -8524,17 +8521,17 @@ nsRuleNode::ComputePositionData(void* aS
 const void*
 nsRuleNode::ComputeTableData(void* aStartStruct,
                              const nsRuleData* aRuleData,
                              nsStyleContext* aContext,
                              nsRuleNode* aHighestNode,
                              const RuleDetail aRuleDetail,
                              const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(Table, (), table, parentTable)
+  COMPUTE_START_RESET(Table, table, parentTable)
 
   // table-layout: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForTableLayout(),
               table->mLayoutStrategy, conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentTable->mLayoutStrategy,
               NS_STYLE_TABLE_LAYOUT_AUTO, 0, 0, 0, 0);
 
@@ -8550,17 +8547,17 @@ nsRuleNode::ComputeTableData(void* aStar
 const void*
 nsRuleNode::ComputeTableBorderData(void* aStartStruct,
                                    const nsRuleData* aRuleData,
                                    nsStyleContext* aContext,
                                    nsRuleNode* aHighestNode,
                                    const RuleDetail aRuleDetail,
                                    const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(TableBorder, (), table, parentTable)
+  COMPUTE_START_INHERITED(TableBorder, table, parentTable)
 
   // border-collapse: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForBorderCollapse(), table->mBorderCollapse,
               conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INHERIT,
               parentTable->mBorderCollapse,
               NS_STYLE_BORDER_SEPARATE, 0, 0, 0, 0);
 
@@ -8611,17 +8608,17 @@ nsRuleNode::ComputeContentData(void* aSt
                                nsStyleContext* aContext,
                                nsRuleNode* aHighestNode,
                                const RuleDetail aRuleDetail,
                                const RuleNodeCacheConditions aConditions)
 {
   uint32_t count;
   nsAutoString buffer;
 
-  COMPUTE_START_RESET(Content, (), content, parentContent)
+  COMPUTE_START_RESET(Content, content, parentContent)
 
   // content: [string, url, counter, attr, enum]+, normal, none, inherit
   const nsCSSValue* contentValue = aRuleData->ValueForContent();
   switch (contentValue->GetUnit()) {
   case eCSSUnit_Null:
     break;
 
   case eCSSUnit_Normal:
@@ -8848,17 +8845,17 @@ nsRuleNode::ComputeContentData(void* aSt
 const void*
 nsRuleNode::ComputeQuotesData(void* aStartStruct,
                               const nsRuleData* aRuleData,
                               nsStyleContext* aContext,
                               nsRuleNode* aHighestNode,
                               const RuleDetail aRuleDetail,
                               const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(Quotes, (), quotes, parentQuotes)
+  COMPUTE_START_INHERITED(Quotes, quotes, parentQuotes)
 
   // quotes: inherit, initial, none, [string string]+
   const nsCSSValue* quotesValue = aRuleData->ValueForQuotes();
   switch (quotesValue->GetUnit()) {
   case eCSSUnit_Null:
     break;
   case eCSSUnit_Inherit:
   case eCSSUnit_Unset:
@@ -8903,17 +8900,17 @@ nsRuleNode::ComputeQuotesData(void* aSta
 const void*
 nsRuleNode::ComputeXULData(void* aStartStruct,
                            const nsRuleData* aRuleData,
                            nsStyleContext* aContext,
                            nsRuleNode* aHighestNode,
                            const RuleDetail aRuleDetail,
                            const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(XUL, (), xul, parentXUL)
+  COMPUTE_START_RESET(XUL, xul, parentXUL)
 
   // box-align: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForBoxAlign(),
               xul->mBoxAlign, conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentXUL->mBoxAlign,
               NS_STYLE_BOX_ALIGN_STRETCH, 0, 0, 0, 0);
 
@@ -8969,17 +8966,17 @@ nsRuleNode::ComputeXULData(void* aStartS
 const void*
 nsRuleNode::ComputeColumnData(void* aStartStruct,
                               const nsRuleData* aRuleData,
                               nsStyleContext* aContext,
                               nsRuleNode* aHighestNode,
                               const RuleDetail aRuleDetail,
                               const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(Column, (mPresContext), column, parent)
+  COMPUTE_START_RESET(Column, column, parent)
 
   // column-width: length, auto, inherit
   SetCoord(*aRuleData->ValueForColumnWidth(),
            column->mColumnWidth, parent->mColumnWidth,
            SETCOORD_LAH | SETCOORD_INITIAL_AUTO |
              SETCOORD_CALC_LENGTH_ONLY | SETCOORD_CALC_CLAMP_NONNEGATIVE |
              SETCOORD_UNSET_INITIAL,
            aContext, mPresContext, conditions);
@@ -9192,17 +9189,17 @@ SetSVGOpacity(const nsCSSValue& aValue,
 const void*
 nsRuleNode::ComputeSVGData(void* aStartStruct,
                            const nsRuleData* aRuleData,
                            nsStyleContext* aContext,
                            nsRuleNode* aHighestNode,
                            const RuleDetail aRuleDetail,
                            const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(SVG, (), svg, parentSVG)
+  COMPUTE_START_INHERITED(SVG, svg, parentSVG)
 
   // clip-rule: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForClipRule(),
               svg->mClipRule, conditions,
               SETDSC_ENUMERATED | SETDSC_UNSET_INHERIT,
               parentSVG->mClipRule,
               NS_STYLE_FILL_RULE_NONZERO, 0, 0, 0, 0);
 
@@ -9732,17 +9729,17 @@ nsRuleNode::SetStyleFilterToCSSValue(nsS
 const void*
 nsRuleNode::ComputeSVGResetData(void* aStartStruct,
                                 const nsRuleData* aRuleData,
                                 nsStyleContext* aContext,
                                 nsRuleNode* aHighestNode,
                                 const RuleDetail aRuleDetail,
                                 const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_RESET(SVGReset, (), svgReset, parentSVGReset)
+  COMPUTE_START_RESET(SVGReset, svgReset, parentSVGReset)
 
   // stop-color:
   const nsCSSValue* stopColorValue = aRuleData->ValueForStopColor();
   if (eCSSUnit_Initial == stopColorValue->GetUnit() ||
       eCSSUnit_Unset == stopColorValue->GetUnit()) {
     svgReset->mStopColor = NS_RGB(0, 0, 0);
   } else {
     SetColor(*stopColorValue, parentSVGReset->mStopColor,
@@ -10026,17 +10023,17 @@ nsRuleNode::ComputeSVGResetData(void* aS
 const void*
 nsRuleNode::ComputeVariablesData(void* aStartStruct,
                                  const nsRuleData* aRuleData,
                                  nsStyleContext* aContext,
                                  nsRuleNode* aHighestNode,
                                  const RuleDetail aRuleDetail,
                                  const RuleNodeCacheConditions aConditions)
 {
-  COMPUTE_START_INHERITED(Variables, (), variables, parentVariables)
+  COMPUTE_START_INHERITED(Variables, variables, parentVariables)
 
   MOZ_ASSERT(aRuleData->mVariables,
              "shouldn't be in ComputeVariablesData if there were no variable "
              "declarations specified");
 
   CSSVariableResolver resolver(&variables->mVariables);
   resolver.Resolve(&parentVariables->mVariables,
                    aRuleData->mVariables);
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -500,22 +500,22 @@ nsStyleContext::CreateEmptyStyleData(con
   MOZ_ASSERT(!mChild && !mEmptyChild &&
              !(mBits & nsCachedStyleData::GetBitForSID(aSID)) &&
              !GetCachedStyleData(aSID),
              "This style should not have been computed");
 
   void* result;
   nsPresContext* presContext = PresContext();
   switch (aSID) {
-#define UNIQUE_CASE(c_, ...) \
+#define UNIQUE_CASE(c_) \
     case eStyleStruct_##c_: \
-      result = new (presContext) nsStyle##c_(__VA_ARGS__); \
+      result = new (presContext) nsStyle##c_(presContext); \
       break;
 
-  UNIQUE_CASE(Border, presContext)
+  UNIQUE_CASE(Border)
   UNIQUE_CASE(Padding)
 
 #undef UNIQUE_CASE
 
   default:
     NS_ERROR("Struct type not supported.");
     return nullptr;
   }
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -10,16 +10,17 @@
  */
 
 #include "nsStyleStruct.h"
 #include "nsStyleStructInlines.h"
 #include "nsStyleConsts.h"
 #include "nsThemeConstants.h"
 #include "nsString.h"
 #include "nsPresContext.h"
+#include "nsIAppShellService.h"
 #include "nsIWidget.h"
 #include "nsCRTGlue.h"
 #include "nsCSSParser.h"
 #include "nsCSSProps.h"
 
 #include "nsCOMPtr.h"
 
 #include "nsBidiUtils.h"
@@ -87,37 +88,53 @@ static bool EqualImages(imgIRequest *aIm
 static int safe_strcmp(const char16_t* a, const char16_t* b)
 {
   if (!a || !b) {
     return (int)(a - b);
   }
   return NS_strcmp(a, b);
 }
 
+int32_t
+StyleStructContext::AppUnitsPerDevPixel()
+{
+  return DeviceContext()->AppUnitsPerDevPixel();
+}
+
+nsDeviceContext*
+StyleStructContext::HackilyFindSomeDeviceContext()
+{
+  nsCOMPtr<nsIAppShellService> appShell(do_GetService("@mozilla.org/appshell/appShellService;1"));
+  MOZ_ASSERT(appShell);
+  nsCOMPtr<mozIDOMWindowProxy> win;
+  appShell->GetHiddenDOMWindow(getter_AddRefs(win));
+  return nsLayoutUtils::GetDeviceContextForScreenInfo(static_cast<nsPIDOMWindowOuter*>(win.get()));
+}
+
 static bool AreShadowArraysEqual(nsCSSShadowArray* lhs,
                                  nsCSSShadowArray* rhs);
 
 // --------------------
 // nsStyleFont
 //
-nsStyleFont::nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext)
+nsStyleFont::nsStyleFont(const nsFont& aFont, StyleStructContext aContext)
   : mFont(aFont)
-  , mSize(nsStyleFont::ZoomText(aPresContext, mFont.size))
+  , mSize(nsStyleFont::ZoomText(aContext, mFont.size))
   , mGenericID(kGenericFont_NONE)
   , mScriptLevel(0)
   , mMathVariant(NS_MATHML_MATHVARIANT_NONE)
   , mMathDisplay(NS_MATHML_DISPLAYSTYLE_INLINE)
   , mMinFontSizeRatio(100) // 100%
   , mExplicitLanguage(false)
   , mAllowZoom(true)
   , mScriptUnconstrainedSize(mSize)
   , mScriptMinSize(nsPresContext::CSSTwipsToAppUnits(
       NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT)))
   , mScriptSizeMultiplier(NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER)
-  , mLanguage(GetLanguage(aPresContext))
+  , mLanguage(GetLanguage(aContext))
 {
   MOZ_COUNT_CTOR(nsStyleFont);
   mFont.size = mSize;
 }
 
 nsStyleFont::nsStyleFont(const nsStyleFont& aSrc)
   : mFont(aSrc.mFont)
   , mSize(aSrc.mSize)
@@ -131,19 +148,19 @@ nsStyleFont::nsStyleFont(const nsStyleFo
   , mScriptUnconstrainedSize(aSrc.mScriptUnconstrainedSize)
   , mScriptMinSize(aSrc.mScriptMinSize)
   , mScriptSizeMultiplier(aSrc.mScriptSizeMultiplier)
   , mLanguage(aSrc.mLanguage)
 {
   MOZ_COUNT_CTOR(nsStyleFont);
 }
 
-nsStyleFont::nsStyleFont(nsPresContext* aPresContext)
-  : nsStyleFont(*(aPresContext->GetDefaultFont(
-      kPresContext_DefaultVariableFont_ID, nullptr)), aPresContext)
+nsStyleFont::nsStyleFont(StyleStructContext aContext)
+  : nsStyleFont(*aContext.GetDefaultFont(kPresContext_DefaultVariableFont_ID),
+                aContext)
 {
 }
 
 void 
 nsStyleFont::Destroy(nsPresContext* aContext) {
   this->~nsStyleFont();
   aContext->PresShell()->
     FreeByObjectID(eArenaObjectID_nsStyleFont, this);
@@ -191,42 +208,42 @@ nsChangeHint nsStyleFont::CalcDifference
       mScriptSizeMultiplier != aOther.mScriptSizeMultiplier) {
     return nsChangeHint_NeutralChange;
   }
 
   return NS_STYLE_HINT_NONE;
 }
 
 /* static */ nscoord
-nsStyleFont::ZoomText(nsPresContext *aPresContext, nscoord aSize)
+nsStyleFont::ZoomText(StyleStructContext aContext, nscoord aSize)
 {
   // aSize can be negative (e.g.: calc(-1px)) so we can't assert that here.
   // The caller is expected deal with that.
-  return NSToCoordTruncClamped(float(aSize) * aPresContext->TextZoom());
+  return NSToCoordTruncClamped(float(aSize) * aContext.TextZoom());
 }
 
 /* static */ nscoord
 nsStyleFont::UnZoomText(nsPresContext *aPresContext, nscoord aSize)
 {
   // aSize can be negative (e.g.: calc(-1px)) so we can't assert that here.
   // The caller is expected deal with that.
   return NSToCoordTruncClamped(float(aSize) / aPresContext->TextZoom());
 }
 
 /* static */ already_AddRefed<nsIAtom>
-nsStyleFont::GetLanguage(nsPresContext* aPresContext)
+nsStyleFont::GetLanguage(StyleStructContext aContext)
 {
-  RefPtr<nsIAtom> language = aPresContext->GetContentLanguage();
+  RefPtr<nsIAtom> language = aContext.GetContentLanguage();
   if (!language) {
     // we didn't find a (usable) Content-Language, so we fall back
     // to whatever the presContext guessed from the charset
     // NOTE this should not be used elsewhere, because we want websites
     // to use UTF-8 with proper language tag, instead of relying on
     // deriving language from charset. See bug 1040668 comment 67.
-    language = aPresContext->GetLanguageFromCharset();
+    language = aContext.GetLanguageFromCharset();
   }
   return language.forget();
 }
 
 static bool IsFixedData(const nsStyleSides& aSides, bool aEnumOK)
 {
   NS_FOR_CSS_SIDES(side) {
     if (!IsFixedUnit(aSides.Get(side), aEnumOK))
@@ -247,17 +264,17 @@ static nscoord CalcCoord(const nsStyleCo
     }
     NS_NOTREACHED("unexpected enum value");
     return 0;
   }
   MOZ_ASSERT(aCoord.ConvertsToLength(), "unexpected unit");
   return nsRuleNode::ComputeCoordPercentCalc(aCoord, 0);
 }
 
-nsStyleMargin::nsStyleMargin()
+nsStyleMargin::nsStyleMargin(StyleStructContext aContext)
   : mHasCachedMargin(false)
   , mCachedMargin(0, 0, 0, 0)
 {
   MOZ_COUNT_CTOR(nsStyleMargin);
   nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
   NS_FOR_CSS_SIDES(side) {
     mMargin.Set(side, zero);
   }
@@ -298,17 +315,17 @@ nsChangeHint nsStyleMargin::CalcDifferen
   }
   // Margin differences can't affect descendant intrinsic sizes and
   // don't need to force children to reflow.
   return nsChangeHint_NeedReflow |
          nsChangeHint_ReflowChangesSizeOrPosition |
          nsChangeHint_ClearAncestorIntrinsics;
 }
 
-nsStylePadding::nsStylePadding()
+nsStylePadding::nsStylePadding(StyleStructContext aContext)
   : mHasCachedPadding(false)
   , mCachedPadding(0, 0, 0, 0)
 {
   MOZ_COUNT_CTOR(nsStylePadding);
   nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
   NS_FOR_CSS_SIDES(side) {
     mPadding.Set(side, zero);
   }
@@ -351,17 +368,17 @@ nsChangeHint nsStylePadding::CalcDiffere
   // Padding differences can't affect descendant intrinsic sizes, but do need
   // to force children to reflow so that we can reposition them, since their
   // offsets are from our frame bounds but our content rect's position within
   // those bounds is moving.
   return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
                          nsChangeHint_ClearDescendantIntrinsics);
 }
 
-nsStyleBorder::nsStyleBorder(nsPresContext* aPresContext)
+nsStyleBorder::nsStyleBorder(StyleStructContext aContext)
   : mBorderColors(nullptr),
     mBoxShadow(nullptr),
     mBorderImageFill(NS_STYLE_BORDER_IMAGE_SLICE_NOFILL),
     mBorderImageRepeatH(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH),
     mBorderImageRepeatV(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH),
     mFloatEdge(NS_STYLE_FLOAT_EDGE_CONTENT),
     mBoxDecorationBreak(NS_STYLE_BOX_DECORATION_BREAK_SLICE),
     mComputedBorder(0, 0, 0, 0)
@@ -379,17 +396,17 @@ nsStyleBorder::nsStyleBorder(nsPresConte
     mBorderImageWidth.Set(side, nsStyleCoord(1.0f, eStyleUnit_Factor));
     mBorderImageOutset.Set(side, nsStyleCoord(0.0f, eStyleUnit_Factor));
 
     mBorder.Side(side) = medium;
     mBorderStyle[side] = NS_STYLE_BORDER_STYLE_NONE | BORDER_COLOR_FOREGROUND;
     mBorderColor[side] = NS_RGB(0, 0, 0);
   }
 
-  mTwipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
+  mTwipsPerPixel = aContext.DevPixelsToAppUnits(1);
 }
 
 nsBorderColors::~nsBorderColors()
 {
   NS_CSS_DELETE_LIST_MEMBER(nsBorderColors, this, mNext);
 }
 
 nsBorderColors*
@@ -565,33 +582,33 @@ nsChangeHint nsStyleBorder::CalcDifferen
   // border values instead.
   if (mBorder != aOther.mBorder) {
     return nsChangeHint_NeutralChange;
   }
 
   return NS_STYLE_HINT_NONE;
 }
 
-nsStyleOutline::nsStyleOutline(nsPresContext* aPresContext)
+nsStyleOutline::nsStyleOutline(StyleStructContext aContext)
 {
   MOZ_COUNT_CTOR(nsStyleOutline);
   // spacing values not inherited
   nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
   NS_FOR_CSS_HALF_CORNERS(corner) {
     mOutlineRadius.Set(corner, zero);
   }
 
   mOutlineOffset = 0;
 
   mOutlineWidth = nsStyleCoord(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated);
   mOutlineStyle = NS_STYLE_BORDER_STYLE_NONE;
   mOutlineColor = NS_RGB(0, 0, 0);
 
   mHasCachedOutline = false;
-  mTwipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
+  mTwipsPerPixel = aContext.DevPixelsToAppUnits(1);
 
   SetOutlineInitialColor();
 }
 
 nsStyleOutline::nsStyleOutline(const nsStyleOutline& aSrc)
   : mOutlineRadius(aSrc.mOutlineRadius)
   , mOutlineWidth(aSrc.mOutlineWidth)
   , mOutlineOffset(aSrc.mOutlineOffset)
@@ -653,21 +670,20 @@ nsChangeHint nsStyleOutline::CalcDiffere
   }
 
   return NS_STYLE_HINT_NONE;
 }
 
 // --------------------
 // nsStyleList
 //
-nsStyleList::nsStyleList(nsPresContext* aPresContext) 
+nsStyleList::nsStyleList(StyleStructContext aContext) 
   : mListStylePosition(NS_STYLE_LIST_STYLE_POSITION_OUTSIDE),
     mListStyleType(NS_LITERAL_STRING("disc")),
-    mCounterStyle(aPresContext->CounterStyleManager()->
-                  BuildCounterStyle(mListStyleType))
+    mCounterStyle(aContext.BuildCounterStyle(mListStyleType))
 {
   MOZ_COUNT_CTOR(nsStyleList);
 }
 
 nsStyleList::~nsStyleList() 
 {
   MOZ_COUNT_DTOR(nsStyleList);
 }
@@ -698,17 +714,17 @@ nsChangeHint nsStyleList::CalcDifference
       return NS_STYLE_HINT_VISUAL;
   }
   return NS_STYLE_HINT_REFLOW;
 }
 
 // --------------------
 // nsStyleXUL
 //
-nsStyleXUL::nsStyleXUL() 
+nsStyleXUL::nsStyleXUL(StyleStructContext aContext)
 { 
   MOZ_COUNT_CTOR(nsStyleXUL);
   mBoxAlign  = NS_STYLE_BOX_ALIGN_STRETCH;
   mBoxDirection = NS_STYLE_BOX_DIRECTION_NORMAL;
   mBoxFlex = 0.0f;
   mBoxOrient = NS_STYLE_BOX_ORIENT_HORIZONTAL;
   mBoxPack   = NS_STYLE_BOX_PACK_START;
   mBoxOrdinal = 1;
@@ -747,31 +763,31 @@ nsChangeHint nsStyleXUL::CalcDifference(
   return NS_STYLE_HINT_REFLOW;
 }
 
 // --------------------
 // nsStyleColumn
 //
 /* static */ const uint32_t nsStyleColumn::kMaxColumnCount = 1000;
 
-nsStyleColumn::nsStyleColumn(nsPresContext* aPresContext)
+nsStyleColumn::nsStyleColumn(StyleStructContext aContext)
 {
   MOZ_COUNT_CTOR(nsStyleColumn);
   mColumnCount = NS_STYLE_COLUMN_COUNT_AUTO;
   mColumnWidth.SetAutoValue();
   mColumnGap.SetNormalValue();
   mColumnFill = NS_STYLE_COLUMN_FILL_BALANCE;
 
   mColumnRuleWidth =
     (StaticPresData::Get()->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
   mColumnRuleStyle = NS_STYLE_BORDER_STYLE_NONE;
   mColumnRuleColor = NS_RGB(0, 0, 0);
   mColumnRuleColorIsForeground = true;
 
-  mTwipsPerPixel = aPresContext->AppUnitsPerDevPixel();
+  mTwipsPerPixel = aContext.AppUnitsPerDevPixel();
 }
 
 nsStyleColumn::~nsStyleColumn() 
 {
   MOZ_COUNT_DTOR(nsStyleColumn);
 }
 
 nsStyleColumn::nsStyleColumn(const nsStyleColumn& aSource)
@@ -817,17 +833,17 @@ nsChangeHint nsStyleColumn::CalcDifferen
   }
 
   return NS_STYLE_HINT_NONE;
 }
 
 // --------------------
 // nsStyleSVG
 //
-nsStyleSVG::nsStyleSVG()
+nsStyleSVG::nsStyleSVG(StyleStructContext aContext)
 {
   MOZ_COUNT_CTOR(nsStyleSVG);
   mFill.mType              = eStyleSVGPaintType_Color;
   mFill.mPaint.mColor      = NS_RGB(0,0,0);
   mFill.mFallbackColor     = NS_RGB(0,0,0);
   mStroke.mType            = eStyleSVGPaintType_None;
   mStroke.mPaint.mColor    = NS_RGB(0,0,0);
   mStroke.mFallbackColor   = NS_RGB(0,0,0);
@@ -1256,17 +1272,17 @@ nsStyleFilter::SetDropShadow(nsCSSShadow
   mDropShadow = aDropShadow;
   mDropShadow->AddRef();
   mType = NS_STYLE_FILTER_DROP_SHADOW;
 }
 
 // --------------------
 // nsStyleSVGReset
 //
-nsStyleSVGReset::nsStyleSVGReset()
+nsStyleSVGReset::nsStyleSVGReset(StyleStructContext aContext)
 {
   MOZ_COUNT_CTOR(nsStyleSVGReset);
   mStopColor               = NS_RGB(0,0,0);
   mFloodColor              = NS_RGB(0,0,0);
   mLightingColor           = NS_RGB(255,255,255);
   mStopOpacity             = 1.0f;
   mFloodOpacity            = 1.0f;
   mDominantBaseline        = NS_STYLE_DOMINANT_BASELINE_AUTO;
@@ -1394,17 +1410,17 @@ bool nsStyleSVGPaint::operator==(const n
   if (mType == eStyleSVGPaintType_Color)
     return mPaint.mColor == aOther.mPaint.mColor;
   return true;
 }
 
 // --------------------
 // nsStylePosition
 //
-nsStylePosition::nsStylePosition(void)
+nsStylePosition::nsStylePosition(StyleStructContext aContext)
 {
   MOZ_COUNT_CTOR(nsStylePosition);
 
   // positioning values not inherited
 
   mObjectPosition.SetInitialPercentValues(0.5f);
 
   nsStyleCoord  autoCoord(eStyleUnit_Auto);
@@ -1723,17 +1739,17 @@ nsStylePosition::ComputedJustifySelf(nsS
   }
   return NS_STYLE_JUSTIFY_NORMAL;
 }
 
 // --------------------
 // nsStyleTable
 //
 
-nsStyleTable::nsStyleTable() 
+nsStyleTable::nsStyleTable(StyleStructContext aContext)
 { 
   MOZ_COUNT_CTOR(nsStyleTable);
   // values not inherited
   mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO;
   mSpan = 1;
 }
 
 nsStyleTable::~nsStyleTable(void) 
@@ -1754,17 +1770,17 @@ nsChangeHint nsStyleTable::CalcDifferenc
       mLayoutStrategy != aOther.mLayoutStrategy)
     return NS_STYLE_HINT_FRAMECHANGE;
   return NS_STYLE_HINT_NONE;
 }
 
 // -----------------------
 // nsStyleTableBorder
 
-nsStyleTableBorder::nsStyleTableBorder()
+nsStyleTableBorder::nsStyleTableBorder(StyleStructContext aContext)
 { 
   MOZ_COUNT_CTOR(nsStyleTableBorder);
   mBorderCollapse = NS_STYLE_BORDER_SEPARATE;
 
   mEmptyCells = NS_STYLE_TABLE_EMPTY_CELLS_SHOW;
   mCaptionSide = NS_STYLE_CAPTION_SIDE_TOP;
   mBorderSpacingCol = 0;
   mBorderSpacingRow = 0;
@@ -1805,20 +1821,20 @@ nsChangeHint nsStyleTableBorder::CalcDif
   else
     return NS_STYLE_HINT_REFLOW;
 }
 
 // --------------------
 // nsStyleColor
 //
 
-nsStyleColor::nsStyleColor(nsPresContext* aPresContext)
+nsStyleColor::nsStyleColor(StyleStructContext aContext)
 {
   MOZ_COUNT_CTOR(nsStyleColor);
-  mColor = aPresContext->DefaultColor();
+  mColor = aContext.DefaultColor();
 }
 
 nsStyleColor::nsStyleColor(const nsStyleColor& aSource)
 {
   MOZ_COUNT_CTOR(nsStyleColor);
   mColor = aSource.mColor;
 }
 
@@ -2599,17 +2615,17 @@ nsStyleImageLayers::Layer::CalcDifferenc
 
   return hint;
 }
 
 // --------------------
 // nsStyleBackground
 //
 
-nsStyleBackground::nsStyleBackground()
+nsStyleBackground::nsStyleBackground(StyleStructContext aContext)
   : mBackgroundColor(NS_RGBA(0, 0, 0, 0))
 {
   MOZ_COUNT_CTOR(nsStyleBackground);
 }
 
 nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
   : mImage(aSource.mImage)
   , mBackgroundColor(aSource.mBackgroundColor)
@@ -2792,17 +2808,17 @@ mozilla::StyleAnimation::operator==(cons
          mDelay == aOther.mDelay &&
          mName == aOther.mName &&
          mDirection == aOther.mDirection &&
          mFillMode == aOther.mFillMode &&
          mPlayState == aOther.mPlayState &&
          mIterationCount == aOther.mIterationCount;
 }
 
-nsStyleDisplay::nsStyleDisplay()
+nsStyleDisplay::nsStyleDisplay(StyleStructContext aContext)
   : mWillChangeBitField(0)
 {
   MOZ_COUNT_CTOR(nsStyleDisplay);
   mAppearance = NS_THEME_NONE;
   mDisplay = NS_STYLE_DISPLAY_INLINE;
   mOriginalDisplay = mDisplay;
   mContain = NS_STYLE_CONTAIN_NONE;
   mPosition = NS_STYLE_POSITION_STATIC;
@@ -3155,20 +3171,20 @@ nsChangeHint nsStyleDisplay::CalcDiffere
 
   return hint;
 }
 
 // --------------------
 // nsStyleVisibility
 //
 
-nsStyleVisibility::nsStyleVisibility(nsPresContext* aPresContext)
+nsStyleVisibility::nsStyleVisibility(StyleStructContext aContext)
 {
   MOZ_COUNT_CTOR(nsStyleVisibility);
-  uint32_t bidiOptions = aPresContext->GetBidi();
+  uint32_t bidiOptions = aContext.GetBidi();
   if (GET_BIDI_OPTION_DIRECTION(bidiOptions) == IBMBIDI_TEXTDIRECTION_RTL)
     mDirection = NS_STYLE_DIRECTION_RTL;
   else
     mDirection = NS_STYLE_DIRECTION_LTR;
 
   mVisible = NS_STYLE_VISIBILITY_VISIBLE;
   mPointerEvents = NS_STYLE_POINTER_EVENTS_AUTO;
   mWritingMode = NS_STYLE_WRITING_MODE_HORIZONTAL_TB;
@@ -3329,17 +3345,17 @@ nsStyleContentData::UntrackImage(nsPresC
 #endif
 }
 
 
 //-----------------------
 // nsStyleContent
 //
 
-nsStyleContent::nsStyleContent(void)
+nsStyleContent::nsStyleContent(StyleStructContext aContext)
   : mMarkerOffset(),
     mContents(nullptr),
     mIncrements(nullptr),
     mResets(nullptr),
     mContentCount(0),
     mIncrementCount(0),
     mResetCount(0)
 {
@@ -3475,17 +3491,17 @@ nsresult nsStyleContent::AllocateContent
   mContentCount = aCount;
   return NS_OK;
 }
 
 // ---------------------
 // nsStyleQuotes
 //
 
-nsStyleQuotes::nsStyleQuotes(void)
+nsStyleQuotes::nsStyleQuotes(StyleStructContext aContext)
   : mQuotesCount(0),
     mQuotes(nullptr)
 {
   MOZ_COUNT_CTOR(nsStyleQuotes);
   SetInitial();
 }
 
 nsStyleQuotes::~nsStyleQuotes(void)
@@ -3549,17 +3565,17 @@ nsChangeHint nsStyleQuotes::CalcDifferen
   }
   return NS_STYLE_HINT_FRAMECHANGE;
 }
 
 // --------------------
 // nsStyleTextReset
 //
 
-nsStyleTextReset::nsStyleTextReset(void) 
+nsStyleTextReset::nsStyleTextReset(StyleStructContext aContext)
 { 
   MOZ_COUNT_CTOR(nsStyleTextReset);
   mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE, eStyleUnit_Enumerated);
   mTextDecorationLine = NS_STYLE_TEXT_DECORATION_LINE_NONE;
   mTextDecorationColor = NS_RGB(0,0,0);
   mTextDecorationStyle =
     NS_STYLE_TEXT_DECORATION_STYLE_SOLID | BORDER_COLOR_FOREGROUND;
   mUnicodeBidi = NS_STYLE_UNICODE_BIDI_NORMAL;
@@ -3627,17 +3643,17 @@ AreShadowArraysEqual(nsCSSShadowArray* l
   }
   return true;
 }
 
 // --------------------
 // nsStyleText
 //
 
-nsStyleText::nsStyleText(nsPresContext* aPresContext)
+nsStyleText::nsStyleText(StyleStructContext aContext)
 { 
   MOZ_COUNT_CTOR(nsStyleText);
   mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
   mTextAlignLast = NS_STYLE_TEXT_ALIGN_AUTO;
   mTextAlignTrue = false;
   mTextAlignLastTrue = false;
   mTextEmphasisColorForeground = true;
   mWebkitTextFillColorForeground = true;
@@ -3646,23 +3662,23 @@ nsStyleText::nsStyleText(nsPresContext* 
   mWordBreak = NS_STYLE_WORDBREAK_NORMAL;
   mWordWrap = NS_STYLE_WORDWRAP_NORMAL;
   mHyphens = NS_STYLE_HYPHENS_MANUAL;
   mRubyAlign = NS_STYLE_RUBY_ALIGN_SPACE_AROUND;
   mRubyPosition = NS_STYLE_RUBY_POSITION_OVER;
   mTextSizeAdjust = NS_STYLE_TEXT_SIZE_ADJUST_AUTO;
   mTextCombineUpright = NS_STYLE_TEXT_COMBINE_UPRIGHT_NONE;
   mTextEmphasisStyle = NS_STYLE_TEXT_EMPHASIS_STYLE_NONE;
-  nsCOMPtr<nsIAtom> language = aPresContext->GetContentLanguage();
+  nsCOMPtr<nsIAtom> language = aContext.GetContentLanguage();
   mTextEmphasisPosition = language &&
     nsStyleUtil::MatchesLanguagePrefix(language, MOZ_UTF16("zh")) ?
     NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT_ZH :
     NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT;
-  mTextEmphasisColor = aPresContext->DefaultColor();
-  mWebkitTextFillColor = aPresContext->DefaultColor();
+  mTextEmphasisColor = aContext.DefaultColor();
+  mWebkitTextFillColor = aContext.DefaultColor();
   mControlCharacterVisibility = nsCSSParser::ControlCharVisibilityDefault();
 
   mWordSpacing.SetCoordValue(0);
   mLetterSpacing.SetNormalValue();
   mLineHeight.SetNormalValue();
   mTextIndent.SetCoordValue(0);
 
   mTextShadow = nullptr;
@@ -3824,17 +3840,17 @@ nsCursorImage::operator=(const nsCursorI
     mHotspotX = aOther.mHotspotX;
     mHotspotY = aOther.mHotspotY;
     SetImage(aOther.GetImage());
   }
 
   return *this;
 }
 
-nsStyleUserInterface::nsStyleUserInterface(void) 
+nsStyleUserInterface::nsStyleUserInterface(StyleStructContext aContext)
 { 
   MOZ_COUNT_CTOR(nsStyleUserInterface);
   mUserInput = NS_STYLE_USER_INPUT_AUTO;
   mUserModify = NS_STYLE_USER_MODIFY_READ_ONLY;
   mUserFocus = NS_STYLE_USER_FOCUS_NONE;
 
   mCursor = NS_STYLE_CURSOR_AUTO; // fix for bugzilla bug 51113
 
@@ -3902,17 +3918,17 @@ nsStyleUserInterface::CopyCursorArrayFro
     }
   }
 }
 
 //-----------------------
 // nsStyleUIReset
 //
 
-nsStyleUIReset::nsStyleUIReset(void) 
+nsStyleUIReset::nsStyleUIReset(StyleStructContext aContext)
 { 
   MOZ_COUNT_CTOR(nsStyleUIReset);
   mUserSelect = NS_STYLE_USER_SELECT_AUTO;
   mForceBrokenImageIcon = 0;
   mIMEMode = NS_STYLE_IME_MODE_AUTO;
   mWindowDragging = NS_STYLE_WINDOW_DRAGGING_DEFAULT;
   mWindowShadow = NS_STYLE_WINDOW_SHADOW_DEFAULT;
 }
@@ -3952,17 +3968,17 @@ nsChangeHint nsStyleUIReset::CalcDiffere
 
   return NS_STYLE_HINT_NONE;
 }
 
 //-----------------------
 // nsStyleVariables
 //
 
-nsStyleVariables::nsStyleVariables()
+nsStyleVariables::nsStyleVariables(StyleStructContext aContext)
 {
   MOZ_COUNT_CTOR(nsStyleVariables);
 }
 
 nsStyleVariables::nsStyleVariables(const nsStyleVariables& aSource)
 {
   MOZ_COUNT_CTOR(nsStyleVariables);
   mVariables = aSource.mVariables;
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -11,16 +11,17 @@
 
 #ifndef nsStyleStruct_h___
 #define nsStyleStruct_h___
 
 #include "mozilla/ArenaObjectID.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/CSSVariableValues.h"
 #include "mozilla/SheetType.h"
+#include "mozilla/StyleStructContext.h"
 #include "nsColor.h"
 #include "nsCoord.h"
 #include "nsMargin.h"
 #include "nsFont.h"
 #include "nsStyleCoord.h"
 #include "nsStyleConsts.h"
 #include "nsChangeHint.h"
 #include "nsPresContext.h"
@@ -141,19 +142,19 @@ static_assert(sizeof(nsRect_Simple) == s
 static_assert(offsetof(nsRect_Simple, x) == offsetof(nsRect, x), "Wrong nsRect_Simple member alignment");
 static_assert(offsetof(nsRect_Simple, y) == offsetof(nsRect, y), "Wrong nsRect_Simple member alignment");
 static_assert(offsetof(nsRect_Simple, width) == offsetof(nsRect, width), "Wrong nsRect_Simple member alignment");
 static_assert(offsetof(nsRect_Simple, height) == offsetof(nsRect, height), "Wrong nsRect_Simple member alignment");
 
 // The lifetime of these objects is managed by the presshell's arena.
 struct nsStyleFont
 {
-  nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext);
+  nsStyleFont(const nsFont& aFont, StyleStructContext aContext);
   nsStyleFont(const nsStyleFont& aStyleFont);
-  explicit nsStyleFont(nsPresContext *aPresContext);
+  explicit nsStyleFont(StyleStructContext aContext);
   ~nsStyleFont(void) {
     MOZ_COUNT_DTOR(nsStyleFont);
   }
 
   nsChangeHint CalcDifference(const nsStyleFont& aOther) const;
   static nsChangeHint MaxDifference() {
     return NS_CombineHint(NS_STYLE_HINT_REFLOW,
                           nsChangeHint_NeutralChange);
@@ -166,24 +167,24 @@ struct nsStyleFont
            nsChangeHint_ClearAncestorIntrinsics;
   }
 
   /**
    * Return aSize multiplied by the current text zoom factor (in aPresContext).
    * aSize is allowed to be negative, but the caller is expected to deal with
    * negative results.  The result is clamped to nscoord_MIN .. nscoord_MAX.
    */
-  static nscoord ZoomText(nsPresContext* aPresContext, nscoord aSize);
+  static nscoord ZoomText(StyleStructContext aContext, nscoord aSize);
   /**
    * Return aSize divided by the current text zoom factor (in aPresContext).
    * aSize is allowed to be negative, but the caller is expected to deal with
    * negative results.  The result is clamped to nscoord_MIN .. nscoord_MAX.
    */
   static nscoord UnZoomText(nsPresContext* aPresContext, nscoord aSize);
-  static already_AddRefed<nsIAtom> GetLanguage(nsPresContext* aPresContext);
+  static already_AddRefed<nsIAtom> GetLanguage(StyleStructContext aPresContext);
 
   void* operator new(size_t sz, nsStyleFont* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleFont, sz);
   }
   void Destroy(nsPresContext* aContext);
 
@@ -410,17 +411,17 @@ private:
   nsAutoPtr<nsStyleSides> mCropRect;
 #ifdef DEBUG
   bool mImageTracked;
 #endif
 };
 
 struct nsStyleColor
 {
-  explicit nsStyleColor(nsPresContext* aPresContext);
+  explicit nsStyleColor(StyleStructContext aContext);
   nsStyleColor(const nsStyleColor& aOther);
   ~nsStyleColor(void) {
     MOZ_COUNT_DTOR(nsStyleColor);
   }
 
   nsChangeHint CalcDifference(const nsStyleColor& aOther) const;
   static nsChangeHint MaxDifference() {
     return nsChangeHint_RepaintFrame;
@@ -712,17 +713,17 @@ struct nsStyleImageLayers {
     for (uint32_t var_ = (layers_).mImageCount; var_-- != 0; )
   #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_, start_, count_) \
     NS_ASSERTION((int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount, "Invalid layer start!"); \
     NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, "Invalid layer range!"); \
     for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
 };
 
 struct nsStyleBackground {
-  nsStyleBackground();
+  explicit nsStyleBackground(StyleStructContext aContext);
   nsStyleBackground(const nsStyleBackground& aOther);
   ~nsStyleBackground();
 
   void* operator new(size_t sz, nsStyleBackground* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleBackground, sz);
   }
@@ -766,17 +767,17 @@ struct nsStyleBackground {
 
 #define NS_SPACING_MARGIN   0
 #define NS_SPACING_PADDING  1
 #define NS_SPACING_BORDER   2
 
 
 struct nsStyleMargin
 {
-  nsStyleMargin(void);
+  explicit nsStyleMargin(StyleStructContext aContext);
   nsStyleMargin(const nsStyleMargin& aMargin);
   ~nsStyleMargin(void) {
     MOZ_COUNT_DTOR(nsStyleMargin);
   }
 
   void* operator new(size_t sz, nsStyleMargin* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
@@ -812,17 +813,17 @@ struct nsStyleMargin
 protected:
   bool          mHasCachedMargin;
   nsMargin      mCachedMargin;
 };
 
 
 struct nsStylePadding
 {
-  nsStylePadding(void);
+  explicit nsStylePadding(StyleStructContext aContext);
   nsStylePadding(const nsStylePadding& aPadding);
   ~nsStylePadding(void) {
     MOZ_COUNT_DTOR(nsStylePadding);
   }
 
   void* operator new(size_t sz, nsStylePadding* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
@@ -1015,17 +1016,17 @@ private:
 static bool IsVisibleBorderStyle(uint8_t aStyle)
 {
   return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
           aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
 }
 
 struct nsStyleBorder
 {
-  explicit nsStyleBorder(nsPresContext* aContext);
+  explicit nsStyleBorder(StyleStructContext aContext);
   nsStyleBorder(const nsStyleBorder& aBorder);
   ~nsStyleBorder();
 
   void* operator new(size_t sz, nsStyleBorder* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleBorder, sz);
   }
@@ -1243,17 +1244,17 @@ private:
   nscoord       mTwipsPerPixel;
 
   nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete;
 };
 
 
 struct nsStyleOutline
 {
-  explicit nsStyleOutline(nsPresContext* aPresContext);
+  explicit nsStyleOutline(StyleStructContext aContext);
   nsStyleOutline(const nsStyleOutline& aOutline);
   ~nsStyleOutline(void) {
     MOZ_COUNT_DTOR(nsStyleOutline);
   }
 
   void* operator new(size_t sz, nsStyleOutline* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
@@ -1343,17 +1344,17 @@ protected:
   uint8_t       mOutlineStyle;    // [reset] See nsStyleConsts.h
 
   nscoord       mTwipsPerPixel;
 };
 
 
 struct nsStyleList
 {
-  explicit nsStyleList(nsPresContext* aPresContext);
+  explicit nsStyleList(StyleStructContext aContext);
   nsStyleList(const nsStyleList& aStyleList);
   ~nsStyleList(void);
 
   void* operator new(size_t sz, nsStyleList* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleList, sz);
   }
@@ -1551,17 +1552,17 @@ struct nsStyleGridTemplate
   bool IsRepeatAutoIndex(uint32_t aIndex) const {
     MOZ_ASSERT(aIndex < uint32_t(2*nsStyleGridLine::kMaxLine));
     return int32_t(aIndex) == mRepeatAutoIndex;
   }
 };
 
 struct nsStylePosition
 {
-  nsStylePosition(void);
+  explicit nsStylePosition(StyleStructContext aContext);
   nsStylePosition(const nsStylePosition& aOther);
   ~nsStylePosition(void);
 
   void* operator new(size_t sz, nsStylePosition* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStylePosition, sz);
   }
@@ -1802,17 +1803,17 @@ struct nsStyleTextOverflow
 
   nsStyleTextOverflowSide mLeft;  // start side when mLogicalDirections is true
   nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
   bool mLogicalDirections;  // true when only one value was specified
 };
 
 struct nsStyleTextReset
 {
-  nsStyleTextReset(void);
+  explicit nsStyleTextReset(StyleStructContext aContext);
   nsStyleTextReset(const nsStyleTextReset& aOther);
   ~nsStyleTextReset(void);
 
   void* operator new(size_t sz, nsStyleTextReset* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleTextReset, sz);
   }
@@ -1888,17 +1889,17 @@ struct nsStyleTextReset
 protected:
   uint8_t mTextDecorationStyle;         // [reset] see nsStyleConsts.h
 
   nscolor mTextDecorationColor;         // [reset] the colors to use for a decoration lines, not used at currentColor
 };
 
 struct nsStyleText
 {
-  explicit nsStyleText(nsPresContext* aPresContext);
+  explicit nsStyleText(StyleStructContext aContext);
   nsStyleText(const nsStyleText& aOther);
   ~nsStyleText(void);
 
   void* operator new(size_t sz, nsStyleText* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleText, sz);
   }
@@ -2097,17 +2098,17 @@ protected:
     : mOrientation(aOrientation)
   { }
 
   uint8_t mOrientation;
 };
 
 struct nsStyleVisibility
 {
-  explicit nsStyleVisibility(nsPresContext* aPresContext);
+  explicit nsStyleVisibility(StyleStructContext aContext);
   nsStyleVisibility(const nsStyleVisibility& aVisibility);
   ~nsStyleVisibility() {
     MOZ_COUNT_DTOR(nsStyleVisibility);
   }
 
   void* operator new(size_t sz, nsStyleVisibility* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
@@ -2380,17 +2381,17 @@ private:
   uint8_t mPlayState;
   float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
 };
 
 } // namespace mozilla
 
 struct nsStyleDisplay
 {
-  nsStyleDisplay();
+  explicit nsStyleDisplay(StyleStructContext aContext);
   nsStyleDisplay(const nsStyleDisplay& aOther);
   ~nsStyleDisplay() {
     MOZ_COUNT_DTOR(nsStyleDisplay);
   }
 
   void* operator new(size_t sz, nsStyleDisplay* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
@@ -2656,17 +2657,17 @@ struct nsStyleDisplay
   // resolved to {left,right} according to the given writing mode. These are
   // defined in WritingModes.h.
   inline uint8_t PhysicalFloats(mozilla::WritingMode aWM) const;
   inline uint8_t PhysicalBreakType(mozilla::WritingMode aWM) const;
 };
 
 struct nsStyleTable
 {
-  nsStyleTable(void);
+  explicit nsStyleTable(StyleStructContext aContext);
   nsStyleTable(const nsStyleTable& aOther);
   ~nsStyleTable(void);
 
   void* operator new(size_t sz, nsStyleTable* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleTable, sz);
   }
@@ -2689,17 +2690,17 @@ struct nsStyleTable
   }
 
   uint8_t       mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_*
   int32_t       mSpan;          // [reset] the number of columns spanned by a colgroup or col
 };
 
 struct nsStyleTableBorder
 {
-  nsStyleTableBorder();
+  explicit nsStyleTableBorder(StyleStructContext aContext);
   nsStyleTableBorder(const nsStyleTableBorder& aOther);
   ~nsStyleTableBorder(void);
 
   void* operator new(size_t sz, nsStyleTableBorder* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleTableBorder, sz);
   }
@@ -2789,17 +2790,17 @@ struct nsStyleCounterData
   int32_t   mValue;
 };
 
 
 #define DELETE_ARRAY_IF(array)  if (array) { delete[] array; array = nullptr; }
 
 struct nsStyleQuotes
 {
-  nsStyleQuotes();
+  explicit nsStyleQuotes(StyleStructContext aContext);
   nsStyleQuotes(const nsStyleQuotes& aQuotes);
   ~nsStyleQuotes();
 
   void* operator new(size_t sz, nsStyleQuotes* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleQuotes, sz);
   }
@@ -2873,17 +2874,17 @@ struct nsStyleQuotes
 
 protected:
   uint32_t            mQuotesCount;
   nsString*           mQuotes;
 };
 
 struct nsStyleContent
 {
-  nsStyleContent(void);
+  explicit nsStyleContent(StyleStructContext aContext);
   nsStyleContent(const nsStyleContent& aContent);
   ~nsStyleContent(void);
 
   void* operator new(size_t sz, nsStyleContent* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleContent, sz);
   }
@@ -2984,17 +2985,17 @@ protected:
 
   uint32_t            mContentCount;
   uint32_t            mIncrementCount;
   uint32_t            mResetCount;
 };
 
 struct nsStyleUIReset
 {
-  nsStyleUIReset(void);
+  explicit nsStyleUIReset(StyleStructContext aContext);
   nsStyleUIReset(const nsStyleUIReset& aOther);
   ~nsStyleUIReset(void);
 
   void* operator new(size_t sz, nsStyleUIReset* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleUIReset, sz);
   }
@@ -3050,17 +3051,17 @@ struct nsCursorImage
   }
 
 private:
   nsCOMPtr<imgIRequest> mImage;
 };
 
 struct nsStyleUserInterface
 {
-  nsStyleUserInterface(void);
+  explicit nsStyleUserInterface(StyleStructContext aContext);
   nsStyleUserInterface(const nsStyleUserInterface& aOther);
   ~nsStyleUserInterface(void);
 
   void* operator new(size_t sz, nsStyleUserInterface* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleUserInterface, sz);
   }
@@ -3098,17 +3099,17 @@ struct nsStyleUserInterface
 
   // Does not free mCursorArray; the caller is responsible for calling
   // |delete [] mCursorArray| first if it is needed.
   void CopyCursorArrayFrom(const nsStyleUserInterface& aSource);
 };
 
 struct nsStyleXUL
 {
-  nsStyleXUL();
+  explicit nsStyleXUL(StyleStructContext aContext);
   nsStyleXUL(const nsStyleXUL& aSource);
   ~nsStyleXUL();
 
   void* operator new(size_t sz, nsStyleXUL* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleXUL, sz);
   }
@@ -3136,17 +3137,17 @@ struct nsStyleXUL
   uint8_t       mBoxDirection;          // [reset] see nsStyleConsts.h
   uint8_t       mBoxOrient;             // [reset] see nsStyleConsts.h
   uint8_t       mBoxPack;               // [reset] see nsStyleConsts.h
   bool          mStretchStack;          // [reset] see nsStyleConsts.h
 };
 
 struct nsStyleColumn
 {
-  explicit nsStyleColumn(nsPresContext* aPresContext);
+  explicit nsStyleColumn(StyleStructContext aContext);
   nsStyleColumn(const nsStyleColumn& aSource);
   ~nsStyleColumn();
 
   void* operator new(size_t sz, nsStyleColumn* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleColumn, sz);
   }
@@ -3231,17 +3232,17 @@ struct nsStyleSVGPaint
 
   bool operator!=(const nsStyleSVGPaint& aOther) const {
     return !(*this == aOther);
   }
 };
 
 struct nsStyleSVG
 {
-  nsStyleSVG();
+  explicit nsStyleSVG(StyleStructContext aContext);
   nsStyleSVG(const nsStyleSVG& aSource);
   ~nsStyleSVG();
 
   void* operator new(size_t sz, nsStyleSVG* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleSVG, sz);
   }
@@ -3519,17 +3520,17 @@ private:
 template<>
 struct nsTArray_CopyChooser<nsStyleFilter>
 {
   typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
 };
 
 struct nsStyleSVGReset
 {
-  nsStyleSVGReset();
+  explicit nsStyleSVGReset(StyleStructContext aContext);
   nsStyleSVGReset(const nsStyleSVGReset& aSource);
   ~nsStyleSVGReset();
 
   void* operator new(size_t sz, nsStyleSVGReset* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleSVGReset, sz);
   }
@@ -3575,17 +3576,17 @@ struct nsStyleSVGReset
 
   uint8_t          mDominantBaseline; // [reset] see nsStyleConsts.h
   uint8_t          mVectorEffect;     // [reset] see nsStyleConsts.h
   uint8_t          mMaskType;         // [reset] see nsStyleConsts.h
 };
 
 struct nsStyleVariables
 {
-  nsStyleVariables();
+  explicit nsStyleVariables(StyleStructContext aContext);
   nsStyleVariables(const nsStyleVariables& aSource);
   ~nsStyleVariables();
 
   void* operator new(size_t sz, nsStyleVariables* aSelf) CPP_THROW_NEW { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleVariables, sz);
   }