Bug 1309752 - Part 1: Take out a method which returns physical property from logical property, to use from other places. r?heycam draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Mon, 24 Apr 2017 17:40:23 +0900
changeset 568588 8dce28f98fc3da25b6d73acde4f65fb90e9e7d81
parent 565531 20dff607fb88ee69135a280bbb7f32df75a86237
child 568589 26bae8982d640850a51ab0f6f44347cede67a3e9
push id55908
push userbmo:dakatsuka@mozilla.com
push dateWed, 26 Apr 2017 09:58:37 +0000
reviewersheycam
bugs1309752
milestone55.0a1
Bug 1309752 - Part 1: Take out a method which returns physical property from logical property, to use from other places. r?heycam We should make logical property to animate. In order to this, we should know the physical property of the logical property. There is a mechanism which converts logical property to physical property in nsCSSDataBlock. However the method is private and do more things. Therefor, take out the method, to use from other classes such a KeyframeEffectReadOnly. MozReview-Commit-ID: iVAfkmHqBq
layout/generic/WritingModes.h
layout/style/nsCSSDataBlock.cpp
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
--- a/layout/generic/WritingModes.h
+++ b/layout/generic/WritingModes.h
@@ -294,17 +294,17 @@ public:
     // orientation and bit 0 of a LogicalAxis value indicating the inline axis,
     // so that it can correctly form mozilla::PhysicalAxis values using bit
     // manipulation.
     static_assert(NS_STYLE_WRITING_MODE_HORIZONTAL_TB == 0 &&
                   NS_STYLE_WRITING_MODE_VERTICAL_RL == 1 &&
                   NS_STYLE_WRITING_MODE_VERTICAL_LR == 3 &&
                   eLogicalAxisBlock == 0 &&
                   eLogicalAxisInline == 1 &&
-                  eAxisVertical == 0 && 
+                  eAxisVertical == 0 &&
                   eAxisHorizontal == 1,
                   "unexpected writing-mode, logical axis or physical axis "
                   "constant values");
     return mozilla::PhysicalAxis((aWritingModeValue ^ aAxis) & 0x1);
   }
 
   mozilla::PhysicalAxis PhysicalAxis(LogicalAxis aAxis) const
   {
@@ -336,16 +336,28 @@ public:
     aWritingModeValue &= ~NS_STYLE_WRITING_MODE_SIDEWAYS_MASK;
 
     // What's left of the writing-mode should be in the range 0-3:
     NS_ASSERTION(aWritingModeValue < 4, "invalid aWritingModeValue value");
 
     return kLogicalBlockSides[aWritingModeValue][aEdge];
   }
 
