Bug 1412179 - implement fieldsets with nonempty legends. r=kats
authorAlexis Beingessner <a.beingessner@gmail.com>
Mon, 15 Apr 2019 23:16:13 +0000
changeset 469586 693535165c9f
parent 469585 951d2c0a477d
child 469587 9feaaddc3761
push id35874
push userccoroiu@mozilla.com
push dateTue, 16 Apr 2019 04:04:58 +0000
treeherdermozilla-central@be3f40425b52 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1412179
milestone68.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 1412179 - implement fieldsets with nonempty legends. r=kats Differential Revision: https://phabricator.services.mozilla.com/D27350
gfx/webrender_bindings/WebRenderAPI.h
layout/forms/nsFieldSetFrame.cpp
layout/reftests/box-shadow/reftest.list
testing/web-platform/meta/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html.ini
testing/web-platform/meta/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html.ini
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -649,16 +649,24 @@ class MOZ_RAII SpaceAndClipChainHelper f
   SpaceAndClipChainHelper(DisplayListBuilder& aBuilder,
                           wr::WrSpatialId aSpatialId
                               MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
       : mBuilder(aBuilder),
         mOldSpaceAndClipChain(aBuilder.mCurrentSpaceAndClipChain) {
     aBuilder.mCurrentSpaceAndClipChain.space = aSpatialId;
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   }
+  SpaceAndClipChainHelper(DisplayListBuilder& aBuilder,
+                          wr::WrClipChainId aClipChainId
+                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+      : mBuilder(aBuilder),
+        mOldSpaceAndClipChain(aBuilder.mCurrentSpaceAndClipChain) {
+    aBuilder.mCurrentSpaceAndClipChain.clip_chain = aClipChainId.id;
+    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+  }
 
   ~SpaceAndClipChainHelper() {
     mBuilder.mCurrentSpaceAndClipChain = mOldSpaceAndClipChain;
   }
 
  private:
   SpaceAndClipChainHelper(const SpaceAndClipChainHelper&) = delete;
 
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -162,25 +162,46 @@ bool nsDisplayFieldSetBorder::CreateWebR
     mozilla::wr::DisplayListBuilder& aBuilder,
     mozilla::wr::IpcResourceUpdateQueue& aResources,
     const StackingContextHelper& aSc,
     mozilla::layers::RenderRootStateManager* aManager,
     nsDisplayListBuilder* aDisplayListBuilder) {
   auto frame = static_cast<nsFieldSetFrame*>(mFrame);
   auto offset = ToReferenceFrame();
   nsRect rect;
+  Maybe<wr::SpaceAndClipChainHelper> clipOut;
 
   if (nsIFrame* legend = frame->GetLegend()) {
     rect = frame->VisualBorderRectRelativeToSelf() + offset;
 
-    // Legends require a "negative" clip around the text, which WR doesn't
-    // support yet.
     nsRect legendRect = legend->GetNormalRect() + offset;
+
+    // Make sure we clip all of the border in case the legend is smaller.
+    nscoord borderTopWidth = frame->GetUsedBorder().top;
+    if (legendRect.height < borderTopWidth) {
+      legendRect.height = borderTopWidth;
+      legendRect.y = offset.y;
+    }
+
     if (!legendRect.IsEmpty()) {
-      return false;
+      // We need to clip out the part of the border where the legend would go
+      auto appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
+      auto layoutRect = wr::ToRoundedLayoutRect(
+          LayoutDeviceRect::FromAppUnits(rect, appUnitsPerDevPixel));
+
+      wr::ComplexClipRegion region;
+      region.rect = wr::ToRoundedLayoutRect(
+          LayoutDeviceRect::FromAppUnits(legendRect, appUnitsPerDevPixel));
+      region.mode = wr::ClipMode::ClipOut;
+      region.radii = wr::EmptyBorderRadius();
+      nsTArray<mozilla::wr::ComplexClipRegion> array{region};
+
+      auto clip = aBuilder.DefineClip(Nothing(), layoutRect, &array, nullptr);
+      auto clipChain = aBuilder.DefineClipChain({clip});
+      clipOut.emplace(aBuilder, clipChain);
     }
   } else {
     rect = nsRect(offset, frame->GetRect().Size());
   }
 
   ImgDrawResult drawResult = nsCSSRendering::CreateWebRenderCommandsForBorder(
       this, mFrame, rect, aBuilder, aResources, aSc, aManager,
       aDisplayListBuilder);
--- a/layout/reftests/box-shadow/reftest.list
+++ b/layout/reftests/box-shadow/reftest.list
@@ -35,14 +35,14 @@ fuzzy(0-26,0-3610) fuzzy-if(d2d,0-26,0-5
 # fuzzy due to blur going inside, but as long as it's essentially black instead of a light gray its ok.
 fuzzy(0-13,0-9445) fuzzy-if(d2d,0-13,0-10926) fuzzy-if(webrender,14-15,11263-13267) == boxshadow-inset-large-offset.html boxshadow-inset-large-offset-ref.html
 
 == overflow-not-scrollable-1.html overflow-not-scrollable-1-ref.html
 == overflow-not-scrollable-1.html overflow-not-scrollable-1-ref2.html
 == overflow-not-scrollable-2.html overflow-not-scrollable-2-ref.html
 fuzzy-if(webrender,0-1,0-655) == 611574-1.html 611574-1-ref.html
 fuzzy-if(webrender,0-4,0-144) == 611574-2.html 611574-2-ref.html
-fuzzy-if(winWidget,0-5,0-30) fuzzy-if(skiaContent,0-16,0-10) fuzzy-if(webrender,20-34,82-84) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows
+fuzzy-if(winWidget,0-5,0-30) fuzzy-if(skiaContent,0-16,0-10) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows
 fuzzy-if(winWidget,0-5,0-30) fuzzy-if(skiaContent,0-16,0-10) fails-if(webrender) == fieldset-inset.html fieldset-inset-ref.html # minor anti-aliasing problem on Windows
 == 1178575.html 1178575-ref.html
 == 1178575-2.html 1178575-2-ref.html
 fuzzy(0-159,0-2) fails-if(!dwrite) == 1212823-1.html 1212823-1-ref.html
 == boxshadow-large-offset.html boxshadow-large-offset-ref.html
deleted file mode 100644
--- a/testing/web-platform/meta/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[fieldset-vertical.html]
-  expected:
-    if webrender and (os == "linux"): FAIL
-    if webrender and (os == "win"): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html.ini
@@ -0,0 +1,3 @@
+[legend-auto-margins.html]
+  fuzzy:
+    if webrender and (os == "linux"): legend-auto-margins-ref.html:maxDifference=8;totalPixels=8-10