mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 15:28:39 +09:00
Support CSS sizing math functions
This commit is contained in:
parent
7766f8f53d
commit
c47cea4ddf
12 changed files with 1234 additions and 28 deletions
|
|
@ -701,6 +701,30 @@ static inline nscoord CalcLength(const nsCSSValue& aValue,
|
|||
aPresContext, aConditions);
|
||||
}
|
||||
|
||||
static inline nscoord
|
||||
CalcLengthTowardZero(const nsCSSValue& aValue,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsPresContext* aPresContext,
|
||||
RuleNodeCacheConditions& aConditions)
|
||||
{
|
||||
NS_ASSERTION(aStyleContext, "Must have style data");
|
||||
|
||||
return CalcLengthWith(aValue, -1, nullptr,
|
||||
aStyleContext, aPresContext,
|
||||
false, true, aConditions,
|
||||
AppUnitRounding::TowardZero);
|
||||
}
|
||||
|
||||
already_AddRefed<nsStyleCoord::CalcNode>
|
||||
nsRuleNode::ComputedCalc::ToCalcNode() const
|
||||
{
|
||||
if (mNode) {
|
||||
RefPtr<nsStyleCoord::CalcNode> node = mNode;
|
||||
return node.forget();
|
||||
}
|
||||
return nsStyleCoord::CalcNode::CreateLeaf(mLength, mPercent, mHasPercent);
|
||||
}
|
||||
|
||||
/* static */ nscoord
|
||||
nsRuleNode::CalcLengthWithInitialFont(nsPresContext* aPresContext,
|
||||
const nsCSSValue& aValue)
|
||||
|
|
@ -733,27 +757,42 @@ struct LengthPercentPairCalcOps : public css::NumbersAlreadyNormalizedOps
|
|||
{
|
||||
if (aValue.GetUnit() == eCSSUnit_Percent) {
|
||||
mHasPercent = true;
|
||||
return result_type(0, aValue.GetPercentValue());
|
||||
return result_type(0, aValue.GetPercentValue(), true);
|
||||
}
|
||||
return result_type(CalcLength(aValue, mContext, mPresContext,
|
||||
mConditions),
|
||||
0.0f);
|
||||
0.0f, false);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeAdditive(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, result_type aValue2)
|
||||
{
|
||||
if (aValue1.HasNode() || aValue2.HasNode()) {
|
||||
RefPtr<nsStyleCoord::CalcNode> node =
|
||||
nsStyleCoord::CalcNode::Create(
|
||||
aCalcFunction == eCSSUnit_Calc_Plus
|
||||
? nsStyleCoord::CalcNode::Type::Add
|
||||
: nsStyleCoord::CalcNode::Type::Subtract);
|
||||
node->mChildren.AppendElement(aValue1.ToCalcNode());
|
||||
node->mChildren.AppendElement(aValue2.ToCalcNode());
|
||||
node->mHasPercent = node->HasPercent();
|
||||
mHasPercent = mHasPercent || node->mHasPercent;
|
||||
return result_type(node.forget());
|
||||
}
|
||||
|
||||
if (aCalcFunction == eCSSUnit_Calc_Plus) {
|
||||
return result_type(NSCoordSaturatingAdd(aValue1.mLength,
|
||||
aValue2.mLength),
|
||||
aValue1.mPercent + aValue2.mPercent);
|
||||
aValue1.mPercent + aValue2.mPercent,
|
||||
aValue1.mHasPercent || aValue2.mHasPercent);
|
||||
}
|
||||
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Minus,
|
||||
"min() and max() are not allowed in calc() on transform");
|
||||
return result_type(NSCoordSaturatingSubtract(aValue1.mLength,
|
||||
aValue2.mLength, 0),
|
||||
aValue1.mPercent - aValue2.mPercent);
|
||||
aValue1.mPercent - aValue2.mPercent,
|
||||
aValue1.mHasPercent || aValue2.mHasPercent);
|
||||
}
|
||||
|
||||
result_type
|
||||
|
|
@ -762,8 +801,19 @@ struct LengthPercentPairCalcOps : public css::NumbersAlreadyNormalizedOps
|
|||
{
|
||||
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Times_L,
|
||||
"unexpected unit");
|
||||
if (aValue2.HasNode()) {
|
||||
RefPtr<nsStyleCoord::CalcNode> node =
|
||||
nsStyleCoord::CalcNode::Create(nsStyleCoord::CalcNode::Type::Multiply);
|
||||
node->mChildren.AppendElement(aValue2.ToCalcNode());
|
||||
node->mNumber = aValue1;
|
||||
node->mHasPercent = node->HasPercent();
|
||||
mHasPercent = mHasPercent || node->mHasPercent;
|
||||
return result_type(node.forget());
|
||||
}
|
||||
|
||||
return result_type(NSCoordSaturatingMultiply(aValue2.mLength, aValue1),
|
||||
aValue1 * aValue2.mPercent);
|
||||
aValue1 * aValue2.mPercent,
|
||||
aValue2.mHasPercent);
|
||||
}
|
||||
|
||||
result_type
|
||||
|
|
@ -774,10 +824,89 @@ struct LengthPercentPairCalcOps : public css::NumbersAlreadyNormalizedOps
|
|||
aCalcFunction == eCSSUnit_Calc_Divided,
|
||||
"unexpected unit");
|
||||
if (aCalcFunction == eCSSUnit_Calc_Divided) {
|
||||
if (aValue1.HasNode()) {
|
||||
RefPtr<nsStyleCoord::CalcNode> node =
|
||||
nsStyleCoord::CalcNode::Create(nsStyleCoord::CalcNode::Type::Divide);
|
||||
node->mChildren.AppendElement(aValue1.ToCalcNode());
|
||||
node->mNumber = aValue2;
|
||||
node->mHasPercent = node->HasPercent();
|
||||
mHasPercent = mHasPercent || node->mHasPercent;
|
||||
return result_type(node.forget());
|
||||
}
|
||||
aValue2 = 1.0f / aValue2;
|
||||
} else if (aValue1.HasNode()) {
|
||||
RefPtr<nsStyleCoord::CalcNode> node =
|
||||
nsStyleCoord::CalcNode::Create(nsStyleCoord::CalcNode::Type::Multiply);
|
||||
node->mChildren.AppendElement(aValue1.ToCalcNode());
|
||||
node->mNumber = aValue2;
|
||||
node->mHasPercent = node->HasPercent();
|
||||
mHasPercent = mHasPercent || node->mHasPercent;
|
||||
return result_type(node.forget());
|
||||
}
|
||||
return result_type(NSCoordSaturatingMultiply(aValue1.mLength, aValue2),
|
||||
aValue1.mPercent * aValue2);
|
||||
aValue1.mPercent * aValue2,
|
||||
aValue1.mHasPercent);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMinMax(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, result_type aValue2)
|
||||
{
|
||||
const bool hasNode = aValue1.HasNode() || aValue2.HasNode();
|
||||
const bool hasPercent = aValue1.mHasPercent || aValue2.mHasPercent;
|
||||
if (!hasNode && !hasPercent) {
|
||||
if (aCalcFunction == eCSSUnit_Calc_Min) {
|
||||
return result_type(std::min(aValue1.mLength, aValue2.mLength),
|
||||
0.0f, false);
|
||||
}
|
||||
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Max, "unexpected unit");
|
||||
return result_type(std::max(aValue1.mLength, aValue2.mLength),
|
||||
0.0f, false);
|
||||
}
|
||||
|
||||
RefPtr<nsStyleCoord::CalcNode> node =
|
||||
nsStyleCoord::CalcNode::Create(
|
||||
aCalcFunction == eCSSUnit_Calc_Min
|
||||
? nsStyleCoord::CalcNode::Type::Min
|
||||
: nsStyleCoord::CalcNode::Type::Max);
|
||||
if (aValue1.HasNode() &&
|
||||
aValue1.mNode->mType == node->mType) {
|
||||
node->mChildren.AppendElements(aValue1.mNode->mChildren);
|
||||
} else {
|
||||
node->mChildren.AppendElement(aValue1.ToCalcNode());
|
||||
}
|
||||
if (aValue2.HasNode() &&
|
||||
aValue2.mNode->mType == node->mType) {
|
||||
node->mChildren.AppendElements(aValue2.mNode->mChildren);
|
||||
} else {
|
||||
node->mChildren.AppendElement(aValue2.ToCalcNode());
|
||||
}
|
||||
node->mHasPercent = node->HasPercent();
|
||||
mHasPercent = mHasPercent || node->mHasPercent;
|
||||
return result_type(node.forget());
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeClamp(result_type aMin, result_type aCenter, result_type aMax)
|
||||
{
|
||||
const bool hasNode = aMin.HasNode() || aCenter.HasNode() || aMax.HasNode();
|
||||
const bool hasPercent = aMin.mHasPercent ||
|
||||
aCenter.mHasPercent ||
|
||||
aMax.mHasPercent;
|
||||
if (!hasNode && !hasPercent) {
|
||||
return result_type(std::max(aMin.mLength,
|
||||
std::min(aCenter.mLength, aMax.mLength)),
|
||||
0.0f, false);
|
||||
}
|
||||
|
||||
RefPtr<nsStyleCoord::CalcNode> node =
|
||||
nsStyleCoord::CalcNode::Create(nsStyleCoord::CalcNode::Type::Clamp);
|
||||
node->mChildren.AppendElement(aMin.ToCalcNode());
|
||||
node->mChildren.AppendElement(aCenter.ToCalcNode());
|
||||
node->mChildren.AppendElement(aMax.ToCalcNode());
|
||||
node->mHasPercent = node->HasPercent();
|
||||
mHasPercent = mHasPercent || node->mHasPercent;
|
||||
return result_type(node.forget());
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -795,7 +924,8 @@ SpecifiedCalcToComputedCalc(const nsCSSValue& aValue, nsStyleCoord& aCoord,
|
|||
|
||||
calcObj->mLength = vals.mLength;
|
||||
calcObj->mPercent = vals.mPercent;
|
||||
calcObj->mHasPercent = ops.mHasPercent;
|
||||
calcObj->mHasPercent = vals.mHasPercent || ops.mHasPercent;
|
||||
calcObj->mNode = vals.mNode;
|
||||
|
||||
aCoord.SetCalcValue(calcObj);
|
||||
}
|
||||
|
|
@ -818,8 +948,7 @@ nsRuleNode::ComputeComputedCalc(const nsStyleCoord& aValue,
|
|||
nscoord aPercentageBasis)
|
||||
{
|
||||
nsStyleCoord::Calc* calc = aValue.GetCalcValue();
|
||||
return calc->mLength +
|
||||
NSToCoordFloorClamped(aPercentageBasis * calc->mPercent);
|
||||
return calc->Resolve(aPercentageBasis);
|
||||
}
|
||||
|
||||
/* static */ nscoord
|
||||
|
|
@ -4797,6 +4926,34 @@ struct LengthNumberCalcOps : public css::NumbersAlreadyNormalizedOps
|
|||
return result;
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMinMax(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, result_type aValue2)
|
||||
{
|
||||
MOZ_ASSERT(aValue1.mIsNumber == aValue2.mIsNumber);
|
||||
LengthNumberCalcObj result;
|
||||
result.mIsNumber = aValue1.mIsNumber;
|
||||
if (aCalcFunction == eCSSUnit_Calc_Min) {
|
||||
result.mValue = std::min(aValue1.mValue, aValue2.mValue);
|
||||
return result;
|
||||
}
|
||||
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Max, "unexpected unit");
|
||||
result.mValue = std::max(aValue1.mValue, aValue2.mValue);
|
||||
return result;
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeClamp(result_type aMin, result_type aCenter, result_type aMax)
|
||||
{
|
||||
MOZ_ASSERT(aMin.mIsNumber == aCenter.mIsNumber &&
|
||||
aCenter.mIsNumber == aMax.mIsNumber);
|
||||
LengthNumberCalcObj result;
|
||||
result.mIsNumber = aCenter.mIsNumber;
|
||||
result.mValue = std::max(aMin.mValue,
|
||||
std::min(aCenter.mValue, aMax.mValue));
|
||||
return result;
|
||||
}
|
||||
|
||||
result_type ComputeLeafValue(const nsCSSValue& aValue)
|
||||
{
|
||||
LengthNumberCalcObj result;
|
||||
|
|
@ -4887,6 +5044,38 @@ struct LengthPercentNumberCalcOps : public css::NumbersAlreadyNormalizedOps
|
|||
return result;
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMinMax(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, result_type aValue2)
|
||||
{
|
||||
MOZ_ASSERT(aValue1.mIsNumber == aValue2.mIsNumber);
|
||||
result_type result;
|
||||
result.mIsNumber = aValue1.mIsNumber;
|
||||
if (aCalcFunction == eCSSUnit_Calc_Min) {
|
||||
result.mLength = std::min(aValue1.mLength, aValue2.mLength);
|
||||
result.mPercent = std::min(aValue1.mPercent, aValue2.mPercent);
|
||||
} else {
|
||||
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Max, "unexpected unit");
|
||||
result.mLength = std::max(aValue1.mLength, aValue2.mLength);
|
||||
result.mPercent = std::max(aValue1.mPercent, aValue2.mPercent);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeClamp(result_type aMin, result_type aCenter, result_type aMax)
|
||||
{
|
||||
MOZ_ASSERT(aMin.mIsNumber == aCenter.mIsNumber &&
|
||||
aCenter.mIsNumber == aMax.mIsNumber);
|
||||
result_type result;
|
||||
result.mIsNumber = aCenter.mIsNumber;
|
||||
result.mLength = std::max(aMin.mLength,
|
||||
std::min(aCenter.mLength, aMax.mLength));
|
||||
result.mPercent = std::max(aMin.mPercent,
|
||||
std::min(aCenter.mPercent, aMax.mPercent));
|
||||
return result;
|
||||
}
|
||||
|
||||
result_type
|
||||
ComputeLeafValue(const nsCSSValue& aValue)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue