{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE QuantifiedConstraints #-}
module HGeometry.Miso.Svg.Draw
( Svg
, SVG
, module Ipe.Draw
) where
import HGeometry.Number.Radical
import Prelude hiding (sqrt)
import Data.List.NonEmpty (NonEmpty(..))
import Control.Lens
import Data.Kind (Type)
import HGeometry.PolyLine
import HGeometry.Point
import HGeometry.Ball
import HGeometry.Box
import HGeometry.LineSegment
import Data.Default
import Ipe.Attributes
import Ipe.Color (black)
import Ipe.Draw
import Ipe.Content
import Miso (View)
import HGeometry.Polygon
import HGeometry.Properties
import qualified HGeometry.Miso.Svg as Svg
import Miso.String (ToMisoString(..), ms, intercalate)
import qualified Miso.Svg as Elem
import qualified Miso.Svg.Property as Prop
import HGeometry.BezierSpline
import qualified Miso
import Data.Void
type data Svg (model :: Type) (action :: Type)
type SVG = Svg () Void
type instance Rendered (Svg model action) = [View () () model action]
instance ( Point_ vertex 2 (NumType vertex)
, ToMisoString (NumType vertex)
, SimplePolygon_ (SimplePolygonF f vertex) vertex (NumType vertex)
) => IsDrawable (Svg model action) (SimplePolygonF f vertex) where
type AttrOf (Svg model action) (SimplePolygonF f vertex) = PathAttributes (NumType vertex)
draw :: [Attr (Svg model action) (SimplePolygonF f vertex)]
-> SimplePolygonF f vertex -> Rendered (Svg model action)
draw [Attr (Svg model action) (SimplePolygonF f vertex)]
ats SimplePolygonF f vertex
poly = [ SimplePolygonF f vertex
-> [Attribute model action] -> View () () model action
forall simplePolygon point r model action context props.
(SimplePolygon_ simplePolygon point r, ToMisoString r) =>
simplePolygon
-> [Attribute model action] -> View context props model action
Svg.dSimplePolygon SimplePolygonF f vertex
poly (PathAttributesF (NumType vertex) Maybe -> [Attribute model action]
forall model.
PathAttributesF (NumType vertex) Maybe -> [Attribute model action]
forall (ats :: (* -> *) -> *) action model.
SvgWriteAttributes ats action =>
ats Maybe -> [Attribute model action]
Svg.svgWriteAttrs (PathAttributesF (NumType vertex) Maybe
-> [Attribute model action])
-> PathAttributesF (NumType vertex) Maybe
-> [Attribute model action]
forall a b. (a -> b) -> a -> b
$ [PathAttributesF (NumType vertex) Maybe
-> PathAttributesF (NumType vertex) Maybe]
-> PathAttributesF (NumType vertex) Maybe
forall at. Default at => [at -> at] -> at
apply [PathAttributesF (NumType vertex) Maybe
-> PathAttributesF (NumType vertex) Maybe]
[Attr (Svg model action) (SimplePolygonF f vertex)]
ats)
]
instance ( Point_ vertex 2 (NumType vertex)
, ToMisoString (NumType vertex)
, PolyLine_ (PolyLineF f vertex) vertex
) => IsDrawable (Svg model action) (PolyLineF f vertex) where
type AttrOf (Svg model action) (PolyLineF f vertex) = PathAttributes (NumType vertex)
draw :: [Attr (Svg model action) (PolyLineF f vertex)]
-> PolyLineF f vertex -> Rendered (Svg model action)
draw [Attr (Svg model action) (PolyLineF f vertex)]
ats PolyLineF f vertex
poly = [ PolyLineF f vertex
-> [Attribute model action] -> View () () model action
forall polyLine point r model action context props.
(PolyLine_ polyLine point, Point_ point 2 r, ToMisoString r) =>
polyLine
-> [Attribute model action] -> View context props model action
Svg.dPolyLine PolyLineF f vertex
poly (PathAttributesF (NumType vertex) Maybe -> [Attribute model action]
forall model.
PathAttributesF (NumType vertex) Maybe -> [Attribute model action]
forall (ats :: (* -> *) -> *) action model.
SvgWriteAttributes ats action =>
ats Maybe -> [Attribute model action]
Svg.svgWriteAttrs (PathAttributesF (NumType vertex) Maybe
-> [Attribute model action])
-> PathAttributesF (NumType vertex) Maybe
-> [Attribute model action]
forall a b. (a -> b) -> a -> b
$ [PathAttributesF (NumType vertex) Maybe
-> PathAttributesF (NumType vertex) Maybe]
-> PathAttributesF (NumType vertex) Maybe
forall at. Default at => [at -> at] -> at
apply [PathAttributesF (NumType vertex) Maybe
-> PathAttributesF (NumType vertex) Maybe]
[Attr (Svg model action) (PolyLineF f vertex)]
ats) ]
instance ( Point_ vertex 2 (NumType vertex)
, ToMisoString (NumType vertex)
, EndPoint_ (endPoint vertex), IxValue (endPoint vertex) ~ vertex
) => IsDrawable (Svg model action) (LineSegment endPoint vertex) where
type AttrOf (Svg model action) (LineSegment endPoint vertex) = PathAttributes (NumType vertex)
draw :: [Attr (Svg model action) (LineSegment endPoint vertex)]
-> LineSegment endPoint vertex -> Rendered (Svg model action)
draw [Attr (Svg model action) (LineSegment endPoint vertex)]
ats LineSegment endPoint vertex
seg = [ LineSegment endPoint vertex
-> [Attribute model action] -> View () () model action
forall lineSegment point r model action context props.
(LineSegment_ lineSegment point, Point_ point 2 r,
ToMisoString r) =>
lineSegment
-> [Attribute model action] -> View context props model action
Svg.dLineSegment LineSegment endPoint vertex
seg (PathAttributesF (NumType vertex) Maybe -> [Attribute model action]
forall model.
PathAttributesF (NumType vertex) Maybe -> [Attribute model action]
forall (ats :: (* -> *) -> *) action model.
SvgWriteAttributes ats action =>
ats Maybe -> [Attribute model action]
Svg.svgWriteAttrs (PathAttributesF (NumType vertex) Maybe
-> [Attribute model action])
-> PathAttributesF (NumType vertex) Maybe
-> [Attribute model action]
forall a b. (a -> b) -> a -> b
$ [PathAttributesF (NumType vertex) Maybe
-> PathAttributesF (NumType vertex) Maybe]
-> PathAttributesF (NumType vertex) Maybe
forall at. Default at => [at -> at] -> at
apply [PathAttributesF (NumType vertex) Maybe
-> PathAttributesF (NumType vertex) Maybe]
[Attr (Svg model action) (LineSegment endPoint vertex)]
ats) ]
instance ( ToMisoString r
) => IsDrawable (Svg model action) (Point 2 r) where
type AttrOf (Svg model action) (Point 2 r) = SymbolAttributes r
draw :: [Attr (Svg model action) (Point 2 r)]
-> Point 2 r -> Rendered (Svg model action)
draw [Attr (Svg model action) (Point 2 r)]
ats Point 2 r
p = [ [Attribute model action] -> View () () model action
forall model action context props.
[Attribute model action] -> View context props model action
Elem.ellipse_ ([ MisoString -> Attribute model action
forall model action. MisoString -> Attribute model action
Prop.cx_ (r -> MisoString
forall str. ToMisoString str => str -> MisoString
ms (r -> MisoString) -> r -> MisoString
forall a b. (a -> b) -> a -> b
$ Point 2 r
pPoint 2 r -> Getting r (Point 2 r) r -> r
forall s a. s -> Getting a s a -> a
^.Getting r (Point 2 r) r
forall (d :: Nat) point r.
(1 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int (Point 2 r) r
xCoord), MisoString -> Attribute model action
forall model action. MisoString -> Attribute model action
Prop.cy_ (r -> MisoString
forall str. ToMisoString str => str -> MisoString
ms (r -> MisoString) -> r -> MisoString
forall a b. (a -> b) -> a -> b
$ Point 2 r
pPoint 2 r -> Getting r (Point 2 r) r -> r
forall s a. s -> Getting a s a -> a
^.Getting r (Point 2 r) r
forall (d :: Nat) point r.
(2 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int (Point 2 r) r
yCoord)
, MisoString -> Attribute model action
forall model action. MisoString -> Attribute model action
Prop.rx_ MisoString
"2", MisoString -> Attribute model action
forall model action. MisoString -> Attribute model action
Prop.ry_ MisoString
"2"
] [Attribute model action]
-> [Attribute model action] -> [Attribute model action]
forall a. Semigroup a => a -> a -> a
<> SymbolAttributesF r Maybe -> [Attribute model action]
forall model. SymbolAttributesF r Maybe -> [Attribute model action]
forall (ats :: (* -> *) -> *) action model.
SvgWriteAttributes ats action =>
ats Maybe -> [Attribute model action]
Svg.svgWriteAttrs ([SymbolAttributesF r Maybe -> SymbolAttributesF r Maybe]
-> SymbolAttributesF r Maybe
forall at. Default at => [at -> at] -> at
apply [SymbolAttributesF r Maybe -> SymbolAttributesF r Maybe]
[Attr (Svg model action) (Point 2 r)]
ats))
]
instance (Point_ point 2 r, Fractional r, ToMisoString r, r ~ NumType point
) => IsDrawable (Svg model action) (CubicBezier point) where
type AttrOf (Svg model action) (CubicBezier point) = PathAttributes (NumType point)
draw :: [Attr (Svg model action) (CubicBezier point)]
-> CubicBezier point -> Rendered (Svg model action)
draw [Attr (Svg model action) (CubicBezier point)]
ats (BezierSpline Vector 4 point
vs) = [ [Attribute model action] -> View () () model action
forall model action context props.
[Attribute model action] -> View context props model action
Elem.path_ ([ MisoString -> Attribute model action
forall model action. MisoString -> Attribute model action
Prop.d_ MisoString
str
] [Attribute model action]
-> [Attribute model action] -> [Attribute model action]
forall a. Semigroup a => a -> a -> a
<> PathAttributesF r Maybe -> [Attribute model action]
forall model. PathAttributesF r Maybe -> [Attribute model action]
forall (ats :: (* -> *) -> *) action model.
SvgWriteAttributes ats action =>
ats Maybe -> [Attribute model action]
Svg.svgWriteAttrs ([PathAttributesF r Maybe -> PathAttributesF r Maybe]
-> PathAttributesF r Maybe -> PathAttributesF r Maybe
forall at. [at -> at] -> at -> at
applyWith [PathAttributesF r Maybe -> PathAttributesF r Maybe]
[Attr (Svg model action) (CubicBezier point)]
ats
(PathAttributesF r Maybe -> PathAttributesF r Maybe)
-> PathAttributesF r Maybe -> PathAttributesF r Maybe
forall a b. (a -> b) -> a -> b
$ PathAttributesF r Maybe
forall a. Default a => a
defPathAttributesF r Maybe
-> (PathAttributesF r Maybe -> PathAttributesF r Maybe)
-> PathAttributesF r Maybe
forall a b. a -> (a -> b) -> b
&(Maybe (IpeColor r) -> Identity (Maybe (IpeColor r)))
-> PathAttributesF r Maybe -> Identity (PathAttributesF r Maybe)
forall s a. HasStroke s a => Lens' s a
Lens' (PathAttributesF r Maybe) (Maybe (IpeColor r))
stroke ((Maybe (IpeColor r) -> Identity (Maybe (IpeColor r)))
-> PathAttributesF r Maybe -> Identity (PathAttributesF r Maybe))
-> Maybe (IpeColor r)
-> PathAttributesF r Maybe
-> PathAttributesF r Maybe
forall s t a b. ASetter s t a b -> b -> s -> t
.~ IpeColor r -> Maybe (IpeColor r)
forall a. a -> Maybe a
Just IpeColor r
forall r. IpeColor r
black
)
)
]
where
str :: MisoString
str = let Point 2 r
v :| [Point 2 r]
rest = Getting (NonEmptyDList (Point 2 r)) (Vector 4 point) (Point 2 r)
-> Vector 4 point -> NonEmpty (Point 2 r)
forall a s. Getting (NonEmptyDList a) s a -> s -> NonEmpty a
toNonEmptyOf ((point -> Const (NonEmptyDList (Point 2 r)) point)
-> Vector 4 point
-> Const (NonEmptyDList (Point 2 r)) (Vector 4 point)
forall (f :: * -> *) a b.
Traversable1 f =>
IndexedTraversal1 Int (f a) (f b) a b
IndexedTraversal1 Int (Vector 4 point) (Vector 4 point) point point
traversed1((point -> Const (NonEmptyDList (Point 2 r)) point)
-> Vector 4 point
-> Const (NonEmptyDList (Point 2 r)) (Vector 4 point))
-> ((Point 2 r -> Const (NonEmptyDList (Point 2 r)) (Point 2 r))
-> point -> Const (NonEmptyDList (Point 2 r)) point)
-> Getting (NonEmptyDList (Point 2 r)) (Vector 4 point) (Point 2 r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Point 2 r -> Const (NonEmptyDList (Point 2 r)) (Point 2 r))
-> point -> Const (NonEmptyDList (Point 2 r)) point
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point (Point 2 r)
asPoint) Vector 4 point
vs
in MisoString
"M " MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> Point 2 r -> MisoString
forall {str}. ToMisoString str => Point 2 str -> MisoString
toStr Point 2 r
v MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
" C " MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString -> [MisoString] -> MisoString
intercalate MisoString
", " [ Point 2 r -> MisoString
forall {str}. ToMisoString str => Point 2 str -> MisoString
toStr Point 2 r
w | Point 2 r
w <- [Point 2 r]
rest ]
toStr :: Point 2 str -> MisoString
toStr (Point2 str
x str
y) = str -> MisoString
forall str. ToMisoString str => str -> MisoString
ms str
x MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
" " MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> str -> MisoString
forall str. ToMisoString str => str -> MisoString
ms str
y
instance ToMisoString r => IsDrawable (Svg model action) (TextLabel r) where
type AttrOf (Svg model action) (TextLabel r) = TextAttributes r
draw :: [Attr (Svg model action) (TextLabel r)]
-> TextLabel r -> Rendered (Svg model action)
draw [Attr (Svg model action) (TextLabel r)]
ats (Label MisoString
txt Point 2 r
loc) = [ [Attribute model action]
-> [View () () model action] -> View () () model action
forall model action context props.
[Attribute model action]
-> [View context props model action]
-> View context props model action
Elem.text_ ([ MisoString -> Attribute model action
forall model action. MisoString -> Attribute model action
Prop.x_ (Point 2 r
locPoint 2 r
-> Getting MisoString (Point 2 r) MisoString -> MisoString
forall s a. s -> Getting a s a -> a
^.(r -> Const MisoString r)
-> Point 2 r -> Const MisoString (Point 2 r)
forall (d :: Nat) point r.
(1 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int (Point 2 r) r
xCoord((r -> Const MisoString r)
-> Point 2 r -> Const MisoString (Point 2 r))
-> ((MisoString -> Const MisoString MisoString)
-> r -> Const MisoString r)
-> Getting MisoString (Point 2 r) MisoString
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(r -> MisoString)
-> (MisoString -> Const MisoString MisoString)
-> r
-> Const MisoString r
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to r -> MisoString
forall str. ToMisoString str => str -> MisoString
ms)
, MisoString -> Attribute model action
forall model action. MisoString -> Attribute model action
Prop.y_ (Point 2 r
locPoint 2 r
-> Getting MisoString (Point 2 r) MisoString -> MisoString
forall s a. s -> Getting a s a -> a
^.(r -> Const MisoString r)
-> Point 2 r -> Const MisoString (Point 2 r)
forall (d :: Nat) point r.
(2 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int (Point 2 r) r
yCoord((r -> Const MisoString r)
-> Point 2 r -> Const MisoString (Point 2 r))
-> ((MisoString -> Const MisoString MisoString)
-> r -> Const MisoString r)
-> Getting MisoString (Point 2 r) MisoString
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(r -> MisoString)
-> (MisoString -> Const MisoString MisoString)
-> r
-> Const MisoString r
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to r -> MisoString
forall str. ToMisoString str => str -> MisoString
ms)
] [Attribute model action]
-> [Attribute model action] -> [Attribute model action]
forall a. Semigroup a => a -> a -> a
<> TextAttributesF r Maybe -> [Attribute model action]
forall model. TextAttributesF r Maybe -> [Attribute model action]
forall (ats :: (* -> *) -> *) action model.
SvgWriteAttributes ats action =>
ats Maybe -> [Attribute model action]
Svg.svgWriteAttrs ([TextAttributesF r Maybe -> TextAttributesF r Maybe]
-> TextAttributesF r Maybe
forall at. Default at => [at -> at] -> at
apply [TextAttributesF r Maybe -> TextAttributesF r Maybe]
[Attr (Svg model action) (TextLabel r)]
ats)
)
[ MisoString -> View () () model action
forall context props model action.
MisoString -> View context props model action
Miso.text (MisoString -> View () () model action)
-> MisoString -> View () () model action
forall a b. (a -> b) -> a -> b
$ MisoString -> MisoString
forall str. ToMisoString str => str -> MisoString
ms MisoString
txt]
]
instance ( Point_ center 2 r, Radical r
, ToMisoString r, r ~ NumType center
) => IsDrawable (Svg model action) (Circle center) where
type AttrOf (Svg model action) (Circle center) = PathAttributes (NumType center)
draw :: [Attr (Svg model action) (Circle center)]
-> Circle center -> Rendered (Svg model action)
draw [Attr (Svg model action) (Circle center)]
ats Circle center
c = [ Circle center
-> [Attribute model action] -> View () () model action
forall point r model action context props.
(Point_ point 2 r, ToMisoString r, Radical r) =>
Circle point
-> [Attribute model action] -> View context props model action
Svg.dCircle Circle center
c (PathAttributesF r Maybe -> [Attribute model action]
forall model. PathAttributesF r Maybe -> [Attribute model action]
forall (ats :: (* -> *) -> *) action model.
SvgWriteAttributes ats action =>
ats Maybe -> [Attribute model action]
Svg.svgWriteAttrs (PathAttributesF r Maybe -> [Attribute model action])
-> PathAttributesF r Maybe -> [Attribute model action]
forall a b. (a -> b) -> a -> b
$ [PathAttributesF r Maybe -> PathAttributesF r Maybe]
-> PathAttributesF r Maybe
forall at. Default at => [at -> at] -> at
apply [PathAttributesF r Maybe -> PathAttributesF r Maybe]
[Attr (Svg model action) (Circle center)]
ats) ]
instance ( Point_ center 2 r, Radical r
, ToMisoString r, r ~ NumType center, Radical r, Fractional r
) => IsDrawable (Svg model action) (Disk center) where
type AttrOf (Svg model action) (Disk center) = PathAttributes (NumType center)
draw :: [Attr (Svg model action) (Disk center)]
-> Disk center -> Rendered (Svg model action)
draw [Attr (Svg model action) (Disk center)]
ats Disk center
c = [ Disk center -> [Attribute model action] -> View () () model action
forall disk point r model action context props.
(Disk_ disk point, ConstructableBall_ disk point, Point_ point 2 r,
ToMisoString r, Radical r) =>
disk -> [Attribute model action] -> View context props model action
Svg.dDisk Disk center
c (PathAttributesF r Maybe -> [Attribute model action]
forall model. PathAttributesF r Maybe -> [Attribute model action]
forall (ats :: (* -> *) -> *) action model.
SvgWriteAttributes ats action =>
ats Maybe -> [Attribute model action]
Svg.svgWriteAttrs (PathAttributesF r Maybe -> [Attribute model action])
-> PathAttributesF r Maybe -> [Attribute model action]
forall a b. (a -> b) -> a -> b
$ [PathAttributesF r Maybe -> PathAttributesF r Maybe]
-> PathAttributesF r Maybe
forall at. Default at => [at -> at] -> at
apply [PathAttributesF r Maybe -> PathAttributesF r Maybe]
[Attr (Svg model action) (Disk center)]
ats) ]
instance ( Point_ corner 2 r
, ToMisoString r, Num r, r ~ NumType corner
) => IsDrawable (Svg model action) (Rectangle corner) where
type AttrOf (Svg model action) (Rectangle corner) = PathAttributes (NumType corner)
draw :: [Attr (Svg model action) (Rectangle corner)]
-> Rectangle corner -> Rendered (Svg model action)
draw [Attr (Svg model action) (Rectangle corner)]
ats Rectangle corner
r = [ Rectangle corner
-> [Attribute model action] -> View () () model action
forall rectangle point r model action context props.
(Rectangle_ rectangle point, Point_ point 2 r, ToMisoString r,
Num r) =>
rectangle
-> [Attribute model action] -> View context props model action
Svg.dRectangle Rectangle corner
r (PathAttributesF r Maybe -> [Attribute model action]
forall model. PathAttributesF r Maybe -> [Attribute model action]
forall (ats :: (* -> *) -> *) action model.
SvgWriteAttributes ats action =>
ats Maybe -> [Attribute model action]
Svg.svgWriteAttrs (PathAttributesF r Maybe -> [Attribute model action])
-> PathAttributesF r Maybe -> [Attribute model action]
forall a b. (a -> b) -> a -> b
$ [PathAttributesF r Maybe -> PathAttributesF r Maybe]
-> PathAttributesF r Maybe
forall at. Default at => [at -> at] -> at
apply [PathAttributesF r Maybe -> PathAttributesF r Maybe]
[Attr (Svg model action) (Rectangle corner)]
ats) ]
apply :: Default at => [at -> at] -> at
apply :: forall at. Default at => [at -> at] -> at
apply = ([at -> at] -> at -> at) -> at -> [at -> at] -> at
forall a b c. (a -> b -> c) -> b -> a -> c
flip [at -> at] -> at -> at
forall at. [at -> at] -> at -> at
applyWith at
forall a. Default a => a
def
applyWith :: [at -> at] -> at -> at
applyWith :: forall at. [at -> at] -> at -> at
applyWith [at -> at]
fs at
z = (at -> (at -> at) -> at) -> at -> [at -> at] -> at
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (((at -> at) -> at -> at) -> at -> (at -> at) -> at
forall a b c. (a -> b -> c) -> b -> a -> c
flip (at -> at) -> at -> at
forall a b. (a -> b) -> a -> b
($)) at
z [at -> at]
fs