---------------------------------------------------------
-- |
-- Copyright   : (c) 2006-2016, alpheccar.org
-- License     : BSD-style
--
-- Maintainer  : misc@NOSPAMalpheccar.org
-- Stability   : experimental
-- Portability : portable
--
-- PDF Shapes
---------------------------------------------------------

module Graphics.PDF.Shapes(
   -- * Shapes
   -- ** Paths
     moveto
   , lineto
   , arcto
   , curveto
   , beginPath
   , closePath
   , addBezierCubic
   , addPolygonToPath
   , addLineToPath
   , strokePath
   , fillPath
   , fillAndStrokePath
   , fillPathEO
   , fillAndStrokePathEO
   , setAsClipPath
   , setAsClipPathEO
   -- ** Usual shapes
   , Shape(..)
   , Line(..)
   , Rectangle(..)
   , Polygon(..)
   , Arc(..)
   , Ellipse(..)
   , Circle(..)
   , RoundRectangle(..)
   -- ** Style
   , CapStyle(..)
   , JoinStyle(..)
   , DashPattern(..)
   , setWidth
   , setLineCap
   , setLineJoin
   , setDash
   , setNoDash
   , setMiterLimit
 ) where

import Graphics.PDF.LowLevel.Types
import Graphics.PDF.Coordinates
import Graphics.PDF.Draw
import Control.Monad.Writer
import Graphics.PDF.LowLevel.Serializer

class Shape a where
    addShape :: a -> Draw ()
    stroke :: a -> Draw ()
    fill :: a -> Draw ()
    fillAndStroke :: a -> Draw ()
    fillEO :: a -> Draw ()
    fillAndStrokeEO :: a -> Draw ()
    stroke a
r = do
        forall a. Shape a => a -> Draw ()
addShape a
r
        Draw ()
strokePath
    fill a
r = do
        forall a. Shape a => a -> Draw ()
addShape a
r
        Draw ()
fillPath
    fillAndStroke a
r = do
        forall a. Shape a => a -> Draw ()
addShape a
r
        Draw ()
fillAndStrokePath
    fillEO a
r = do
        forall a. Shape a => a -> Draw ()
addShape a
r
        Draw ()
fillPathEO
    fillAndStrokeEO a
r = do
        forall a. Shape a => a -> Draw ()
addShape a
r
        Draw ()
fillAndStrokePathEO
    
data Line = Line PDFFloat PDFFloat PDFFloat PDFFloat deriving(Line -> Line -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Line -> Line -> Bool
$c/= :: Line -> Line -> Bool
== :: Line -> Line -> Bool
$c== :: Line -> Line -> Bool
Eq)
instance Shape Line where
    addShape :: Line -> Draw ()
addShape (Line PDFFloat
x0 PDFFloat
y0 PDFFloat
x1 PDFFloat
y1)= do
        Point -> Draw ()
moveto (PDFFloat
x0 forall a. a -> a -> Complex a
:+ PDFFloat
y0)
        Point -> Draw ()
lineto (PDFFloat
x1 forall a. a -> a -> Complex a
:+ PDFFloat
y1)
    fill :: Line -> Draw ()
fill Line
_ = forall a. HasCallStack => String -> a
error String
"Can't fill a line !"
    fillAndStroke :: Line -> Draw ()
fillAndStroke Line
_ = forall a. HasCallStack => String -> a
error String
"Can't fill a line !"
    fillEO :: Line -> Draw ()
fillEO Line
_ = forall a. HasCallStack => String -> a
error String
"Can't fill a line !"
    fillAndStrokeEO :: Line -> Draw ()
fillAndStrokeEO Line
_ = forall a. HasCallStack => String -> a
error String
"Can't fill a line !"
    
data Rectangle = Rectangle !Point !Point deriving (Rectangle -> Rectangle -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Rectangle -> Rectangle -> Bool
$c/= :: Rectangle -> Rectangle -> Bool
== :: Rectangle -> Rectangle -> Bool
$c== :: Rectangle -> Rectangle -> Bool
Eq) 
instance Shape Rectangle where
 addShape :: Rectangle -> Draw ()
addShape (Rectangle Point
a Point
b) 
     = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize Char