+  static mozilla::Side PhysicalSideForInlineAxis(uint8_t aWritingModeValue,
+                                                 uint8_t aTextOrientation,
+                                                 uint8_t aDirection,
+                                                 LogicalEdge aEdge)
+  {
+    uint8_t writingMode = WritingModeFromStyles(aWritingModeValue,
+                                                aTextOrientation,
+                                                aDirection);
+    WritingMode wm(writingMode);
+    return wm.PhysicalSideForInlineAxis(aEdge);
+  }
+
   mozilla::Side PhysicalSideForInlineAxis(LogicalEdge aEdge) const
   {
     // indexes are four-bit values:
     //   bit 0 = the eOrientationMask value
     //   bit 1 = the eInlineFlowMask value
     //   bit 2 = the eBlockFlowMask value
     //   bit 3 = the eLineOrientMask value
     // Not all of these combinations can actually be specified via CSS: there
@@ -490,64 +502,75 @@ public:
   {
     NS_ASSERTION(aStyleVisibility, "we need an nsStyleVisibility here");
     InitFromStyleVisibility(aStyleVisibility);
   }
 
 private:
   void InitFromStyleVisibility(const nsStyleVisibility* aStyleVisibility)
   {
-    switch (aStyleVisibility->mWritingMode) {
+    mWritingMode = WritingModeFromStyles(aStyleVisibility->mWritingMode,
+                                         aStyleVisibility->mTextOrientation,
+                                         aStyleVisibility->mDirection);
+  }
+
+  static uint8_t WritingModeFromStyles(uint8_t aWritingMode,
+                                       uint8_t aTextOrientation,
+                                       uint8_t aDirection)
+  {
+    switch (aWritingMode) {
       case NS_STYLE_WRITING_MODE_HORIZONTAL_TB:
-        mWritingMode = 0;
+        aWritingMode = 0;
         break;
 
       case NS_STYLE_WRITING_MODE_VERTICAL_LR:
       {
-        mWritingMode = eBlockFlowMask |
+        aWritingMode = eBlockFlowMask |
                        eLineOrientMask |
                        eOrientationMask;
-        uint8_t textOrientation = aStyleVisibility->mTextOrientation;
+        uint8_t textOrientation = aTextOrientation;
         if (textOrientation == NS_STYLE_TEXT_ORIENTATION_SIDEWAYS) {
-          mWritingMode |= eSidewaysMask;
+          aWritingMode |= eSidewaysMask;
         }
         break;
       }
 
       case NS_STYLE_WRITING_MODE_VERTICAL_RL:
       {
-        mWritingMode = eOrientationMask;
-        uint8_t textOrientation = aStyleVisibility->mTextOrientation;
+        aWritingMode = eOrientationMask;
+        uint8_t textOrientation = aTextOrientation;
         if (textOrientation == NS_STYLE_TEXT_ORIENTATION_SIDEWAYS) {
-          mWritingMode |= eSidewaysMask;
+          aWritingMode |= eSidewaysMask;
         }
         break;
       }
 
       case NS_STYLE_WRITING_MODE_SIDEWAYS_LR:
-        mWritingMode = eBlockFlowMask |
+        aWritingMode = eBlockFlowMask |
                        eInlineFlowMask |
                        eOrientationMask |
                        eSidewaysMask;
         break;
 
       case NS_STYLE_WRITING_MODE_SIDEWAYS_RL:
-        mWritingMode = eOrientationMask |
+        aWritingMode = eOrientationMask |
                        eSidewaysMask;
         break;
 
       default:
         NS_NOTREACHED("unknown writing mode!");
-        mWritingMode = 0;
+        aWritingMode = 0;
         break;
     }
 
-    if (NS_STYLE_DIRECTION_RTL == aStyleVisibility->mDirection) {
-      mWritingMode ^= eInlineFlowMask | eBidiMask;
+    if (NS_STYLE_DIRECTION_RTL == aDirection) {
+      aWritingMode ^= eInlineFlowMask | eBidiMask;
     }
+
+    return aWritingMode;
   }
 public:
 
   /**
    * This function performs fixup for elements with 'unicode-bidi: plaintext',
    * where inline directionality is derived from the Unicode bidi categories
    * of the element's content, and not the CSS 'direction' property.
    *
@@ -1498,17 +1521,17 @@ public:
       mWritingMode(aWritingMode),
 #endif
       mRect(aIStart, aBStart, aISize, aBSize)
   { }
 
   LogicalRect(WritingMode aWritingMode,
               const LogicalPoint& aOrigin,
               const LogicalSize& aSize)
-    : 
+    :
 #ifdef DEBUG
       mWritingMode(aWritingMode),
 #endif
       mRect(aOrigin.mPoint, aSize.mSize)
   {
     CHECK_WRITING_MODE(aOrigin.GetWritingMode());
     CHECK_WRITING_MODE(aSize.GetWritingMode());
   }
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -10,17 +10,16 @@
  */
 
 #include "nsCSSDataBlock.h"
 
 #include "CSSVariableImageTable.h"
 #include "mozilla/css/Declaration.h"
 #include "mozilla/css/ImageLoader.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/WritingModes.h"
 #include "nsAutoPtr.h"
 #include "nsIDocument.h"
 #include "nsRuleData.h"
 #include "nsStyleContext.h"
 #include "nsStyleSet.h"
 
 using namespace mozilla;
 using namespace mozilla::css;
@@ -209,62 +208,26 @@ MapSinglePropertyInto(nsCSSPropertyID aT
 /**
  * If aProperty is a logical property, converts it to the equivalent physical
  * property based on writing mode information obtained from aRuleData's
  * style context.
  */
 static inline void
 EnsurePhysicalProperty(nsCSSPropertyID& aProperty, nsRuleData* aRuleData)
 {
-  bool isAxisProperty =
-    nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_AXIS);
-  bool isBlock =
-    nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_BLOCK_AXIS);
-
-  int index;
-
-  if (isAxisProperty) {
-    LogicalAxis logicalAxis = isBlock ? eLogicalAxisBlock : eLogicalAxisInline;
-    uint8_t wm = aRuleData->mStyleContext->StyleVisibility()->mWritingMode;
-    PhysicalAxis axis =
-      WritingMode::PhysicalAxisForLogicalAxis(wm, logicalAxis);
-
-    // We rely on physical axis constants values matching the order of the
-    // physical properties in the logical group array.
-    static_assert(eAxisVertical == 0 && eAxisHorizontal == 1,
-                  "unexpected axis constant values");
-    index = axis;
-  } else {
-    bool isEnd =
-      nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_END_EDGE);
-
-    LogicalEdge edge = isEnd ? eLogicalEdgeEnd : eLogicalEdgeStart;
-
-    // We handle block axis logical properties separately to save a bit of
-    // work that the WritingMode constructor does that is unnecessary
-    // unless we have an inline axis property.
-    mozilla::Side side;
-    if (isBlock) {
-      uint8_t wm = aRuleData->mStyleContext->StyleVisibility()->mWritingMode;
-      side = WritingMode::PhysicalSideForBlockAxis(wm, edge);
-    } else {
-      WritingMode wm(aRuleData->mStyleContext);
-      side = wm.PhysicalSideForInlineAxis(edge);
-    }
-
-    // We rely on the physical side constant values matching the order of
-    // the physical properties in the logical group array.
-    static_assert(eSideTop == 0 && eSideRight == 1 &&
-                  eSideBottom == 2 && eSideLeft == 3,
-                  "unexpected side constant values");
-    index = side;
-  }
+  nsCSSPropertyID physicalID =
+    nsCSSProps::PhysicalProperty(
+     aProperty,
+     aRuleData->mStyleContext->StyleVisibility()->mWritingMode,
+     aRuleData->mStyleContext->StyleVisibility()->mTextOrientation,
+     aRuleData->mStyleContext->StyleVisibility()->mDirection);
 
   const nsCSSPropertyID* props = nsCSSProps::LogicalGroup(aProperty);
-  size_t len = isAxisProperty ? 2 : 4;
+  size_t len =
+    nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_AXIS) ? 2 : 4;
 #ifdef DEBUG
     for (size_t i = 0; i < len; i++) {
     MOZ_ASSERT(props[i] != eCSSProperty_UNKNOWN,
                "unexpected logical group length");
   }
   MOZ_ASSERT(props[len] == eCSSProperty_UNKNOWN,
              "unexpected logical group length");
 #endif
@@ -290,17 +253,17 @@ EnsurePhysicalProperty(nsCSSPropertyID& 
       // data cached in the rule tree could be used with a style context
       // with a different value of the depended-upon data.
       uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
       aRuleData->mConditions.SetWritingModeDependency(wm);
       break;
     }
   }
 
-  aProperty = props[index];
+  aProperty = physicalID;
 }
 
 void
 nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
 {
   // If we have no data for these structs, then return immediately.
   // This optimization should make us return most of the time, so we
   // have to worry much less (although still some) about the speed of
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -21,16 +21,18 @@
 #include "mozilla/dom/AnimationEffectReadOnlyBinding.h" // for PlaybackDirection
 #include "mozilla/LookAndFeel.h" // for system colors
 
 #include "nsString.h"
 #include "nsStaticNameTable.h"
 
 #include "mozilla/Preferences.h"
 
+#include "mozilla/WritingModes.h"
+
 using namespace mozilla;
 
 typedef nsCSSProps::KTableEntry KTableEntry;
 
 // By wrapping internal-only properties in this macro, we are not
 // exposing them in the CSSOM. Since currently it is not necessary to
 // allow accessing them in that way, it is easier and cheaper to just
 // do this rather than exposing them conditionally.
@@ -3129,18 +3131,76 @@ nsCSSProps::LogicalGroup(nsCSSPropertyID
       return kLogicalGroupTable[gLogicalGroupMappingTable[i + 1]];
     }
   }
 
   MOZ_ASSERT(false, "missing gLogicalGroupMappingTable entry");
   return nullptr;
 }
 
