diff --git a/lib/scenic/script.ex b/lib/scenic/script.ex index b0869757..64539d00 100644 --- a/lib/scenic/script.ex +++ b/lib/scenic/script.ex @@ -202,6 +202,7 @@ defmodule Scenic.Script do @op_sector 0x2F @op_circle 0x30 @op_ellipse 0x31 + @op_arc 0x32 @op_push_state 0x40 @op_pop_state 0x41 @@ -829,6 +830,33 @@ defmodule Scenic.Script do [{:ellipse, {radius0, radius1}} | ops] end + @doc """ + Adds a new **circle arc** shaped segment to the path. + + This adds to the current path. It does not fill or stroke anything. + + ## Parameters + + - cx, cy: The coordinates of the arc's center. + - r: the radius of the arc. + - a0, a1: the angles which the arc is drawn from angle a0 to a1, in radians. + - dir: s the direction of the arc sweep: + - `1` for counter clockwise sweep; + - `2` for clockwise sweep. + """ + @spec arc( + ops :: t(), + cx :: number, + cy :: number, + r :: number, + a0 :: number, + a1 :: number, + dir :: integer + ) :: ops :: t() + def arc(ops, cx, cy, r, a0, a1, dir) do + [{:arc, {cx, cy, r, a0, a1, dir}} | ops] + end + @doc """ Add a triangle to the current path. @@ -1539,6 +1567,23 @@ defmodule Scenic.Script do ] end + defp serialize_op({:arc, {cx, cy, r, a0, a1, dir}}) do + [ + << + @op_arc::16-big, + 0::16 + >>, + << + cx::float-32-big, + cy::float-32-big, + r::float-32-big, + a0::float-32-big, + a1::float-32-big, + dir::32-big + >> + ] + end + defp serialize_op({:bezier_to, {cp1x, cp1y, cp2x, cp2y, x, y}}) do [ << @@ -2263,6 +2308,20 @@ defmodule Scenic.Script do {{:arc_to, {x1, y1, x2, y2, radius}}, bin} end + defp deserialize_op(<< + @op_arc::16-big, + 0::16, + cx::float-32-big, + cy::float-32-big, + r::float-32-big, + a0::float-32-big, + a1::float-32-big, + dir::32-big, + bin::binary + >>) do + {{:arc, {cx, cy, r, a0, a1, dir}}, bin} + end + defp deserialize_op(<< @op_bezier_to::16-big, 0::16, diff --git a/test/scenic/script_test.exs b/test/scenic/script_test.exs index 6e6b6577..6790b864 100644 --- a/test/scenic/script_test.exs +++ b/test/scenic/script_test.exs @@ -351,6 +351,12 @@ defmodule Scenic.ScriptTest do assert expected == Script.serialize(expected) |> Script.deserialize() end + test "arc works" do + expected = [{:arc, {0.0, 0.0, 5.0, 0.0, 6.0, 1}}] + assert Script.arc([], 0, 0, 5, 0, 6, 1) == expected + assert expected == Script.serialize(expected) |> Script.deserialize() + end + # -------------------------------------------------------- # transform commands