'\n'
                        , forall a. PdfObject a => a -> Builder
toPDF Point
a
                        , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                        , forall a. PdfObject a => a -> Builder
toPDF (Point
b forall a. Num a => a -> a -> a
- Point
a)
                        , forall s a. SerializeValue s a => a -> s
serialize String
" re" ]
 
data Arc = Arc PDFFloat PDFFloat PDFFloat PDFFloat deriving(Arc -> Arc -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Arc -> Arc -> Bool
$c/= :: Arc -> Arc -> Bool
== :: Arc -> Arc -> Bool
$c== :: Arc -> Arc -> Bool
Eq)
instance Shape Arc where
    addShape :: Arc -> Draw ()
addShape (Arc PDFFloat
x0 PDFFloat
y0 PDFFloat
x1 PDFFloat
y1) = do
        let height :: PDFFloat
height = PDFFloat
y1 forall a. Num a => a -> a -> a
- PDFFloat
y0
            width :: PDFFloat
width = PDFFloat
x1 forall a. Num a => a -> a -> a
- PDFFloat
x0
            kappa :: PDFFloat
kappa = PDFFloat
0.5522847498
        Point -> Draw ()
beginPath (PDFFloat
x0 forall a. a -> a -> Complex a
:+ PDFFloat
y0)
        Point -> Point -> Point -> Draw ()
addBezierCubic ((PDFFloat
x0forall a. Num a => a -> a -> a
+PDFFloat
widthforall a. Num a => a -> a -> a
*PDFFloat
kappa) forall a. a -> a -> Complex a
:+ PDFFloat
y0) (PDFFloat
x1 forall a. a -> a -> Complex a
:+ (PDFFloat
y1forall a. Num a => a -> a -> a
-PDFFloat
heightforall a. Num a => a -> a -> a
*PDFFloat
kappa)) (PDFFloat
x1 forall a. a -> a -> Complex a
:+ PDFFloat
y1)
               
data Ellipse = Ellipse PDFFloat PDFFloat PDFFloat PDFFloat deriving(Ellipse -> Ellipse -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ellipse -> Ellipse -> Bool
$c/= :: Ellipse -> Ellipse -> Bool
== :: Ellipse -> Ellipse -> Bool
$c== :: Ellipse -> Ellipse -> Bool
Eq)
instance Shape Ellipse where
    addShape :: Ellipse -> Draw ()
addShape (Ellipse PDFFloat
x0 PDFFloat
y0 PDFFloat
x1 PDFFloat
y1) = do
        let xm :: PDFFloat
xm = (PDFFloat
x0forall a. Num a => a -> a -> a
+PDFFloat
x1)forall a. Fractional a => a -> a -> a
/PDFFloat
2.0
            ym :: PDFFloat
ym = (PDFFloat
y0forall a. Num a => a -> a -> a
+PDFFloat
y1)forall a. Fractional a => a -> a -> a
/PDFFloat
2.0
            k :: PDFFloat
k = PDFFloat
0.5522847498
            h :: PDFFloat
h = PDFFloat
kforall a. Num a => a -> a -> a
*(forall a. Num a => a -> a
abs (PDFFloat
y1 forall a. Num a => a -> a -> a
- PDFFloat
y0)forall a. Fractional a => a -> a -> a
/PDFFloat
2.0)
            w :: PDFFloat
w = PDFFloat
kforall a. Num a => a -> a -> a
*(forall a. Num a => a -> a
abs (PDFFloat
x1 forall a. Num a => a -> a -> a
- PDFFloat
x0)forall a. Fractional a => a -> a -> a
/PDFFloat
2.0)

        Point -> Draw ()
beginPath (PDFFloat
xm forall a. a -> a -> Complex a
:+ PDFFloat
y0)
        Point -> Point -> Point -> Draw ()
addBezierCubic ((PDFFloat
xm forall a. Num a => a -> a -> a
+ PDFFloat
w) forall a. a -> a -> Complex a
:+ PDFFloat
y0) (PDFFloat
x1 forall a. a -> a -> Complex a
:+ (PDFFloat
ym forall a. Num a => a -> a -> a
- PDFFloat
h)) (PDFFloat
x1 forall a. a -> a -> Complex a
:+ PDFFloat
ym)
        Point -> Point -> Point -> Draw ()
