Implement motion math ray() `at position`

As per spec update: https://drafts.fxtf.org/motion/#valdef-ray-at-position
ray() now consumes `at position` argument.

Note: animation of `at position` will be done in next CL.

Fixed: 1450184
Change-Id: I52abae96fc02b60a56c50d23176cd380f66bedd2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4574765
Commit-Queue: Daniil Sakhapov <sakhapov@chromium.org>
Reviewed-by: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/main@{#1151323}
diff --git a/css/motion/offset-path-ray-013-ref.html b/css/motion/offset-path-ray-013-ref.html
new file mode 100644
index 0000000..d6bf4c0
--- /dev/null
+++ b/css/motion/offset-path-ray-013-ref.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Motion Path test reference: ray() path with position and offset-position</title>
+<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
+
+<style>
+  #outer {
+    top: 100px;
+    left: 100px;
+    position: relative;
+    width: 600px;
+    height: 400px;
+  }
+  #box {
+    background-color: green;
+    position: relative;
+    top: 100px;
+    left: 100px;
+    transform: translate(-50px, -130px);
+    width: 100px;
+    height: 100px;
+  }
+</style>
+
+<div id="outer">
+  <div id="inner">
+    <div id="box"></div>
+  </div>
+</div>
diff --git a/css/motion/offset-path-ray-013.html b/css/motion/offset-path-ray-013.html
new file mode 100644
index 0000000..196ff4e
--- /dev/null
+++ b/css/motion/offset-path-ray-013.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Motion Path test: ray() path with position and offset-position</title>
+<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
+<link rel="match" href="offset-path-ray-013-ref.html">
+<link rel="help" href="https://drafts.fxtf.org/motion/#ray-function">
+
+<style>
+  #outer {
+    top: 100px;
+    left: 100px;
+    position: relative;
+    width: 600px;
+    height: 400px;
+  }
+  #box {
+    background-color: green;
+    position: relative;
+    top: 100px;
+    left: 100px;
+    offset-path: ray(0deg closest-side at 100px 30%);
+    offset-distance: 100%;
+    offset-position: 10px 90%;
+    width: 100px;
+    height: 100px;
+  }
+</style>
+
+<div id="outer">
+  <div id="box"></div>
+</div>
diff --git a/css/motion/offset-path-ray-014-ref.html b/css/motion/offset-path-ray-014-ref.html
new file mode 100644
index 0000000..cd0fab4
--- /dev/null
+++ b/css/motion/offset-path-ray-014-ref.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Motion Path test reference: ray() path with default position</title>
+<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
+
+<style>
+  #outer {
+    top: 100px;
+    left: 100px;
+    position: relative;
+    width: 600px;
+    height: 400px;
+  }
+  #box {
+    background-color: green;
+    position: relative;
+    top: 100px;
+    left: 100px;
+    transform: translate(150px, -150px);
+    width: 100px;
+    height: 100px;
+  }
+</style>
+
+<div id="outer">
+  <div id="inner">
+    <div id="box"></div>
+  </div>
+</div>
diff --git a/css/motion/offset-path-ray-014.html b/css/motion/offset-path-ray-014.html
new file mode 100644
index 0000000..42e431d
--- /dev/null
+++ b/css/motion/offset-path-ray-014.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Motion Path test: ray() path with default position</title>
+<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
+<link rel="match" href="offset-path-ray-014-ref.html">
+<link rel="help" href="https://drafts.fxtf.org/motion/#ray-function">
+
+<style>
+  #outer {
+    top: 100px;
+    left: 100px;
+    position: relative;
+    width: 600px;
+    height: 400px;
+  }
+  #box {
+    background-color: green;
+    position: relative;
+    top: 100px;
+    left: 100px;
+    offset-path: ray(0deg closest-side);
+    offset-distance: 100%;
+    offset-position: normal;
+    width: 100px;
+    height: 100px;
+  }
+</style>
+
+<div id="outer">
+  <div id="box"></div>
+</div>
diff --git a/css/motion/parsing/offset-path-parsing-valid.html b/css/motion/parsing/offset-path-parsing-valid.html
index 69acc92..8a22b94 100644
--- a/css/motion/parsing/offset-path-parsing-valid.html
+++ b/css/motion/parsing/offset-path-parsing-valid.html
@@ -21,6 +21,11 @@
 test_valid_value("offset-path", "ray(270deg farthest-corner contain)");
 test_valid_value("offset-path", "ray(-720deg sides)");
 test_valid_value("offset-path", "ray(calc(180deg - 45deg) farthest-side)", "ray(calc(135deg) farthest-side)");
+test_valid_value("offset-path", "ray(0deg at 100px 100px)");
+test_valid_value("offset-path", "ray(0deg sides at center center)");
+test_valid_value("offset-path", "ray(0deg at center center sides)", "ray(0deg sides at center center)");
+test_valid_value("offset-path", "ray(0deg at center center contain)", "ray(0deg contain at center center)");
+test_valid_value("offset-path", "ray(at 10px 10px 0deg contain)", "ray(0deg contain at 10px 10px)");
 
 test_valid_value("offset-path", 'path("m 20 0 h -100")');
 test_valid_value("offset-path", 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 300 300 Z")');