module Graphics.Curves.Compile where
import Prelude hiding (minimum, maximum, any, or, and)
import Control.Applicative
import Data.Foldable
import Data.Monoid
import Graphics.Curves.Math
import Graphics.Curves.BoundingBox
import Graphics.Curves.Image
import Graphics.Curves.Colour
import Graphics.Curves.Curve
import Debug.Trace
type Segments = BBTree (AnnotatedSegment LineStyle)
data FillStyle = FillStyle Colour Scalar LineStyle
data LineStyle = LineStyle Colour Scalar Scalar
instance Monoid LineStyle where
mempty = LineStyle transparent 0 0
mappend (LineStyle c1 w1 b1) (LineStyle c2 w2 b2) =
LineStyle (c1 `blend` c2) (max w1 w2) (max b1 b2)
data CompiledImage
= Segments FillStyle Segments
| CIUnion (Op (Maybe Colour)) BoundingBox CompiledImage CompiledImage
| CIEmpty
instance HasBoundingBox CompiledImage where
bounds (Segments fs b) = relaxBoundingBox (max fw lw) $ bounds b
where
fw = case fs of
FillStyle c w _ | not $ isTransparent c -> w/2
_ -> 0
lw = case fs of
FillStyle _ _ (LineStyle c w b) | not $ isTransparent c -> w + b
_ -> 0
bounds (CIUnion _ b _ _) = b
bounds CIEmpty = Empty
compileImage :: Image -> CompiledImage
compileImage = compileImage' 1
setLineStyle :: CurveStyle -> AnnotatedSegment (Scalar, Scalar) -> AnnotatedSegment LineStyle
setLineStyle s seg = fmap mkLineStyle seg
where
mkLineStyle (d, r) = LineStyle (lineColour s d r) (lineWidth s d r) (lineBlur s d r)
compileImage' :: Scalar -> Image -> CompiledImage
compileImage' res (ICurve c) = Segments fs ss
where
s = curveStyle c
fs = FillStyle (fillColour s) (fillBlur s) (foldMap annotation ss)
ss = setLineStyle (curveStyle c) <$> curveToSegments res c
compileImage' res IEmpty = CIEmpty
compileImage' res (Combine blend a b) =
CIUnion blend (bounds (ca, cb)) ca cb
where
ca = compileImage' res a
cb = compileImage' res b