addBezierCubic (PDFFloat
x1 forall a. a -> a -> Complex a
:+ (PDFFloat
ym forall a. Num a => a -> a -> a
+ PDFFloat
h)) ((PDFFloat
xm forall a. Num a => a -> a -> a
+ PDFFloat
w) forall a. a -> a -> Complex a
:+ PDFFloat
y1) (PDFFloat
xm forall a. a -> a -> Complex a
:+ PDFFloat
y1)
        Point -> Point -> Point -> Draw ()
addBezierCubic ((PDFFloat
xm forall a. Num a => a -> a -> a
- PDFFloat
w) forall a. a -> a -> Complex a
:+ PDFFloat
y1) (PDFFloat
x0 forall a. a -> a -> Complex a
:+ (PDFFloat
ym forall a. Num a => a -> a -> a
+ PDFFloat
h)) (PDFFloat
x0 forall a. a -> a -> Complex a
:+ PDFFloat
ym)
        Point -> Point -> Point -> Draw ()
addBezierCubic (PDFFloat
x0 forall a. a -> a -> Complex a
:+ (PDFFloat
ym forall a. Num a => a -> a -> a
- PDFFloat
h)) ((PDFFloat
xm forall a. Num a => a -> a -> a
- PDFFloat
w) forall a. a -> a -> Complex a
:+ PDFFloat
y0) (PDFFloat
xm forall a. a -> a -> Complex a
:+ PDFFloat
y0)

data RoundRectangle = RoundRectangle PDFFloat PDFFloat PDFFloat PDFFloat PDFFloat PDFFloat deriving(RoundRectangle -> RoundRectangle -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RoundRectangle -> RoundRectangle -> Bool
$c/= :: RoundRectangle -> RoundRectangle -> Bool
== :: RoundRectangle -> RoundRectangle -> Bool
$c== :: RoundRectangle -> RoundRectangle -> Bool
Eq)
instance Shape RoundRectangle where
    addShape :: RoundRectangle -> Draw ()
addShape (RoundRectangle PDFFloat
rw PDFFloat
rh PDFFloat
x0 PDFFloat
y0 PDFFloat
x1 PDFFloat
y1) = do
        let k :: PDFFloat
k = PDFFloat
0.5522847498
            h :: PDFFloat
h = PDFFloat
kforall a. Num a => a -> a -> a
*PDFFloat
rw
            w :: PDFFloat
w = PDFFloat
kforall a. Num a => a -> a -> a
*PDFFloat
rh

        Point -> Draw ()
beginPath ((PDFFloat
x0forall a. Num a => a -> a -> a
+PDFFloat
rw) forall a. a -> a -> Complex a
:+ PDFFloat
y0)
        Point -> Draw ()
addLineToPath ((PDFFloat
x1forall a. Num a => a -> a -> a
-PDFFloat
rw) forall a. a -> a -> Complex a
:+ PDFFloat
y0)
        Point -> Point -> Point -> Draw ()
addBezierCubic ((PDFFloat
x1forall a. Num a => a -> a -> a
-PDFFloat
rw forall a. Num a => a -> a -> a
+ PDFFloat
w) forall a. a -> a -> Complex a
:+ PDFFloat
y0) (PDFFloat
x1 forall a. a -> a -> Complex a
:+ (PDFFloat
y0forall a. Num a => a -> a -> a
+PDFFloat
rh forall a. Num a => a -> a -> a
- PDFFloat
h)) (PDFFloat
x1 forall a. a -> a -> Complex a
:+ (PDFFloat
y0forall a. Num a => a -> a -> a
+PDFFloat
rh))
        Point -> Draw ()
addLineToPath (PDFFloat
x1 forall a. a -> a -> Complex a
:+ (PDFFloat
y1forall a. Num a => a -> a -> a
-PDFFloat
rh))
        Point -> Point -> Point -> Draw ()
