Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (282794 => 282795)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-09-21 00:24:50 UTC (rev 282795)
@@ -1,3 +1,14 @@
+2021-09-20 Nikos Mouchtaris <[email protected]>
+
+ Implement exp,log functions calc functions
+ https://bugs.webkit.org/show_bug.cgi?id=229897
+
+ Reviewed by Simon Fraser.
+
+ * web-platform-tests/css/css-values/exp-log-compute.html: Added.
+ * web-platform-tests/css/css-values/exp-log-invalid.html: Added.
+ * web-platform-tests/css/css-values/exp-log-serialize.html: Added.
+
2021-09-20 Youenn Fablet <[email protected]>
Make sure RTCRtpSender.setParameters returns an exception with a valid type
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-compute-expected.txt (0 => 282795)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-compute-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-compute-expected.txt 2021-09-21 00:24:50 UTC (rev 282795)
@@ -0,0 +1,19 @@
+
+PASS log(1) should be used-value-equivalent to 0
+PASS log(10, 10) should be used-value-equivalent to 1
+PASS exp(0) should be used-value-equivalent to 1
+PASS calc(log(e) ) should be used-value-equivalent to 1
+PASS calc(e - exp(1)) should be used-value-equivalent to 0
+PASS calc(log( 1 + 1 + 2 /2 - 2) ) should be used-value-equivalent to 0
+PASS calc(log(1) + exp(0)) should be used-value-equivalent to 2
+PASS calc(exp(log(1) + exp(0)*2)) should be used-value-equivalent to 7.4
+PASS calc(log(log(1) + exp(0)*10)) should be used-value-equivalent to 2.3
+PASS calc(log(log(1) + exp(0)*20, 10)) should be used-value-equivalent to 1.3
+PASS calc(log(e) / log(e) + exp(0)*2 * log(e)) should be used-value-equivalent to 3
+PASS calc(log((1 + 1) /2) / log(e) + exp(0*1)*2 * log(e)) should be used-value-equivalent to 2
+PASS calc(log((3 + 1) /2, 2) / log(e) + exp(0*1)*2 * log(e)) should be used-value-equivalent to 3
+PASS calc(log((3 + 1) /2, 2) / log(e, e) + exp(0*1)*2 * log(e, e)) should be used-value-equivalent to 3
+PASS calc(exp(0) + 1) should be used-value-equivalent to 2
+PASS calc(log(exp(1))) should be used-value-equivalent to 1
+PASS calc(log(exp(log(e)))) should be used-value-equivalent to 1
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-compute.html (0 => 282795)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-compute.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-compute.html 2021-09-21 00:24:50 UTC (rev 282795)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="help" href=""
+<link rel="help" href=""
+<link rel="help" href=""
+<link rel="author" title="Apple Inc">
+<script src=""
+<script src=""
+<script src=""
+<div id="target"></div>
+<script>
+// Simple tests
+test_math_used('log(1)', '0', {type:'number'});
+test_math_used('log(10, 10)', '1', {type:'number'});
+test_math_used('exp(0)', '1', {type:'number'});
+
+// Test e
+test_math_used('calc(log(e) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(e - exp(1))', '0', {type:'number', approx:0.1});
+
+//General calculations
+test_math_used('calc(log( 1 + 1 + 2 /2 - 2) )', '0', {type:'number', approx:0.1});
+test_math_used('calc(log(1) + exp(0))', '2'), {type:'number', approx:0.1};
+test_math_used('calc(exp(log(1) + exp(0)*2))', '7.4'), {type:'number', approx:0.1};
+test_math_used('calc(log(log(1) + exp(0)*10))', '2.3'), {type:'number', approx:0.1};
+test_math_used('calc(log(log(1) + exp(0)*20, 10))', '1.3'), {type:'number', approx:0.1};
+test_math_used('calc(log(e) / log(e) + exp(0)*2 * log(e))', '3', {type:'number', approx:0.1});
+test_math_used('calc(log((1 + 1) /2) / log(e) + exp(0*1)*2 * log(e))', '2', {type:'number', approx:0.1});
+test_math_used('calc(log((3 + 1) /2, 2) / log(e) + exp(0*1)*2 * log(e))', '3', {type:'number', approx:0.1});
+test_math_used('calc(log((3 + 1) /2, 2) / log(e, e) + exp(0*1)*2 * log(e, e))', '3', {type:'number', approx:0.1});
+test_math_used('calc(exp(0) + 1)', '2', {type:'number', approx:0.1});
+
+// Test nesting
+test_math_used('calc(log(exp(1)))', '1', {type:'number', approx:0.1});
+test_math_used('calc(log(exp(log(e))))', '1', {type:'number', approx:0.1});
+</script>
\ No newline at end of file
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-invalid-expected.txt (0 => 282795)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-invalid-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-invalid-expected.txt 2021-09-21 00:24:50 UTC (rev 282795)
@@ -0,0 +1,50 @@
+
+PASS e.style['opacity'] = "exp()" should not set the property value
+PASS e.style['opacity'] = "exp( )" should not set the property value
+PASS e.style['opacity'] = "exp(,)" should not set the property value
+PASS e.style['opacity'] = "exp(1, )" should not set the property value
+PASS e.style['opacity'] = "exp(, 1)" should not set the property value
+PASS e.style['opacity'] = "exp(1 + )" should not set the property value
+PASS e.style['opacity'] = "exp(1 - )" should not set the property value
+PASS e.style['opacity'] = "exp(1 * )" should not set the property value
+PASS e.style['opacity'] = "exp(1 / )" should not set the property value
+PASS e.style['opacity'] = "exp(1 2)" should not set the property value
+PASS e.style['opacity'] = "exp(1, , 2)" should not set the property value
+PASS e.style['opacity'] = "log()" should not set the property value
+PASS e.style['opacity'] = "log( )" should not set the property value
+PASS e.style['opacity'] = "log(,)" should not set the property value
+PASS e.style['opacity'] = "log(1, )" should not set the property value
+PASS e.style['opacity'] = "log(, 1)" should not set the property value
+PASS e.style['opacity'] = "log(1 + )" should not set the property value
+PASS e.style['opacity'] = "log(1 - )" should not set the property value
+PASS e.style['opacity'] = "log(1 * )" should not set the property value
+PASS e.style['opacity'] = "log(1 / )" should not set the property value
+PASS e.style['opacity'] = "log(1 2)" should not set the property value
+PASS e.style['opacity'] = "log(1, , 2)" should not set the property value
+PASS e.style['opacity'] = "exp(0px)" should not set the property value
+PASS e.style['opacity'] = "exp(0s)" should not set the property value
+PASS e.style['opacity'] = "exp(0deg)" should not set the property value
+PASS e.style['opacity'] = "exp(0Hz)" should not set the property value
+PASS e.style['opacity'] = "exp(0dpi)" should not set the property value
+PASS e.style['opacity'] = "exp(0fr)" should not set the property value
+PASS e.style['opacity'] = "exp(1, 1%)" should not set the property value
+PASS e.style['opacity'] = "exp(1, 0px)" should not set the property value
+PASS e.style['opacity'] = "exp(1, 0s)" should not set the property value
+PASS e.style['opacity'] = "exp(1, 0deg)" should not set the property value
+PASS e.style['opacity'] = "exp(1, 0Hz)" should not set the property value
+PASS e.style['opacity'] = "exp(1, 0dpi)" should not set the property value
+PASS e.style['opacity'] = "exp(1, 0fr)" should not set the property value
+PASS e.style['opacity'] = "log(0px)" should not set the property value
+PASS e.style['opacity'] = "log(0s)" should not set the property value
+PASS e.style['opacity'] = "log(0deg)" should not set the property value
+PASS e.style['opacity'] = "log(0Hz)" should not set the property value
+PASS e.style['opacity'] = "log(0dpi)" should not set the property value
+PASS e.style['opacity'] = "log(0fr)" should not set the property value
+PASS e.style['opacity'] = "log(1, 1%)" should not set the property value
+PASS e.style['opacity'] = "log(1, 0px)" should not set the property value
+PASS e.style['opacity'] = "log(1, 0s)" should not set the property value
+PASS e.style['opacity'] = "log(1, 0deg)" should not set the property value
+PASS e.style['opacity'] = "log(1, 0Hz)" should not set the property value
+PASS e.style['opacity'] = "log(1, 0dpi)" should not set the property value
+PASS e.style['opacity'] = "log(1, 0fr)" should not set the property value
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-invalid.html (0 => 282795)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-invalid.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-invalid.html 2021-09-21 00:24:50 UTC (rev 282795)
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<link rel="help" href=""
+<link rel="help" href=""
+<link rel="help" href=""
+<link rel="author" title="Apple Inc">
+<script src=""
+<script src=""
+<script src=""
+<script>
+function test_invalid_number(value) {
+ test_invalid_value('opacity', value);
+}
+
+// Syntax checking
+test_invalid_number('exp()');
+test_invalid_number('exp( )');
+test_invalid_number('exp(,)');
+test_invalid_number('exp(1, )');
+test_invalid_number('exp(, 1)');
+test_invalid_number('exp(1 + )');
+test_invalid_number('exp(1 - )');
+test_invalid_number('exp(1 * )');
+test_invalid_number('exp(1 / )');
+test_invalid_number('exp(1 2)');
+test_invalid_number('exp(1, , 2)');
+test_invalid_number('log()');
+test_invalid_number('log( )');
+test_invalid_number('log(,)');
+test_invalid_number('log(1, )');
+test_invalid_number('log(, 1)');
+test_invalid_number('log(1 + )');
+test_invalid_number('log(1 - )');
+test_invalid_number('log(1 * )');
+test_invalid_number('log(1 / )');
+test_invalid_number('log(1 2)');
+test_invalid_number('log(1, , 2)');
+
+// Type checking
+test_invalid_number('exp(0px)');
+test_invalid_number('exp(0s)');
+test_invalid_number('exp(0deg)');
+test_invalid_number('exp(0Hz)');
+test_invalid_number('exp(0dpi)');
+test_invalid_number('exp(0fr)');
+test_invalid_number('exp(1, 1%)');
+test_invalid_number('exp(1, 0px)');
+test_invalid_number('exp(1, 0s)');
+test_invalid_number('exp(1, 0deg)');
+test_invalid_number('exp(1, 0Hz)');
+test_invalid_number('exp(1, 0dpi)');
+test_invalid_number('exp(1, 0fr)');
+test_invalid_number('log(0px)');
+test_invalid_number('log(0s)');
+test_invalid_number('log(0deg)');
+test_invalid_number('log(0Hz)');
+test_invalid_number('log(0dpi)');
+test_invalid_number('log(0fr)');
+test_invalid_number('log(1, 1%)');
+test_invalid_number('log(1, 0px)');
+test_invalid_number('log(1, 0s)');
+test_invalid_number('log(1, 0deg)');
+test_invalid_number('log(1, 0Hz)');
+test_invalid_number('log(1, 0dpi)');
+test_invalid_number('log(1, 0fr)');
+</script>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-serialize-expected.txt (0 => 282795)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-serialize-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-serialize-expected.txt 2021-09-21 00:24:50 UTC (rev 282795)
@@ -0,0 +1,18 @@
+
+FAIL 'exp(0)' as a specified value should serialize as 'calc(1)'. assert_equals: 'exp(0)' and 'calc(1)' should serialize the same in specified values. expected "calc(1)" but got "exp(0)"
+FAIL 'scale(exp(0))' as a specified value should serialize as 'scale(calc(1))'. assert_equals: 'scale(exp(0))' and 'scale(calc(1))' should serialize the same in specified values. expected "scale(calc(1))" but got "scale(exp(0))"
+PASS 'exp(0)' as a computed value should serialize as '1'.
+PASS 'scale(exp(0))' as a computed value should serialize as 'matrix(1, 0, 0, 1, 0, 0)'.
+FAIL 'log(1)' as a specified value should serialize as 'calc(0)'. assert_equals: 'log(1)' and 'calc(0)' should serialize the same in specified values. expected "calc(0)" but got "log(1)"
+FAIL 'scale(log(1))' as a specified value should serialize as 'scale(calc(0))'. assert_equals: 'scale(log(1))' and 'scale(calc(0))' should serialize the same in specified values. expected "scale(calc(0))" but got "scale(log(1))"
+PASS 'log(1)' as a computed value should serialize as '0'.
+PASS 'scale(log(1))' as a computed value should serialize as 'matrix(0, 0, 0, 0, 0, 0)'.
+PASS 'calc(exp(0) + log(1) + log(1))' as a specified value should serialize as 'calc(1)'.
+PASS 'scale(calc(exp(0) + log(1) + log(1)))' as a specified value should serialize as 'scale(calc(1))'.
+PASS 'calc(exp(0) + log(1) + log(1))' as a computed value should serialize as '1'.
+PASS 'scale(calc(exp(0) + log(1) + log(1)))' as a computed value should serialize as 'matrix(1, 0, 0, 1, 0, 0)'.
+PASS 'calc(log(1) + 0.5)' as a specified value should serialize as 'calc(0.5)'.
+PASS 'scale(calc(log(1) + 0.5))' as a specified value should serialize as 'scale(calc(0.5))'.
+PASS 'calc(log(1) + 0.5)' as a computed value should serialize as '0.5'.
+PASS 'scale(calc(log(1) + 0.5))' as a computed value should serialize as 'matrix(0.5, 0, 0, 0.5, 0, 0)'.
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-serialize.html (0 => 282795)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-serialize.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/exp-log-serialize.html 2021-09-21 00:24:50 UTC (rev 282795)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<link rel="help" href=""
+<link rel="help" href=""
+<link rel="help" href=""
+<link rel="author" title="Apple Inc">
+<script src=""
+<script src=""
+<script src=""
+<div id=target></div>
+<script>
+function test_serialization(t,s,c) {
+ test_specified_serialization('opacity', t, s);
+ test_specified_serialization('transform', `scale(${t})`, `scale(${s})`);
+ test_computed_serialization('opacity', t, c);
+ test_computed_serialization('transform', `scale(${t})`, `matrix(${c}, 0, 0, ${c}, 0, 0)`);
+}
+
+test_serialization(
+ 'exp(0)',
+ 'calc(1)',
+ '1');
+test_serialization(
+ 'log(1)',
+ 'calc(0)',
+ '0');
+
+test_serialization(
+ 'calc(exp(0) + log(1) + log(1))',
+ 'calc(1)',
+ '1');
+
+test_serialization(
+ 'calc(log(1) + 0.5)',
+ 'calc(0.5)',
+ '0.5');
+</script>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (282794 => 282795)
--- trunk/Source/WebCore/ChangeLog 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/Source/WebCore/ChangeLog 2021-09-21 00:24:50 UTC (rev 282795)
@@ -1,3 +1,40 @@
+2021-09-20 Nikos Mouchtaris <[email protected]>
+
+ Implement exp,log functions calc functions
+ https://bugs.webkit.org/show_bug.cgi?id=229897
+
+ Reviewed by Simon Fraser.
+
+ Added support for calc functions exp and log. Involved adding exp and log CSS keywords and handling
+ for parsing these functions and their arguments as well as computing the result based on the arguments.
+ Spec for these functions: https://drafts.csswg.org/css-values-4/#exponent-funcs.
+
+ Tests: imported/w3c/web-platform-tests/css/css-values/exp-log-compute.html
+ imported/w3c/web-platform-tests/css/css-values/exp-log-invalid.html
+ imported/w3c/web-platform-tests/css/css-values/exp-log-serialize.html
+
+ * css/CSSValueKeywords.in:
+ * css/calc/CSSCalcExpressionNodeParser.cpp:
+ (WebCore::CSSCalcExpressionNodeParser::parseCalcFunction):
+ * css/calc/CSSCalcOperationNode.cpp:
+ (WebCore::determineCategory):
+ (WebCore::functionFromOperator):
+ (WebCore::CSSCalcOperationNode::createLog):
+ (WebCore::CSSCalcOperationNode::createExp):
+ (WebCore::CSSCalcOperationNode::combineChildren):
+ (WebCore::CSSCalcOperationNode::simplifyNode):
+ (WebCore::functionPrefixForOperator):
+ (WebCore::CSSCalcOperationNode::evaluateOperator):
+ * css/calc/CSSCalcOperationNode.h:
+ * css/calc/CSSCalcValue.cpp:
+ (WebCore::createCSS):
+ (WebCore::CSSCalcValue::isCalcFunction):
+ * platform/calc/CalcExpressionOperation.cpp:
+ (WebCore::CalcExpressionOperation::evaluate const):
+ * platform/calc/CalcOperator.cpp:
+ (WebCore::operator<<):
+ * platform/calc/CalcOperator.h:
+
2021-09-20 Ross Kirsling <[email protected]>
Unreviewed build fix for WinCairo with ENABLE_EXPERIMENTAL_FEATURES off.
Modified: trunk/Source/WebCore/css/CSSValueKeywords.in (282794 => 282795)
--- trunk/Source/WebCore/css/CSSValueKeywords.in 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/Source/WebCore/css/CSSValueKeywords.in 2021-09-21 00:24:50 UTC (rev 282795)
@@ -1351,6 +1351,8 @@
cos
e
pi
+exp
+log
from-image
Modified: trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.cpp (282794 => 282795)
--- trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.cpp 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.cpp 2021-09-21 00:24:50 UTC (rev 282795)
@@ -129,6 +129,11 @@
minArgumentCount = 3;
maxArgumentCount = 3;
break;
+
+ case CSSValueLog:
+ maxArgumentCount = 2;
+ break;
+ case CSSValueExp:
case CSSValueSin:
case CSSValueCos:
case CSSValueTan:
@@ -187,6 +192,12 @@
case CSSValueCalc:
result = CSSCalcOperationNode::createSum(WTFMove(nodes));
break;
+ case CSSValueLog:
+ result = CSSCalcOperationNode::createLog(WTFMove(nodes));
+ break;
+ case CSSValueExp:
+ result = CSSCalcOperationNode::createExp(WTFMove(nodes));
+ break;
// TODO: clamp, sin, cos, tan, asin, acos, atan, atan2, pow, sqrt, hypot
default:
break;
Modified: trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp (282794 => 282795)
--- trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp 2021-09-21 00:24:50 UTC (rev 282795)
@@ -79,6 +79,8 @@
case CalcOperator::Min:
case CalcOperator::Max:
case CalcOperator::Clamp:
+ case CalcOperator::Log:
+ case CalcOperator::Exp:
ASSERT_NOT_REACHED();
return CalculationCategory::Other;
}
@@ -150,6 +152,8 @@
case CalcOperator::Min:
case CalcOperator::Max:
case CalcOperator::Clamp:
+ case CalcOperator::Log:
+ case CalcOperator::Exp:
// The type of a min(), max(), or clamp() _expression_ is the result of adding the types of its comma-separated calculations
return CalculationCategory::Other;
}
@@ -267,6 +271,10 @@
return CSSValueCos;
case CalcOperator::Tan:
return CSSValueTan;
+ case CalcOperator::Exp:
+ return CSSValueExp;
+ case CalcOperator::Log:
+ return CSSValueLog;
}
return CSSValueCalc;
}
@@ -319,6 +327,40 @@
return adoptRef(new CSSCalcOperationNode(newCategory, CalcOperator::Multiply, WTFMove(values)));
}
+RefPtr<CSSCalcOperationNode> CSSCalcOperationNode::createLog(Vector<Ref<CSSCalcExpressionNode>>&& values)
+{
+ if (values.size() != 1 && values.size() != 2)
+ return nullptr;
+ for (auto& value : values) {
+ // TODO: Support infinity
+ if (value->category() != CalculationCategory::Number || !value->doubleValue(value->primitiveType())) {
+ LOG_WITH_STREAM(Calc, stream << "Failed to create log node because unable to determine category from " << prettyPrintNodes(values));
+ return nullptr;
+ }
+ }
+
+ // TODO: Support infinity
+ if ((values.size() == 2 && values[1]->doubleValue(values[1]->primitiveType()) == 1)) {
+ LOG_WITH_STREAM(Calc, stream << "Failed to create log node because unable to determine category from " << prettyPrintNodes(values));
+ return nullptr;
+ }
+
+ return adoptRef(new CSSCalcOperationNode(CalculationCategory::Number, CalcOperator::Log, WTFMove(values)));
+}
+
+RefPtr<CSSCalcOperationNode> CSSCalcOperationNode::createExp(Vector<Ref<CSSCalcExpressionNode>>&& values)
+{
+ if (values.size() != 1)
+ return nullptr;
+
+ if (values[0]->category() != CalculationCategory::Number) {
+ LOG_WITH_STREAM(Calc, stream << "Failed to create exp node because unable to determine category from " << prettyPrintNodes(values));
+ return nullptr;
+ }
+
+ return adoptRef(new CSSCalcOperationNode(CalculationCategory::Number, CalcOperator::Exp, WTFMove(values)));
+}
+
RefPtr<CSSCalcOperationNode> CSSCalcOperationNode::createMinOrMaxOrClamp(CalcOperator op, Vector<Ref<CSSCalcExpressionNode>>&& values, CalculationCategory destinationCategory)
{
ASSERT(op == CalcOperator::Min || op == CalcOperator::Max || op == CalcOperator::Clamp);
@@ -435,6 +477,13 @@
if (m_children.size() == 1 && isTrigNode()) {
double resolvedValue = doubleValue(m_children[0]->primitiveType());
auto newChild = CSSCalcPrimitiveValueNode::create(CSSPrimitiveValue::create(resolvedValue, CSSUnitType::CSS_NUMBER));
+ m_children.clear();
+ m_children.append(WTFMove(newChild));
+ }
+
+ if (isExpNode()) {
+ double resolvedValue = doubleValue(m_children[0]->primitiveType());
+ auto newChild = CSSCalcPrimitiveValueNode::create(CSSPrimitiveValue::create(resolvedValue, CSSUnitType::CSS_NUMBER));
m_children.clear();
m_children.append(WTFMove(newChild));
@@ -630,7 +679,7 @@
if (is<CSSCalcOperationNode>(rootNode)) {
auto& calcOperationNode = downcast<CSSCalcOperationNode>(rootNode.get());
// Simplify operations with only one child node (other than root and operations that only need one node).
- if (calcOperationNode.children().size() == 1 && depth && !calcOperationNode.isTrigNode())
+ if (calcOperationNode.children().size() == 1 && depth && !calcOperationNode.isTrigNode() && !calcOperationNode.isExpNode())
return WTFMove(calcOperationNode.children()[0]);
if (calcOperationNode.isCalcSumNode()) {
@@ -649,6 +698,9 @@
if (calcOperationNode.isTrigNode() && depth)
calcOperationNode.combineChildren();
+ if (calcOperationNode.isExpNode() && depth)
+ calcOperationNode.combineChildren();
+
// If only one child remains, return the child (except at the root).
auto shouldCombineParentWithOnlyChild = [](const CSSCalcOperationNode& parent, int depth)
{
@@ -840,6 +892,8 @@
case CalcOperator::Min: return "min(";
case CalcOperator::Max: return "max(";
case CalcOperator::Clamp: return "clamp(";
+ case CalcOperator::Exp: return "exp(";
+ case CalcOperator::Log: return "log(";
}
return "";
@@ -1056,7 +1110,19 @@
return std::numeric_limits<double>::quiet_NaN();
return std::tan(children[0]);
}
+ case CalcOperator::Log: {
+ if (children.size() != 1 && children.size() != 2)
+ return std::numeric_limits<double>::quiet_NaN();
+ if (children.size() == 1)
+ return std::log(children[0]);
+ return std::log(children[0]) / std::log(children[1]);
}
+ case CalcOperator::Exp: {
+ if (children.size() != 1)
+ return std::numeric_limits<double>::quiet_NaN();
+ return std::exp(children[0]);
+ }
+ }
ASSERT_NOT_REACHED();
return 0;
}
Modified: trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h (282794 => 282795)
--- trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h 2021-09-21 00:24:50 UTC (rev 282795)
@@ -38,6 +38,8 @@
static RefPtr<CSSCalcOperationNode> createProduct(Vector<Ref<CSSCalcExpressionNode>>&& values);
static RefPtr<CSSCalcOperationNode> createMinOrMaxOrClamp(CalcOperator, Vector<Ref<CSSCalcExpressionNode>>&& values, CalculationCategory destinationCategory);
static RefPtr<CSSCalcOperationNode> createTrig(CalcOperator, Vector<Ref<CSSCalcExpressionNode>>&& values);
+ static RefPtr<CSSCalcOperationNode> createLog(Vector<Ref<CSSCalcExpressionNode>>&& values);
+ static RefPtr<CSSCalcOperationNode> createExp(Vector<Ref<CSSCalcExpressionNode>>&& values);
static Ref<CSSCalcExpressionNode> simplify(Ref<CSSCalcExpressionNode>&&);
@@ -48,6 +50,7 @@
bool isCalcProductNode() const { return m_operator == CalcOperator::Multiply; }
bool isMinOrMaxNode() const { return m_operator == CalcOperator::Min || m_operator == CalcOperator::Max; }
bool isTrigNode() const { return m_operator == CalcOperator::Sin || m_operator == CalcOperator::Cos || m_operator == CalcOperator::Tan; }
+ bool isExpNode() const { return m_operator == CalcOperator::Exp || m_operator == CalcOperator::Log; }
bool shouldSortChildren() const { return isCalcSumNode() || isCalcProductNode(); }
void hoistChildrenWithOperator(CalcOperator);
Modified: trunk/Source/WebCore/css/calc/CSSCalcValue.cpp (282794 => 282795)
--- trunk/Source/WebCore/css/calc/CSSCalcValue.cpp 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/Source/WebCore/css/calc/CSSCalcValue.cpp 2021-09-21 00:24:50 UTC (rev 282795)
@@ -180,7 +180,19 @@
return nullptr;
return CSSCalcOperationNode::createMinOrMaxOrClamp(op, WTFMove(children), operationNode.destinationCategory());
}
+ case CalcOperator::Log: {
+ auto children = createCSS(operationChildren, style);
+ if (children.size() != 1 && children.size() != 2)
+ return nullptr;
+ return CSSCalcOperationNode::createLog(WTFMove(children));
}
+ case CalcOperator::Exp: {
+ auto children = createCSS(operationChildren, style);
+ if (children.size() != 1)
+ return nullptr;
+ return CSSCalcOperationNode::createExp(WTFMove(children));
+ }
+ }
return nullptr;
}
case CalcExpressionNodeType::BlendLength: {
@@ -294,6 +306,8 @@
case CSSValueSin:
case CSSValueCos:
case CSSValueTan:
+ case CSSValueExp:
+ case CSSValueLog:
return true;
default:
return false;
Modified: trunk/Source/WebCore/platform/calc/CalcExpressionOperation.cpp (282794 => 282795)
--- trunk/Source/WebCore/platform/calc/CalcExpressionOperation.cpp 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/Source/WebCore/platform/calc/CalcExpressionOperation.cpp 2021-09-21 00:24:50 UTC (rev 282795)
@@ -102,7 +102,19 @@
return std::numeric_limits<double>::quiet_NaN();
return std::tan(m_children[0]->evaluate(maxValue));
}
+ case CalcOperator::Log: {
+ if (m_children.size() != 1 && m_children.size() != 2)
+ return std::numeric_limits<float>::quiet_NaN();
+ if (m_children.size() == 1)
+ return std::log(m_children[0]->evaluate(maxValue));
+ return std::log(m_children[0]->evaluate(maxValue)) / std::log(m_children[1]->evaluate(maxValue));
}
+ case CalcOperator::Exp: {
+ if (m_children.size() != 1)
+ return std::numeric_limits<float>::quiet_NaN();
+ return std::exp(m_children[0]->evaluate(maxValue));
+ }
+ }
ASSERT_NOT_REACHED();
return std::numeric_limits<float>::quiet_NaN();
}
Modified: trunk/Source/WebCore/platform/calc/CalcOperator.cpp (282794 => 282795)
--- trunk/Source/WebCore/platform/calc/CalcOperator.cpp 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/Source/WebCore/platform/calc/CalcOperator.cpp 2021-09-21 00:24:50 UTC (rev 282795)
@@ -43,6 +43,8 @@
case CalcOperator::Sin: ts << "sin"; break;
case CalcOperator::Cos: ts << "cos"; break;
case CalcOperator::Tan: ts << "tan"; break;
+ case CalcOperator::Exp: ts << "exp"; break;
+ case CalcOperator::Log: ts << "log"; break;
}
return ts;
}
Modified: trunk/Source/WebCore/platform/calc/CalcOperator.h (282794 => 282795)
--- trunk/Source/WebCore/platform/calc/CalcOperator.h 2021-09-21 00:14:38 UTC (rev 282794)
+++ trunk/Source/WebCore/platform/calc/CalcOperator.h 2021-09-21 00:24:50 UTC (rev 282795)
@@ -41,6 +41,8 @@
Sin,
Cos,
Tan,
+ Exp,
+ Log,
};
TextStream& operator<<(TextStream&, CalcOperator);