-
-#define ENUM_DATA_FOR_PROPERTY(name_, id_, method_, flags_, pref_,          \
+/* static */ nsCSSPropertyID
+nsCSSProps::PhysicalProperty(const nsCSSPropertyID aProperty,
+                             const uint8_t aWritingModeValue,
+                             const uint8_t aTextOrientation,
+                             const uint8_t aDirection)
+{
+  MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands,
+             "out of range");
+  MOZ_ASSERT(nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL),
+             "aProperty must be a logical longhand property");
+
+  bool isAxisProperty =
+    nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_AXIS);
+  bool isBlock =
+    nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_BLOCK_AXIS);
+
+  int index;
+
+  if (isAxisProperty) {
+    LogicalAxis logicalAxis = isBlock ? eLogicalAxisBlock : eLogicalAxisInline;
+    PhysicalAxis axis =
+      WritingMode::PhysicalAxisForLogicalAxis(aWritingModeValue, logicalAxis);
+
+    // We rely on physical axis constants values matching the order of the
+    // physical properties in the logical group array.
+    static_assert(eAxisVertical == 0 && eAxisHorizontal == 1,
+                  "unexpected axis constant values");
+    index = axis;
+  } else {
+    bool isEnd =
+      nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_END_EDGE);
+
+    LogicalEdge edge = isEnd ? eLogicalEdgeEnd : eLogicalEdgeStart;
+
+    // We handle block axis logical properties separately to save a bit of
+    // work that the WritingMode constructor does that is unnecessary
+    // unless we have an inline axis property.
+    mozilla::Side side = isBlock
+      ? WritingMode::PhysicalSideForBlockAxis(aWritingModeValue, edge)
+      : WritingMode::PhysicalSideForInlineAxis(aWritingModeValue,
+                                               aTextOrientation,
+                                               aDirection,
+                                               edge);
+
+    // We rely on the physical side constant values matching the order of
+    // the physical properties in the logical group array.
+    static_assert(eSideTop == 0 && eSideRight == 1 &&
+                  eSideBottom == 2 && eSideLeft == 3,
+                  "unexpected side constant values");
+    index = side;
+  }
+
+  const nsCSSPropertyID* props = nsCSSProps::LogicalGroup(aProperty);
+  MOZ_ASSERT(props[index] != eCSSProperty_UNKNOWN,
+             "Corresponded physical property could not find");
+
+  return props[index];
+}
+
+#define ENUM_DATA_FOR_PROPERTY(name_, id_, method_, flags_, pref_,      \
                                parsevariant_, kwtable_, stylestructoffset_, \
                                animtype_)                                   \
   ePropertyIndex_for_##id_,
 
 // The order of these enums must match the g*Flags arrays in nsRuleNode.cpp.
 
 enum FontCheckCounter {
   #define CSS_PROP_FONT ENUM_DATA_FOR_PROPERTY
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -585,16 +585,24 @@ public:
    *
    * (Note that the running time of this function is proportional to the
    * number of logical longhand properties that exist.  If we start
    * getting too many of these properties, we should make kLogicalGroupTable
    * be a simple array of eCSSProperty_COUNT length.)
    */
   static const nsCSSPropertyID* LogicalGroup(nsCSSPropertyID aProperty);
 
+  /**
+   * Returns a physical longhand property from given parameters.
+   */
+  static nsCSSPropertyID PhysicalProperty(const nsCSSPropertyID aProperty,
+                                          const uint8_t aWritingModeValue,
+                                          const uint8_t aTextOrientation,
+                                          const uint8_t aDirection);
+
 private:
   static bool gPropertyEnabled[eCSSProperty_COUNT_with_aliases];
 
 private:
   // Defined in the generated nsCSSPropsGenerated.inc.
   static const char* const kIDLNameTable[eCSSProperty_COUNT];
 
 public:
@@ -753,17 +761,17 @@ public:
   // Not const because we modify its entries when the pref
   // "layout.css.float-logical-values.enabled" changes:
   static KTableEntry kClearKTable[];
   static const KTableEntry kColorKTable[];
   static const KTableEntry kContentKTable[];
   static const KTableEntry kControlCharacterVisibilityKTable[];
   static const KTableEntry kCursorKTable[];
   static const KTableEntry kDirectionKTable[];
-  // Not const because we modify its entries when various 
+  // Not const because we modify its entries when various
   // "layout.css.*.enabled" prefs changes:
   static KTableEntry kDisplayKTable[];
   static const KTableEntry kElevationKTable[];
   static const KTableEntry kEmptyCellsKTable[];
   // -- tables for parsing the {align,justify}-{content,items,self} properties --
   static const KTableEntry kAlignAllKeywords[];
   static const KTableEntry kAlignOverflowPosition[]; // <overflow-position>
   static const KTableEntry kAlignSelfPosition[];     // <self-position>