addBezierCubic (PDFFloat
x1 forall a. a -> a -> Complex a
:+ (PDFFloat
y1forall a. Num a => a -> a -> a
-PDFFloat
rh forall a. Num a => a -> a -> a
+ PDFFloat
h)) ((PDFFloat
x1forall a. Num a => a -> a -> a
-PDFFloat
rw forall a. Num a => a -> a -> a
+ PDFFloat
w) forall a. a -> a -> Complex a
:+ PDFFloat
y1) ((PDFFloat
x1forall a. Num a => a -> a -> a
-PDFFloat
rw) forall a. a -> a -> Complex a
:+ PDFFloat
y1)
        Point -> Draw ()
addLineToPath ((PDFFloat
x0forall a. Num a => a -> a -> a
+PDFFloat
rw) forall a. a -> a -> Complex a
:+ PDFFloat
y1)
        Point -> Point -> Point -> Draw ()
addBezierCubic ((PDFFloat
x0forall a. Num a => a -> a -> a
+PDFFloat
rw forall a. Num a => a -> a -> a
- PDFFloat
w) forall a. a -> a -> Complex a
:+ PDFFloat
y1) (PDFFloat
x0 forall a. a -> a -> Complex a
:+ (PDFFloat
y1forall a. Num a => a -> a -> a
-PDFFloat
rh forall a. Num a => a -> a -> a
+ PDFFloat
h)) (PDFFloat
x0 forall a. a -> a -> Complex a
:+ (PDFFloat
y1forall a. Num a => a -> a -> a
-PDFFloat
rh))
        Point -> Draw ()
addLineToPath (PDFFloat
x0 forall a. a -> a -> Complex a
:+ (PDFFloat
y0forall a. Num a => a -> a -> a
+PDFFloat
rh))
        Point -> Point -> Point -> Draw ()
addBezierCubic (PDFFloat
x0 forall a. a -> a -> Complex a
:+ (PDFFloat
y0forall a. Num a => a -> a -> a
+PDFFloat
rh forall a. Num a => a -> a -> a
- PDFFloat
h)) ((PDFFloat
x0forall a. Num a => a -> a -> a
+PDFFloat
rw forall a. Num a => a -> a -> a
- PDFFloat
w) forall a. a -> a -> Complex a
:+ PDFFloat
y0) ((PDFFloat
x0forall a. Num a => a -> a -> a
+PDFFloat
rw) forall a. a -> a -> Complex a
:+ PDFFloat
y0)
        Point -> Draw ()
addLineToPath ((PDFFloat
x1forall a. Num a => a -> a -> a
-PDFFloat
rw) forall a. a -> a -> Complex a
:+ PDFFloat
y0)
        
data Circle = Circle PDFFloat PDFFloat PDFFloat deriving(Circle -> Circle -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Circle -> Circle -> Bool
$c/= :: Circle -> Circle -> Bool
== :: Circle -> Circle -> Bool
$c== :: Circle -> Circle -> Bool
Eq)
instance Shape Circle where
    addShape :: Circle -> Draw ()
addShape (Circle PDFFloat
x0 PDFFloat
y0 PDFFloat
r) = forall a. Shape a => a -> Draw ()
addShape (PDFFloat -> PDFFloat -> PDFFloat -> PDFFloat -> Ellipse
Ellipse (PDFFloat
x0forall a. Num a => a -> a -> a
-PDFFloat
r) (PDFFloat
y0forall a. Num a => a -> a -> a
-PDFFloat
r) (PDFFloat
x0forall a. Num a => a -> a -> a
+PDFFloat
r) (PDFFloat
y0forall a. Num a => a -> a -> a
+PDFFloat
r) )
                
newtype Polygon = Polygon [Point]
instance Shape Polygon where
    addShape :: Polygon -> Draw ()
addShape (Polygon [Point]
l) = [Point] -> Draw ()
addPolygonToPath [Point]
l


-- | Set pen width
setWidth :: MonadPath m => PDFFloat -> m ()
setWidth :: forall (m :: * -> *). MonadPath m => PDFFloat -> m ()
setWidth PDFFloat
w = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$[ forall s a. SerializeValue s a => a -> s
serialize String
"\n" 
                             , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
w
                             , forall s a. SerializeValue s a => a -> s
serialize String
" w"
                             ]

