Changeset 283013 in webkit
- Timestamp:
- Sep 23, 2021 3:01:16 PM (10 months ago)
- Location:
- trunk
- Files:
-
- 6 added
- 11 edited
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-values/acos-asin-atan-atan2-computed-expected.txt (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-values/acos-asin-atan-atan2-computed.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-values/acos-asin-atan-atan2-invalid-expected.txt (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-values/acos-asin-atan-atan2-invalid.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-values/acos-asin-atan-atan2-serialize-expected.txt (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-values/acos-asin-atan-atan2-serialize.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/support/numeric-testcommon.js (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/css/CSSValueKeywords.in (modified) (1 diff)
-
Source/WebCore/css/calc/CSSCalcExpressionNodeParser.cpp (modified) (2 diffs)
-
Source/WebCore/css/calc/CSSCalcOperationNode.cpp (modified) (12 diffs)
-
Source/WebCore/css/calc/CSSCalcOperationNode.h (modified) (2 diffs)
-
Source/WebCore/css/calc/CSSCalcValue.cpp (modified) (2 diffs)
-
Source/WebCore/platform/calc/CalcExpressionOperation.cpp (modified) (1 diff)
-
Source/WebCore/platform/calc/CalcOperator.cpp (modified) (1 diff)
-
Source/WebCore/platform/calc/CalcOperator.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r282922 r283013 1 2021-09-23 Nikos Mouchtaris <nmouchtaris@apple.com> 2 3 Implement atan, acos, asin, atan2 calc functions 4 https://bugs.webkit.org/show_bug.cgi?id=229775 5 6 Reviewed by Simon Fraser. 7 8 * web-platform-tests/css/css-values/acos-asin-atan-atan2-computed-expected.txt: Added. 9 * web-platform-tests/css/css-values/acos-asin-atan-atan2-computed.html: Added. 10 * web-platform-tests/css/css-values/acos-asin-atan-atan2-invalid-expected.txt: Added. 11 * web-platform-tests/css/css-values/acos-asin-atan-atan2-invalid.html: Added. 12 * web-platform-tests/css/css-values/acos-asin-atan-atan2-serialize-expected.txt: Added. 13 * web-platform-tests/css/css-values/acos-asin-atan-atan2-serialize.html: Added. 14 * web-platform-tests/css/support/numeric-testcommon.js: 15 1 16 2021-09-22 Myles C. Maxfield <mmaxfield@apple.com> 2 17 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/support/numeric-testcommon.js
r282402 r283013 185 185 const expectedValue = getComputedStyle(testEl)[prop]; 186 186 assert_not_equals(expectedValue, '', `${expectedString} isn't valid in '${prop}'; got the default value instead.`) 187 if(approx && type == "number"){187 if(approx && (type == "number" || type == "angle")){ 188 188 let parsedUsed = usedValue.split('(')[1].split(')')[0].split(',').map(parseFloat); 189 189 let parsedExpected = expectedValue.split('(')[1].split(')')[0].split(',').map(parseFloat); -
trunk/Source/WebCore/ChangeLog
r282988 r283013 1 2021-09-23 Nikos Mouchtaris <nmouchtaris@apple.com> 2 3 Implement atan, acos, asin, atan2 calc functions 4 https://bugs.webkit.org/show_bug.cgi?id=229775 5 6 Reviewed by Simon Fraser. 7 8 Added support for calc functions asin, acos, atan, atan2. Involved adding function CSS 9 keywords and handling for parsing these functions and their arguments as well as computing 10 the result based on the arguments. Spec for these functions: 11 https://drafts.csswg.org/css-values-4/#trig-funcs. 12 13 Tests: imported/w3c/web-platform-tests/css/css-values/acos-asin-atan-atan2-computed.html 14 imported/w3c/web-platform-tests/css/css-values/acos-asin-atan-atan2-invalid.html 15 imported/w3c/web-platform-tests/css/css-values/acos-asin-atan-atan2-serialize.html 16 17 * css/CSSValueKeywords.in: 18 * css/calc/CSSCalcExpressionNodeParser.cpp: 19 (WebCore::CSSCalcExpressionNodeParser::parseCalcFunction): 20 * css/calc/CSSCalcOperationNode.cpp: 21 (WebCore::determineCategory): 22 (WebCore::functionFromOperator): 23 (WebCore::CSSCalcOperationNode::createInverseTrig): 24 (WebCore::CSSCalcOperationNode::createAtan2): 25 (WebCore::CSSCalcOperationNode::combineChildren): 26 (WebCore::CSSCalcOperationNode::simplifyNode): 27 (WebCore::CSSCalcOperationNode::primitiveType const): 28 (WebCore::CSSCalcOperationNode::doubleValue const): 29 (WebCore::functionPrefixForOperator): 30 (WebCore::CSSCalcOperationNode::evaluateOperator): 31 * css/calc/CSSCalcOperationNode.h: 32 * css/calc/CSSCalcValue.cpp: 33 (WebCore::createCSS): 34 (WebCore::CSSCalcValue::isCalcFunction): 35 * platform/calc/CalcExpressionOperation.cpp: 36 (WebCore::CalcExpressionOperation::evaluate const): 37 Return converted to degrees based on spec: https://drafts.csswg.org/css-values-4/#trig-funcs. 38 * platform/calc/CalcOperator.cpp: 39 (WebCore::operator<<): 40 * platform/calc/CalcOperator.h: 41 1 42 2021-09-23 Tim Horton <timothy_horton@apple.com> 2 43 -
trunk/Source/WebCore/css/CSSValueKeywords.in
r282851 r283013 1354 1354 exp 1355 1355 log 1356 asin 1357 acos 1358 atan 1359 atan2 1356 1360 1357 1361 from-image -
trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.cpp
r282795 r283013 138 138 case CSSValueCos: 139 139 case CSSValueTan: 140 141 case CSSValueAcos: 142 case CSSValueAsin: 143 case CSSValueAtan: 140 144 case CSSValueCalc: 141 145 maxArgumentCount = 1; 142 146 break; 143 // TODO: clamp, sin, cos, tan, asin, acos, atan, atan2, pow, sqrt, hypot. 147 case CSSValueAtan2: 148 maxArgumentCount = 2; 149 break; 150 // TODO: pow, sqrt, hypot. 144 151 default: 145 152 break; … … 199 206 result = CSSCalcOperationNode::createExp(WTFMove(nodes)); 200 207 break; 201 // TODO: clamp, sin, cos, tan, asin, acos, atan, atan2, pow, sqrt, hypot 208 case CSSValueAcos: 209 result = CSSCalcOperationNode::createInverseTrig(CalcOperator::Acos, WTFMove(nodes)); 210 break; 211 case CSSValueAsin: 212 result = CSSCalcOperationNode::createInverseTrig(CalcOperator::Asin, WTFMove(nodes)); 213 break; 214 case CSSValueAtan: 215 result = CSSCalcOperationNode::createInverseTrig(CalcOperator::Atan, WTFMove(nodes)); 216 break; 217 case CSSValueAtan2: 218 result = CSSCalcOperationNode::createAtan2(WTFMove(nodes)); 219 break; 220 // TODO: pow, sqrt, hypot 202 221 default: 203 222 break; -
trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp
r282795 r283013 82 82 case CalcOperator::Log: 83 83 case CalcOperator::Exp: 84 case CalcOperator::Asin: 85 case CalcOperator::Acos: 86 case CalcOperator::Atan: 87 case CalcOperator::Atan2: 84 88 ASSERT_NOT_REACHED(); 85 89 return CalculationCategory::Other; … … 155 159 case CalcOperator::Log: 156 160 case CalcOperator::Exp: 161 case CalcOperator::Asin: 162 case CalcOperator::Acos: 163 case CalcOperator::Atan: 164 case CalcOperator::Atan2: 157 165 // The type of a min(), max(), or clamp() expression is the result of adding the types of its comma-separated calculations 158 166 return CalculationCategory::Other; … … 276 284 case CalcOperator::Log: 277 285 return CSSValueLog; 286 case CalcOperator::Asin: 287 return CSSValueAsin; 288 case CalcOperator::Acos: 289 return CSSValueAcos; 290 case CalcOperator::Atan: 291 return CSSValueAtan; 292 case CalcOperator::Atan2: 293 return CSSValueAtan2; 278 294 } 279 295 return CSSValueCalc; … … 312 328 313 329 return adoptRef(new CSSCalcOperationNode(newCategory, CalcOperator::Add, WTFMove(values))); 330 } 331 332 RefPtr<CSSCalcOperationNode> CSSCalcOperationNode::createInverseTrig(CalcOperator op, Vector<Ref<CSSCalcExpressionNode>>&& values) 333 { 334 if (values.size() != 1) 335 return nullptr; 336 337 auto childCategory = values[0]->category(); 338 if (childCategory != CalculationCategory::Number) { 339 LOG_WITH_STREAM(Calc, stream << "Failed to create trig node because unable to determine category from " << prettyPrintNodes(values)); 340 return nullptr; 341 } 342 343 return adoptRef(new CSSCalcOperationNode(CalculationCategory::Angle, op, WTFMove(values))); 344 } 345 346 RefPtr<CSSCalcOperationNode> CSSCalcOperationNode::createAtan2(Vector<Ref<CSSCalcExpressionNode>>&& values) 347 { 348 if (values.size() != 2) 349 return nullptr; 350 351 auto child1Category = values[0]->category(); 352 auto child2Category = values[1]->category(); 353 if (child1Category != child2Category) { 354 LOG_WITH_STREAM(Calc, stream << "Failed to create atan2 node because unable to determine category from " << prettyPrintNodes(values)); 355 return nullptr; 356 } 357 return adoptRef(new CSSCalcOperationNode(CalculationCategory::Angle, CalcOperator::Atan2, WTFMove(values))); 314 358 } 315 359 … … 485 529 double resolvedValue = doubleValue(m_children[0]->primitiveType()); 486 530 auto newChild = CSSCalcPrimitiveValueNode::create(CSSPrimitiveValue::create(resolvedValue, CSSUnitType::CSS_NUMBER)); 487 531 m_children.clear(); 532 m_children.append(WTFMove(newChild)); 533 } 534 535 if (m_children.size() == 1 && isInverseTrigNode()) { 536 double resolvedValue = doubleValue(m_children[0]->primitiveType()); 537 auto newChild = CSSCalcPrimitiveValueNode::create(CSSPrimitiveValue::create(resolvedValue, CSSUnitType::CSS_DEG)); 488 538 m_children.clear(); 489 539 m_children.append(WTFMove(newChild)); … … 622 672 m_children.append(WTFMove(newChild)); 623 673 } 674 675 if (calcOperator() == CalcOperator::Atan2) { 676 double resolvedValue = doubleValue(m_children[0]->primitiveType()); 677 auto newChild = CSSCalcPrimitiveValueNode::create(CSSPrimitiveValue::create(resolvedValue, CSSUnitType::CSS_DEG)); 678 m_children.clear(); 679 m_children.append(WTFMove(newChild)); 680 } 624 681 } 625 682 … … 680 737 auto& calcOperationNode = downcast<CSSCalcOperationNode>(rootNode.get()); 681 738 // Simplify operations with only one child node (other than root and operations that only need one node). 682 if (calcOperationNode.children().size() == 1 && depth && !calcOperationNode.isTrigNode() && !calcOperationNode.isExpNode() )739 if (calcOperationNode.children().size() == 1 && depth && !calcOperationNode.isTrigNode() && !calcOperationNode.isExpNode() && !calcOperationNode.isInverseTrigNode()) 683 740 return WTFMove(calcOperationNode.children()[0]); 684 741 … … 702 759 calcOperationNode.combineChildren(); 703 760 761 if (calcOperationNode.isInverseTrigNode() && depth) 762 calcOperationNode.combineChildren(); 763 764 if (calcOperationNode.isAtan2Node() && depth) 765 calcOperationNode.combineChildren(); 766 704 767 // If only one child remains, return the child (except at the root). 705 768 auto shouldCombineParentWithOnlyChild = [](const CSSCalcOperationNode& parent, int depth) … … 789 852 case CalculationCategory::Time: 790 853 case CalculationCategory::Frequency: 791 if (m_children.size() == 1 )854 if (m_children.size() == 1 && !isInverseTrigNode()) 792 855 return m_children.first()->primitiveType(); 793 856 return canonicalUnitTypeForCalculationCategory(unitCategory); … … 835 898 if (isTrigNode() && unitType != CSSUnitType::CSS_NUMBER) 836 899 childType = CSSUnitType::CSS_RAD; 900 if (isInverseTrigNode()) 901 childType = CSSUnitType::CSS_NUMBER; 902 if (isAtan2Node()) 903 childType = child->primitiveType(); 837 904 return child->doubleValue(childType); 838 905 })); … … 895 962 case CalcOperator::Exp: return "exp("; 896 963 case CalcOperator::Log: return "log("; 964 case CalcOperator::Asin: return "asin("; 965 case CalcOperator::Acos: return "acos("; 966 case CalcOperator::Atan: return "atan("; 967 case CalcOperator::Atan2: return "atan2("; 897 968 } 898 969 … … 1123 1194 return std::exp(children[0]); 1124 1195 } 1196 case CalcOperator::Asin: { 1197 if (children.size() != 1) 1198 return std::numeric_limits<double>::quiet_NaN(); 1199 return rad2deg(std::asin(children[0])); 1200 } 1201 case CalcOperator::Acos: { 1202 if (children.size() != 1) 1203 return std::numeric_limits<double>::quiet_NaN(); 1204 return rad2deg(std::acos(children[0])); 1205 } 1206 case CalcOperator::Atan: { 1207 if (children.size() != 1) 1208 return std::numeric_limits<double>::quiet_NaN(); 1209 return rad2deg(std::atan(children[0])); 1210 } 1211 case CalcOperator::Atan2: { 1212 if (children.size() != 2) 1213 return std::numeric_limits<double>::quiet_NaN(); 1214 return rad2deg(atan2(children[0], children[1])); 1215 } 1125 1216 } 1126 1217 ASSERT_NOT_REACHED(); -
trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h
r282795 r283013 41 41 static RefPtr<CSSCalcOperationNode> createLog(Vector<Ref<CSSCalcExpressionNode>>&& values); 42 42 static RefPtr<CSSCalcOperationNode> createExp(Vector<Ref<CSSCalcExpressionNode>>&& values); 43 static RefPtr<CSSCalcOperationNode> createInverseTrig(CalcOperator, Vector<Ref<CSSCalcExpressionNode>>&& values); 44 static RefPtr<CSSCalcOperationNode> createAtan2(Vector<Ref<CSSCalcExpressionNode>>&& values); 43 45 44 46 static Ref<CSSCalcExpressionNode> simplify(Ref<CSSCalcExpressionNode>&&); … … 52 54 bool isTrigNode() const { return m_operator == CalcOperator::Sin || m_operator == CalcOperator::Cos || m_operator == CalcOperator::Tan; } 53 55 bool isExpNode() const { return m_operator == CalcOperator::Exp || m_operator == CalcOperator::Log; } 56 bool isInverseTrigNode() const { return m_operator == CalcOperator::Asin || m_operator == CalcOperator::Acos || m_operator == CalcOperator::Atan; } 57 bool isAtan2Node() const { return m_operator == CalcOperator::Atan2; } 54 58 bool shouldSortChildren() const { return isCalcSumNode() || isCalcProductNode(); } 55 59 -
trunk/Source/WebCore/css/calc/CSSCalcValue.cpp
r282795 r283013 193 193 return CSSCalcOperationNode::createExp(WTFMove(children)); 194 194 } 195 case CalcOperator::Asin: 196 case CalcOperator::Acos: 197 case CalcOperator::Atan: { 198 auto children = createCSS(operationChildren, style); 199 if (children.size() != 1) 200 return nullptr; 201 return CSSCalcOperationNode::createInverseTrig(op, WTFMove(children)); 202 } 203 case CalcOperator::Atan2: { 204 auto children = createCSS(operationChildren, style); 205 if (children.size() != 2) 206 return nullptr; 207 return CSSCalcOperationNode::createAtan2(WTFMove(children)); 208 } 195 209 } 196 210 return nullptr; … … 309 323 case CSSValueExp: 310 324 case CSSValueLog: 325 case CSSValueAsin: 326 case CSSValueAcos: 327 case CSSValueAtan: 328 case CSSValueAtan2: 311 329 return true; 312 330 default: -
trunk/Source/WebCore/platform/calc/CalcExpressionOperation.cpp
r282795 r283013 115 115 return std::exp(m_children[0]->evaluate(maxValue)); 116 116 } 117 case CalcOperator::Asin: { 118 if (m_children.size() != 1) 119 return std::numeric_limits<float>::quiet_NaN(); 120 return rad2deg(std::asin(m_children[0]->evaluate(maxValue))); 121 } 122 case CalcOperator::Acos: { 123 if (m_children.size() != 1) 124 return std::numeric_limits<float>::quiet_NaN(); 125 return rad2deg(std::acos(m_children[0]->evaluate(maxValue))); 126 } 127 case CalcOperator::Atan: { 128 if (m_children.size() != 1) 129 return std::numeric_limits<float>::quiet_NaN(); 130 return rad2deg(std::atan(m_children[0]->evaluate(maxValue))); 131 } 132 case CalcOperator::Atan2: { 133 if (m_children.size() != 2) 134 return std::numeric_limits<float>::quiet_NaN(); 135 return rad2deg(atan2(m_children[0]->evaluate(maxValue), m_children[1]->evaluate(maxValue))); 136 } 117 137 } 118 138 ASSERT_NOT_REACHED(); -
trunk/Source/WebCore/platform/calc/CalcOperator.cpp
r282795 r283013 46 46 case CalcOperator::Exp: ts << "exp"; break; 47 47 case CalcOperator::Log: ts << "log"; break; 48 case CalcOperator::Asin: ts << "asin"; break; 49 case CalcOperator::Acos: ts << "acos"; break; 50 case CalcOperator::Atan: ts << "atan"; break; 51 case CalcOperator::Atan2: ts << "atan2"; break; 48 52 } 49 53 return ts; -
trunk/Source/WebCore/platform/calc/CalcOperator.h
r282795 r283013 44 44 Exp, 45 45 Log, 46 Asin, 47 Acos, 48 Atan, 49 Atan2, 46 50 }; 47 51
Note: See TracChangeset
for help on using the changeset viewer.