Bug 1561738 - Stop using nsStyleSides for -moz-image-rect. r=boris
☠☠ backed out by df2c3d2f218e ☠ ☠
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 28 Jun 2019 09:46:17 +0000
changeset 543340 9ed20d0fb9bafca54f7a935ee656c21ef4023199
parent 543339 483b1e134ace636bd745403be2017a1b3cd18993
child 543341 98f100abc2ba9226fabcddda36647f32fd4cae23
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersboris
bugs1561738
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1561738 - Stop using nsStyleSides for -moz-image-rect. r=boris Differential Revision: https://phabricator.services.mozilla.com/D36119
layout/style/GeckoBindings.cpp
layout/style/ServoBindings.toml
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
servo/components/style/gecko/conversions.rs
--- a/layout/style/GeckoBindings.cpp
+++ b/layout/style/GeckoBindings.cpp
@@ -1165,17 +1165,17 @@ void Gecko_CopyImageValueFrom(nsStyleIma
   MOZ_ASSERT(aImage);
   MOZ_ASSERT(aOther);
 
   *aImage = *aOther;
 }
 
 void Gecko_InitializeImageCropRect(nsStyleImage* aImage) {
   MOZ_ASSERT(aImage);
-  aImage->SetCropRect(MakeUnique<nsStyleSides>());
+  aImage->SetCropRect(MakeUnique<nsStyleImage::CropRect>());
 }
 
 void Gecko_SetCursorArrayLength(nsStyleUI* aStyleUI, size_t aLen) {
   aStyleUI->mCursorImages.Clear();
   aStyleUI->mCursorImages.SetLength(aLen);
 }
 
 void Gecko_SetCursorImageValue(nsCursorImage* aCursor,
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -513,16 +513,17 @@ cbindgen-types = [
     { gecko = "StyleLoadData", servo = "gecko::url::LoadData" },
     { gecko = "StyleGenericFilter", servo = "values::generics::effects::Filter" },
     { gecko = "StyleGenericGradient", servo = "values::generics::image::Gradient" },
     { gecko = "StyleLineDirection", servo = "values::computed::image::LineDirection" },
     { gecko = "StyleGridTemplateAreas", servo = "values::computed::position::GridTemplateAreas" },
     { gecko = "StyleGenericGridLine", servo = "values::generics::grid::GridLine" },
     { gecko = "StyleGenericTrackSize", servo = "values::generics::grid::TrackSize" },
     { gecko = "StyleGenericTrackBreadth", servo = "values::generics::grid::TrackBreadth" },
+    { gecko = "StyleNumberOrPercentage", servo = "values::computed::NumberOrPercentage" },
 ]
 
 mapped-generic-types = [
     { generic = true, gecko = "mozilla::RustCell", servo = "::std::cell::Cell" },
     { generic = false, gecko = "ServoNodeData", servo = "AtomicRefCell<ElementData>" },
     { generic = false, gecko = "mozilla::ServoWritingMode", servo = "::logical_geometry::WritingMode" },
     { generic = false, gecko = "mozilla::ServoCustomPropertiesMap", servo = "Option<::servo_arc::Arc<::custom_properties::CustomPropertiesMap>>" },
     { generic = false, gecko = "mozilla::ServoRuleNode", servo = "Option<::rule_tree::StrongRuleNode>" },
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1901,19 +1901,19 @@ void nsStyleImage::DoCopy(const nsStyleI
   if (aOther.mType == eStyleImageType_Image) {
     SetImageRequest(do_AddRef(aOther.mImage));
   } else if (aOther.mType == eStyleImageType_Gradient) {
     SetGradientData(MakeUnique<StyleGradient>(*aOther.mGradient));
   } else if (aOther.mType == eStyleImageType_Element) {
     SetElementId(do_AddRef(aOther.mElementId));
   }
 
-  UniquePtr<nsStyleSides> cropRectCopy;
+  UniquePtr<CropRect> cropRectCopy;
   if (aOther.mCropRect) {
-    cropRectCopy = MakeUnique<nsStyleSides>(*aOther.mCropRect.get());
+    cropRectCopy = MakeUnique<CropRect>(*aOther.mCropRect.get());
   }
   SetCropRect(std::move(cropRectCopy));
 }
 
 void nsStyleImage::SetNull() {
   if (mType == eStyleImageType_Gradient) {
     delete mGradient;
     mGradient = nullptr;
@@ -1961,33 +1961,28 @@ void nsStyleImage::SetElementId(already_
   }
 
   if (RefPtr<nsAtom> atom = aElementId) {
     mElementId = atom.forget().take();
     mType = eStyleImageType_Element;
   }
 }
 
-void nsStyleImage::SetCropRect(UniquePtr<nsStyleSides> aCropRect) {
+void nsStyleImage::SetCropRect(UniquePtr<CropRect> aCropRect) {
   mCropRect = std::move(aCropRect);
 }
 
-static int32_t ConvertToPixelCoord(const nsStyleCoord& aCoord,
+static int32_t ConvertToPixelCoord(const StyleNumberOrPercentage& aCoord,
                                    int32_t aPercentScale) {
   double pixelValue;
-  switch (aCoord.GetUnit()) {
-    case eStyleUnit_Percent:
-      pixelValue = aCoord.GetPercentValue() * aPercentScale;
-      break;
-    case eStyleUnit_Factor:
-      pixelValue = aCoord.GetFactorValue();
-      break;
-    default:
-      MOZ_ASSERT_UNREACHABLE("unexpected unit for image crop rect");
-      return 0;
+  if (aCoord.IsNumber()) {
+    pixelValue = aCoord.AsNumber();
+  } else {
+    MOZ_ASSERT(aCoord.IsPercentage());
+    pixelValue = aCoord.AsPercentage()._0 * aPercentScale;
   }
   MOZ_ASSERT(pixelValue >= 0, "we ensured non-negative while parsing");
   pixelValue = std::min(pixelValue, double(INT32_MAX));  // avoid overflow
   return NS_lround(pixelValue);
 }
 
 already_AddRefed<nsIURI> nsStyleImageRequest::GetImageURI() const {
   nsCOMPtr<nsIURI> uri;
@@ -2024,21 +2019,23 @@ bool nsStyleImage::ComputeActualCropRect
 
   nsIntSize imageSize;
   imageContainer->GetWidth(&imageSize.width);
   imageContainer->GetHeight(&imageSize.height);
   if (imageSize.width <= 0 || imageSize.height <= 0) {
     return false;
   }
 
-  int32_t left = ConvertToPixelCoord(mCropRect->GetLeft(), imageSize.width);
-  int32_t top = ConvertToPixelCoord(mCropRect->GetTop(), imageSize.height);
-  int32_t right = ConvertToPixelCoord(mCropRect->GetRight(), imageSize.width);
+  int32_t left =
+      ConvertToPixelCoord(mCropRect->Get(eSideLeft), imageSize.width);
+  int32_t top = ConvertToPixelCoord(mCropRect->Get(eSideTop), imageSize.height);
+  int32_t right =
+      ConvertToPixelCoord(mCropRect->Get(eSideRight), imageSize.width);
   int32_t bottom =
-      ConvertToPixelCoord(mCropRect->GetBottom(), imageSize.height);
+      ConvertToPixelCoord(mCropRect->Get(eSideBottom), imageSize.height);
 
   // IntersectRect() returns an empty rect if we get negative width or height
   nsIntRect cropRect(left, top, right - left, bottom - top);
   nsIntRect imageRect(nsIntPoint(0, 0), imageSize);
   aActualCropRect.IntersectRect(imageRect, cropRect);
 
   if (aIsEntireImage) {
     *aIsEntireImage = aActualCropRect.IsEqualInterior(imageRect);
@@ -2138,28 +2135,28 @@ bool nsStyleImage::IsLoaded() const {
              (status & imgIRequest::STATUS_LOAD_COMPLETE);
     }
     default:
       MOZ_ASSERT_UNREACHABLE("unexpected image type");
       return false;
   }
 }
 
-static inline bool EqualRects(const UniquePtr<nsStyleSides>& aRect1,
-                              const UniquePtr<nsStyleSides>& aRect2) {
+static inline bool EqualRects(const nsStyleImage::CropRect* aRect1,
+                              const nsStyleImage::CropRect* aRect2) {
   return aRect1 == aRect2 || /* handles null== null, and optimize */
          (aRect1 && aRect2 && *aRect1 == *aRect2);
 }
 
 bool nsStyleImage::operator==(const nsStyleImage& aOther) const {
   if (mType != aOther.mType) {
     return false;
   }
 
-  if (!EqualRects(mCropRect, aOther.mCropRect)) {
+  if (!EqualRects(mCropRect.get(), aOther.mCropRect.get())) {
     return false;
   }
 
   if (mType == eStyleImageType_Image) {
     return DefinitelyEqualImages(mImage, aOther.mImage);
   }
 
   if (mType == eStyleImageType_Gradient) {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -252,26 +252,28 @@ struct CachedBorderImageData {
  * (2) A CSS linear or radial gradient.
  * (3) An element within a document, or an <img>, <video>, or <canvas> element
  *     not in a document.
  * (*) Optionally a crop rect can be set to paint a partial (rectangular)
  * region of an image. (Currently, this feature is only supported with an
  * image of type (1)).
  */
 struct nsStyleImage {
+  using CropRect = mozilla::StyleRect<mozilla::StyleNumberOrPercentage>;
+
   nsStyleImage();
   ~nsStyleImage();
   nsStyleImage(const nsStyleImage& aOther);
   nsStyleImage& operator=(const nsStyleImage& aOther);
 
   void SetNull();
   void SetImageRequest(already_AddRefed<nsStyleImageRequest> aImage);
   void SetGradientData(mozilla::UniquePtr<mozilla::StyleGradient>);
   void SetElementId(already_AddRefed<nsAtom> aElementId);
-  void SetCropRect(mozilla::UniquePtr<nsStyleSides> aCropRect);
+  void SetCropRect(mozilla::UniquePtr<CropRect> aCropRect);
 
   void ResolveImage(mozilla::dom::Document& aDocument,
                     const nsStyleImage* aOldImage) {
     MOZ_ASSERT(mType != eStyleImageType_Image || mImage);
     if (mType == eStyleImageType_Image && !mImage->IsResolved()) {
       const nsStyleImageRequest* oldRequest =
           (aOldImage && aOldImage->GetType() == eStyleImageType_Image)
               ? aOldImage->ImageRequest()
@@ -293,20 +295,20 @@ struct nsStyleImage {
   }
   bool IsResolved() const {
     return mType != eStyleImageType_Image || ImageRequest()->IsResolved();
   }
   const nsAtom* GetElementId() const {
     NS_ASSERTION(mType == eStyleImageType_Element, "Data is not an element!");
     return mElementId;
   }
-  const mozilla::UniquePtr<nsStyleSides>& GetCropRect() const {
+  const CropRect* GetCropRect() const {
     NS_ASSERTION(mType == eStyleImageType_Image,
                  "Only image data can have a crop rect");
-    return mCropRect;
+    return mCropRect.get();
   }
 
   already_AddRefed<nsIURI> GetImageURI() const;
 
   const mozilla::StyleComputedImageUrl* GetURLValue() const;
 
   /**
    * Compute the actual crop rect in pixels, using the source image bounds.
@@ -389,17 +391,17 @@ struct nsStyleImage {
   nsStyleImageType mType;
   union {
     nsStyleImageRequest* mImage;
     mozilla::StyleGradient* mGradient;
     nsAtom* mElementId;
   };
 
   // This is _currently_ used only in conjunction with eStyleImageType_Image.
-  mozilla::UniquePtr<nsStyleSides> mCropRect;
+  mozilla::UniquePtr<CropRect> mCropRect;
 };
 
 struct nsStyleImageLayers {
   // Indices into kBackgroundLayerTable and kMaskLayerTable
   enum {
     shorthand = 0,
     color,
     image,
--- a/servo/components/style/gecko/conversions.rs
+++ b/servo/components/style/gecko/conversions.rs
@@ -64,28 +64,17 @@ impl nsStyleImage {
             },
             GenericImage::Rect(ref image_rect) => {
                 unsafe {
                     bindings::Gecko_SetLayerImageImageValue(self, &image_rect.url);
                     bindings::Gecko_InitializeImageCropRect(self);
 
                     // Set CropRect
                     let ref mut rect = *self.mCropRect.mPtr;
-                    image_rect
-                        .top
-                        .to_gecko_style_coord(&mut rect.data_at_mut(0));
-                    image_rect
-                        .right
-                        .to_gecko_style_coord(&mut rect.data_at_mut(1));
-                    image_rect
-                        .bottom
-                        .to_gecko_style_coord(&mut rect.data_at_mut(2));
-                    image_rect
-                        .left
-                        .to_gecko_style_coord(&mut rect.data_at_mut(3));
+                    *rect = Rect(image_rect.top, image_rect.right, image_rect.bottom, image_rect.left);
                 }
             },
             GenericImage::Element(ref element) => unsafe {
                 bindings::Gecko_SetImageElement(self, element.as_ptr());
             },
         }
     }
 
@@ -93,49 +82,33 @@ impl nsStyleImage {
         unsafe {
             bindings::Gecko_SetGradientImageValue(self, Box::into_raw(gradient));
         }
     }
 
     /// Converts into Image.
     pub unsafe fn into_image(self: &nsStyleImage) -> Option<Image> {
         use crate::gecko_bindings::structs::nsStyleImageType;
-        use crate::values::computed::{MozImageRect, NumberOrPercentage};
+        use crate::values::computed::MozImageRect;
 
         match self.mType {
             nsStyleImageType::eStyleImageType_Null => None,
             nsStyleImageType::eStyleImageType_Image => {
                 let url = self.get_image_url();
                 if self.mCropRect.mPtr.is_null() {
                     Some(GenericImage::Url(url))
                 } else {
-                    let ref rect = *self.mCropRect.mPtr;
-                    match (
-                        NumberOrPercentage::from_gecko_style_coord(&rect.data_at(0)),
-                        NumberOrPercentage::from_gecko_style_coord(&rect.data_at(1)),
-                        NumberOrPercentage::from_gecko_style_coord(&rect.data_at(2)),
-                        NumberOrPercentage::from_gecko_style_coord(&rect.data_at(3)),
-                    ) {
-                        (Some(top), Some(right), Some(bottom), Some(left)) => {
-                            Some(GenericImage::Rect(Box::new(MozImageRect {
-                                url,
-                                top,
-                                right,
-                                bottom,
-                                left,
-                            })))
-                        },
-                        _ => {
-                            debug_assert!(
-                                false,
-                                "mCropRect could not convert to NumberOrPercentage"
-                            );
-                            None
-                        },
-                    }
+                    let rect = &*self.mCropRect.mPtr;
+                    Some(GenericImage::Rect(Box::new(MozImageRect {
+                        url,
+                        top: rect.0,
+                        right: rect.1,
+                        bottom: rect.2,
+                        left: rect.3,
+                    })))
                 }
             },
             nsStyleImageType::eStyleImageType_Gradient => {
                 let gradient: &Gradient = &**self.__bindgen_anon_1.mGradient.as_ref();
                 Some(GenericImage::Gradient(Box::new(gradient.clone())))
             },
             nsStyleImageType::eStyleImageType_Element => {
                 use crate::gecko_string_cache::Atom;