wumpus-basic-0.13.0: src/Wumpus/Basic/Graphic/GraphicTypes.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS -Wall #-}
--------------------------------------------------------------------------------
-- |
-- Module : Wumpus.Basic.Graphic.GraphicTypes
-- Copyright : (c) Stephen Tetley 2010
-- License : BSD3
--
-- Maintainer : stephen.tetley@gmail.com
-- Stability : highly unstable
-- Portability : GHC
--
-- Refined instances of of the Drawing type modelling specific
-- graphic types.
--
-- \*\* WARNING \*\* - some names are expected to change.
--
--------------------------------------------------------------------------------
module Wumpus.Basic.Graphic.GraphicTypes
(
-- * Function from Point to Point
PointDisplace
-- * Advance vector
, AdvanceVec
-- * Drawing info
, DrawingInfo
, LocDrawingInfo
, LocThetaDrawingInfo
-- * Graphic
, Graphic
, LocGraphic
, LocThetaGraphic
, ConnectorGraphic
, DGraphic
, DLocGraphic
, DLocThetaGraphic
, DConnectorGraphic
-- * Image
, Image
, LocImage
, LocThetaImage
, ConnectorImage
, DImage
, DLocImage
, DLocThetaImage
, DConnectorImage
-- * /Advance vector/ graphic
, AdvGraphic
, DAdvGraphic
-- * Bounded graphic / loc graphic
, BoundedGraphic
, DBoundedGraphic
, BoundedLocGraphic
, DBoundedLocGraphic
-- * Extract from an Advance vector
, advanceH
, advanceV
-- * Run functions
, runGraphic
, runLocGraphic
, runImage
, runLocImage
-- * Combinators
, moveLoc
, at
-- * Dropping answers
, extrGraphic
, extrLocGraphic
, fontDeltaGraphic
, fontDeltaImage
, xlinkGraphic
, xlinkImage
, intoImage
, intoLocImage
, intoConnectorImage
, intoLocThetaImage
, makeAdvGraphic
) where
import Wumpus.Basic.Graphic.Base
import Wumpus.Basic.Graphic.ContextFunction
import Wumpus.Basic.Graphic.DrawingContext
import Wumpus.Core -- package: wumpus-core
type PointDisplace u = Point2 u -> Point2 u
type AdvanceVec u = Vec2 u
--------------------------------------------------------------------------------
-- DrawingInfo
-- | A query on the DrawingContext.
--
-- Alias for 'CF'.
--
type DrawingInfo a = CF a
-- | A query on the DrawingContext respective to the supplied
-- point.
--
-- Alias for 'LocCF'.
--
type LocDrawingInfo u a = LocCF u a
-- | A query on the DrawingContext respective to the supplied
-- point and angle.
--
-- Alias for 'LocCF'.
--
type LocThetaDrawingInfo u a = LocThetaCF u a
--------------------------------------------------------------------------------
-- Graphic
-- | Simple drawing - produce a primitive, access the DrawingContext
-- if required.
--
type Graphic u = CF (PrimGraphic u)
-- | Commonly graphics take a start point as well as a drawing
-- context.
--
-- Here they are called a LocGraphic - graphic with a (starting)
-- location.
--
type LocGraphic u = LocCF u (PrimGraphic u)
-- | A function from @point * angle -> graphic@
--
type LocThetaGraphic u = LocThetaCF u (PrimGraphic u)
-- | ConnectorGraphic is a connector drawn between two points
-- contructing a Graphic.
--
type ConnectorGraphic u = ConnectorCF u (PrimGraphic u)
type DGraphic = Graphic Double
type DLocGraphic = LocGraphic Double
type DLocThetaGraphic = LocThetaGraphic Double
type DConnectorGraphic = ConnectorGraphic Double
type instance DUnit (Graphic u) = u
--------------------------------------------------------------------------------
-- Image
-- | Images return a value as well as drawing. A /node/ is a
-- typical example - nodes are drawing but the also support
-- taking anchor points.
--
type Image u a = CF (a, PrimGraphic u)
type LocImage u a = LocCF u (a,PrimGraphic u)
type LocThetaImage u a = LocThetaCF u (a,PrimGraphic u)
-- | ConnectorImage is a connector drawn between two points
-- constructing an Image.
--
-- Usually the answer type of a ConnectorImage will be a Path so
-- the Points ar @midway@, @atstart@ etc. can be taken on it.
--
type ConnectorImage u a = ConnectorCF u (a, PrimGraphic u)
type DImage a = Image Double a
type DLocImage a = LocImage Double a
type DLocThetaImage a = LocThetaImage Double a
type DConnectorImage a = ConnectorImage Double a
type instance DUnit (Image u a) = u
--------------------------------------------------------------------------------
-- | /Advance vector/ graphic - this partially models the
-- PostScript @show@ command which moves the /current point/ by the
-- width (advance) vector as each character is drawn.
--
type AdvGraphic u = LocImage u (Point2 u)
type DAdvGraphic = AdvGraphic Double
type instance DUnit (AdvGraphic u) = u
--------------------------------------------------------------------------------
-- | Graphic with a bounding box.
--
type BoundedGraphic u = Image u (BoundingBox u)
type DBoundedGraphic = BoundedGraphic Double
type instance DUnit (BoundedGraphic u) = u
-- | LocGraphic with a bounding box.
--
type BoundedLocGraphic u = LocImage u (BoundingBox u)
type DBoundedLocGraphic = BoundedLocGraphic Double
type instance DUnit (BoundedLocGraphic u) = u
--------------------------------------------------------------------------------
-- Graphic instances
-- Affine instances
instance (Real u, Floating u) => Rotate (Graphic u) where
rotate ang = postpro (rotate ang)
instance (Real u, Floating u) => RotateAbout (Graphic u) where
rotateAbout ang pt = postpro (rotateAbout ang pt)
instance Num u => Scale (Graphic u) where
scale sx sy = postpro (scale sx sy)
instance Num u => Translate (Graphic u) where
translate dx dy = postpro (translate dx dy)
--------------------------------------------------------------------------------
-- Image instances
-- Affine instances
instance (Real u, Floating u, Rotate a, DUnit a ~ u) =>
Rotate (Image u a) where
rotate ang = postpro (\(a,b) -> (rotate ang a, rotate ang b))
instance (Real u, Floating u, RotateAbout a, DUnit a ~ u) =>
RotateAbout (Image u a) where
rotateAbout ang pt =
postpro (\(a,b) -> (rotateAbout ang pt a, rotateAbout ang pt b))
instance (Num u, Scale a, DUnit a ~ u) => Scale (Image u a) where
scale sx sy = postpro (\(a,b) -> (scale sx sy a, scale sx sy b))
instance (Num u, Translate a, DUnit a ~ u) => Translate (Image u a) where
translate dx dy = postpro (\(a,b) -> (translate dx dy a, translate dx dy b))
--------------------------------------------------------------------------------
-- | Extract the horizontal component of an advance vector.
--
-- For left-to-right latin text, the vertical component of an
-- advance vector is expected to be 0. Ingoring it seems
-- permissible, e.g. when calculating bounding boxes for
-- left-to-right text.
--
advanceH :: Num u => AdvanceVec u -> u
advanceH (V2 w _) = w
-- | Extract the verticaltal component of an advance vector.
--
-- For left-to-right latin text, the vertical component of an
-- advance vector is expected to be 0.
--
advanceV :: Num u => AdvanceVec u -> u
advanceV (V2 _ h) = h
--------------------------------------------------------------------------------
-- Run functions
runGraphic :: DrawingContext -> Graphic u -> PrimGraphic u
runGraphic ctx df = runCF ctx df
runLocGraphic :: DrawingContext -> Point2 u -> LocGraphic u -> PrimGraphic u
runLocGraphic ctx pt df = runCF ctx (unCF1 pt df)
runImage :: DrawingContext -> Image u a -> (a, PrimGraphic u)
runImage ctx img = runCF ctx img
runLocImage :: DrawingContext -> Point2 u -> LocImage u a -> (a, PrimGraphic u)
runLocImage ctx pt img = runCF ctx (unCF1 pt img)
--------------------------------------------------------------------------------
-- Combinators
moveLoc :: (Point2 u -> Point2 u) -> LocCF u a -> LocCF u a
moveLoc = prepro1
infixr 1 `at`
at :: CF (Point2 u -> b) -> Point2 u -> CF b
at = situ1
-------------------------------------------------------------------------------
-- Dropping /answers/
extrGraphic :: Image u a -> Graphic u
extrGraphic = postpro snd
extrLocGraphic :: LocImage u a -> LocGraphic u
extrLocGraphic = postpro1 snd
--------------------------------------------------------------------------------
metamorphPrim :: (Primitive u -> Primitive u) -> PrimGraphic u -> PrimGraphic u
metamorphPrim f = primGraphic . f . getPrimGraphic
fontDeltaGraphic :: Graphic u -> Graphic u
fontDeltaGraphic df =
drawingCtx `bind` \ctx -> postpro (fun $ font_props ctx) df
where
fun attr = metamorphPrim (fontDeltaContext attr)
fontDeltaImage :: Image u a -> Image u a
fontDeltaImage df =
drawingCtx `bind` \ctx -> postpro (fun $ font_props ctx) df
where
fun attr = \(a,prim) -> (a, metamorphPrim (fontDeltaContext attr) prim)
xlinkGraphic :: XLink -> Graphic u -> Graphic u
xlinkGraphic hypl = postpro (metamorphPrim (xlink hypl))
xlinkImage :: XLink -> Image u a -> Image u a
xlinkImage hypl =
postpro (\(a,prim) -> (a, metamorphPrim (xlink hypl) prim))
intoImage :: CF a -> Graphic u -> Image u a
intoImage = postcomb (,)
intoLocImage :: LocCF u a -> LocGraphic u -> LocImage u a
intoLocImage = postcomb1 (,)
-- Drawing $ \ctx a -> (getDrawing f ctx a, getDrawing g ctx a)
intoConnectorImage :: ConnectorCF u a
-> ConnectorGraphic u
-> ConnectorImage u a
intoConnectorImage = postcomb2 (,)
intoLocThetaImage :: LocThetaCF u a
-> LocThetaGraphic u
-> LocThetaImage u a
intoLocThetaImage = postcomb2 (,)
-- | Construction is different to intoZZ functions hence the
-- different name.
--
makeAdvGraphic :: PointDisplace u
-> LocGraphic u
-> AdvGraphic u
makeAdvGraphic pf df = postcomb1 (,) (postpro1 pf locPoint) df