sylvia-0.2.2: Sylvia/Render/Backend.hs
-- |
-- Module : Sylvia.Render.Backend
-- Copyright : GPLv3
--
-- Maintainer : chrisyco@gmail.com
-- Portability : portable
--
-- This module provides an interface, 'Backend', that all rendering
-- methods must implement.
module Sylvia.Render.Backend
(
-- * An interface
Backend(..)
-- * Helper functions
, drawDot
, drawBox
, stackHorizontally
) where
import Data.Monoid
import Sylvia.Render.Pair
-- | An action that yields an image.
--
-- 'mempty' should yield an empty image and 'mappend' should stack two
-- images together.
class Monoid r => Backend r where
-- | Draw a dotted rectangle.
drawDottedRectangle
:: PInt -- ^ Corner position
-> PInt -- ^ Size
-> r
-- | Draw a line segment from one point to another.
drawLine :: PInt -> PInt -> r
-- | Draw a line, but instead of drawing a diagonal line, draw a
-- zigzag instead.
drawZigzag :: PInt -> PInt -> r
-- | Draw a simple circle segment, centered at a point.
drawCircleSegment
:: PInt -- ^ Center point
-> Double -- ^ Start angle, in radians
-> Double -- ^ End angle, also in radians. Radians are cool.
-> r
-- | Translate the given image by a vector.
relativeTo :: PInt -> r -> r
-- | Draw a full circle, centered at a point.
drawDot :: Backend r => PInt -> r
drawDot center = drawCircleSegment center 0 (2 * pi)
-- | Draw a box, complete with a throat and ear.
drawBox
:: Backend r
=> PInt -- ^ Top-left corner point
-> PInt -- ^ Size
-> Int -- ^ Y offset of ear and throat
-> r
drawBox corner size throatY
= drawDottedRectangle corner size
<> drawCircleSegment (corner |+| ( 0 :| height + throatY)) (1 * rightAngle) (3 * rightAngle)
<> drawCircleSegment (corner |+| (width :| height + throatY)) (3 * rightAngle) (1 * rightAngle)
where
width :| height = size
rightAngle = pi / 2
-- | Take a list of images and line them up in a row.
stackHorizontally :: Backend r => [(r, PInt)] -> (r, PInt)
stackHorizontally = foldr step (mempty, 0 :| 0)
where
step (image', (w' :| h')) (image, (w :| h))
= (relativeTo ((-w - 1) :| 0) image' <> image, (w + w' + 2) :| max h h')