-- | Set pen width
setMiterLimit :: MonadPath m => PDFFloat -> m ()
setMiterLimit :: forall (m :: * -> *). MonadPath m => PDFFloat -> m ()
setMiterLimit PDFFloat
w = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$[ forall s a. SerializeValue s a => a -> s
serialize String
"\n" 
                                  , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
w
                                  , forall s a. SerializeValue s a => a -> s
serialize String
" M"
                                  ]

-- | Line cap styles
data CapStyle = ButtCap
              | RoundCap
              | SquareCap
              deriving(CapStyle -> CapStyle -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CapStyle -> CapStyle -> Bool
$c/= :: CapStyle -> CapStyle -> Bool
== :: CapStyle -> CapStyle -> Bool
$c== :: CapStyle -> CapStyle -> Bool
Eq,Int -> CapStyle
CapStyle -> Int
CapStyle -> [CapStyle]
CapStyle -> CapStyle
CapStyle -> CapStyle -> [CapStyle]
CapStyle -> CapStyle -> CapStyle -> [CapStyle]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: CapStyle -> CapStyle -> CapStyle -> [CapStyle]
$cenumFromThenTo :: CapStyle -> CapStyle -> CapStyle -> [CapStyle]
enumFromTo :: CapStyle -> CapStyle -> [CapStyle]
$cenumFromTo :: CapStyle -> CapStyle -> [CapStyle]
enumFromThen :: CapStyle -> CapStyle -> [CapStyle]
$cenumFromThen :: CapStyle -> CapStyle -> [CapStyle]
enumFrom :: CapStyle -> [CapStyle]
$cenumFrom :: CapStyle -> [CapStyle]
fromEnum :: CapStyle -> Int
$cfromEnum :: CapStyle -> Int
toEnum :: Int -> CapStyle
$ctoEnum :: Int -> CapStyle
pred :: CapStyle -> CapStyle
$cpred :: CapStyle -> CapStyle
succ :: CapStyle -> CapStyle
$csucc :: CapStyle -> CapStyle
Enum)
              
-- | Line join styles
data JoinStyle = MiterJoin
               | RoundJoin
               | BevelJoin
               deriving(JoinStyle -> JoinStyle -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JoinStyle -> JoinStyle -> Bool
$c/= :: JoinStyle -> JoinStyle -> Bool
== :: JoinStyle -> JoinStyle -> Bool
$c== :: JoinStyle -> JoinStyle -> Bool
Eq,Int -> JoinStyle
JoinStyle -> Int
JoinStyle -> [JoinStyle]
JoinStyle -> JoinStyle
JoinStyle -> JoinStyle -> [JoinStyle]
JoinStyle -> JoinStyle -> JoinStyle -> [JoinStyle]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: JoinStyle -> JoinStyle -> JoinStyle -> [JoinStyle]
$cenumFromThenTo :: JoinStyle -> JoinStyle -> JoinStyle -> [JoinStyle]
enumFromTo :: JoinStyle -> JoinStyle -> [JoinStyle]
$cenumFromTo :: JoinStyle -> JoinStyle -> [JoinStyle]
enumFromThen :: JoinStyle -> JoinStyle -> [JoinStyle]
$cenumFromThen :: JoinStyle -> JoinStyle -> [JoinStyle]
enumFrom :: JoinStyle -> [JoinStyle]
$cenumFrom :: JoinStyle -> [JoinStyle]
fromEnum :: JoinStyle -> Int
$cfromEnum :: JoinStyle -> Int
toEnum :: Int -> JoinStyle
$ctoEnum :: Int -> JoinStyle
pred :: JoinStyle -> JoinStyle
$cpred :: JoinStyle -> JoinStyle
succ :: JoinStyle -> JoinStyle
$csucc :: JoinStyle -> JoinStyle
Enum)
                            
-- | Set line cap
setLineCap :: MonadPath m => CapStyle -> m ()
setLineCap :: forall (m :: * -> *). MonadPath m => CapStyle -> m ()
setLineCap CapStyle
w = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$[ forall s a. SerializeValue s a => a -> s
serialize String
"\n " 
                               , forall a. PdfObject a => a -> Builder
toPDF (forall a. Enum a => a -> Int
fromEnum  CapStyle
w)
                               , forall s a. SerializeValue s a => a -> s
serialize String
" J"
                               ]

