Bug 1311270 - Part 1. Move geomery box computing from nsCSSClipPathInstance to nsLayoutUtils.
Simply move ComputeHTMLReferenceRect and ComputeSVGReferenceRect from
nsCSSClipPathInstance to nsLayoutUtils to reuse the code in both clip-path and
mask.
MozReview-Commit-ID: 59LofAeEhKQ
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -113,16 +113,17 @@
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/Telemetry.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/RuleNodeCacheConditions.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "RegionBuilder.h"
+#include "SVGSVGElement.h"
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
#endif
#include "GeckoProfiler.h"
#include "nsAnimationManager.h"
#include "nsTransitionManager.h"
@@ -9170,8 +9171,132 @@ nsLayoutUtils::IsInvisibleBreak(nsINode*
return false;
}
break;
}
}
return lineNonEmpty;
}
+
+static nsRect
+ComputeSVGReferenceRect(nsIFrame* aFrame,
+ StyleClipPathGeometryBox aGeometryBox)
+{
+ MOZ_ASSERT(aFrame->GetContent()->IsSVGElement());
+ nsRect r;
+
+ // For SVG elements without associated CSS layout box, the used value for
+ // content-box, padding-box, border-box and margin-box is fill-box.
+ switch (aGeometryBox) {
+ case StyleClipPathGeometryBox::Stroke: {
+ // XXX Bug 1299876
+ // The size of srtoke-box is not correct if this graphic element has
+ // specific stroke-linejoin or stroke-linecap.
+ gfxRect bbox = nsSVGUtils::GetBBox(aFrame,
+ nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeStroke);
+ r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
+ nsPresContext::AppUnitsPerCSSPixel());
+ break;
+ }
+ case StyleClipPathGeometryBox::View: {
+ nsIContent* content = aFrame->GetContent();
+ nsSVGElement* element = static_cast<nsSVGElement*>(content);
+ SVGSVGElement* svgElement = element->GetCtx();
+ MOZ_ASSERT(svgElement);
+
+ if (svgElement && svgElement->HasViewBoxRect()) {
+ // If a ‘viewBox‘ attribute is specified for the SVG viewport creating
+ // element:
+ // 1. The reference box is positioned at the origin of the coordinate
+ // system established by the ‘viewBox‘ attribute.
+ // 2. The dimension of the reference box is set to the width and height
+ // values of the ‘viewBox‘ attribute.
+ nsSVGViewBox* viewBox = svgElement->GetViewBox();
+ const nsSVGViewBoxRect& value = viewBox->GetAnimValue();
+ r = nsRect(nsPresContext::CSSPixelsToAppUnits(value.x),
+ nsPresContext::CSSPixelsToAppUnits(value.y),
+ nsPresContext::CSSPixelsToAppUnits(value.width),
+ nsPresContext::CSSPixelsToAppUnits(value.height));
+ } else {
+ // No viewBox is specified, uses the nearest SVG viewport as reference
+ // box.
+ svgFloatSize viewportSize = svgElement->GetViewportSize();
+ r = nsRect(0, 0,
+ nsPresContext::CSSPixelsToAppUnits(viewportSize.width),
+ nsPresContext::CSSPixelsToAppUnits(viewportSize.height));
+ }
+
+ break;
+ }
+ case StyleClipPathGeometryBox::NoBox:
+ case StyleClipPathGeometryBox::Border:
+ case StyleClipPathGeometryBox::Content:
+ case StyleClipPathGeometryBox::Padding:
+ case StyleClipPathGeometryBox::Margin:
+ case StyleClipPathGeometryBox::Fill: {
+ gfxRect bbox = nsSVGUtils::GetBBox(aFrame,
+ nsSVGUtils::eBBoxIncludeFill);
+ r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
+ nsPresContext::AppUnitsPerCSSPixel());
+ break;
+ }
+ default:{
+ MOZ_ASSERT_UNREACHABLE("unknown StyleClipPathGeometryBox type");
+ gfxRect bbox = nsSVGUtils::GetBBox(aFrame,
+ nsSVGUtils::eBBoxIncludeFill);
+ r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
+ nsPresContext::AppUnitsPerCSSPixel());
+ break;
+ }
+ }
+
+ return r;
+}
+
+static nsRect
+ComputeHTMLReferenceRect(nsIFrame* aFrame,
+ StyleClipPathGeometryBox aGeometryBox)
+{
+ nsRect r;
+
+ // For elements with associated CSS layout box, the used value for fill-box,
+ // stroke-box and view-box is border-box.
+ switch (aGeometryBox) {
+ case StyleClipPathGeometryBox::Content:
+ r = aFrame->GetContentRectRelativeToSelf();
+ break;
+ case StyleClipPathGeometryBox::Padding:
+ r = aFrame->GetPaddingRectRelativeToSelf();
+ break;
+ case StyleClipPathGeometryBox::Margin:
+ r = aFrame->GetMarginRectRelativeToSelf();
+ break;
+ case StyleClipPathGeometryBox::NoBox:
+ case StyleClipPathGeometryBox::Border:
+ case StyleClipPathGeometryBox::Fill:
+ case StyleClipPathGeometryBox::Stroke:
+ case StyleClipPathGeometryBox::View:
+ r = aFrame->GetRectRelativeToSelf();
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("unknown StyleClipPathGeometryBox type");
+ r = aFrame->GetRectRelativeToSelf();
+ break;
+ }
+
+ return r;
+}
+
+/* static */ nsRect
+nsLayoutUtils::ComputeGeometryBox(nsIFrame* aFrame,
+ StyleClipPathGeometryBox aGeometryBox)
+{
+ // We use ComputeSVGReferenceRect for all SVG elements, except <svg>
+ // element, which does have an associated CSS layout box. In this case we
+ // should still use ComputeHTMLReferenceRect for region computing.
+ nsRect r = aFrame->IsFrameOfType(nsIFrame::eSVG) &&
+ (aFrame->GetType() != nsGkAtoms::svgOuterSVGFrame)
+ ? ComputeSVGReferenceRect(aFrame, aGeometryBox)
+ : ComputeHTMLReferenceRect(aFrame, aGeometryBox);
+
+ return r;
+}
\ No newline at end of file
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -25,17 +25,17 @@
#include "nsRuleNode.h"
#include "imgIContainer.h"
#include "mozilla/gfx/2D.h"
#include "Units.h"
#include "mozilla/ToString.h"
#include "mozilla/ReflowOutput.h"
#include "ImageContainer.h"
#include "gfx2DGlue.h"
-
+#include "nsStyleConsts.h"
#include <limits>
#include <algorithm>
class nsPresContext;
class nsIContent;
class nsIAtom;
class nsIScrollableFrame;
class nsIDOMEvent;
@@ -147,16 +147,17 @@ public:
typedef mozilla::layers::ScrollMetadata ScrollMetadata;
typedef FrameMetrics::ViewID ViewID;
typedef mozilla::CSSPoint CSSPoint;
typedef mozilla::CSSSize CSSSize;
typedef mozilla::CSSIntSize CSSIntSize;
typedef mozilla::CSSRect CSSRect;
typedef mozilla::ScreenMargin ScreenMargin;
typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize;
+ typedef mozilla::StyleClipPathGeometryBox StyleClipPathGeometryBox;
/**
* Finds previously assigned ViewID for the given content element, if any.
* Returns whether a ViewID was previously assigned.
*/
static bool FindIDFor(const nsIContent* aContent, ViewID* aOutViewId);
/**
@@ -2864,16 +2865,19 @@ public:
* aNextLineFrame is returned null in this case.
* false if the node causes a visible break or if the node is no break.
*
* @param aNextLineFrame assigned to first frame on the next line if such a
* next line exists, null otherwise.
*/
static bool IsInvisibleBreak(nsINode* aNode, nsIFrame** aNextLineFrame = nullptr);
+ static nsRect ComputeGeometryBox(nsIFrame* aFrame,
+ StyleClipPathGeometryBox aGeometryBox);
+
private:
static uint32_t sFontSizeInflationEmPerLine;
static uint32_t sFontSizeInflationMinTwips;
static uint32_t sFontSizeInflationLineThreshold;
static int32_t sFontSizeInflationMappingIntercept;
static uint32_t sFontSizeInflationMaxRatio;
static bool sFontSizeInflationForceEnabled;
static bool sFontSizeInflationDisabledInMasterProcess;
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -63,132 +63,22 @@ nsCSSClipPathInstance::HitTestBasicShape
RefPtr<DrawTarget> drawTarget =
gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
RefPtr<Path> path = instance.CreateClipPath(drawTarget);
float pixelRatio = float(nsPresContext::AppUnitsPerCSSPixel()) /
aFrame->PresContext()->AppUnitsPerDevPixel();
return path->ContainsPoint(ToPoint(aPoint) * pixelRatio, Matrix());
}
-nsRect
-nsCSSClipPathInstance::ComputeSVGReferenceRect()
-{
- MOZ_ASSERT(mTargetFrame->GetContent()->IsSVGElement());
- nsRect r;
-
- // For SVG elements without associated CSS layout box, the used value for
- // content-box, padding-box, border-box and margin-box is fill-box.
- switch (mClipPathStyle.GetReferenceBox()) {
- case StyleClipPathGeometryBox::Stroke: {
- // XXX Bug 1299876
- // The size of srtoke-box is not correct if this graphic element has
- // specific stroke-linejoin or stroke-linecap.
- gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
- nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeStroke);
- r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
- nsPresContext::AppUnitsPerCSSPixel());
- break;
- }
- case StyleClipPathGeometryBox::View: {
- nsIContent* content = mTargetFrame->GetContent();
- nsSVGElement* element = static_cast<nsSVGElement*>(content);
- SVGSVGElement* svgElement = element->GetCtx();
- MOZ_ASSERT(svgElement);
-
- if (svgElement && svgElement->HasViewBoxRect()) {
- // If a ‘viewBox‘ attribute is specified for the SVG viewport creating
- // element:
- // 1. The reference box is positioned at the origin of the coordinate
- // system established by the ‘viewBox‘ attribute.
- // 2. The dimension of the reference box is set to the width and height
- // values of the ‘viewBox‘ attribute.
- nsSVGViewBox* viewBox = svgElement->GetViewBox();
- const nsSVGViewBoxRect& value = viewBox->GetAnimValue();
- r = nsRect(nsPresContext::CSSPixelsToAppUnits(value.x),
- nsPresContext::CSSPixelsToAppUnits(value.y),
- nsPresContext::CSSPixelsToAppUnits(value.width),
- nsPresContext::CSSPixelsToAppUnits(value.height));
- } else {
- // No viewBox is specified, uses the nearest SVG viewport as reference
- // box.
- svgFloatSize viewportSize = svgElement->GetViewportSize();
- r = nsRect(0, 0,
- nsPresContext::CSSPixelsToAppUnits(viewportSize.width),
- nsPresContext::CSSPixelsToAppUnits(viewportSize.height));
- }
-
- break;
- }
- case StyleClipPathGeometryBox::NoBox:
- case StyleClipPathGeometryBox::Border:
- case StyleClipPathGeometryBox::Content:
- case StyleClipPathGeometryBox::Padding:
- case StyleClipPathGeometryBox::Margin:
- case StyleClipPathGeometryBox::Fill: {
- gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
- nsSVGUtils::eBBoxIncludeFill);
- r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
- nsPresContext::AppUnitsPerCSSPixel());
- break;
- }
- default:{
- MOZ_ASSERT_UNREACHABLE("unknown StyleClipPathGeometryBox type");
- gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
- nsSVGUtils::eBBoxIncludeFill);
- r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
- nsPresContext::AppUnitsPerCSSPixel());
- break;
- }
- }
-
- return r;
-}
-
-nsRect
-nsCSSClipPathInstance::ComputeHTMLReferenceRect()
-{
- nsRect r;
-
- // For elements with associated CSS layout box, the used value for fill-box,
- // stroke-box and view-box is border-box.
- switch (mClipPathStyle.GetReferenceBox()) {
- case StyleClipPathGeometryBox::Content:
- r = mTargetFrame->GetContentRectRelativeToSelf();
- break;
- case StyleClipPathGeometryBox::Padding:
- r = mTargetFrame->GetPaddingRectRelativeToSelf();
- break;
- case StyleClipPathGeometryBox::Margin:
- r = mTargetFrame->GetMarginRectRelativeToSelf();
- break;
- case StyleClipPathGeometryBox::NoBox:
- case StyleClipPathGeometryBox::Border:
- case StyleClipPathGeometryBox::Fill:
- case StyleClipPathGeometryBox::Stroke:
- case StyleClipPathGeometryBox::View:
- r = mTargetFrame->GetRectRelativeToSelf();
- break;
- default:
- MOZ_ASSERT_UNREACHABLE("unknown StyleClipPathGeometryBox type");
- r = mTargetFrame->GetRectRelativeToSelf();
- break;
- }
-
- return r;
-}
-
already_AddRefed<Path>
nsCSSClipPathInstance::CreateClipPath(DrawTarget* aDrawTarget)
{
- // We use ComputeSVGReferenceRect for all SVG elements, except <svg>
- // element, which does have an associated CSS layout box. In this case we
- // should still use ComputeHTMLReferenceRect for region computing.
- nsRect r = mTargetFrame->IsFrameOfType(nsIFrame::eSVG) &&
- (mTargetFrame->GetType() != nsGkAtoms::svgOuterSVGFrame)
- ? ComputeSVGReferenceRect() : ComputeHTMLReferenceRect();
+ nsRect r =
+ nsLayoutUtils::ComputeGeometryBox(mTargetFrame,
+ mClipPathStyle.GetReferenceBox());
if (mClipPathStyle.GetType() != StyleShapeSourceType::Shape) {
// TODO Clip to border-radius/reference box if no shape
// was specified.
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
return builder->Finish();
}
--- a/layout/svg/nsCSSClipPathInstance.h
+++ b/layout/svg/nsCSSClipPathInstance.h
@@ -44,19 +44,16 @@ private:
already_AddRefed<Path> CreateClipPathPolygon(DrawTarget* aDrawTarget,
const nsRect& aRefBox);
already_AddRefed<Path> CreateClipPathInset(DrawTarget* aDrawTarget,
const nsRect& aRefBox);
- nsRect ComputeHTMLReferenceRect();
- nsRect ComputeSVGReferenceRect();
-
/**
* The frame for the element that is currently being clipped.
*/
nsIFrame* mTargetFrame;
StyleClipPath mClipPathStyle;
};
} // namespace mozilla