mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-04 11:26:09 +00:00
Bug 1581237 - Use <coord-box> as the reference box of the containing block for ray(). r=emilio
So now we use <coord-box> to decide which box we should use. Also, we have to tweak the calculation of path length to take the top left point into consideration, for padding-box and content-box. border-box is the default value, so other tests should cover it. Differential Revision: https://phabricator.services.mozilla.com/D180397
This commit is contained in:
parent
2af89d148a
commit
97e7095dbd
@ -30,6 +30,11 @@ using nsStyleTransformMatrix::TransformReferenceBox;
|
||||
// https://drafts.fxtf.org/motion-1/#valdef-offset-path-coord-box
|
||||
static const nsIFrame* GetOffsetPathReferenceBox(const nsIFrame* aFrame,
|
||||
nsRect& aOutputRect) {
|
||||
const StyleOffsetPath& offsetPath = aFrame->StyleDisplay()->mOffsetPath;
|
||||
if (offsetPath.IsNone()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT)) {
|
||||
MOZ_ASSERT(aFrame->GetContent()->IsSVGElement());
|
||||
auto* viewportElement =
|
||||
@ -39,14 +44,11 @@ static const nsIFrame* GetOffsetPathReferenceBox(const nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
const nsIFrame* containingBlock = aFrame->GetContainingBlock();
|
||||
// FIXME: Bug 1581237: We should use <coord-box> as the box of its containing.
|
||||
// Also, we will add <coord-box> into offset-path syntax in Bug 1598156.
|
||||
// For now, we always use the default value, border-box.
|
||||
// block.
|
||||
// https://drafts.fxtf.org/motion-1/#valdef-offset-path-coord-box
|
||||
constexpr StyleGeometryBox styleCoordBox = StyleGeometryBox::BorderBox;
|
||||
aOutputRect =
|
||||
nsLayoutUtils::ComputeHTMLReferenceRect(containingBlock, styleCoordBox);
|
||||
const StyleCoordBox coordBox = offsetPath.IsCoordBox()
|
||||
? offsetPath.AsCoordBox()
|
||||
: offsetPath.AsOffsetPath().coord_box;
|
||||
aOutputRect = nsLayoutUtils::ComputeHTMLReferenceRect(
|
||||
containingBlock, nsLayoutUtils::CoordBoxToGeometryBox(coordBox));
|
||||
return containingBlock;
|
||||
}
|
||||
|
||||
@ -82,12 +84,15 @@ RayReferenceData::RayReferenceData(const nsIFrame* aFrame) {
|
||||
.Size());
|
||||
}
|
||||
|
||||
// The distance is measured between the initial position and the intersection of
|
||||
// the ray with the box.
|
||||
// The distance is measured between the origin and the intersection of the ray
|
||||
// with the reference box of the containing block.
|
||||
// Note: |aOrigin| and |aContaingBlock| should be in the same coordinate system
|
||||
// (i.e. the nsIFrame::mRect of the containing block).
|
||||
// https://drafts.fxtf.org/motion-1/#size-sides
|
||||
static CSSCoord ComputeSides(const CSSPoint& aInitialPosition,
|
||||
const CSSSize& aContainerSize,
|
||||
static CSSCoord ComputeSides(const CSSPoint& aOrigin,
|
||||
const CSSRect& aContainingBlock,
|
||||
const StyleAngle& aAngle) {
|
||||
const CSSPoint& topLeft = aContainingBlock.TopLeft();
|
||||
// Given an acute angle |theta| (i.e. |t|) of a right-angled triangle, the
|
||||
// hypotenuse |h| is the side that connects the two acute angles. The side
|
||||
// |b| adjacent to |theta| is the side of the triangle that connects |theta|
|
||||
@ -96,28 +101,29 @@ static CSSCoord ComputeSides(const CSSPoint& aInitialPosition,
|
||||
// e.g. if the angle |t| is 0 ~ 90 degrees, and b * tan(theta) <= b',
|
||||
// h = b / cos(t):
|
||||
// b*tan(t)
|
||||
// (0, 0) #--------*-----*--# (aContainerSize.width, 0)
|
||||
// (topLeft) #--------*-----*--# (aContainingBlock.XMost(), topLeft.y)
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | b h |
|
||||
// | |t/ |
|
||||
// | |/ |
|
||||
// (aInitialPosition) *---b'---* (aContainerSize.width, aInitialPosition.y)
|
||||
// (aOrigin) *---b'---* (aContainingBlock.XMost(), aOrigin.y)
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// #-----------------# (aContainerSize.width,
|
||||
// (0, aContainerSize.height) aContainerSize.height)
|
||||
double theta = aAngle.ToRadians();
|
||||
// #-----------------# (aContainingBlock.XMost(),
|
||||
// (topLeft.x, aContainingBlock.YMost())
|
||||
// aContainingBlock.YMost())
|
||||
const double theta = aAngle.ToRadians();
|
||||
double sint = std::sin(theta);
|
||||
double cost = std::cos(theta);
|
||||
|
||||
double b = cost >= 0 ? aInitialPosition.y.value
|
||||
: aContainerSize.height - aInitialPosition.y.value;
|
||||
double bPrime = sint >= 0 ? aContainerSize.width - aInitialPosition.x.value
|
||||
: aInitialPosition.x.value;
|
||||
const double b = cost >= 0 ? aOrigin.y.value - topLeft.y
|
||||
: aContainingBlock.YMost() - aOrigin.y.value;
|
||||
const double bPrime = sint >= 0 ? aContainingBlock.XMost() - aOrigin.x.value
|
||||
: aOrigin.x.value - topLeft.x;
|
||||
sint = std::fabs(sint);
|
||||
cost = std::fabs(cost);
|
||||
|
||||
@ -184,17 +190,18 @@ static CSSCoord ComputeRayPathLength(const StyleRaySize aRaySizeType,
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return ComputeSides(aOrigin, aContainingBlock.Size(), aAngle);
|
||||
return ComputeSides(aOrigin, aContainingBlock, aAngle);
|
||||
}
|
||||
|
||||
// left: the length between the initial point and the left side.
|
||||
// right: the length between the initial point and the right side.
|
||||
// top: the length between the initial point and the top side.
|
||||
// bottom: the lenght between the initial point and the bottom side.
|
||||
CSSCoord left = std::abs(aOrigin.x);
|
||||
CSSCoord right = std::abs(aContainingBlock.width - aOrigin.x);
|
||||
CSSCoord top = std::abs(aOrigin.y);
|
||||
CSSCoord bottom = std::abs(aContainingBlock.height - aOrigin.y);
|
||||
// left: the length between the origin and the left side.
|
||||
// right: the length between the origin and the right side.
|
||||
// top: the length between the origin and the top side.
|
||||
// bottom: the lenght between the origin and the bottom side.
|
||||
const CSSPoint& topLeft = aContainingBlock.TopLeft();
|
||||
const CSSCoord left = std::abs(aOrigin.x - topLeft.x);
|
||||
const CSSCoord right = std::abs(aContainingBlock.XMost() - aOrigin.x);
|
||||
const CSSCoord top = std::abs(aOrigin.y - topLeft.y);
|
||||
const CSSCoord bottom = std::abs(aContainingBlock.YMost() - aOrigin.y);
|
||||
|
||||
switch (aRaySizeType) {
|
||||
case StyleRaySize::ClosestSide:
|
||||
@ -216,7 +223,7 @@ static CSSCoord ComputeRayPathLength(const StyleRaySize aRaySizeType,
|
||||
}
|
||||
return sqrt(h.value * h.value + v.value * v.value);
|
||||
}
|
||||
default:
|
||||
case StyleRaySize::Sides:
|
||||
MOZ_ASSERT_UNREACHABLE("Unsupported ray size");
|
||||
}
|
||||
|
||||
|
@ -9572,6 +9572,26 @@ nsRect nsLayoutUtils::ComputeHTMLReferenceRect(const nsIFrame* aFrame,
|
||||
return r;
|
||||
}
|
||||
|
||||
/* static */
|
||||
StyleGeometryBox nsLayoutUtils::CoordBoxToGeometryBox(StyleCoordBox aCoordBox) {
|
||||
switch (aCoordBox) {
|
||||
case StyleCoordBox::ContentBox:
|
||||
return StyleGeometryBox::ContentBox;
|
||||
case StyleCoordBox::PaddingBox:
|
||||
return StyleGeometryBox::PaddingBox;
|
||||
case StyleCoordBox::BorderBox:
|
||||
return StyleGeometryBox::BorderBox;
|
||||
case StyleCoordBox::FillBox:
|
||||
return StyleGeometryBox::FillBox;
|
||||
case StyleCoordBox::StrokeBox:
|
||||
return StyleGeometryBox::StrokeBox;
|
||||
case StyleCoordBox::ViewBox:
|
||||
return StyleGeometryBox::ViewBox;
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown coord-box type");
|
||||
return StyleGeometryBox::BorderBox;
|
||||
}
|
||||
|
||||
static StyleGeometryBox ShapeBoxToGeometryBox(const StyleShapeBox& aBox) {
|
||||
switch (aBox) {
|
||||
case StyleShapeBox::BorderBox:
|
||||
|
@ -2946,6 +2946,8 @@ class nsLayoutUtils {
|
||||
|
||||
static nsRect ComputeHTMLReferenceRect(const nsIFrame*, StyleGeometryBox);
|
||||
|
||||
static StyleGeometryBox CoordBoxToGeometryBox(mozilla::StyleCoordBox);
|
||||
|
||||
static nsRect ComputeGeometryBox(nsIFrame*, StyleGeometryBox);
|
||||
|
||||
static nsRect ComputeGeometryBox(nsIFrame*,
|
||||
|
@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Motion Path test reference: ray() path with padding-box</title>
|
||||
|
||||
<style>
|
||||
#outer {
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 50px;
|
||||
border: 50px solid black;
|
||||
}
|
||||
#box {
|
||||
background-color: green;
|
||||
transform: translate(-50px, -50px);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="outer">
|
||||
<div id="box"></div>
|
||||
</div>
|
@ -0,0 +1,30 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Motion Path test: ray() path with padding-box</title>
|
||||
<link rel="match" href="offset-path-ray-015-ref.html">
|
||||
<link rel="help" href="https://drafts.fxtf.org/motion/#ray-function">
|
||||
|
||||
<style>
|
||||
#outer {
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 50px;
|
||||
border: 50px solid black;
|
||||
}
|
||||
#box {
|
||||
background-color: green;
|
||||
offset-path: ray(0deg sides at 0% 0%) padding-box;
|
||||
offset-rotate: 0deg;
|
||||
offset-anchor: 0% 0%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="outer">
|
||||
<div id="box"></div>
|
||||
</div>
|
@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Motion Path test reference: ray() path with content-box</title>
|
||||
|
||||
<style>
|
||||
#outer {
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 50px;
|
||||
border: 50px solid black;
|
||||
}
|
||||
#box {
|
||||
background-color: green;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="outer">
|
||||
<div id="box"></div>
|
||||
</div>
|
@ -0,0 +1,31 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Motion Path test: ray() path with content-box</title>
|
||||
<link rel="match" href="offset-path-ray-016-ref.html">
|
||||
<link rel="help" href="https://drafts.fxtf.org/motion/#ray-function">
|
||||
|
||||
<style>
|
||||
#outer {
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 50px;
|
||||
border: 50px solid black;
|
||||
}
|
||||
#box {
|
||||
background-color: green;
|
||||
offset-path: ray(0deg sides at 0% 0%) content-box;
|
||||
offset-rotate: 0deg;
|
||||
offset-anchor: 0% 0%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="outer">
|
||||
<div style="width: 100px; height: 100px; background-color: red;"></div>
|
||||
<div id="box"></div>
|
||||
</div>
|
@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Motion Path test reference: ray() path with padding-box</title>
|
||||
|
||||
<style>
|
||||
#outer {
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 50px;
|
||||
border: 50px solid black;
|
||||
}
|
||||
#box {
|
||||
background-color: green;
|
||||
transform: translate(100px, -50px);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="outer">
|
||||
<div id="box"></div>
|
||||
</div>
|
@ -0,0 +1,31 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Motion Path test: ray() path with padding-box</title>
|
||||
<link rel="match" href="offset-path-ray-017-ref.html">
|
||||
<link rel="help" href="https://drafts.fxtf.org/motion/#ray-function">
|
||||
|
||||
<style>
|
||||
#outer {
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 50px;
|
||||
border: 50px solid black;
|
||||
}
|
||||
#box {
|
||||
background-color: green;
|
||||
offset-path: ray(0deg sides at 50% 50%) padding-box;
|
||||
offset-distance: 100%;
|
||||
offset-rotate: 0deg;
|
||||
offset-anchor: 0% 0%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="outer">
|
||||
<div id="box"></div>
|
||||
</div>
|
@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Motion Path test reference: ray() path with content-box</title>
|
||||
|
||||
<style>
|
||||
#outer {
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 50px;
|
||||
border: 50px solid black;
|
||||
}
|
||||
#box {
|
||||
background-color: green;
|
||||
transform: translate(100px, 0px);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="outer">
|
||||
<div id="box"></div>
|
||||
</div>
|
@ -0,0 +1,31 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Motion Path test: ray() path with content-box</title>
|
||||
<link rel="match" href="offset-path-ray-018-ref.html">
|
||||
<link rel="help" href="https://drafts.fxtf.org/motion/#ray-function">
|
||||
|
||||
<style>
|
||||
#outer {
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 50px;
|
||||
border: 50px solid black;
|
||||
}
|
||||
#box {
|
||||
background-color: green;
|
||||
offset-path: ray(0deg sides at 50% 50%) content-box;
|
||||
offset-distance: 100%;
|
||||
offset-rotate: 0deg;
|
||||
offset-anchor: 0% 0%;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="outer">
|
||||
<div id="box"></div>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user