-- | Set line join
setLineJoin :: MonadPath m => JoinStyle -> m ()
setLineJoin :: forall (m :: * -> *). MonadPath m => JoinStyle -> m ()
setLineJoin JoinStyle
w = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$[ forall s a. SerializeValue s a => a -> s
serialize String
"\n " 
                                , forall a. PdfObject a => a -> Builder
toPDF (forall a. Enum a => a -> Int
fromEnum  JoinStyle
w)
                                , forall s a. SerializeValue s a => a -> s
serialize String
" j"
                                ]

data DashPattern = DashPattern ![PDFFloat] PDFFloat deriving(DashPattern -> DashPattern -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DashPattern -> DashPattern -> Bool
$c/= :: DashPattern -> DashPattern -> Bool
== :: DashPattern -> DashPattern -> Bool
$c== :: DashPattern -> DashPattern -> Bool
Eq)

-- | Set the dash pattern
setDash :: MonadPath m => DashPattern -> m()
setDash :: forall (m :: * -> *). MonadPath m => DashPattern -> m ()
setDash (DashPattern [PDFFloat]
a PDFFloat
p) = 
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcatforall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize String
"\n " 
                    , forall a. PdfObject a => a -> Builder
toPDF [PDFFloat]
a
                    , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                    , forall a. PdfObject a => a -> Builder
toPDF PDFFloat
p
                    , forall s a. SerializeValue s a => a -> s
serialize String
" d"
                    ]

-- | No dash pattern
setNoDash :: MonadPath m => m ()
setNoDash :: forall (m :: * -> *). MonadPath m => m ()
setNoDash = forall (m :: * -> *). MonadPath m => DashPattern -> m ()
setDash ([PDFFloat] -> PDFFloat -> DashPattern
DashPattern [] PDFFloat
0)
    
-- | Begin a new path at a position
beginPath :: Point 
          -> Draw ()
beginPath :: Point -> Draw ()
beginPath = Point -> Draw ()
moveto

-- | Close current path 
closePath :: Draw ()
closePath :: Draw ()
closePath = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nh"


-- | Append a cubic Bezier curve to the current path. The curve extends 
-- from the current point to the point (x3 , y3), using (x1 , y1 ) and 
-- (x2, y2) as the Bezier control points
addBezierCubic :: Point
               -> Point
               -> Point
               -> Draw ()
addBezierCubic :: Point -> Point -> Point -> Draw ()
addBezierCubic Point
b Point
c Point
d = do
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize String
"\n" 
                     , forall a. PdfObject a => a -> Builder
toPDF Point
b
                     , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                     , forall a. PdfObject a => a -> Builder
toPDF Point
c
                     , forall s a. SerializeValue s a => a -> s
serialize Char
' '
                     , forall a. PdfObject a => a -> Builder
toPDF Point
d
                     , forall s a. SerializeValue s a => a -> s
serialize String
" c"
                     ]
    forall a. (forall s. DrawTuple s -> STRef s a) -> a -> Draw ()
writeDrawST forall s. DrawTuple s -> STRef s Point
penPosition Point
d
                    
-- | Move pen to a given point without drawing anything
moveto :: Point 
       -> Draw ()
moveto :: Point -> Draw ()
moveto Point
a = do 
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ [ forall s a. SerializeValue s a => a -> s
serialize String
"\n" 
                     , forall a. PdfObject a => a -> Builder
toPDF Point
a
                     , forall s a. SerializeValue s a => a -> s
serialize String
" m"
                     ]
    forall a. (forall s. DrawTuple s -> STRef s a) -> a -> Draw ()
writeDrawST forall s. DrawTuple s -> STRef s Point
penPosition Point
a

-- | Draw a line from current point to the one specified by lineto
lineto :: Point 
       -> Draw () 
lineto :: Point -> Draw ()
lineto Point
a = do
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$[ forall s a. SerializeValue s a => a -> s
serialize String
"\n" 
                    , forall a. PdfObject a => a -> Builder
toPDF Point
a
                    , forall s a. SerializeValue s a => a -> s
serialize String
" l"
                    ]
    forall a. (forall s. DrawTuple s -> STRef s a) -> a -> Draw ()
writeDrawST forall s. DrawTuple s -> STRef s Point
penPosition Point
a

curveto :: Point -> Point -> Point -> Draw ()
curveto :: Point -> Point -> Point -> Draw ()
curveto = Point -> Point -> Point -> Draw ()
addBezierCubic

-- | Approximate a circular arc by one cubic bezier curve.
-- larger arc angles mean larger distortions
arcto :: Angle   -- ^ Extent of arc
      -> Point   -- ^ Center of arc
      -> Draw ()
arcto :: Angle -> Point -> Draw ()
arcto Angle
extent 
    = let theta :: PDFFloat
theta = Angle -> PDFFloat
toRadian Angle
extent
          kappa :: PDFFloat
kappa = PDFFloat
4 forall a. Fractional a => a -> a -> a
/ PDFFloat
3 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
tan (PDFFloat
theta forall a. Fractional a => a -> a -> a
/ PDFFloat
4)
          cis_theta :: Point
cis_theta = forall a. Floating a => a -> Complex a
cis PDFFloat
theta
          rot90 :: Complex a -> Complex a
rot90 (a
x :+ a
y) = ((-a
y) forall a. a -> a -> Complex a
:+ a
x)
       in if PDFFloat
theta forall a. Eq a => a -> a -> Bool
== PDFFloat
0
          then \Point
_center -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
          else \Point
center -> do
            Point
a <- forall a. (forall s. DrawTuple s -> STRef s a) -> Draw a
readDrawST forall s. DrawTuple s -> STRef s Point
penPosition
            let delta :: Point
delta  = Point
a forall a. Num a => a -> a -> a
- Point
center
                delta' :: Point
delta' = forall t. RealFloat t => t -> Complex t -> Complex t
scalePt PDFFloat
kappa (forall {a}. Num a => Complex a -> Complex a
rot90 Point
delta)
                d :: Point
d = Point
center forall a. Num a => a -> a -> a
+ Point
delta forall a. Num a => a -> a -> a
* Point
cis_theta
                c :: Point
c = Point
d forall a. Num a => a -> a -> a
- Point
delta' forall a. Num a => a -> a -> a
* Point
cis_theta
                b :: Point
b = Point
a forall a. Num a => a -> a -> a
+ Point
delta'
            Point -> Point -> Point -> Draw ()
curveto Point
b Point
c Point
d

addLineToPath :: Point 
              -> Draw ()
addLineToPath :: Point -> Draw ()
addLineToPath = Point -> Draw ()
lineto

-- | Add a polygon to current path
addPolygonToPath :: [Point]
                 -> Draw ()
addPolygonToPath :: [Point] -> Draw ()
addPolygonToPath []  = forall (m :: * -> *) a. Monad m => a -> m a
return ()
addPolygonToPath (Point
l : [Point]
ls) =  do
    Point -> Draw ()
moveto Point
l
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Point -> Draw ()
addLineToPath [Point]
ls  
    
-- | Draw current path
strokePath :: Draw ()             
strokePath :: Draw ()
strokePath = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nS"

-- | Fill current path
fillPath :: Draw ()             
fillPath :: Draw ()
fillPath = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nf"

-- | Fill current path
fillAndStrokePath :: Draw ()             
fillAndStrokePath :: Draw ()
fillAndStrokePath = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nB"

-- | Set clipping path
setAsClipPathEO :: Draw ()             
setAsClipPathEO :: Draw ()
setAsClipPathEO = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nW* n"

-- | Set clipping path
setAsClipPath :: Draw ()             
setAsClipPath :: Draw ()
setAsClipPath = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nW n"

-- | Fill current path using even odd rule
fillPathEO :: Draw ()             
fillPathEO :: Draw ()
fillPathEO = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nf*"

-- | Fill current path using even odd rule
fillAndStrokePathEO :: Draw ()             
fillAndStrokePathEO :: Draw ()
fillAndStrokePathEO = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. SerializeValue s a => a -> s
serialize forall a b. (a -> b) -> a -> b
$ String
"\nB*"