packages feed

wumpus-basic 0.12.0 → 0.13.0

raw patch · 59 files changed

+6685/−4156 lines, 59 filesdep +directorydep +filepathdep ~vector-spacedep ~wumpus-corePVP ok

version bump matches the API change (PVP)

Dependencies added: directory, filepath

Dependency ranges changed: vector-space, wumpus-core

API changes (from Hackage documentation)

- Wumpus.Basic.Anchors: center :: (CenterAnchor t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: class CardinalAnchor t
- Wumpus.Basic.Anchors: class CardinalAnchor2 t
- Wumpus.Basic.Anchors: class CenterAnchor t
- Wumpus.Basic.Anchors: class RadialAnchor t
- Wumpus.Basic.Anchors: east :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: eastwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
- Wumpus.Basic.Anchors: north :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: northeast :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: northeastwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
- Wumpus.Basic.Anchors: northwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
- Wumpus.Basic.Anchors: northwest :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: northwestwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
- Wumpus.Basic.Anchors: radialAnchor :: (RadialAnchor t, (DUnit t) ~ u) => Radian -> t -> Point2 u
- Wumpus.Basic.Anchors: radialConnectorPoints :: (Real u, Floating u, CenterAnchor t1, RadialAnchor t1, CenterAnchor t2, RadialAnchor t2, u ~ (DUnit t1), (DUnit t1) ~ (DUnit t2)) => t1 -> t2 -> (Point2 u, Point2 u)
- Wumpus.Basic.Anchors: south :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: southeast :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: southeastwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
- Wumpus.Basic.Anchors: southwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
- Wumpus.Basic.Anchors: southwest :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: southwestwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
- Wumpus.Basic.Anchors: west :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
- Wumpus.Basic.Anchors: westwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
- Wumpus.Basic.Graphic.Base: anteriorGraphic :: Graphic u -> GraphicTrafoF u
- Wumpus.Basic.Graphic.Base: data DrawingR a
- Wumpus.Basic.Graphic.Base: imageTrafoDrawing :: DrawingTrafoF a -> ImageTrafoF u a
- Wumpus.Basic.Graphic.Base: imageTrafoGraphic :: GraphicTrafoF u -> ImageTrafoF u a
- Wumpus.Basic.Graphic.Base: instance (DUnit a ~ u, Num u, Scale a) => Scale (Image u a)
- Wumpus.Basic.Graphic.Base: instance (DUnit a ~ u, Num u, Translate a) => Translate (Image u a)
- Wumpus.Basic.Graphic.Base: instance (DUnit a ~ u, Real u, Floating u, Rotate a) => Rotate (Image u a)
- Wumpus.Basic.Graphic.Base: instance (DUnit a ~ u, Real u, Floating u, RotateAbout a) => RotateAbout (Image u a)
- Wumpus.Basic.Graphic.Base: instance (Real u, Floating u) => Rotate (Graphic u)
- Wumpus.Basic.Graphic.Base: instance (Real u, Floating u) => RotateAbout (Graphic u)
- Wumpus.Basic.Graphic.Base: instance Applicative DrawingR
- Wumpus.Basic.Graphic.Base: instance DrawingCtxM DrawingR
- Wumpus.Basic.Graphic.Base: instance Functor DrawingR
- Wumpus.Basic.Graphic.Base: instance Monad DrawingR
- Wumpus.Basic.Graphic.Base: instance Monoid a => Monoid (DrawingR a)
- Wumpus.Basic.Graphic.Base: instance Num u => Scale (Graphic u)
- Wumpus.Basic.Graphic.Base: instance Num u => Translate (Graphic u)
- Wumpus.Basic.Graphic.Base: instance OPlus a => OPlus (DrawingR a)
- Wumpus.Basic.Graphic.Base: intoConnectorImage :: ConnectorDrawingR u a -> ConnectorGraphic u -> ConnectorImage u a
- Wumpus.Basic.Graphic.Base: intoImage :: DrawingR a -> Graphic u -> Image u a
- Wumpus.Basic.Graphic.Base: intoImageTrafo :: DrawingTrafoF a -> GraphicTrafoF u -> ImageTrafoF u a
- Wumpus.Basic.Graphic.Base: intoLocImage :: LocDrawingR u a -> LocGraphic u -> LocImage u a
- Wumpus.Basic.Graphic.Base: intoThetaLocImage :: ThetaLocDrawingR u a -> ThetaLocGraphic u -> ThetaLocImage u a
- Wumpus.Basic.Graphic.Base: runDrawingR :: DrawingContext -> DrawingR a -> a
- Wumpus.Basic.Graphic.Base: runGraphic :: DrawingContext -> Graphic u -> PrimGraphic u
- Wumpus.Basic.Graphic.Base: runImage :: DrawingContext -> Image u a -> (a, PrimGraphic u)
- Wumpus.Basic.Graphic.Base: superiorGraphic :: Graphic u -> GraphicTrafoF u
- Wumpus.Basic.Graphic.Base: type ConnectorDrawingR u a = Point2 u -> Point2 u -> DrawingR a
- Wumpus.Basic.Graphic.Base: type ConnectorGraphic u = Point2 u -> Point2 u -> Graphic u
- Wumpus.Basic.Graphic.Base: type ConnectorImage u a = Point2 u -> Point2 u -> Image u a
- Wumpus.Basic.Graphic.Base: type DConnectorDrawingR a = ConnectorDrawingR Double a
- Wumpus.Basic.Graphic.Base: type DConnectorGraphic = ConnectorGraphic Double
- Wumpus.Basic.Graphic.Base: type DConnectorImage a = ConnectorImage Double a
- Wumpus.Basic.Graphic.Base: type DGraphic = Graphic Double
- Wumpus.Basic.Graphic.Base: type DImage a = Image Double a
- Wumpus.Basic.Graphic.Base: type DLocDrawingR a = LocDrawingR Double a
- Wumpus.Basic.Graphic.Base: type DLocGraphic = LocGraphic Double
- Wumpus.Basic.Graphic.Base: type DLocImage a = LocImage Double a
- Wumpus.Basic.Graphic.Base: type DPoint2F = Point2F Double
- Wumpus.Basic.Graphic.Base: type DThetaLocDrawingR a = ThetaLocDrawingR Double a
- Wumpus.Basic.Graphic.Base: type DThetaLocGraphic = ThetaLocGraphic Double
- Wumpus.Basic.Graphic.Base: type DThetaLocImage a = ThetaLocImage Double a
- Wumpus.Basic.Graphic.Base: type DrawingTrafoF a = DrawingR a -> DrawingR a
- Wumpus.Basic.Graphic.Base: type Graphic u = DrawingR (PrimGraphic u)
- Wumpus.Basic.Graphic.Base: type GraphicTrafoF u = Graphic u -> Graphic u
- Wumpus.Basic.Graphic.Base: type Image u a = DrawingR (a, PrimGraphic u)
- Wumpus.Basic.Graphic.Base: type ImageTrafoF u a = Image u a -> Image u a
- Wumpus.Basic.Graphic.Base: type LocDrawingR u a = Point2 u -> DrawingR a
- Wumpus.Basic.Graphic.Base: type LocGraphic u = Point2 u -> Graphic u
- Wumpus.Basic.Graphic.Base: type LocImage u a = Point2 u -> Image u a
- Wumpus.Basic.Graphic.Base: type Point2F u = Point2 u -> Point2 u
- Wumpus.Basic.Graphic.Base: type ThetaLocDrawingR u a = Radian -> LocDrawingR u a
- Wumpus.Basic.Graphic.Base: type ThetaLocGraphic u = Radian -> LocGraphic u
- Wumpus.Basic.Graphic.Base: type ThetaLocImage u a = Radian -> LocImage u a
- Wumpus.Basic.Graphic.Base: wrapPrim :: Primitive u -> PrimGraphic u
- Wumpus.Basic.Graphic.Base: xlinkGraphic :: XLink -> Graphic u -> Graphic u
- Wumpus.Basic.Graphic.Base: xlinkImage :: XLink -> Image u a -> Image u a
- Wumpus.Basic.Graphic.Drawing: at :: (Point2 u -> a) -> Point2 u -> a
- Wumpus.Basic.Graphic.Drawing: data DrawingT u m a
- Wumpus.Basic.Graphic.Drawing: draw :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => Graphic u -> m ()
- Wumpus.Basic.Graphic.Drawing: drawi :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => Image u a -> m a
- Wumpus.Basic.Graphic.Drawing: drawi_ :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => Image u a -> m ()
- Wumpus.Basic.Graphic.Drawing: evalDrawing :: DrawingContext -> Drawing u a -> a
- Wumpus.Basic.Graphic.Drawing: evalDrawingT :: Monad m => DrawingContext -> DrawingT u m a -> m a
- Wumpus.Basic.Graphic.Drawing: execDrawing :: DrawingContext -> Drawing u a -> HPrim u
- Wumpus.Basic.Graphic.Drawing: execDrawingT :: Monad m => DrawingContext -> DrawingT u m a -> m (HPrim u)
- Wumpus.Basic.Graphic.Drawing: execFdcDrawing :: (Real u, Floating u, FromPtSize u) => DrawingContext -> Drawing u a -> Maybe (Picture u)
- Wumpus.Basic.Graphic.Drawing: execFdcDrawingT :: (Real u, Floating u, FromPtSize u, Monad m) => DrawingContext -> DrawingT u m a -> m (Maybe (Picture u))
- Wumpus.Basic.Graphic.Drawing: instance Applicative (Drawing u)
- Wumpus.Basic.Graphic.Drawing: instance DrawingCtxM (Drawing u)
- Wumpus.Basic.Graphic.Drawing: instance Functor (Drawing u)
- Wumpus.Basic.Graphic.Drawing: instance Monad (Drawing u)
- Wumpus.Basic.Graphic.Drawing: instance Monad m => Applicative (DrawingT u m)
- Wumpus.Basic.Graphic.Drawing: instance Monad m => DrawingCtxM (DrawingT u m)
- Wumpus.Basic.Graphic.Drawing: instance Monad m => Functor (DrawingT u m)
- Wumpus.Basic.Graphic.Drawing: instance Monad m => Monad (DrawingT u m)
- Wumpus.Basic.Graphic.Drawing: instance Monad m => TraceM (DrawingT u m)
- Wumpus.Basic.Graphic.Drawing: instance TraceM (Drawing u)
- Wumpus.Basic.Graphic.Drawing: liftToPictureMb :: (Real u, Floating u, FromPtSize u) => HPrim u -> Maybe (Picture u)
- Wumpus.Basic.Graphic.Drawing: liftToPictureU :: (Real u, Floating u, FromPtSize u) => HPrim u -> Picture u
- Wumpus.Basic.Graphic.Drawing: mbPictureU :: (Real u, Floating u, FromPtSize u) => Maybe (Picture u) -> Picture u
- Wumpus.Basic.Graphic.Drawing: node :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ (MonUnit m)) => LocGraphic u -> m ()
- Wumpus.Basic.Graphic.Drawing: nodei :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ (MonUnit m)) => LocImage u a -> m a
- Wumpus.Basic.Graphic.Drawing: runDrawingT :: Monad m => DrawingContext -> DrawingT u m a -> m (a, HPrim u)
- Wumpus.Basic.Graphic.Drawing: runFdcDrawing :: (Real u, Floating u, FromPtSize u) => DrawingContext -> Drawing u a -> (a, Maybe (Picture u))
- Wumpus.Basic.Graphic.Drawing: runFdcDrawingT :: (Real u, Floating u, FromPtSize u, Monad m) => DrawingContext -> DrawingT u m a -> m (a, Maybe (Picture u))
- Wumpus.Basic.Graphic.Drawing: xdraw :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => XLink -> Graphic u -> m ()
- Wumpus.Basic.Graphic.Drawing: xdrawi :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => XLink -> Image u a -> m a
- Wumpus.Basic.Graphic.Drawing: xdrawi_ :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => XLink -> Image u a -> m ()
- Wumpus.Basic.Graphic.DrawingContext: instance Eq DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: instance Show DrawingContext
- Wumpus.Basic.Graphic.PrimGraphic: borderedCircle :: Floating u => Int -> u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: borderedDisk :: Num u => u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: borderedEllipse :: Num u => u -> u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: borderedPath :: Num u => PrimPath u -> Graphic u
- Wumpus.Basic.Graphic.PrimGraphic: borderedRectangle :: Fractional u => u -> u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: centermonoTextline :: (Fractional u, Ord u, FromPtSize u) => String -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: closedStroke :: Num u => PrimPath u -> Graphic u
- Wumpus.Basic.Graphic.PrimGraphic: curveBetween :: Fractional u => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Graphic u
- Wumpus.Basic.Graphic.PrimGraphic: displace :: Num u => u -> u -> Point2 u -> Point2 u
- Wumpus.Basic.Graphic.PrimGraphic: displaceParallel :: Floating u => u -> Radian -> Point2F u
- Wumpus.Basic.Graphic.PrimGraphic: displacePerpendicular :: Floating u => u -> Radian -> Point2F u
- Wumpus.Basic.Graphic.PrimGraphic: drawGraphic :: (Real u, Floating u, FromPtSize u) => DrawingContext -> Graphic u -> Picture u
- Wumpus.Basic.Graphic.PrimGraphic: filledCircle :: Floating u => Int -> u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: filledDisk :: Num u => u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: filledEllipse :: Num u => u -> u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: filledPath :: Num u => PrimPath u -> Graphic u
- Wumpus.Basic.Graphic.PrimGraphic: filledRectangle :: Fractional u => u -> u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: hdisplace :: Num u => u -> Point2 u -> Point2 u
- Wumpus.Basic.Graphic.PrimGraphic: hkernline :: Num u => [KerningChar u] -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: localPoint :: (Point2 u -> Point2 u) -> LocGraphic u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: openStroke :: Num u => PrimPath u -> Graphic u
- Wumpus.Basic.Graphic.PrimGraphic: parallelvec :: Floating u => u -> Radian -> Vec2 u
- Wumpus.Basic.Graphic.PrimGraphic: perpendicularvec :: Floating u => u -> Radian -> Vec2 u
- Wumpus.Basic.Graphic.PrimGraphic: rtextline :: Num u => String -> ThetaLocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: straightLine :: Fractional u => Vec2 u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: straightLineBetween :: Fractional u => Point2 u -> Point2 u -> Graphic u
- Wumpus.Basic.Graphic.PrimGraphic: strokedCircle :: Floating u => Int -> u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: strokedDisk :: Num u => u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: strokedEllipse :: Num u => u -> u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: strokedRectangle :: Fractional u => u -> u -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: supplyPt :: Point2 u -> LocGraphic u -> Graphic u
- Wumpus.Basic.Graphic.PrimGraphic: textline :: Num u => String -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: textlineMulti :: Fractional u => [String] -> LocGraphic u
- Wumpus.Basic.Graphic.PrimGraphic: vdisplace :: Num u => u -> Point2 u -> Point2 u
- Wumpus.Basic.Graphic.PrimGraphic: vecdisplace :: Num u => Vec2 u -> Point2 u -> Point2 u
- Wumpus.Basic.Graphic.PrimGraphic: vkernline :: Num u => [KerningChar u] -> LocGraphic u
- Wumpus.Basic.Graphic.Query: monoMultiLineTextHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => Int -> m u
- Wumpus.Basic.Graphic.Query: monoNumeralHeight :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoSpacerWidth :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoTextHeight :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.PictureLanguage: HBottom :: HAlign
- Wumpus.Basic.PictureLanguage: HCenter :: HAlign
- Wumpus.Basic.PictureLanguage: HTop :: HAlign
- Wumpus.Basic.PictureLanguage: VCenter :: VAlign
- Wumpus.Basic.PictureLanguage: VLeft :: VAlign
- Wumpus.Basic.PictureLanguage: VRight :: VAlign
- Wumpus.Basic.PictureLanguage: alignH :: (Fractional u, Ord u) => HAlign -> Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: alignHSep :: (Fractional u, Ord u) => HAlign -> u -> Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: alignV :: (Fractional u, Ord u) => VAlign -> Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: alignVSep :: (Fractional u, Ord u) => VAlign -> u -> Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: atPoint :: (Num u, Ord u) => Picture u -> Point2 u -> Picture u
- Wumpus.Basic.PictureLanguage: centerOver :: (Fractional u, Ord u) => Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: centerPoint :: Fractional u => Picture u -> Point2 u
- Wumpus.Basic.PictureLanguage: centeredAt :: (Fractional u, Ord u) => Picture u -> Point2 u -> Picture u
- Wumpus.Basic.PictureLanguage: data HAlign
- Wumpus.Basic.PictureLanguage: data VAlign
- Wumpus.Basic.PictureLanguage: hcat :: (Num u, Ord u) => Picture u -> [Picture u] -> Picture u
- Wumpus.Basic.PictureLanguage: hcatA :: (Fractional u, Ord u) => HAlign -> Picture u -> [Picture u] -> Picture u
- Wumpus.Basic.PictureLanguage: hsep :: (Num u, Ord u) => u -> Picture u -> [Picture u] -> Picture u
- Wumpus.Basic.PictureLanguage: hsepA :: (Fractional u, Ord u) => HAlign -> u -> Picture u -> [Picture u] -> Picture u
- Wumpus.Basic.PictureLanguage: hspace :: (Num u, Ord u) => u -> Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: instance Eq HAlign
- Wumpus.Basic.PictureLanguage: instance Eq VAlign
- Wumpus.Basic.PictureLanguage: instance Show HAlign
- Wumpus.Basic.PictureLanguage: instance Show VAlign
- Wumpus.Basic.PictureLanguage: nextToH :: (Num u, Ord u) => Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: nextToV :: (Num u, Ord u) => Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: over :: (Num u, Ord u) => Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: stackOver :: (Num u, Ord u) => [Picture u] -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: stackOverCenter :: (Fractional u, Ord u) => [Picture u] -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: under :: (Num u, Ord u) => Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: vcat :: (Num u, Ord u) => Picture u -> [Picture u] -> Picture u
- Wumpus.Basic.PictureLanguage: vcatA :: (Fractional u, Ord u) => VAlign -> Picture u -> [Picture u] -> Picture u
- Wumpus.Basic.PictureLanguage: vsep :: (Num u, Ord u) => u -> Picture u -> [Picture u] -> Picture u
- Wumpus.Basic.PictureLanguage: vsepA :: (Fractional u, Ord u) => VAlign -> u -> Picture u -> [Picture u] -> Picture u
- Wumpus.Basic.PictureLanguage: vspace :: (Num u, Ord u) => u -> Picture u -> Picture u -> Picture u
- Wumpus.Basic.PictureLanguage: zconcat :: (Num u, Ord u) => Picture u -> [Picture u] -> Picture u
- Wumpus.Basic.Shapes.Coordinate: coordinateMark :: (Real u, Floating u) => Coordinate u -> Image u (CoordinateAnchor u)
- Wumpus.Basic.Shapes.Plaintext: data Plaintext u
- Wumpus.Basic.Shapes.Plaintext: data PlaintextAnchor u
- Wumpus.Basic.Shapes.Plaintext: drawText :: (Real u, Floating u, FromPtSize u) => Plaintext u -> Image u (PlaintextAnchor u)
- Wumpus.Basic.Shapes.Plaintext: instance (Real u, Floating u) => CardinalAnchor (PlaintextAnchor u)
- Wumpus.Basic.Shapes.Plaintext: instance (Real u, Floating u) => CardinalAnchor2 (PlaintextAnchor u)
- Wumpus.Basic.Shapes.Plaintext: instance (Real u, Floating u) => CenterAnchor (PlaintextAnchor u)
- Wumpus.Basic.Shapes.Plaintext: instance (Real u, Floating u) => RadialAnchor (PlaintextAnchor u)
- Wumpus.Basic.Shapes.Plaintext: instance Eq u => Eq (Plaintext u)
- Wumpus.Basic.Shapes.Plaintext: instance Num u => Translate (Plaintext u)
- Wumpus.Basic.Shapes.Plaintext: instance Ord u => Ord (Plaintext u)
- Wumpus.Basic.Shapes.Plaintext: instance Rotate (Plaintext u)
- Wumpus.Basic.Shapes.Plaintext: instance Show u => Show (Plaintext u)
- Wumpus.Basic.Shapes.Plaintext: plaintext :: Num u => String -> Plaintext u
- Wumpus.Basic.Shapes.Plaintext: type DPlaintext = Plaintext Double
- Wumpus.Basic.Shapes.Plaintext: type DPlaintextAnchor = PlaintextAnchor Double
- Wumpus.Basic.Text.LRSymbol: aleph :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: alpha :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: ampersand :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: angle :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: angleleft :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: angleright :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: approxequal :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowboth :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowdblboth :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowdbldown :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowdblleft :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowdblright :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowdblup :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowdown :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowleft :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowright :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: arrowup :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: asteriskmath :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: bar :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: beta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: braceleft :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: braceright :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: bracketleft :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: bracketright :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: bullet :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: carriagereturn :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: chi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: circlemultiply :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: circleplus :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: club :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: colon :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: comma :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: congruent :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: copyrightsans :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: copyrightserif :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: degree :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: delta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: diamond :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: divide :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: dotmath :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: eight :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: element :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: ellipsis :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: emptyset :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: epsilon :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: equal :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: equivalence :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: eta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: exclam :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: existential :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: five :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: florin :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: four :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: fraction :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: gamma :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: gradient :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: greater :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: greaterequal :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: heart :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: infinity :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: integral :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: intersection :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: iota :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: kappa :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: lambda :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: less :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: lessequal :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: logicaland :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: logicalnot :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: logicalor :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: lozenge :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: minus :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: minute :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: mu :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: multiply :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: nine :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: notelement :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: notequal :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: notsubset :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: nu :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: numbersign :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: omega :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: omega1 :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: omicron :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: one :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: parenleft :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: parenright :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: partialdiff :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: percent :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: period :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: perpendicular :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: phi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: phi1 :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: pi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: plus :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: plusminus :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: product :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: propersubset :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: propersuperset :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: proportional :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: psi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: question :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: radical :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: radicalex :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: reflexsubset :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: reflexsuperset :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: registersans :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: registerserif :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: rho :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: second :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: semicolon :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: seven :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: sigma :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: sigma1 :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: similar :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: six :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: slash :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: space :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: spade :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: suchthat :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: summation :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: tau :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: therefore :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: theta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: theta1 :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: three :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: trademarksans :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: trademarkserif :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: two :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uAlpha :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uBeta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uChi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uDelta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uEpsilon :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uEta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uEuro :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uGamma :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uIfraktur :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uIota :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uKappa :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uLambda :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uMu :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uNu :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uOmega :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uOmicron :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uPhi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uPi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uPsi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uRfraktur :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uRho :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uSigma :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uTau :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uTheta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uUpsilon :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uUpsilon1 :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uXi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: uZeta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: underscore :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: union :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: universal :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: upsilon :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: weierstrass :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: xi :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: zero :: Num u => LRText u ()
- Wumpus.Basic.Text.LRSymbol: zeta :: Num u => LRText u ()
- Wumpus.Basic.Text.LRText: char :: Num u => Char -> LRText u ()
- Wumpus.Basic.Text.LRText: data LRText u a
- Wumpus.Basic.Text.LRText: escInt :: Num u => Int -> LRText u ()
- Wumpus.Basic.Text.LRText: escName :: Num u => String -> LRText u ()
- Wumpus.Basic.Text.LRText: execLRText :: (Num u, FromPtSize u) => LRText u a -> LocGraphic u
- Wumpus.Basic.Text.LRText: instance Applicative (LRText u)
- Wumpus.Basic.Text.LRText: instance Functor (LRText u)
- Wumpus.Basic.Text.LRText: instance Monad (LRText u)
- Wumpus.Basic.Text.LRText: kern :: Num u => u -> LRText u ()
- Wumpus.Basic.Text.LRText: runLRText :: (Num u, FromPtSize u) => LRText u a -> LocImage u a
- Wumpus.Basic.Text.LRText: symb :: Num u => Char -> LRText u ()
- Wumpus.Basic.Text.LRText: symbEscInt :: Num u => Int -> LRText u ()
- Wumpus.Basic.Text.LRText: symbEscName :: Num u => String -> LRText u ()
- Wumpus.Basic.Utils.Combinators: bindAsk :: Monad m => m a -> (a -> r1 -> m b) -> r1 -> m b
- Wumpus.Basic.Utils.Combinators: bindAskR2 :: Monad m => m a -> (a -> r1 -> r2 -> m b) -> r1 -> r2 -> m b
- Wumpus.Basic.Utils.Combinators: bindInto :: Monad m => (r1 -> m a) -> (a -> m b) -> r1 -> m b
- Wumpus.Basic.Utils.Combinators: bindR :: Monad m => (r -> m a) -> (a -> r -> m b) -> r -> m b
- Wumpus.Basic.Utils.Combinators: bindR2 :: Monad m => (r1 -> r2 -> m a) -> (a -> r1 -> r2 -> m b) -> r1 -> r2 -> m b
- Wumpus.Basic.Utils.Combinators: fork :: (a -> b) -> (a -> c) -> a -> (b, c)
- Wumpus.Basic.Utils.Combinators: forkA :: Applicative f => f a -> f b -> f (a, b)
- Wumpus.Basic.Utils.Combinators: prod :: (a -> c) -> (b -> d) -> (a, b) -> (c, d)
- Wumpus.Basic.Utils.Combinators: rlift1 :: Monad m => m a -> (r -> m a)
- Wumpus.Basic.Utils.Combinators: rlift2 :: Monad m => m a -> (r1 -> r2 -> m a)
+ Wumpus.Basic.DrawingComposition: alignH :: (Fractional u, Ord u) => HAlign -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: alignHSep :: (Fractional u, Ord u) => HAlign -> u -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: alignV :: (Fractional u, Ord u) => VAlign -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: alignVSep :: (Fractional u, Ord u) => VAlign -> u -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: atPoint :: (Num u, Ord u) => Drawing u -> Point2 u -> Drawing u
+ Wumpus.Basic.DrawingComposition: centeredAt :: (Fractional u, Ord u) => Drawing u -> Point2 u -> Drawing u
+ Wumpus.Basic.DrawingComposition: centric :: (Fractional u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: hcat :: (Real u, Floating u, FromPtSize u) => [Drawing u] -> Drawing u
+ Wumpus.Basic.DrawingComposition: hcatA :: (Real u, Floating u, FromPtSize u) => HAlign -> [Drawing u] -> Drawing u
+ Wumpus.Basic.DrawingComposition: hsep :: (Real u, Floating u, FromPtSize u) => u -> [Drawing u] -> Drawing u
+ Wumpus.Basic.DrawingComposition: hsepA :: (Real u, Floating u, FromPtSize u) => HAlign -> u -> [Drawing u] -> Drawing u
+ Wumpus.Basic.DrawingComposition: hspace :: (Num u, Ord u) => u -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: nextToH :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: nextToV :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: over :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: under :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: vcat :: (Real u, Floating u, FromPtSize u) => [Drawing u] -> Drawing u
+ Wumpus.Basic.DrawingComposition: vcatA :: (Real u, Floating u, FromPtSize u) => VAlign -> [Drawing u] -> Drawing u
+ Wumpus.Basic.DrawingComposition: vsep :: (Real u, Floating u, FromPtSize u) => u -> [Drawing u] -> Drawing u
+ Wumpus.Basic.DrawingComposition: vsepA :: (Real u, Floating u, FromPtSize u) => VAlign -> u -> [Drawing u] -> Drawing u
+ Wumpus.Basic.DrawingComposition: vspace :: (Num u, Ord u) => u -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.DrawingComposition: zconcat :: (Real u, Floating u, FromPtSize u) => [Drawing u] -> Drawing u
+ Wumpus.Basic.FontLoader.AfmLoader: afmV4Dot1Loader :: FilePath -> FontLoader AfmUnit
+ Wumpus.Basic.FontLoader.AfmLoader: loadAfmMetrics :: FilePath -> [FontName] -> IO BaseGlyphMetrics
+ Wumpus.Basic.FontLoader.AfmParserBase: afmFileParser :: CharParser AfmGlyphMetrics -> CharParser AfmFile
+ Wumpus.Basic.FontLoader.AfmParserBase: charBBox :: CharParser AfmBoundingBox
+ Wumpus.Basic.FontLoader.AfmParserBase: cint :: CharParser Int
+ Wumpus.Basic.FontLoader.AfmParserBase: double :: CharParser Double
+ Wumpus.Basic.FontLoader.AfmParserBase: getCapHeight :: GlobalInfo -> Maybe AfmUnit
+ Wumpus.Basic.FontLoader.AfmParserBase: getEncodingScheme :: GlobalInfo -> Maybe String
+ Wumpus.Basic.FontLoader.AfmParserBase: getFontBBox :: GlobalInfo -> Maybe AfmBoundingBox
+ Wumpus.Basic.FontLoader.AfmParserBase: hexInt :: CharParser Int
+ Wumpus.Basic.FontLoader.AfmParserBase: int :: CharParser Int
+ Wumpus.Basic.FontLoader.AfmParserBase: integer :: CharParser Integer
+ Wumpus.Basic.FontLoader.AfmParserBase: keyName :: CharParser AfmKey
+ Wumpus.Basic.FontLoader.AfmParserBase: keyStringPair :: CharParser (AfmKey, String)
+ Wumpus.Basic.FontLoader.AfmParserBase: lexeme :: CharParser a -> CharParser a
+ Wumpus.Basic.FontLoader.AfmParserBase: metric :: String -> a -> CharParser a -> CharParser a
+ Wumpus.Basic.FontLoader.AfmParserBase: name :: CharParser String
+ Wumpus.Basic.FontLoader.AfmParserBase: name1 :: CharParser String
+ Wumpus.Basic.FontLoader.AfmParserBase: newlineOrEOF :: CharParser ()
+ Wumpus.Basic.FontLoader.AfmParserBase: number :: CharParser AfmUnit
+ Wumpus.Basic.FontLoader.AfmParserBase: octInt :: CharParser Int
+ Wumpus.Basic.FontLoader.AfmParserBase: runQuery :: String -> CharParser a -> GlobalInfo -> Maybe a
+ Wumpus.Basic.FontLoader.AfmParserBase: semi :: CharParser Char
+ Wumpus.Basic.FontLoader.AfmParserBase: startCharMetrics :: CharParser Int
+ Wumpus.Basic.FontLoader.AfmParserBase: symbol :: String -> CharParser String
+ Wumpus.Basic.FontLoader.AfmParserBase: textQuery :: String -> GlobalInfo -> Maybe String
+ Wumpus.Basic.FontLoader.AfmParserBase: uptoNewline :: CharParser String
+ Wumpus.Basic.FontLoader.AfmParserBase: versionNumber :: CharParser String
+ Wumpus.Basic.FontLoader.AfmV2Parser: parseAfmV2File :: FilePath -> IO (Either ParseError AfmFile)
+ Wumpus.Basic.FontLoader.AfmV4Dot1Parser: parseAfmV4Dot1File :: FilePath -> IO (Either ParseError AfmFile)
+ Wumpus.Basic.FontLoader.Base: AfmFile :: Maybe String -> AfmBoundingBox -> Maybe AfmUnit -> [AfmGlyphMetrics] -> AfmFile
+ Wumpus.Basic.FontLoader.Base: AfmGlyphMetrics :: !PSCharCode -> !Vec2 AfmUnit -> !String -> AfmGlyphMetrics
+ Wumpus.Basic.FontLoader.Base: FontLoader :: (cu -> PtSize) -> FilePath -> (FontName -> FilePath) -> (FilePath -> IO (Either String interim)) -> (interim -> GlyphMetricsTable cu) -> FontLoader cu
+ Wumpus.Basic.FontLoader.Base: afmUnitScale :: AfmUnit -> PtSize
+ Wumpus.Basic.FontLoader.Base: afmValue :: FromPtSize u => AfmUnit -> PtSize -> u
+ Wumpus.Basic.FontLoader.Base: afm_cap_height :: AfmFile -> Maybe AfmUnit
+ Wumpus.Basic.FontLoader.Base: afm_char_code :: AfmGlyphMetrics -> !PSCharCode
+ Wumpus.Basic.FontLoader.Base: afm_char_name :: AfmGlyphMetrics -> !String
+ Wumpus.Basic.FontLoader.Base: afm_encoding :: AfmFile -> Maybe String
+ Wumpus.Basic.FontLoader.Base: afm_font_bbox :: AfmFile -> AfmBoundingBox
+ Wumpus.Basic.FontLoader.Base: afm_glyph_metrics :: AfmFile -> [AfmGlyphMetrics]
+ Wumpus.Basic.FontLoader.Base: afm_width_vector :: AfmGlyphMetrics -> !Vec2 AfmUnit
+ Wumpus.Basic.FontLoader.Base: buildGlyphMetricsTable :: BoundingBox AfmUnit -> Vec2 AfmUnit -> AfmUnit -> AfmFile -> GlyphMetricsTable AfmUnit
+ Wumpus.Basic.FontLoader.Base: data AfmFile
+ Wumpus.Basic.FontLoader.Base: data AfmGlyphMetrics
+ Wumpus.Basic.FontLoader.Base: data AfmUnit
+ Wumpus.Basic.FontLoader.Base: data FontLoader cu
+ Wumpus.Basic.FontLoader.Base: file_name_locator :: FontLoader cu -> FontName -> FilePath
+ Wumpus.Basic.FontLoader.Base: font_parser :: FontLoader cu -> FilePath -> IO (Either String interim)
+ Wumpus.Basic.FontLoader.Base: instance Eq AfmGlyphMetrics
+ Wumpus.Basic.FontLoader.Base: instance Eq AfmUnit
+ Wumpus.Basic.FontLoader.Base: instance Floating AfmUnit
+ Wumpus.Basic.FontLoader.Base: instance Fractional AfmUnit
+ Wumpus.Basic.FontLoader.Base: instance Num AfmUnit
+ Wumpus.Basic.FontLoader.Base: instance Ord AfmUnit
+ Wumpus.Basic.FontLoader.Base: instance Real AfmUnit
+ Wumpus.Basic.FontLoader.Base: instance RealFloat AfmUnit
+ Wumpus.Basic.FontLoader.Base: instance RealFrac AfmUnit
+ Wumpus.Basic.FontLoader.Base: instance Show AfmFile
+ Wumpus.Basic.FontLoader.Base: instance Show AfmGlyphMetrics
+ Wumpus.Basic.FontLoader.Base: instance Show AfmUnit
+ Wumpus.Basic.FontLoader.Base: loadBaseGlyphMetrics :: FontLoader u -> [FontName] -> IO BaseGlyphMetrics
+ Wumpus.Basic.FontLoader.Base: loadFont :: FontLoader cu -> FontName -> IO (FontLoadResult cu)
+ Wumpus.Basic.FontLoader.Base: path_to_font_dir :: FontLoader cu -> FilePath
+ Wumpus.Basic.FontLoader.Base: post_process :: FontLoader cu -> interim -> GlyphMetricsTable cu
+ Wumpus.Basic.FontLoader.Base: type AfmBoundingBox = BoundingBox AfmUnit
+ Wumpus.Basic.FontLoader.Base: type AfmKey = String
+ Wumpus.Basic.FontLoader.Base: type BaseGlyphMetrics = Map FontName GlyphMetrics
+ Wumpus.Basic.FontLoader.Base: type FontLoadErr = String
+ Wumpus.Basic.FontLoader.Base: type FontLoadResult cu = Either FontLoadErr (GlyphMetricsTable cu)
+ Wumpus.Basic.FontLoader.Base: type GlobalInfo = Map AfmKey String
+ Wumpus.Basic.FontLoader.Base: type PSCharCode = Int
+ Wumpus.Basic.FontLoader.Base: type PSEncodingScheme = String
+ Wumpus.Basic.FontLoader.Base: unit_scale_fun :: FontLoader cu -> cu -> PtSize
+ Wumpus.Basic.FontLoader.GSFontMap: core14_alias_table :: GSFontMap
+ Wumpus.Basic.FontLoader.GSFontMap: ghostscript_version :: String
+ Wumpus.Basic.FontLoader.GSFontMap: gsFontAlias :: GSFontMap -> String -> Maybe String
+ Wumpus.Basic.FontLoader.GSFontMap: gsMetricsFile :: GSFontMap -> String -> Maybe FilePath
+ Wumpus.Basic.FontLoader.GSFontMap: type GSFontMap = Map String (String, FilePath)
+ Wumpus.Basic.FontLoader.GSLoader: gsFontLoader :: FilePath -> FontLoader AfmUnit
+ Wumpus.Basic.FontLoader.GSLoader: loadGSMetrics :: FilePath -> [FontName] -> IO BaseGlyphMetrics
+ Wumpus.Basic.Graphic.Anchors: center :: (CenterAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: class CardinalAnchor t
+ Wumpus.Basic.Graphic.Anchors: class CardinalAnchor2 t
+ Wumpus.Basic.Graphic.Anchors: class CenterAnchor t
+ Wumpus.Basic.Graphic.Anchors: class RadialAnchor t
+ Wumpus.Basic.Graphic.Anchors: east :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: eastwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: instance Fractional u => CardinalAnchor (BoundingBox u)
+ Wumpus.Basic.Graphic.Anchors: instance Fractional u => CardinalAnchor2 (BoundingBox u)
+ Wumpus.Basic.Graphic.Anchors: instance Fractional u => CenterAnchor (BoundingBox u)
+ Wumpus.Basic.Graphic.Anchors: north :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: northeast :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: northeastwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: northwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: northwest :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: northwestwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: radialAnchor :: (RadialAnchor t, (DUnit t) ~ u) => Radian -> t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: radialConnectorPoints :: (Real u, Floating u, CenterAnchor t1, RadialAnchor t1, CenterAnchor t2, RadialAnchor t2, u ~ (DUnit t1), (DUnit t1) ~ (DUnit t2)) => t1 -> t2 -> (Point2 u, Point2 u)
+ Wumpus.Basic.Graphic.Anchors: south :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: southeast :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: southeastwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: southwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: southwest :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: southwestwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: west :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Graphic.Anchors: westwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Graphic.Base: HBottom :: HAlign
+ Wumpus.Basic.Graphic.Base: HCenter :: HAlign
+ Wumpus.Basic.Graphic.Base: HTop :: HAlign
+ Wumpus.Basic.Graphic.Base: VCenter :: VAlign
+ Wumpus.Basic.Graphic.Base: VLeft :: VAlign
+ Wumpus.Basic.Graphic.Base: VRight :: VAlign
+ Wumpus.Basic.Graphic.Base: data HAlign
+ Wumpus.Basic.Graphic.Base: data VAlign
+ Wumpus.Basic.Graphic.Base: instance Enum HAlign
+ Wumpus.Basic.Graphic.Base: instance Enum VAlign
+ Wumpus.Basic.Graphic.Base: instance Eq HAlign
+ Wumpus.Basic.Graphic.Base: instance Eq VAlign
+ Wumpus.Basic.Graphic.Base: instance Ord HAlign
+ Wumpus.Basic.Graphic.Base: instance Ord VAlign
+ Wumpus.Basic.Graphic.Base: instance Ord u => OPlus (BoundingBox u)
+ Wumpus.Basic.Graphic.Base: instance Show HAlign
+ Wumpus.Basic.Graphic.Base: instance Show VAlign
+ Wumpus.Basic.Graphic.Base: primGraphic :: Primitive u -> PrimGraphic u
+ Wumpus.Basic.Graphic.ContextFunction: accumulate1 :: (ans -> ans -> ans) -> CF (s1 -> (s1, ans)) -> CF (s1 -> (s1, ans)) -> CF (s1 -> (s1, ans))
+ Wumpus.Basic.Graphic.ContextFunction: accumulate2 :: (ans -> ans -> ans) -> CF (s1 -> s2 -> (s1, s2, ans)) -> CF (s1 -> s2 -> (s1, s2, ans)) -> CF (s1 -> s2 -> (s1, s2, ans))
+ Wumpus.Basic.Graphic.ContextFunction: apply :: CF (a -> ans) -> CF a -> CF ans
+ Wumpus.Basic.Graphic.ContextFunction: apply1 :: CF (r1 -> a -> ans) -> CF (r1 -> a) -> CF (r1 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: apply2 :: CF (r1 -> r2 -> a -> ans) -> CF (r1 -> r2 -> a) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: bind :: CF a -> (a -> CF ans) -> CF ans
+ Wumpus.Basic.Graphic.ContextFunction: bind1 :: CF (r1 -> a) -> (a -> CF (r1 -> ans)) -> CF (r1 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: bind2 :: CF (r1 -> r2 -> a) -> (a -> CF (r1 -> r2 -> ans)) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: connCtx :: ConnectorCF u DrawingContext
+ Wumpus.Basic.Graphic.ContextFunction: connEnd :: ConnectorCF u (Point2 u)
+ Wumpus.Basic.Graphic.ContextFunction: connStart :: ConnectorCF u (Point2 u)
+ Wumpus.Basic.Graphic.ContextFunction: data CF a
+ Wumpus.Basic.Graphic.ContextFunction: dblstatic :: CF ans -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: drawingCtx :: CF DrawingContext
+ Wumpus.Basic.Graphic.ContextFunction: instance Applicative CF
+ Wumpus.Basic.Graphic.ContextFunction: instance DrawingCtxM CF
+ Wumpus.Basic.Graphic.ContextFunction: instance Functor CF
+ Wumpus.Basic.Graphic.ContextFunction: instance Monad CF
+ Wumpus.Basic.Graphic.ContextFunction: instance Monoid a => Monoid (CF a)
+ Wumpus.Basic.Graphic.ContextFunction: instance OPlus a => OPlus (CF a)
+ Wumpus.Basic.Graphic.ContextFunction: locCtx :: LocCF u DrawingContext
+ Wumpus.Basic.Graphic.ContextFunction: locPoint :: LocCF u (Point2 u)
+ Wumpus.Basic.Graphic.ContextFunction: locThetaAng :: LocThetaCF u Radian
+ Wumpus.Basic.Graphic.ContextFunction: locThetaCtx :: LocThetaCF u DrawingContext
+ Wumpus.Basic.Graphic.ContextFunction: locThetaPoint :: LocThetaCF u (Point2 u)
+ Wumpus.Basic.Graphic.ContextFunction: postcomb :: (a -> b -> ans) -> CF a -> CF b -> CF ans
+ Wumpus.Basic.Graphic.ContextFunction: postcomb1 :: (a -> b -> c) -> CF (r1 -> a) -> CF (r1 -> b) -> CF (r1 -> c)
+ Wumpus.Basic.Graphic.ContextFunction: postcomb2 :: (a -> b -> ans) -> CF (r1 -> r2 -> a) -> CF (r1 -> r2 -> b) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: postpro :: (a -> ans) -> CF a -> CF ans
+ Wumpus.Basic.Graphic.ContextFunction: postpro1 :: (a -> ans) -> CF (r1 -> a) -> CF (r1 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: postpro2 :: (a -> ans) -> CF (r1 -> r2 -> a) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: prepro1 :: (r1 -> a) -> CF (a -> ans) -> CF (r1 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: prepro2 :: (r1 -> a) -> (r2 -> b) -> CF (a -> b -> ans) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: prepro2a :: (r1 -> a) -> CF (a -> r2 -> ans) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: prepro2b :: (r2 -> a) -> CF (r1 -> a -> ans) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: promote1 :: (r1 -> CF ans) -> CF (r1 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: promote2 :: (r1 -> r2 -> CF ans) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: queryCtx :: (DrawingContext -> a) -> CF a
+ Wumpus.Basic.Graphic.ContextFunction: raise :: a -> CF a
+ Wumpus.Basic.Graphic.ContextFunction: raise1 :: (r1 -> ans) -> CF (r1 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: raise2 :: (r1 -> r2 -> ans) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: runCF :: DrawingContext -> CF a -> a
+ Wumpus.Basic.Graphic.ContextFunction: situ1 :: CF (r1 -> ans) -> r1 -> CF ans
+ Wumpus.Basic.Graphic.ContextFunction: situ2 :: CF (r1 -> r2 -> ans) -> r1 -> r2 -> CF ans
+ Wumpus.Basic.Graphic.ContextFunction: static1 :: CF ans -> CF (r1 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: static2 :: CF (r1 -> ans) -> CF (r1 -> r2 -> ans)
+ Wumpus.Basic.Graphic.ContextFunction: type ConnectorCF u a = LocCF u (Point2 u -> a)
+ Wumpus.Basic.Graphic.ContextFunction: type DConnectorCF a = ConnectorCF Double a
+ Wumpus.Basic.Graphic.ContextFunction: type DLocCF a = LocCF Double a
+ Wumpus.Basic.Graphic.ContextFunction: type DLocThetaCF a = LocThetaCF Double a
+ Wumpus.Basic.Graphic.ContextFunction: type LocCF u a = CF (Point2 u -> a)
+ Wumpus.Basic.Graphic.ContextFunction: type LocThetaCF u a = LocCF u (Radian -> a)
+ Wumpus.Basic.Graphic.ContextFunction: unCF1 :: r1 -> CF (r1 -> a) -> CF a
+ Wumpus.Basic.Graphic.ContextFunction: unCF2 :: r1 -> r2 -> CF (r1 -> r2 -> a) -> CF a
+ Wumpus.Basic.Graphic.ContextFunction: unConnector :: Point2 u -> Point2 u -> ConnectorCF u a -> CF a
+ Wumpus.Basic.Graphic.ContextFunction: unLoc :: Point2 u -> LocCF u a -> CF a
+ Wumpus.Basic.Graphic.ContextFunction: unLocTheta :: Point2 u -> Radian -> LocThetaCF u a -> CF a
+ Wumpus.Basic.Graphic.ContextFunction: unTheta :: Radian -> LocThetaCF u a -> LocCF u a
+ Wumpus.Basic.Graphic.ContextFunction: wrap :: a -> CF a
+ Wumpus.Basic.Graphic.ContextFunction: wrap1 :: a -> CF (r1 -> a)
+ Wumpus.Basic.Graphic.ContextFunction: wrap2 :: a -> CF (r1 -> r2 -> a)
+ Wumpus.Basic.Graphic.Drawing: clipDrawing :: (Num u, Ord u) => (PrimPath u) -> Drawing u -> Drawing u
+ Wumpus.Basic.Graphic.Drawing: drawTracing :: (Real u, Floating u, FromPtSize u) => TraceDrawing u a -> Drawing u
+ Wumpus.Basic.Graphic.Drawing: drawingConcat :: (Picture u -> Picture u -> Picture u) -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Graphic.Drawing: instance (Num u, Ord u) => Scale (Drawing u)
+ Wumpus.Basic.Graphic.Drawing: instance (Num u, Ord u) => Translate (Drawing u)
+ Wumpus.Basic.Graphic.Drawing: instance (Real u, Floating u) => Rotate (Drawing u)
+ Wumpus.Basic.Graphic.Drawing: instance (Real u, Floating u) => RotateAbout (Drawing u)
+ Wumpus.Basic.Graphic.Drawing: modifyDrawing :: (Picture u -> Picture u) -> Drawing u -> Drawing u
+ Wumpus.Basic.Graphic.Drawing: runDrawingU :: DrawingContext -> Drawing u -> Picture u
+ Wumpus.Basic.Graphic.Drawing: type DDrawing = Drawing Double
+ Wumpus.Basic.Graphic.DrawingContext: fallback_metrics :: DrawingContext -> GlyphMetrics
+ Wumpus.Basic.Graphic.DrawingContext: glyph_tables :: DrawingContext -> BaseGlyphMetrics
+ Wumpus.Basic.Graphic.DrawingContext: metricsContext :: FontSize -> BaseGlyphMetrics -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: withFontMetrics :: (GlyphMetrics -> PtSize -> u) -> DrawingContext -> u
+ Wumpus.Basic.Graphic.GlyphMetrics: GlyphMetrics :: (forall u. FromPtSize u => PtSize -> BoundingBox u) -> (forall u. FromPtSize u => PtSize -> (CodePoint -> Vec2 u)) -> (forall u. FromPtSize u => PtSize -> u) -> GlyphMetrics
+ Wumpus.Basic.Graphic.GlyphMetrics: GlyphMetricsTable :: BoundingBox cu -> Vec2 cu -> IntMap (Vec2 cu) -> cu -> GlyphMetricsTable cu
+ Wumpus.Basic.Graphic.GlyphMetrics: buildMetrics :: (cu -> PtSize) -> GlyphMetricsTable cu -> GlyphMetrics
+ Wumpus.Basic.Graphic.GlyphMetrics: data GlyphMetrics
+ Wumpus.Basic.Graphic.GlyphMetrics: data GlyphMetricsTable cu
+ Wumpus.Basic.Graphic.GlyphMetrics: get_av_lookup :: GlyphMetrics -> forall u. FromPtSize u => PtSize -> (CodePoint -> Vec2 u)
+ Wumpus.Basic.Graphic.GlyphMetrics: get_bounding_box :: GlyphMetrics -> forall u. FromPtSize u => PtSize -> BoundingBox u
+ Wumpus.Basic.Graphic.GlyphMetrics: get_cap_height :: GlyphMetrics -> forall u. FromPtSize u => PtSize -> u
+ Wumpus.Basic.Graphic.GlyphMetrics: glyph_adv_vecs :: GlyphMetricsTable cu -> IntMap (Vec2 cu)
+ Wumpus.Basic.Graphic.GlyphMetrics: glyph_bounding_box :: GlyphMetricsTable cu -> BoundingBox cu
+ Wumpus.Basic.Graphic.GlyphMetrics: glyph_cap_height :: GlyphMetricsTable cu -> cu
+ Wumpus.Basic.Graphic.GlyphMetrics: glyph_default_adv_vec :: GlyphMetricsTable cu -> Vec2 cu
+ Wumpus.Basic.Graphic.GlyphMetrics: monospace_metrics :: GlyphMetrics
+ Wumpus.Basic.Graphic.GlyphMetrics: type BaseGlyphMetrics = Map FontName GlyphMetrics
+ Wumpus.Basic.Graphic.GlyphMetrics: type CodePoint = Int
+ Wumpus.Basic.Graphic.GlyphMetrics: type FontName = String
+ Wumpus.Basic.Graphic.GraphicOperations: borderedCircle :: Floating u => Int -> u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: borderedDisk :: Num u => u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: borderedEllipse :: Num u => u -> u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: borderedPath :: Num u => PrimPath u -> Graphic u
+ Wumpus.Basic.Graphic.GraphicOperations: borderedRectangle :: Fractional u => u -> u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: centermonoTextline :: (Fractional u, Ord u, FromPtSize u) => String -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: closedStroke :: Num u => PrimPath u -> Graphic u
+ Wumpus.Basic.Graphic.GraphicOperations: curveBetween :: Fractional u => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Graphic u
+ Wumpus.Basic.Graphic.GraphicOperations: displace :: Num u => u -> u -> PointDisplace u
+ Wumpus.Basic.Graphic.GraphicOperations: displaceParallel :: Floating u => u -> Radian -> PointDisplace u
+ Wumpus.Basic.Graphic.GraphicOperations: displacePerpendicular :: Floating u => u -> Radian -> PointDisplace u
+ Wumpus.Basic.Graphic.GraphicOperations: drawGraphic :: (Real u, Floating u, FromPtSize u) => DrawingContext -> Graphic u -> Picture u
+ Wumpus.Basic.Graphic.GraphicOperations: escapedline :: Num u => EscapedText -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: filledCircle :: Floating u => Int -> u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: filledDisk :: Num u => u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: filledEllipse :: Num u => u -> u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: filledPath :: Num u => PrimPath u -> Graphic u
+ Wumpus.Basic.Graphic.GraphicOperations: filledRectangle :: Fractional u => u -> u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: hdisplace :: Num u => u -> PointDisplace u
+ Wumpus.Basic.Graphic.GraphicOperations: hkernline :: Num u => [KerningChar u] -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: illustrateBoundedGraphic :: Fractional u => BoundedGraphic u -> BoundedGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: illustrateBoundedLocGraphic :: Fractional u => BoundedLocGraphic u -> BoundedLocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: localPoint :: (Point2 u -> Point2 u) -> LocGraphic u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: openStroke :: Num u => PrimPath u -> Graphic u
+ Wumpus.Basic.Graphic.GraphicOperations: parallelvec :: Floating u => u -> Radian -> Vec2 u
+ Wumpus.Basic.Graphic.GraphicOperations: perpendicularvec :: Floating u => u -> Radian -> Vec2 u
+ Wumpus.Basic.Graphic.GraphicOperations: rescapedline :: Num u => EscapedText -> LocThetaGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: rtextline :: Num u => String -> LocThetaGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: straightLine :: Fractional u => Vec2 u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: straightLineBetween :: Fractional u => Point2 u -> Point2 u -> Graphic u
+ Wumpus.Basic.Graphic.GraphicOperations: strokedCircle :: Floating u => Int -> u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: strokedDisk :: Num u => u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: strokedEllipse :: Num u => u -> u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: strokedRectangle :: Fractional u => u -> u -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: supplyPt :: Point2 u -> LocGraphic u -> Graphic u
+ Wumpus.Basic.Graphic.GraphicOperations: textline :: Num u => String -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: textlineMulti :: Fractional u => [String] -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicOperations: vdisplace :: Num u => u -> PointDisplace u
+ Wumpus.Basic.Graphic.GraphicOperations: vecdisplace :: Num u => Vec2 u -> PointDisplace u
+ Wumpus.Basic.Graphic.GraphicOperations: vkernline :: Num u => [KerningChar u] -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicTypes: advanceH :: Num u => AdvanceVec u -> u
+ Wumpus.Basic.Graphic.GraphicTypes: advanceV :: Num u => AdvanceVec u -> u
+ Wumpus.Basic.Graphic.GraphicTypes: at :: CF (Point2 u -> b) -> Point2 u -> CF b
+ Wumpus.Basic.Graphic.GraphicTypes: extrGraphic :: Image u a -> Graphic u
+ Wumpus.Basic.Graphic.GraphicTypes: extrLocGraphic :: LocImage u a -> LocGraphic u
+ Wumpus.Basic.Graphic.GraphicTypes: fontDeltaGraphic :: Graphic u -> Graphic u
+ Wumpus.Basic.Graphic.GraphicTypes: fontDeltaImage :: Image u a -> Image u a
+ Wumpus.Basic.Graphic.GraphicTypes: instance (DUnit a ~ u, Num u, Scale a) => Scale (Image u a)
+ Wumpus.Basic.Graphic.GraphicTypes: instance (DUnit a ~ u, Num u, Translate a) => Translate (Image u a)
+ Wumpus.Basic.Graphic.GraphicTypes: instance (DUnit a ~ u, Real u, Floating u, Rotate a) => Rotate (Image u a)
+ Wumpus.Basic.Graphic.GraphicTypes: instance (DUnit a ~ u, Real u, Floating u, RotateAbout a) => RotateAbout (Image u a)
+ Wumpus.Basic.Graphic.GraphicTypes: instance (Real u, Floating u) => Rotate (Graphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: instance (Real u, Floating u) => RotateAbout (Graphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: instance Num u => Scale (Graphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: instance Num u => Translate (Graphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: intoConnectorImage :: ConnectorCF u a -> ConnectorGraphic u -> ConnectorImage u a
+ Wumpus.Basic.Graphic.GraphicTypes: intoImage :: CF a -> Graphic u -> Image u a
+ Wumpus.Basic.Graphic.GraphicTypes: intoLocImage :: LocCF u a -> LocGraphic u -> LocImage u a
+ Wumpus.Basic.Graphic.GraphicTypes: intoLocThetaImage :: LocThetaCF u a -> LocThetaGraphic u -> LocThetaImage u a
+ Wumpus.Basic.Graphic.GraphicTypes: makeAdvGraphic :: PointDisplace u -> LocGraphic u -> AdvGraphic u
+ Wumpus.Basic.Graphic.GraphicTypes: moveLoc :: (Point2 u -> Point2 u) -> LocCF u a -> LocCF u a
+ Wumpus.Basic.Graphic.GraphicTypes: runGraphic :: DrawingContext -> Graphic u -> PrimGraphic u
+ Wumpus.Basic.Graphic.GraphicTypes: runImage :: DrawingContext -> Image u a -> (a, PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: runLocGraphic :: DrawingContext -> Point2 u -> LocGraphic u -> PrimGraphic u
+ Wumpus.Basic.Graphic.GraphicTypes: runLocImage :: DrawingContext -> Point2 u -> LocImage u a -> (a, PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: type AdvGraphic u = LocImage u (Point2 u)
+ Wumpus.Basic.Graphic.GraphicTypes: type AdvanceVec u = Vec2 u
+ Wumpus.Basic.Graphic.GraphicTypes: type BoundedGraphic u = Image u (BoundingBox u)
+ Wumpus.Basic.Graphic.GraphicTypes: type BoundedLocGraphic u = LocImage u (BoundingBox u)
+ Wumpus.Basic.Graphic.GraphicTypes: type ConnectorGraphic u = ConnectorCF u (PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: type ConnectorImage u a = ConnectorCF u (a, PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: type DAdvGraphic = AdvGraphic Double
+ Wumpus.Basic.Graphic.GraphicTypes: type DBoundedGraphic = BoundedGraphic Double
+ Wumpus.Basic.Graphic.GraphicTypes: type DBoundedLocGraphic = BoundedLocGraphic Double
+ Wumpus.Basic.Graphic.GraphicTypes: type DConnectorGraphic = ConnectorGraphic Double
+ Wumpus.Basic.Graphic.GraphicTypes: type DConnectorImage a = ConnectorImage Double a
+ Wumpus.Basic.Graphic.GraphicTypes: type DGraphic = Graphic Double
+ Wumpus.Basic.Graphic.GraphicTypes: type DImage a = Image Double a
+ Wumpus.Basic.Graphic.GraphicTypes: type DLocGraphic = LocGraphic Double
+ Wumpus.Basic.Graphic.GraphicTypes: type DLocImage a = LocImage Double a
+ Wumpus.Basic.Graphic.GraphicTypes: type DLocThetaGraphic = LocThetaGraphic Double
+ Wumpus.Basic.Graphic.GraphicTypes: type DLocThetaImage a = LocThetaImage Double a
+ Wumpus.Basic.Graphic.GraphicTypes: type DrawingInfo a = CF a
+ Wumpus.Basic.Graphic.GraphicTypes: type Graphic u = CF (PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: type Image u a = CF (a, PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: type LocDrawingInfo u a = LocCF u a
+ Wumpus.Basic.Graphic.GraphicTypes: type LocGraphic u = LocCF u (PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: type LocImage u a = LocCF u (a, PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: type LocThetaDrawingInfo u a = LocThetaCF u a
+ Wumpus.Basic.Graphic.GraphicTypes: type LocThetaGraphic u = LocThetaCF u (PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: type LocThetaImage u a = LocThetaCF u (a, PrimGraphic u)
+ Wumpus.Basic.Graphic.GraphicTypes: type PointDisplace u = Point2 u -> Point2 u
+ Wumpus.Basic.Graphic.GraphicTypes: xlinkGraphic :: XLink -> Graphic u -> Graphic u
+ Wumpus.Basic.Graphic.GraphicTypes: xlinkImage :: XLink -> Image u a -> Image u a
+ Wumpus.Basic.Graphic.Query: avLookupTable :: (FromPtSize u, DrawingCtxM m) => m (Int -> Vec2 u)
+ Wumpus.Basic.Graphic.Query: fontAttr :: DrawingCtxM m => m FontAttr
+ Wumpus.Basic.Graphic.Query: fontFace :: DrawingCtxM m => m FontFace
+ Wumpus.Basic.Graphic.Query: glyphBoundingBox :: (FromPtSize u, DrawingCtxM m) => m (BoundingBox u)
+ Wumpus.Basic.Graphic.Query: glyphCapHeight :: (FromPtSize u, DrawingCtxM m) => m u
+ Wumpus.Basic.Graphic.Query: glyphHeight :: (FromPtSize u, DrawingCtxM m) => m u
+ Wumpus.Basic.Graphic.Query: glyphHeightRange :: (FromPtSize u, DrawingCtxM m) => m (u, u)
+ Wumpus.Basic.Graphic.Query: monoAscenderHeight :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoCapHeight :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoFontPointSize :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoMultiLineHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => Int -> m u
+ Wumpus.Basic.Graphic.TraceDrawing: data TraceDrawing u a
+ Wumpus.Basic.Graphic.TraceDrawing: data TraceDrawingT u m a
+ Wumpus.Basic.Graphic.TraceDrawing: draw :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => Graphic u -> m ()
+ Wumpus.Basic.Graphic.TraceDrawing: drawi :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => Image u a -> m a
+ Wumpus.Basic.Graphic.TraceDrawing: drawi_ :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => Image u a -> m ()
+ Wumpus.Basic.Graphic.TraceDrawing: evalTraceDrawing :: DrawingContext -> TraceDrawing u a -> a
+ Wumpus.Basic.Graphic.TraceDrawing: evalTraceDrawingT :: Monad m => DrawingContext -> TraceDrawingT u m a -> m a
+ Wumpus.Basic.Graphic.TraceDrawing: execTraceDrawing :: DrawingContext -> TraceDrawing u a -> HPrim u
+ Wumpus.Basic.Graphic.TraceDrawing: execTraceDrawingT :: Monad m => DrawingContext -> TraceDrawingT u m a -> m (HPrim u)
+ Wumpus.Basic.Graphic.TraceDrawing: instance Applicative (TraceDrawing u)
+ Wumpus.Basic.Graphic.TraceDrawing: instance DrawingCtxM (TraceDrawing u)
+ Wumpus.Basic.Graphic.TraceDrawing: instance Functor (TraceDrawing u)
+ Wumpus.Basic.Graphic.TraceDrawing: instance Monad (TraceDrawing u)
+ Wumpus.Basic.Graphic.TraceDrawing: instance Monad m => Applicative (TraceDrawingT u m)
+ Wumpus.Basic.Graphic.TraceDrawing: instance Monad m => DrawingCtxM (TraceDrawingT u m)
+ Wumpus.Basic.Graphic.TraceDrawing: instance Monad m => Functor (TraceDrawingT u m)
+ Wumpus.Basic.Graphic.TraceDrawing: instance Monad m => Monad (TraceDrawingT u m)
+ Wumpus.Basic.Graphic.TraceDrawing: instance Monad m => TraceM (TraceDrawingT u m)
+ Wumpus.Basic.Graphic.TraceDrawing: instance TraceM (TraceDrawing u)
+ Wumpus.Basic.Graphic.TraceDrawing: liftToPictureMb :: (Real u, Floating u, FromPtSize u) => HPrim u -> Maybe (Picture u)
+ Wumpus.Basic.Graphic.TraceDrawing: liftToPictureU :: (Real u, Floating u, FromPtSize u) => HPrim u -> Picture u
+ Wumpus.Basic.Graphic.TraceDrawing: mbPictureU :: (Real u, Floating u, FromPtSize u) => Maybe (Picture u) -> Picture u
+ Wumpus.Basic.Graphic.TraceDrawing: node :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ (MonUnit m)) => LocGraphic u -> m ()
+ Wumpus.Basic.Graphic.TraceDrawing: nodei :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ (MonUnit m)) => LocImage u a -> m a
+ Wumpus.Basic.Graphic.TraceDrawing: query :: DrawingCtxM m => CF a -> m a
+ Wumpus.Basic.Graphic.TraceDrawing: runTraceDrawing :: DrawingContext -> TraceDrawing u a -> (a, HPrim u)
+ Wumpus.Basic.Graphic.TraceDrawing: runTraceDrawingT :: Monad m => DrawingContext -> TraceDrawingT u m a -> m (a, HPrim u)
+ Wumpus.Basic.Graphic.TraceDrawing: xdraw :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => XLink -> Graphic u -> m ()
+ Wumpus.Basic.Graphic.TraceDrawing: xdrawi :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => XLink -> Image u a -> m a
+ Wumpus.Basic.Graphic.TraceDrawing: xdrawi_ :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => XLink -> Image u a -> m ()
+ Wumpus.Basic.Shapes.Base: shapeAngle :: ShapeGeom u Radian
+ Wumpus.Basic.Shapes.Coordinate: coordinateDot :: (Real u, Floating u, FromPtSize u) => Coordinate u -> Image u (CoordinateAnchor u)
+ Wumpus.Basic.Shapes.Coordinate: coordinateX :: (Real u, Floating u, FromPtSize u) => Coordinate u -> Image u (CoordinateAnchor u)
+ Wumpus.Basic.Shapes.Coordinate: instance (Real u, Floating u) => Rotate (Coordinate u)
+ Wumpus.Basic.Shapes.Coordinate: instance (Real u, Floating u) => RotateAbout (Coordinate u)
+ Wumpus.Basic.Shapes.Coordinate: instance Num u => Scale (Coordinate u)
+ Wumpus.Basic.Text.LRText: instance Eq u => Eq (InterimText1 u)
+ Wumpus.Basic.Text.LRText: instance Show u => Show (InterimText1 u)
+ Wumpus.Basic.Text.LRText: multiAlignCenter :: (Fractional u, Ord u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Basic.Text.LRText: multiAlignLeft :: (Fractional u, Ord u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Basic.Text.LRText: multiAlignRight :: (Fractional u, Ord u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Basic.Text.LRText: singleLineBL :: (Ord u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Basic.Text.LRText: singleLineCC :: (Fractional u, Ord u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Basic.Utils.FormatCombinators: (<+>) :: Doc -> Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: (<>) :: Doc -> Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: angles :: Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: braces :: Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: brackets :: Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: char :: Char -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: class Format a
+ Wumpus.Basic.Utils.FormatCombinators: comma :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: data Doc
+ Wumpus.Basic.Utils.FormatCombinators: double :: Double -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: dquotes :: Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: empty :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: enclose :: Doc -> Doc -> Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: fill :: Int -> Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: fillStringL :: Int -> String -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: fillStringR :: Int -> String -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: float :: Double -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: format :: Format a => a -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: hcat :: [Doc] -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: hex4 :: Int -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: hsep :: [Doc] -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: indent :: Int -> Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: instance Monoid Doc
+ Wumpus.Basic.Utils.FormatCombinators: instance Show Doc
+ Wumpus.Basic.Utils.FormatCombinators: int :: Int -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: integer :: Integer -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: integral :: Integral a => a -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: langle :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: lbrace :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: lbracket :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: line :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: list :: [Doc] -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: lparen :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: parens :: Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: punctuate :: Doc -> [Doc] -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: rangle :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: rbrace :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: rbracket :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: rparen :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: semiBraces :: [Doc] -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: semicolon :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: separate :: Doc -> [Doc] -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: showsDoc :: ShowS -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: space :: Doc
+ Wumpus.Basic.Utils.FormatCombinators: squotes :: Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: text :: String -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: tupled :: [Doc] -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: type DocS = Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: vcat :: [Doc] -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: vconcat :: Doc -> Doc -> Doc
+ Wumpus.Basic.Utils.FormatCombinators: writeDoc :: FilePath -> Doc -> IO ()
+ Wumpus.Basic.Utils.ParserCombinators: (<?>) :: Parser s a -> String -> Parser s a
+ Wumpus.Basic.Utils.ParserCombinators: Fail :: String -> [s] -> Result s ans
+ Wumpus.Basic.Utils.ParserCombinators: Okay :: ans -> [s] -> Result s ans
+ Wumpus.Basic.Utils.ParserCombinators: alphaNum :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: anyChar :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: apply :: Functor f => f a -> (a -> b) -> f b
+ Wumpus.Basic.Utils.ParserCombinators: between :: Applicative f => f open -> f close -> f a -> f a
+ Wumpus.Basic.Utils.ParserCombinators: chainl :: MonadPlus m => m a -> m (a -> a -> a) -> a -> m a
+ Wumpus.Basic.Utils.ParserCombinators: chainl1 :: MonadPlus m => m a -> m (a -> a -> a) -> m a
+ Wumpus.Basic.Utils.ParserCombinators: chainr :: MonadPlus m => m a -> m (a -> a -> a) -> a -> m a
+ Wumpus.Basic.Utils.ParserCombinators: chainr1 :: MonadPlus m => m a -> m (a -> a -> a) -> m a
+ Wumpus.Basic.Utils.ParserCombinators: char :: Char -> CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: choice :: Alternative f => [f a] -> f a
+ Wumpus.Basic.Utils.ParserCombinators: count :: Applicative f => Int -> f a -> f [a]
+ Wumpus.Basic.Utils.ParserCombinators: data Parser s r
+ Wumpus.Basic.Utils.ParserCombinators: data Result s ans
+ Wumpus.Basic.Utils.ParserCombinators: digit :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: eof :: Parser s ()
+ Wumpus.Basic.Utils.ParserCombinators: equals :: Eq s => s -> Parser s s
+ Wumpus.Basic.Utils.ParserCombinators: failure :: Parser s a
+ Wumpus.Basic.Utils.ParserCombinators: hexDigit :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: instance (Eq s, Eq ans) => Eq (Result s ans)
+ Wumpus.Basic.Utils.ParserCombinators: instance (Ord s, Ord ans) => Ord (Result s ans)
+ Wumpus.Basic.Utils.ParserCombinators: instance (Show s, Show ans) => Show (Result s ans)
+ Wumpus.Basic.Utils.ParserCombinators: instance Alternative (Parser s)
+ Wumpus.Basic.Utils.ParserCombinators: instance Applicative (Parser s)
+ Wumpus.Basic.Utils.ParserCombinators: instance Functor (Parser s)
+ Wumpus.Basic.Utils.ParserCombinators: instance Monad (Parser s)
+ Wumpus.Basic.Utils.ParserCombinators: instance MonadPlus (Parser s)
+ Wumpus.Basic.Utils.ParserCombinators: letter :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: lookahead :: Parser s a -> (a -> Parser s b) -> Parser s b
+ Wumpus.Basic.Utils.ParserCombinators: lower :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: many1 :: Alternative f => f a -> f [a]
+ Wumpus.Basic.Utils.ParserCombinators: manyTill :: Alternative f => f a -> f b -> f [a]
+ Wumpus.Basic.Utils.ParserCombinators: manyTill1 :: Alternative f => f a -> f b -> f [a]
+ Wumpus.Basic.Utils.ParserCombinators: newline :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: noneOf :: Eq s => [s] -> Parser s s
+ Wumpus.Basic.Utils.ParserCombinators: octDigit :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: oneOf :: Eq s => [s] -> Parser s s
+ Wumpus.Basic.Utils.ParserCombinators: option :: Alternative f => a -> f a -> f a
+ Wumpus.Basic.Utils.ParserCombinators: optionMaybe :: Alternative f => f a -> f (Maybe a)
+ Wumpus.Basic.Utils.ParserCombinators: optionUnit :: Alternative f => f a -> f ()
+ Wumpus.Basic.Utils.ParserCombinators: peek :: Parser s a -> Parser s a
+ Wumpus.Basic.Utils.ParserCombinators: runParser :: Parser s a -> [s] -> Result s a
+ Wumpus.Basic.Utils.ParserCombinators: runParserEither :: Show s => Parser s a -> [s] -> Either ParseError a
+ Wumpus.Basic.Utils.ParserCombinators: satisfy :: (s -> Bool) -> Parser s s
+ Wumpus.Basic.Utils.ParserCombinators: sepBy :: Alternative f => f a -> f b -> f [a]
+ Wumpus.Basic.Utils.ParserCombinators: sepBy1 :: Alternative f => f a -> f b -> f [a]
+ Wumpus.Basic.Utils.ParserCombinators: sepEndBy :: Alternative f => f a -> f b -> f [a]
+ Wumpus.Basic.Utils.ParserCombinators: sepEndBy1 :: Alternative f => f a -> f b -> f [a]
+ Wumpus.Basic.Utils.ParserCombinators: skipMany :: Alternative f => f a -> f ()
+ Wumpus.Basic.Utils.ParserCombinators: skipMany1 :: Alternative f => f a -> f ()
+ Wumpus.Basic.Utils.ParserCombinators: skipOne :: Applicative f => f a -> f ()
+ Wumpus.Basic.Utils.ParserCombinators: space :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: string :: String -> CharParser String
+ Wumpus.Basic.Utils.ParserCombinators: tab :: CharParser Char
+ Wumpus.Basic.Utils.ParserCombinators: throwError :: String -> Parser s a
+ Wumpus.Basic.Utils.ParserCombinators: type CharParser a = Parser Char a
+ Wumpus.Basic.Utils.ParserCombinators: type CharResult a = Result Char a
+ Wumpus.Basic.Utils.ParserCombinators: type ParseError = String
+ Wumpus.Basic.Utils.ParserCombinators: upper :: CharParser Char
+ Wumpus.Basic.Utils.TokenParsers: commentLexemeParser :: String -> (String, String) -> [Char] -> LexemeParser
+ Wumpus.Basic.Utils.TokenParsers: commentLineLexemeParser :: String -> [Char] -> LexemeParser
+ Wumpus.Basic.Utils.TokenParsers: commentMultiLexemeParser :: String -> String -> [Char] -> LexemeParser
+ Wumpus.Basic.Utils.TokenParsers: data LexemeParser
+ Wumpus.Basic.Utils.TokenParsers: double :: CharParser Double
+ Wumpus.Basic.Utils.TokenParsers: hexBase :: CharParser Int
+ Wumpus.Basic.Utils.TokenParsers: integer :: CharParser Integer
+ Wumpus.Basic.Utils.TokenParsers: lexeme :: LexemeParser -> CharParser a -> CharParser a
+ Wumpus.Basic.Utils.TokenParsers: natural :: CharParser Integer
+ Wumpus.Basic.Utils.TokenParsers: octBase :: CharParser Int
+ Wumpus.Basic.Utils.TokenParsers: octHask :: CharParser Int
+ Wumpus.Basic.Utils.TokenParsers: spaceCharLexemeParser :: [Char] -> LexemeParser
+ Wumpus.Basic.Utils.TokenParsers: spaceLexemeParser :: LexemeParser
+ Wumpus.Basic.Utils.TokenParsers: whiteSpace :: LexemeParser -> CharParser ()
- Wumpus.Basic.Arrows.Tips: Arrowhead :: ThetaLocImage u u -> Arrowhead u
+ Wumpus.Basic.Arrows.Tips: Arrowhead :: LocThetaImage u u -> Arrowhead u
- Wumpus.Basic.Arrows.Tips: getArrowhead :: Arrowhead u -> ThetaLocImage u u
+ Wumpus.Basic.Arrows.Tips: getArrowhead :: Arrowhead u -> LocThetaImage u u
- Wumpus.Basic.Graphic.Drawing: data Drawing u a
+ Wumpus.Basic.Graphic.Drawing: data Drawing u
- Wumpus.Basic.Graphic.Drawing: runDrawing :: DrawingContext -> Drawing u a -> (a, HPrim u)
+ Wumpus.Basic.Graphic.Drawing: runDrawing :: DrawingContext -> Drawing u -> Maybe (Picture u)
- Wumpus.Basic.Graphic.DrawingContext: DrawingContext :: StrokeAttr -> FontAttr -> RGBi -> RGBi -> Double -> DrawingContext
+ Wumpus.Basic.Graphic.DrawingContext: DrawingContext :: BaseGlyphMetrics -> GlyphMetrics -> StrokeAttr -> FontAttr -> RGBi -> RGBi -> Double -> DrawingContext
- Wumpus.Basic.Paths.Base: toPrimPath :: Path u -> PrimPath u
+ Wumpus.Basic.Paths.Base: toPrimPath :: Num u => Path u -> PrimPath u
- Wumpus.Basic.Shapes.Base: shapeCenter :: (Real u, Floating u) => ShapeGeom u (Point2 u)
+ Wumpus.Basic.Shapes.Base: shapeCenter :: ShapeGeom u (Point2 u)
- Wumpus.Basic.Shapes.Coordinate: coordinate :: Num u => Point2 u -> Coordinate u
+ Wumpus.Basic.Shapes.Coordinate: coordinate :: Num u => LocCoordinate u

Files

CHANGES view
@@ -1,5 +1,27 @@  +0.11.0 to 0.12.0:++  * Changes Base types in  @Basic.Graphic@. The @Graphic@ and +    @Image@ types now produce (wrapped) @Primitives@, rather than +    Hughes lists of @Primitives@. This means they can now be +    transformed with the affine transformations. Removed the +    function @ati@, it is replaced by @at@.++  * Added @Basic.Utils.Combinators@.++  * Arrowheads and Connectors reworked - Arrowheads are now a +    functional type, Connectors use new Image combining +    operations from @Basic.Graphic.Base@.++  * Path connectors re-worked and renamed. ++  * Dot hierarchy changed - @Basic.Dots@ becomes +    @Basic.Dots.AnchorDots@; @Basic.Dots.Primitive@ becomes+    @Basic.Dots.Marks@.++  * @Basic.Shapes@ - internals reworked.+ 0.10.0 to 0.11.0:     * Reworked arrowheads and connectors - connectors are now 
demo/ArrowCircuit.hs view
@@ -8,15 +8,20 @@  module ArrowCircuit where -import Wumpus.Basic.Anchors import Wumpus.Basic.Arrows+import Wumpus.Basic.FontLoader.AfmLoader+import Wumpus.Basic.FontLoader.GSLoader import Wumpus.Basic.Graphic import Wumpus.Basic.Paths  import Wumpus.Basic.SafeFonts import Wumpus.Basic.Shapes+import Wumpus.Basic.Text.LRText  import Wumpus.Core                      -- package: wumpus-core +import FontLoaderUtils++ import Data.AffineSpace  import System.Directory@@ -24,27 +29,52 @@  main :: IO () main = do +    (mb_gs, mb_afm) <- processCmdLine default_font_loader_help     createDirectoryIfMissing True "./out/"-    writeEPS_latin1 "./out/arrow_circuit.eps" pic1-    writeSVG_latin1 "./out/arrow_circuit.svg" pic1 +    maybe gs_failk  makeGSPicture  $ mb_gs+    maybe afm_failk makeAfmPicture $ mb_afm+  where+    gs_failk  = putStrLn "No GhostScript font path supplied..."+    afm_failk = putStrLn "No AFM v4.1 font path supplied..." -times_ctx :: DrawingContext-times_ctx = fontface times_roman $ standardContext 11+makeGSPicture :: FilePath -> IO ()+makeGSPicture font_dir = do +    putStrLn "Using GhostScript metrics..."+    base_metrics <- loadGSMetrics font_dir ["Times-Roman", "Times-Italic"]+    let pic1 = runDrawingU (makeCtx base_metrics) circuit_drawing+    writeEPS "./out/arrow_circuit01.eps" pic1+    writeSVG "./out/arrow_circuit01.svg" pic1  +makeAfmPicture :: FilePath -> IO ()+makeAfmPicture font_dir = do +    putStrLn "Using AFM 4.1 metrics..."+    base_metrics <- loadAfmMetrics font_dir ["Times-Roman", "Times-Italic"]+    let pic1 = runDrawingU (makeCtx base_metrics) circuit_drawing+    writeEPS "./out/arrow_circuit02.eps" pic1+    writeSVG "./out/arrow_circuit02.svg" pic1 ++ +makeCtx :: BaseGlyphMetrics -> DrawingContext+makeCtx = fontface times_roman . metricsContext 11+++ -- Note - quite a bit of this diagram was produced /by eye/,  -- rather than using anchors directly - e.g. the placing of the  -- ptext labels and the anchors displaced by vectors. --++-- Note `at` currently does not work for Shapes.          -pic1 :: Picture Double -pic1 = liftToPictureU $ execDrawing times_ctx $ do-    a1 <- drawi $ strokedShape $ rrectangle 12 66 30 `at` P2 0 72+circuit_drawing :: Drawing Double +circuit_drawing = drawTracing $ do+    a1 <- drawi $ strokedShape $ rrectangle 12 66 30 $ P2 0 72     atext a1 "CONST 0"-    a2 <- drawi $ strokedShape $ circle 16 `at` P2 120 60+    a2 <- drawi $ strokedShape $ circle 16 $ P2 120 60     atext a2 "IF"-    a3 <- drawi $ strokedShape $ circle 16 `at` P2 240 28+    a3 <- drawi $ strokedShape $ circle 16 $ P2 240 28     atext a3 "+1"-    a4 <- drawi $ strokedShape $ rectangle 66 30 `at` P2 120 0+    a4 <- drawi $ strokedShape $ rectangle 66 30 $ P2 120 0     atext a4 "DELAY 0"     connWith connLine (east a1) (east a1 .+^ hvec 76)     connWith connLine (east a2) (east a2 .+^ hvec 180)@@ -58,25 +88,24 @@     return ()  --- Note - conn from Basic.Graphic is now questionable...  connWith :: ( TraceM m, DrawingCtxM m, u ~ MonUnit m             , Real u, Floating u, FromPtSize u )           => ConnectorPath u -> Point2 u -> Point2 u -> m () connWith con p0 p1 = localize doublesize $ -    drawi_ $ strokeConnector (rightArrow con tri45) p0 p1+    drawi_ $ situ2 (strokeConnector (rightArrow con tri45)) p0 p1   atext :: ( CenterAnchor t, DUnit t ~ u          , Real u, Floating u, FromPtSize u          , TraceM m, DrawingCtxM m, u ~ MonUnit m )       => t -> String -> m ()-atext ancr ss = let (P2 x y) = center ancr in-   drawi_ $ drawText $ translate x y $ plaintext ss+atext ancr ss = let pt = center ancr in+   drawi_ $ singleLineCC ss `at` pt   ptext :: ( Real u, Floating u, FromPtSize u          , TraceM m, DrawingCtxM m, u ~ MonUnit m )       => Point2 u -> String -> m ()-ptext (P2 x y) ss = localize (fontsize 14 . fontface times_italic) $ -    drawi_ $ drawText $ translate x y $ plaintext ss+ptext pt ss = localize (fontsize 14 . fontface times_italic) $ +    drawi_ $ singleLineCC ss `at` pt
demo/Arrowheads.hs view
@@ -19,19 +19,12 @@ main :: IO () main = do      createDirectoryIfMissing True "./out/"-    demo01--pt2 :: Point2 Double-pt2 = P2 100 10---demo01 :: IO ()-demo01 = do -    writeEPS_latin1 "./out/arrowheads01.eps" pic1-    writeSVG_latin1 "./out/arrowheads01.svg" pic1+    let pic1 = runDrawingU std_ctx arrow_drawing+    writeEPS "./out/arrowheads01.eps" pic1+    writeSVG "./out/arrowheads01.svg" pic1 -pic1 :: Picture Double-pic1 = liftToPictureU $ execDrawing std_ctx $ tableGraphic $ arrtable+arrow_drawing :: Drawing Double+arrow_drawing = drawTracing $ tableGraphic arrtable  arrtable :: [(Arrowhead Double, Arrowhead Double)] arrtable = @@ -66,7 +59,7 @@     ]  tableGraphic :: (Real u, Floating u, FromPtSize u) -             => [(Arrowhead u, Arrowhead u)] -> Drawing u ()+             => [(Arrowhead u, Arrowhead u)] -> TraceDrawing u () tableGraphic tips = zipWithM_ makeArrowDrawing tips ps   where     ps = unchain (coordinateScalingContext 120 24) $ tableDown 20 4@@ -79,9 +72,10 @@   makeArrowDrawing :: (Real u, Floating u, FromPtSize u) -                 => (Arrowhead u, Arrowhead u) -> Point2 u -> Drawing u ()+                 => (Arrowhead u, Arrowhead u) -> Point2 u +                 -> TraceDrawing u () makeArrowDrawing (arrl,arrr) p0 = -    drawi_ $ strokeConnector (leftrightArrow connLine arrl arrr) p0 p1+    drawi_ $ situ2 (strokeConnector (leftrightArrow connLine arrl arrr)) p0 p1   where     p1 = p0 .+^ hvec 100   
demo/ClipPic.hs view
@@ -14,36 +14,38 @@  import Wumpus.Basic.Chains import Wumpus.Basic.Colour.SVGColours+import Wumpus.Basic.DrawingComposition import Wumpus.Basic.Graphic import Wumpus.Basic.Paths-import Wumpus.Basic.PictureLanguage-import Wumpus.Basic.Text.LRSymbol-import Wumpus.Basic.Text.LRText+import Wumpus.Basic.SafeFonts  import Wumpus.Core                              -- package: wumpus-core +import Data.AffineSpace                         -- package: vector-space+ import System.Directory   main :: IO () main = do      createDirectoryIfMissing True "./out/"-    >> writeEPS_latin1 "./out/clip_pic.eps" pic-    >> writeSVG_latin1 "./out/clip_pic.svg" pic+    let pic = runDrawingU pic_drawing_ctx big_pic+    writeEPS "./out/clip_pic.eps" pic+    writeSVG "./out/clip_pic.svg" pic   pic_drawing_ctx :: DrawingContext pic_drawing_ctx = standardContext 14  -pic :: DPicture-pic = pic1 `nextToV` (stackOver [cpic1, cpic2, cpic3] cpic4)+big_pic :: DDrawing+big_pic = pic1 `nextToV` zconcat [cpic1, cpic2, cpic3, cpic4]  fillPath :: Num u => Path u -> Graphic u fillPath = filledPath . toPrimPath -pic1 :: DPicture-pic1 = liftToPictureU $ execDrawing pic_drawing_ctx $ +pic1 :: DDrawing+pic1 = drawTracing $          localize (fillColour medium_slate_blue) $ do             draw $ fillPath path01             localize (fillColour powder_blue) $ @@ -52,30 +54,29 @@             draw $ fillPath path04  -background :: RGBi -> DPicture -background rgb = liftToPictureU $ execDrawing pic_drawing_ctx $ -                   localize (strokeColour rgb) $ do                  -                     mapM_ iheartHaskell ps-+background :: RGBi -> DDrawing+background rgb = drawTracing $ +    localize (strokeColour rgb) $ mapM_ iheartHaskell ps    where      ps = unchain (coordinateScalingContext 86 16) $ tableDown 18 8 -cpic1 :: DPicture -cpic1 = clip (toPrimPath path01) (background black)+cpic1 :: DDrawing +cpic1 = clipDrawing (toPrimPath path01) (background black)   -cpic2 :: DPicture -cpic2 = clip (toPrimPath path02) (background medium_violet_red)+cpic2 :: DDrawing+cpic2 = clipDrawing (toPrimPath path02) (background medium_violet_red) -cpic3 :: DPicture -cpic3 = clip (toPrimPath path03) (background black)+cpic3 :: DDrawing +cpic3 = clipDrawing (toPrimPath path03) (background black) -cpic4 :: DPicture -cpic4 = clip (toPrimPath path04) (background black)+cpic4 :: DDrawing +cpic4 = clipDrawing (toPrimPath path04) (background black)  -iheartHaskell :: Num u => FromPtSize u => Point2 u -> Drawing u () -iheartHaskell pt = -    draw $ (execLRText $ char 'I' >> heart >> mapM_ char "Haskell") `at` pt+iheartHaskell :: Num u => FromPtSize u => Point2 u -> TraceDrawing u () +iheartHaskell pt = do+    draw $ textline "I Haskell" `at` pt+    draw $ localize (fontface symbol) $ textline "&heart;" `at` (pt .+^ hvec 7)   path01 :: Floating u => Path u
+ demo/ColourChartUtils.hs view
@@ -0,0 +1,502 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  ColourChartUtils+-- Copyright   :  (c) Stephen Tetley 2009+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- All the SVG / X11 \"named colours\" listed in tables. +--+--------------------------------------------------------------------------------++module ColourChartUtils+  ( +  -- * Tables of all colours+    all_x11_colours+  , all_svg_colours++  ) where++import qualified Wumpus.Basic.Colour.SVGColours    as SVG+import qualified Wumpus.Basic.Colour.X11Colours    as X11++import Wumpus.Core.Colour ( RGBi )+++all_svg_colours :: [(String,RGBi)]+all_svg_colours = +  [ ("alice_blue",              SVG.alice_blue)+  , ("antique_white",           SVG.antique_white)+  , ("aqua",                    SVG.aqua)+  , ("aquamarine",              SVG.aquamarine)+  , ("azure",                   SVG.azure)+  , ("beige",                   SVG.beige)+  , ("bisque",                  SVG.bisque)+  , ("black",                   SVG.black)+  , ("blanched_almond",         SVG.blanched_almond)+  , ("blue",                    SVG.blue)+  , ("blue_violet",             SVG.blue_violet)+  , ("brown",                   SVG.brown)+  , ("burlywood",               SVG.burlywood)+  , ("cadet_blue",              SVG.cadet_blue)+  , ("chartreuse",              SVG.chartreuse)+  , ("chocolate",               SVG.chocolate)+  , ("coral",                   SVG.coral)+  , ("cornflower_blue",         SVG.cornflower_blue)+  , ("cornsilk",                SVG.cornsilk)+  , ("crimson",                 SVG.crimson)+  , ("cyan",                    SVG.cyan)+  , ("dark_blue",               SVG.dark_blue)+  , ("dark_cyan",               SVG.dark_cyan)+  , ("dark_goldenrod",          SVG.dark_goldenrod)+  , ("dark_gray",               SVG.dark_gray)+  , ("dark_green",              SVG.dark_green)+  , ("dark_grey",               SVG.dark_grey)+  , ("dark_khaki",              SVG.dark_khaki)+  , ("dark_magenta",            SVG.dark_magenta)+  , ("dark_olive_green",        SVG.dark_olive_green)+  , ("dark_orange",             SVG.dark_orange)+  , ("dark_orchid",             SVG.dark_orchid)+  , ("dark_red",                SVG.dark_red)+  , ("dark_salmon",             SVG.dark_salmon)+  , ("dark_sea_green",          SVG.dark_sea_green)+  , ("dark_slate_blue",         SVG.dark_slate_blue)+  , ("dark_slate_gray",         SVG.dark_slate_gray)+  , ("dark_slate_grey",         SVG.dark_slate_grey)+  , ("dark_turquoise",          SVG.dark_turquoise)+  , ("dark_violet",             SVG.dark_violet)+  , ("deep_pink",               SVG.deep_pink)+  , ("deep_sky_blue",           SVG.deep_sky_blue)+  , ("dim_gray",                SVG.dim_gray)+  , ("dim_grey",                SVG.dim_grey)+  , ("dodger_blue",             SVG.dodger_blue)+  , ("firebrick",               SVG.firebrick)+  , ("floral_white",            SVG.floral_white)+  , ("forest_green",            SVG.forest_green)+  , ("fuchsia",                 SVG.fuchsia)+  , ("gainsboro",               SVG.gainsboro)+  , ("ghost_white",             SVG.ghost_white)+  , ("gold",                    SVG.gold)+  , ("goldenrod",               SVG.goldenrod)+  , ("gray",                    SVG.gray)+  , ("grey",                    SVG.grey)+  , ("green",                   SVG.green)+  , ("green_yellow",            SVG.green_yellow)+  , ("honeydew",                SVG.honeydew)+  , ("hot_pink",                SVG.hot_pink)+  , ("indian_red",              SVG.indian_red)+  , ("indigo",                  SVG.indigo)+  , ("ivory",                   SVG.ivory)+  , ("khaki",                   SVG.khaki)+  , ("lavender",                SVG.lavender)+  , ("lavender_blush",          SVG.lavender_blush)+  , ("lawn_green",              SVG.lawn_green)+  , ("lemon_chiffon",           SVG.lemon_chiffon)+  , ("light_blue",              SVG.light_blue)+  , ("light_coral",             SVG.light_coral)+  , ("light_cyan",              SVG.light_cyan)+  , ("light_goldenrod_yellow",  SVG.light_goldenrod_yellow)+  , ("light_gray",              SVG.light_gray)+  , ("light_green",             SVG.light_green)+  , ("light_grey",              SVG.light_grey)+  , ("light_pink",              SVG.light_pink)+  , ("light_salmon",            SVG.light_salmon)+  , ("light_sea_green",         SVG.light_sea_green)+  , ("light_sky_blue",          SVG.light_sky_blue)+  , ("light_slate_gray",        SVG.light_slate_gray)+  , ("light_slate_grey",        SVG.light_slate_grey)+  , ("light_steel_blue",        SVG.light_steel_blue)+  , ("light_yellow",            SVG.light_yellow)+  , ("lime",                    SVG.lime)+  , ("lime_green",              SVG.lime_green)+  , ("linen",                   SVG.linen)+  , ("magenta",                 SVG.magenta)+  , ("maroon",                  SVG.maroon)+  , ("medium_aquamarine",       SVG.medium_aquamarine)+  , ("medium_blue",             SVG.medium_blue)+  , ("medium_orchid",           SVG.medium_orchid)+  , ("medium_purple",           SVG.medium_purple)+  , ("medium_sea_green",        SVG.medium_sea_green)+  , ("medium_slate_blue",       SVG.medium_slate_blue)+  , ("medium_spring_green",     SVG.medium_spring_green)+  , ("medium_turquoise",        SVG.medium_turquoise)+  , ("medium_violet_red",       SVG.medium_violet_red)+  , ("midnight_blue",           SVG.midnight_blue)+  , ("mintcream",               SVG.mintcream)+  , ("mistyrose",               SVG.mistyrose)+  , ("moccasin",                SVG.moccasin)+  , ("navajo_white",            SVG.navajo_white)+  , ("navy",                    SVG.navy)+  , ("old_lace",                SVG.old_lace)+  , ("olive",                   SVG.olive)+  , ("olive_drab",              SVG.olive_drab)+  , ("orange",                  SVG.orange)+  , ("orange_red",              SVG.orange_red)+  , ("orchid",                  SVG.orchid)+  , ("pale_goldenrod",          SVG.pale_goldenrod)+  , ("pale_green",              SVG.pale_green)+  , ("pale_turquoise",          SVG.pale_turquoise)+  , ("pale_violet_red",         SVG.pale_violet_red)+  , ("papaya_whip",             SVG.papaya_whip)+  , ("peach_puff",              SVG.peach_puff)+  , ("peru",                    SVG.peru)+  , ("pink",                    SVG.pink)+  , ("plum",                    SVG.plum)+  , ("powder_blue",             SVG.powder_blue)+  , ("purple",                  SVG.purple)+  , ("red",                     SVG.red)+  , ("rosy_brown",              SVG.rosy_brown)+  , ("royal_blue",              SVG.royal_blue)+  , ("saddle_brown",            SVG.saddle_brown)+  , ("salmon",                  SVG.salmon)+  , ("sandy_brown",             SVG.sandy_brown)+  , ("sea_green",               SVG.sea_green)+  , ("seashell",                SVG.seashell)+  , ("sienna",                  SVG.sienna)+  , ("silver",                  SVG.silver)+  , ("sky_blue",                SVG.sky_blue)+  , ("slate_blue",              SVG.slate_blue)+  , ("slate_gray",              SVG.slate_gray)+  , ("slate_grey",              SVG.slate_grey)+  , ("snow",                    SVG.snow)+  , ("spring_green",            SVG.spring_green)+  , ("steel_blue",              SVG.steel_blue)+  , ("tan",                     SVG.tan)+  , ("teal",                    SVG.teal)+  , ("thistle",                 SVG.thistle)+  , ("tomato",                  SVG.tomato)+  , ("turquoise",               SVG.turquoise)+  , ("violet",                  SVG.violet)+  , ("wheat",                   SVG.wheat)+  , ("white",                   SVG.white)+  , ("whitesmoke",              SVG.whitesmoke)+  , ("yellow",                  SVG.yellow)+  , ("yellow_green",            SVG.yellow_green)+  ]++++all_x11_colours :: [(String,RGBi)]+all_x11_colours = +  [ ("antique_white1",          X11.antique_white1)+  , ("antique_white2",          X11.antique_white2)+  , ("antique_white3",          X11.antique_white3)+  , ("antique_white4",          X11.antique_white4)+  , ("aquamarine1",             X11.aquamarine1)+  , ("aquamarine2",             X11.aquamarine2)+  , ("aquamarine3",             X11.aquamarine3)+  , ("aquamarine4",             X11.aquamarine4)+  , ("azure1",                  X11.azure1)+  , ("azure2",                  X11.azure2)+  , ("azure3",                  X11.azure3)+  , ("azure4",                  X11.azure4)+  , ("bisque1",                 X11.bisque1)+  , ("bisque2",                 X11.bisque2)+  , ("bisque3",                 X11.bisque3)+  , ("bisque4",                 X11.bisque4)+  , ("blue1",                   X11.blue1)+  , ("blue2",                   X11.blue2)+  , ("blue3",                   X11.blue3)+  , ("blue4",                   X11.blue4)+  , ("brown1",                  X11.brown1)+  , ("brown2",                  X11.brown2)+  , ("brown3",                  X11.brown3)+  , ("brown4",                  X11.brown4)+  , ("burlywood1",              X11.burlywood1)+  , ("burlywood2",              X11.burlywood2)+  , ("burlywood3",              X11.burlywood3)+  , ("burlywood4",              X11.burlywood4)+  , ("cadet_blue1",             X11.cadet_blue1)+  , ("cadet_blue2",             X11.cadet_blue2)+  , ("cadet_blue3",             X11.cadet_blue3)+  , ("cadet_blue4",             X11.cadet_blue4)+  , ("chartreuse1",             X11.chartreuse1)+  , ("chartreuse2",             X11.chartreuse2)+  , ("chartreuse3",             X11.chartreuse3)+  , ("chartreuse4",             X11.chartreuse4)+  , ("chocolate1",              X11.chocolate1)+  , ("chocolate2",              X11.chocolate2)+  , ("chocolate3",              X11.chocolate3)+  , ("chocolate4",              X11.chocolate4)+  , ("coral1",                  X11.coral1)+  , ("coral2",                  X11.coral2)+  , ("coral3",                  X11.coral3)+  , ("coral4",                  X11.coral4)+  , ("cornsilk1",               X11.cornsilk1)+  , ("cornsilk2",               X11.cornsilk2)+  , ("cornsilk3",               X11.cornsilk3)+  , ("cornsilk4",               X11.cornsilk4)+  , ("cyan1",                   X11.cyan1)+  , ("cyan2",                   X11.cyan2)+  , ("cyan3",                   X11.cyan3)+  , ("cyan4",                   X11.cyan4)+  , ("dark_goldenrod1",         X11.dark_goldenrod1)+  , ("dark_goldenrod2",         X11.dark_goldenrod2)+  , ("dark_goldenrod3",         X11.dark_goldenrod3)+  , ("dark_goldenrod4",         X11.dark_goldenrod4)+  , ("dark_olive_green1",       X11.dark_olive_green1)+  , ("dark_olive_green2",       X11.dark_olive_green2)+  , ("dark_olive_green3",       X11.dark_olive_green3)+  , ("dark_olive_green4",       X11.dark_olive_green4)+  , ("dark_orange1",            X11.dark_orange1)+  , ("dark_orange2",            X11.dark_orange2)+  , ("dark_orange3",            X11.dark_orange3)+  , ("dark_orange4",            X11.dark_orange4)+  , ("dark_orchid1",            X11.dark_orchid1)+  , ("dark_orchid2",            X11.dark_orchid2)+  , ("dark_orchid3",            X11.dark_orchid3)+  , ("dark_orchid4",            X11.dark_orchid4)+  , ("dark_sea_green1",         X11.dark_sea_green1)+  , ("dark_sea_green2",         X11.dark_sea_green2)+  , ("dark_sea_green3",         X11.dark_sea_green3)+  , ("dark_sea_green4",         X11.dark_sea_green4)+  , ("dark_slate_gray1",        X11.dark_slate_gray1)+  , ("dark_slate_gray2",        X11.dark_slate_gray2)+  , ("dark_slate_gray3",        X11.dark_slate_gray3)+  , ("dark_slate_gray4",        X11.dark_slate_gray4)+  , ("deep_pink1",              X11.deep_pink1)+  , ("deep_pink2",              X11.deep_pink2)+  , ("deep_pink3",              X11.deep_pink3)+  , ("deep_pink4",              X11.deep_pink4)+  , ("deep_sky_blue1",          X11.deep_sky_blue1)+  , ("deep_sky_blue2",          X11.deep_sky_blue2)+  , ("deep_sky_blue3",          X11.deep_sky_blue3)+  , ("deep_sky_blue4",          X11.deep_sky_blue4)+  , ("dodger_blue1",            X11.dodger_blue1)+  , ("dodger_blue2",            X11.dodger_blue2)+  , ("dodger_blue3",            X11.dodger_blue3)+  , ("dodger_blue4",            X11.dodger_blue4)+  , ("firebrick1",              X11.firebrick1)+  , ("firebrick2",              X11.firebrick2)+  , ("firebrick3",              X11.firebrick3)+  , ("firebrick4",              X11.firebrick4)+  , ("gold1",                   X11.gold1)+  , ("gold2",                   X11.gold2)+  , ("gold3",                   X11.gold3)+  , ("gold4",                   X11.gold4)+  , ("goldenrod1",              X11.goldenrod1)+  , ("goldenrod2",              X11.goldenrod2)+  , ("goldenrod3",              X11.goldenrod3)+  , ("goldenrod4",              X11.goldenrod4)+  , ("green1",                  X11.green1)+  , ("green2",                  X11.green2)+  , ("green3",                  X11.green3)+  , ("green4",                  X11.green4)+  , ("honeydew1",               X11.honeydew1)+  , ("honeydew2",               X11.honeydew2)+  , ("honeydew3",               X11.honeydew3)+  , ("honeydew4",               X11.honeydew4)+  , ("hot_pink1",               X11.hot_pink1)+  , ("hot_pink2",               X11.hot_pink2)+  , ("hot_pink3",               X11.hot_pink3)+  , ("hot_pink4",               X11.hot_pink4)+  , ("indian_red1",             X11.indian_red1)+  , ("indian_red2",             X11.indian_red2)+  , ("indian_red3",             X11.indian_red3)+  , ("indian_red4",             X11.indian_red4)+  , ("ivory1",                  X11.ivory1)+  , ("ivory2",                  X11.ivory2)+  , ("ivory3",                  X11.ivory3)+  , ("ivory4",                  X11.ivory4)+  , ("khaki1",                  X11.khaki1)+  , ("khaki2",                  X11.khaki2)+  , ("khaki3",                  X11.khaki3)+  , ("khaki4",                  X11.khaki4)+  , ("lavender_blush1",         X11.lavender_blush1)+  , ("lavender_blush2",         X11.lavender_blush2)+  , ("lavender_blush3",         X11.lavender_blush3)+  , ("lavender_blush4",         X11.lavender_blush4)+  , ("lemon_chiffon1",          X11.lemon_chiffon1)+  , ("lemon_chiffon2",          X11.lemon_chiffon2)+  , ("lemon_chiffon3",          X11.lemon_chiffon3)+  , ("lemon_chiffon4",          X11.lemon_chiffon4)+  , ("light_blue1",             X11.light_blue1)+  , ("light_blue2",             X11.light_blue2)+  , ("light_blue3",             X11.light_blue3)+  , ("light_blue4",             X11.light_blue4)+  , ("light_cyan1",             X11.light_cyan1)+  , ("light_cyan2",             X11.light_cyan2)+  , ("light_cyan3",             X11.light_cyan3)+  , ("light_cyan4",             X11.light_cyan4)+  , ("light_goldenrod1",        X11.light_goldenrod1)+  , ("light_goldenrod2",        X11.light_goldenrod2)+  , ("light_goldenrod3",        X11.light_goldenrod3)+  , ("light_goldenrod4",        X11.light_goldenrod4)+  , ("light_pink1",             X11.light_pink1)+  , ("light_pink2",             X11.light_pink2)+  , ("light_pink3",             X11.light_pink3)+  , ("light_pink4",             X11.light_pink4)+  , ("light_salmon1",           X11.light_salmon1)+  , ("light_salmon2",           X11.light_salmon2)+  , ("light_salmon3",           X11.light_salmon3)+  , ("light_salmon4",           X11.light_salmon4)+  , ("light_sky_blue1",         X11.light_sky_blue1)+  , ("light_sky_blue2",         X11.light_sky_blue2)+  , ("light_sky_blue3",         X11.light_sky_blue3)+  , ("light_sky_blue4",         X11.light_sky_blue4)+  , ("light_steel_blue1",       X11.light_steel_blue1)+  , ("light_steel_blue2",       X11.light_steel_blue2)+  , ("light_steel_blue3",       X11.light_steel_blue3)+  , ("light_steel_blue4",       X11.light_steel_blue4)+  , ("light_yellow1",           X11.light_yellow1)+  , ("light_yellow2",           X11.light_yellow2)+  , ("light_yellow3",           X11.light_yellow3)+  , ("light_yellow4",           X11.light_yellow4)+  , ("magenta1",                X11.magenta1)+  , ("magenta2",                X11.magenta2)+  , ("magenta3",                X11.magenta3)+  , ("magenta4",                X11.magenta4)+  , ("maroon1",                 X11.maroon1)+  , ("maroon2",                 X11.maroon2)+  , ("maroon3",                 X11.maroon3)+  , ("maroon4",                 X11.maroon4)+  , ("medium_orchid1",          X11.medium_orchid1)+  , ("medium_orchid2",          X11.medium_orchid2)+  , ("medium_orchid3",          X11.medium_orchid3)+  , ("medium_orchid4",          X11.medium_orchid4)+  , ("medium_purple1",          X11.medium_purple1)+  , ("medium_purple2",          X11.medium_purple2)+  , ("medium_purple3",          X11.medium_purple3)+  , ("medium_purple4",          X11.medium_purple4)+  , ("misty_rose1",             X11.misty_rose1)+  , ("misty_rose2",             X11.misty_rose2)+  , ("misty_rose3",             X11.misty_rose3)+  , ("misty_rose4",             X11.misty_rose4)+  , ("navajo_white1",           X11.navajo_white1)+  , ("navajo_white2",           X11.navajo_white2)+  , ("navajo_white3",           X11.navajo_white3)+  , ("navajo_white4",           X11.navajo_white4)+  , ("olive_drab1",             X11.olive_drab1)+  , ("olive_drab2",             X11.olive_drab2)+  , ("olive_drab3",             X11.olive_drab3)+  , ("olive_drab4",             X11.olive_drab4)+  , ("orange1",                 X11.orange1)+  , ("orange2",                 X11.orange2)+  , ("orange3",                 X11.orange3)+  , ("orange4",                 X11.orange4)+  , ("orange_red1",             X11.orange_red1)+  , ("orange_red2",             X11.orange_red2)+  , ("orange_red3",             X11.orange_red3)+  , ("orange_red4",             X11.orange_red4)+  , ("orchid1",                 X11.orchid1)+  , ("orchid2",                 X11.orchid2)+  , ("orchid3",                 X11.orchid3)+  , ("orchid4",                 X11.orchid4)+  , ("pale_green1",             X11.pale_green1)+  , ("pale_green2",             X11.pale_green2)+  , ("pale_green3",             X11.pale_green3)+  , ("pale_green4",             X11.pale_green4)+  , ("pale_turquoise1",         X11.pale_turquoise1)+  , ("pale_turquoise2",         X11.pale_turquoise2)+  , ("pale_turquoise3",         X11.pale_turquoise3)+  , ("pale_turquoise4",         X11.pale_turquoise4)+  , ("pale_violet_red1",        X11.pale_violet_red1)+  , ("pale_violet_red2",        X11.pale_violet_red2)+  , ("pale_violet_red3",        X11.pale_violet_red3)+  , ("pale_Violet_red4",        X11.pale_violet_red4)+  , ("peach_puff1",             X11.peach_puff1)+  , ("peach_puff2",             X11.peach_puff2)+  , ("peach_puff3",             X11.peach_puff3)+  , ("peach_puff4",             X11.peach_puff4)+  , ("pink1",                   X11.pink1)+  , ("pink2",                   X11.pink2)+  , ("pink3",                   X11.pink3)+  , ("pink4",                   X11.pink4)+  , ("plum1",                   X11.plum1)+  , ("plum2",                   X11.plum2)+  , ("plum3",                   X11.plum3)+  , ("plum4",                   X11.plum4)+  , ("purple1",                 X11.purple1)+  , ("purple2",                 X11.purple2)+  , ("purple3",                 X11.purple3)+  , ("purple4",                 X11.purple4)+  , ("red1",                    X11.red1)+  , ("red2",                    X11.red2)+  , ("red3",                    X11.red3)+  , ("red4",                    X11.red4)+  , ("rosy_brown1",             X11.rosy_brown1)+  , ("rosy_brown2",             X11.rosy_brown2)+  , ("rosy_brown3",             X11.rosy_brown3)+  , ("rosy_brown4",             X11.rosy_brown4)+  , ("royal_blue1",             X11.royal_blue1)+  , ("royal_blue2",             X11.royal_blue2)+  , ("royal_blue3",             X11.royal_blue3)+  , ("royal_blue4",             X11.royal_blue4)+  , ("salmon1",                 X11.salmon1)+  , ("salmon2",                 X11.salmon2)+  , ("salmon3",                 X11.salmon3)+  , ("salmon4",                 X11.salmon4)+  , ("sea_green1",              X11.sea_green1)+  , ("sea_green2",              X11.sea_green2)+  , ("sea_green3",              X11.sea_green3)+  , ("sea_green4",              X11.sea_green4)+  , ("seashell1",               X11.seashell1)+  , ("seashell2",               X11.seashell2)+  , ("seashell3",               X11.seashell3)+  , ("seashell4",               X11.seashell4)+  , ("sienna1",                 X11.sienna1)+  , ("sienna2",                 X11.sienna2)+  , ("sienna3",                 X11.sienna3)+  , ("sienna4",                 X11.sienna4)+  , ("sky_blue1",               X11.sky_blue1)+  , ("sky_blue2",               X11.sky_blue2)+  , ("sky_blue3",               X11.sky_blue3)+  , ("sky_blue4",               X11.sky_blue4)+  , ("slate_blue1",             X11.slate_blue1)+  , ("slate_blue2",             X11.slate_blue2)+  , ("slate_blue3",             X11.slate_blue3)+  , ("slate_blue4",             X11.slate_blue4)+  , ("slate_gray1",             X11.slate_gray1)+  , ("slate_gray2",             X11.slate_gray2)+  , ("slate_gray3",             X11.slate_gray3)+  , ("slate_gray4",             X11.slate_gray4)+  , ("snow1",                   X11.snow1)+  , ("snow2",                   X11.snow2)+  , ("snow3",                   X11.snow3)+  , ("snow4",                   X11.snow4)+  , ("spring_green1",           X11.spring_green1)+  , ("spring_green2",           X11.spring_green2)+  , ("spring_green3",           X11.spring_green3)+  , ("spring_green4",           X11.spring_green4)+  , ("steel_blue1",             X11.steel_blue1)+  , ("steel_blue2",             X11.steel_blue2)+  , ("steel_blue3",             X11.steel_blue3)+  , ("steel_blue4",             X11.steel_blue4)+  , ("tan1",                    X11.tan1)+  , ("tan2",                    X11.tan2)+  , ("tan3",                    X11.tan3)+  , ("tan4",                    X11.tan4)+  , ("thistle1",                X11.thistle1)+  , ("thistle2",                X11.thistle2)+  , ("thistle3",                X11.thistle3)+  , ("thistle4",                X11.thistle4)+  , ("tomato1",                 X11.tomato1)+  , ("tomato2",                 X11.tomato2)+  , ("tomato3",                 X11.tomato3)+  , ("tomato4",                 X11.tomato4)+  , ("turquoise1",              X11.turquoise1)+  , ("turquoise2",              X11.turquoise2)+  , ("turquoise3",              X11.turquoise3)+  , ("turquoise4",              X11.turquoise4)+  , ("violet_red1",             X11.violet_red1)+  , ("violet_red2",             X11.violet_red2)+  , ("violet_red3",             X11.violet_red3)+  , ("violet_red4",             X11.violet_red4)+  , ("wheat1",                  X11.wheat1)+  , ("wheat2",                  X11.wheat2)+  , ("wheat3",                  X11.wheat3)+  , ("wheat4",                  X11.wheat4)+  , ("yellow1",                 X11.yellow1)+  , ("yellow2",                 X11.yellow2)+  , ("yellow3",                 X11.yellow3)+  , ("yellow4",                 X11.yellow4)+  ]++++
demo/ColourCharts.hs view
@@ -2,7 +2,7 @@  module ColourCharts where -import ColourDefns+import ColourChartUtils  import Wumpus.Basic.Chains import Wumpus.Basic.Graphic@@ -16,33 +16,39 @@ main :: IO () main = do      createDirectoryIfMissing True "./out/"-    writeEPS_latin1 "./out/SVGcolours.eps" svg-    writeSVG_latin1 "./out/SVGcolours.svg" svg-    writeEPS_latin1 "./out/X11colours.eps" $ uniformScale 0.75 x11_portrait-    writeSVG_latin1 "./out/X11colours.svg" x11_landscape+    --+    let svg_pic = runDrawingU draw_ctx svg +    writeEPS "./out/SVGcolours.eps" svg_pic+    writeSVG "./out/SVGcolours.svg" svg_pic+    --+    let x11_p = runDrawingU draw_ctx x11_portrait+    writeEPS "./out/X11colours.eps" $ uniformScale 0.75 x11_p+    let x11_l = runDrawingU draw_ctx x11_landscape+    writeSVG "./out/X11colours.svg" x11_l -svg :: Picture Double-svg = makePicture 52 all_svg_colours+draw_ctx :: DrawingContext+draw_ctx = (standardContext 9) -x11_landscape :: Picture Double-x11_landscape = makePicture 52 all_x11_colours+svg :: Drawing Double+svg = makeDrawing 52 all_svg_colours -x11_portrait :: Picture Double-x11_portrait = makePicture 72 all_x11_colours     +x11_landscape :: Drawing Double+x11_landscape = makeDrawing 52 all_x11_colours -makePicture :: Int -> [(String,RGBi)] -> DPicture -makePicture row_count xs = -    liftToPictureU $ execDrawing (standardContext 9) $ -        tableGraphic row_count xs+x11_portrait :: Drawing Double+x11_portrait = makeDrawing 72 all_x11_colours      -tableGraphic :: Int -> [(String,RGBi)] -> Drawing Double ()+makeDrawing :: Int -> [(String,RGBi)] -> DDrawing+makeDrawing row_count xs = drawTracing $ tableGraphic row_count xs++tableGraphic :: Int -> [(String,RGBi)] -> TraceDrawing Double () tableGraphic row_count xs =      zipWithM_ (\(name,rgb) pt -> colourSample name rgb pt) xs ps   where     ps = unchain (coordinateScalingContext 152 11) $ tableDown row_count 10   -colourSample :: String -> RGBi -> DPoint2 -> Drawing Double ()+colourSample :: String -> RGBi -> DPoint2 -> TraceDrawing Double () colourSample name rgb pt = localize (fillColour rgb) $ do      draw $ borderedRectangle 15 10 `at` pt     draw $ textline name `at` displace 20 2 pt 
− demo/ColourDefns.hs
@@ -1,502 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  ColourDefns--- Copyright   :  (c) Stephen Tetley 2009--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ All the SVG / X11 \"named colours\" listed in tables. --------------------------------------------------------------------------------------module ColourDefns-  ( -  -- * Tables of all colours-    all_x11_colours-  , all_svg_colours--  ) where--import qualified Wumpus.Basic.Colour.SVGColours    as SVG-import qualified Wumpus.Basic.Colour.X11Colours    as X11--import Wumpus.Core.Colour ( RGBi )---all_svg_colours :: [(String,RGBi)]-all_svg_colours = -  [ ("alice_blue",              SVG.alice_blue)-  , ("antique_white",           SVG.antique_white)-  , ("aqua",                    SVG.aqua)-  , ("aquamarine",              SVG.aquamarine)-  , ("azure",                   SVG.azure)-  , ("beige",                   SVG.beige)-  , ("bisque",                  SVG.bisque)-  , ("black",                   SVG.black)-  , ("blanched_almond",         SVG.blanched_almond)-  , ("blue",                    SVG.blue)-  , ("blue_violet",             SVG.blue_violet)-  , ("brown",                   SVG.brown)-  , ("burlywood",               SVG.burlywood)-  , ("cadet_blue",              SVG.cadet_blue)-  , ("chartreuse",              SVG.chartreuse)-  , ("chocolate",               SVG.chocolate)-  , ("coral",                   SVG.coral)-  , ("cornflower_blue",         SVG.cornflower_blue)-  , ("cornsilk",                SVG.cornsilk)-  , ("crimson",                 SVG.crimson)-  , ("cyan",                    SVG.cyan)-  , ("dark_blue",               SVG.dark_blue)-  , ("dark_cyan",               SVG.dark_cyan)-  , ("dark_goldenrod",          SVG.dark_goldenrod)-  , ("dark_gray",               SVG.dark_gray)-  , ("dark_green",              SVG.dark_green)-  , ("dark_grey",               SVG.dark_grey)-  , ("dark_khaki",              SVG.dark_khaki)-  , ("dark_magenta",            SVG.dark_magenta)-  , ("dark_olive_green",        SVG.dark_olive_green)-  , ("dark_orange",             SVG.dark_orange)-  , ("dark_orchid",             SVG.dark_orchid)-  , ("dark_red",                SVG.dark_red)-  , ("dark_salmon",             SVG.dark_salmon)-  , ("dark_sea_green",          SVG.dark_sea_green)-  , ("dark_slate_blue",         SVG.dark_slate_blue)-  , ("dark_slate_gray",         SVG.dark_slate_gray)-  , ("dark_slate_grey",         SVG.dark_slate_grey)-  , ("dark_turquoise",          SVG.dark_turquoise)-  , ("dark_violet",             SVG.dark_violet)-  , ("deep_pink",               SVG.deep_pink)-  , ("deep_sky_blue",           SVG.deep_sky_blue)-  , ("dim_gray",                SVG.dim_gray)-  , ("dim_grey",                SVG.dim_grey)-  , ("dodger_blue",             SVG.dodger_blue)-  , ("firebrick",               SVG.firebrick)-  , ("floral_white",            SVG.floral_white)-  , ("forest_green",            SVG.forest_green)-  , ("fuchsia",                 SVG.fuchsia)-  , ("gainsboro",               SVG.gainsboro)-  , ("ghost_white",             SVG.ghost_white)-  , ("gold",                    SVG.gold)-  , ("goldenrod",               SVG.goldenrod)-  , ("gray",                    SVG.gray)-  , ("grey",                    SVG.grey)-  , ("green",                   SVG.green)-  , ("green_yellow",            SVG.green_yellow)-  , ("honeydew",                SVG.honeydew)-  , ("hot_pink",                SVG.hot_pink)-  , ("indian_red",              SVG.indian_red)-  , ("indigo",                  SVG.indigo)-  , ("ivory",                   SVG.ivory)-  , ("khaki",                   SVG.khaki)-  , ("lavender",                SVG.lavender)-  , ("lavender_blush",          SVG.lavender_blush)-  , ("lawn_green",              SVG.lawn_green)-  , ("lemon_chiffon",           SVG.lemon_chiffon)-  , ("light_blue",              SVG.light_blue)-  , ("light_coral",             SVG.light_coral)-  , ("light_cyan",              SVG.light_cyan)-  , ("light_goldenrod_yellow",  SVG.light_goldenrod_yellow)-  , ("light_gray",              SVG.light_gray)-  , ("light_green",             SVG.light_green)-  , ("light_grey",              SVG.light_grey)-  , ("light_pink",              SVG.light_pink)-  , ("light_salmon",            SVG.light_salmon)-  , ("light_sea_green",         SVG.light_sea_green)-  , ("light_sky_blue",          SVG.light_sky_blue)-  , ("light_slate_gray",        SVG.light_slate_gray)-  , ("light_slate_grey",        SVG.light_slate_grey)-  , ("light_steel_blue",        SVG.light_steel_blue)-  , ("light_yellow",            SVG.light_yellow)-  , ("lime",                    SVG.lime)-  , ("lime_green",              SVG.lime_green)-  , ("linen",                   SVG.linen)-  , ("magenta",                 SVG.magenta)-  , ("maroon",                  SVG.maroon)-  , ("medium_aquamarine",       SVG.medium_aquamarine)-  , ("medium_blue",             SVG.medium_blue)-  , ("medium_orchid",           SVG.medium_orchid)-  , ("medium_purple",           SVG.medium_purple)-  , ("medium_sea_green",        SVG.medium_sea_green)-  , ("medium_slate_blue",       SVG.medium_slate_blue)-  , ("medium_spring_green",     SVG.medium_spring_green)-  , ("medium_turquoise",        SVG.medium_turquoise)-  , ("medium_violet_red",       SVG.medium_violet_red)-  , ("midnight_blue",           SVG.midnight_blue)-  , ("mintcream",               SVG.mintcream)-  , ("mistyrose",               SVG.mistyrose)-  , ("moccasin",                SVG.moccasin)-  , ("navajo_white",            SVG.navajo_white)-  , ("navy",                    SVG.navy)-  , ("old_lace",                SVG.old_lace)-  , ("olive",                   SVG.olive)-  , ("olive_drab",              SVG.olive_drab)-  , ("orange",                  SVG.orange)-  , ("orange_red",              SVG.orange_red)-  , ("orchid",                  SVG.orchid)-  , ("pale_goldenrod",          SVG.pale_goldenrod)-  , ("pale_green",              SVG.pale_green)-  , ("pale_turquoise",          SVG.pale_turquoise)-  , ("pale_violet_red",         SVG.pale_violet_red)-  , ("papaya_whip",             SVG.papaya_whip)-  , ("peach_puff",              SVG.peach_puff)-  , ("peru",                    SVG.peru)-  , ("pink",                    SVG.pink)-  , ("plum",                    SVG.plum)-  , ("powder_blue",             SVG.powder_blue)-  , ("purple",                  SVG.purple)-  , ("red",                     SVG.red)-  , ("rosy_brown",              SVG.rosy_brown)-  , ("royal_blue",              SVG.royal_blue)-  , ("saddle_brown",            SVG.saddle_brown)-  , ("salmon",                  SVG.salmon)-  , ("sandy_brown",             SVG.sandy_brown)-  , ("sea_green",               SVG.sea_green)-  , ("seashell",                SVG.seashell)-  , ("sienna",                  SVG.sienna)-  , ("silver",                  SVG.silver)-  , ("sky_blue",                SVG.sky_blue)-  , ("slate_blue",              SVG.slate_blue)-  , ("slate_gray",              SVG.slate_gray)-  , ("slate_grey",              SVG.slate_grey)-  , ("snow",                    SVG.snow)-  , ("spring_green",            SVG.spring_green)-  , ("steel_blue",              SVG.steel_blue)-  , ("tan",                     SVG.tan)-  , ("teal",                    SVG.teal)-  , ("thistle",                 SVG.thistle)-  , ("tomato",                  SVG.tomato)-  , ("turquoise",               SVG.turquoise)-  , ("violet",                  SVG.violet)-  , ("wheat",                   SVG.wheat)-  , ("white",                   SVG.white)-  , ("whitesmoke",              SVG.whitesmoke)-  , ("yellow",                  SVG.yellow)-  , ("yellow_green",            SVG.yellow_green)-  ]----all_x11_colours :: [(String,RGBi)]-all_x11_colours = -  [ ("antique_white1",          X11.antique_white1)-  , ("antique_white2",          X11.antique_white2)-  , ("antique_white3",          X11.antique_white3)-  , ("antique_white4",          X11.antique_white4)-  , ("aquamarine1",             X11.aquamarine1)-  , ("aquamarine2",             X11.aquamarine2)-  , ("aquamarine3",             X11.aquamarine3)-  , ("aquamarine4",             X11.aquamarine4)-  , ("azure1",                  X11.azure1)-  , ("azure2",                  X11.azure2)-  , ("azure3",                  X11.azure3)-  , ("azure4",                  X11.azure4)-  , ("bisque1",                 X11.bisque1)-  , ("bisque2",                 X11.bisque2)-  , ("bisque3",                 X11.bisque3)-  , ("bisque4",                 X11.bisque4)-  , ("blue1",                   X11.blue1)-  , ("blue2",                   X11.blue2)-  , ("blue3",                   X11.blue3)-  , ("blue4",                   X11.blue4)-  , ("brown1",                  X11.brown1)-  , ("brown2",                  X11.brown2)-  , ("brown3",                  X11.brown3)-  , ("brown4",                  X11.brown4)-  , ("burlywood1",              X11.burlywood1)-  , ("burlywood2",              X11.burlywood2)-  , ("burlywood3",              X11.burlywood3)-  , ("burlywood4",              X11.burlywood4)-  , ("cadet_blue1",             X11.cadet_blue1)-  , ("cadet_blue2",             X11.cadet_blue2)-  , ("cadet_blue3",             X11.cadet_blue3)-  , ("cadet_blue4",             X11.cadet_blue4)-  , ("chartreuse1",             X11.chartreuse1)-  , ("chartreuse2",             X11.chartreuse2)-  , ("chartreuse3",             X11.chartreuse3)-  , ("chartreuse4",             X11.chartreuse4)-  , ("chocolate1",              X11.chocolate1)-  , ("chocolate2",              X11.chocolate2)-  , ("chocolate3",              X11.chocolate3)-  , ("chocolate4",              X11.chocolate4)-  , ("coral1",                  X11.coral1)-  , ("coral2",                  X11.coral2)-  , ("coral3",                  X11.coral3)-  , ("coral4",                  X11.coral4)-  , ("cornsilk1",               X11.cornsilk1)-  , ("cornsilk2",               X11.cornsilk2)-  , ("cornsilk3",               X11.cornsilk3)-  , ("cornsilk4",               X11.cornsilk4)-  , ("cyan1",                   X11.cyan1)-  , ("cyan2",                   X11.cyan2)-  , ("cyan3",                   X11.cyan3)-  , ("cyan4",                   X11.cyan4)-  , ("dark_goldenrod1",         X11.dark_goldenrod1)-  , ("dark_goldenrod2",         X11.dark_goldenrod2)-  , ("dark_goldenrod3",         X11.dark_goldenrod3)-  , ("dark_goldenrod4",         X11.dark_goldenrod4)-  , ("dark_olive_green1",       X11.dark_olive_green1)-  , ("dark_olive_green2",       X11.dark_olive_green2)-  , ("dark_olive_green3",       X11.dark_olive_green3)-  , ("dark_olive_green4",       X11.dark_olive_green4)-  , ("dark_orange1",            X11.dark_orange1)-  , ("dark_orange2",            X11.dark_orange2)-  , ("dark_orange3",            X11.dark_orange3)-  , ("dark_orange4",            X11.dark_orange4)-  , ("dark_orchid1",            X11.dark_orchid1)-  , ("dark_orchid2",            X11.dark_orchid2)-  , ("dark_orchid3",            X11.dark_orchid3)-  , ("dark_orchid4",            X11.dark_orchid4)-  , ("dark_sea_green1",         X11.dark_sea_green1)-  , ("dark_sea_green2",         X11.dark_sea_green2)-  , ("dark_sea_green3",         X11.dark_sea_green3)-  , ("dark_sea_green4",         X11.dark_sea_green4)-  , ("dark_slate_gray1",        X11.dark_slate_gray1)-  , ("dark_slate_gray2",        X11.dark_slate_gray2)-  , ("dark_slate_gray3",        X11.dark_slate_gray3)-  , ("dark_slate_gray4",        X11.dark_slate_gray4)-  , ("deep_pink1",              X11.deep_pink1)-  , ("deep_pink2",              X11.deep_pink2)-  , ("deep_pink3",              X11.deep_pink3)-  , ("deep_pink4",              X11.deep_pink4)-  , ("deep_sky_blue1",          X11.deep_sky_blue1)-  , ("deep_sky_blue2",          X11.deep_sky_blue2)-  , ("deep_sky_blue3",          X11.deep_sky_blue3)-  , ("deep_sky_blue4",          X11.deep_sky_blue4)-  , ("dodger_blue1",            X11.dodger_blue1)-  , ("dodger_blue2",            X11.dodger_blue2)-  , ("dodger_blue3",            X11.dodger_blue3)-  , ("dodger_blue4",            X11.dodger_blue4)-  , ("firebrick1",              X11.firebrick1)-  , ("firebrick2",              X11.firebrick2)-  , ("firebrick3",              X11.firebrick3)-  , ("firebrick4",              X11.firebrick4)-  , ("gold1",                   X11.gold1)-  , ("gold2",                   X11.gold2)-  , ("gold3",                   X11.gold3)-  , ("gold4",                   X11.gold4)-  , ("goldenrod1",              X11.goldenrod1)-  , ("goldenrod2",              X11.goldenrod2)-  , ("goldenrod3",              X11.goldenrod3)-  , ("goldenrod4",              X11.goldenrod4)-  , ("green1",                  X11.green1)-  , ("green2",                  X11.green2)-  , ("green3",                  X11.green3)-  , ("green4",                  X11.green4)-  , ("honeydew1",               X11.honeydew1)-  , ("honeydew2",               X11.honeydew2)-  , ("honeydew3",               X11.honeydew3)-  , ("honeydew4",               X11.honeydew4)-  , ("hot_pink1",               X11.hot_pink1)-  , ("hot_pink2",               X11.hot_pink2)-  , ("hot_pink3",               X11.hot_pink3)-  , ("hot_pink4",               X11.hot_pink4)-  , ("indian_red1",             X11.indian_red1)-  , ("indian_red2",             X11.indian_red2)-  , ("indian_red3",             X11.indian_red3)-  , ("indian_red4",             X11.indian_red4)-  , ("ivory1",                  X11.ivory1)-  , ("ivory2",                  X11.ivory2)-  , ("ivory3",                  X11.ivory3)-  , ("ivory4",                  X11.ivory4)-  , ("khaki1",                  X11.khaki1)-  , ("khaki2",                  X11.khaki2)-  , ("khaki3",                  X11.khaki3)-  , ("khaki4",                  X11.khaki4)-  , ("lavender_blush1",         X11.lavender_blush1)-  , ("lavender_blush2",         X11.lavender_blush2)-  , ("lavender_blush3",         X11.lavender_blush3)-  , ("lavender_blush4",         X11.lavender_blush4)-  , ("lemon_chiffon1",          X11.lemon_chiffon1)-  , ("lemon_chiffon2",          X11.lemon_chiffon2)-  , ("lemon_chiffon3",          X11.lemon_chiffon3)-  , ("lemon_chiffon4",          X11.lemon_chiffon4)-  , ("light_blue1",             X11.light_blue1)-  , ("light_blue2",             X11.light_blue2)-  , ("light_blue3",             X11.light_blue3)-  , ("light_blue4",             X11.light_blue4)-  , ("light_cyan1",             X11.light_cyan1)-  , ("light_cyan2",             X11.light_cyan2)-  , ("light_cyan3",             X11.light_cyan3)-  , ("light_cyan4",             X11.light_cyan4)-  , ("light_goldenrod1",        X11.light_goldenrod1)-  , ("light_goldenrod2",        X11.light_goldenrod2)-  , ("light_goldenrod3",        X11.light_goldenrod3)-  , ("light_goldenrod4",        X11.light_goldenrod4)-  , ("light_pink1",             X11.light_pink1)-  , ("light_pink2",             X11.light_pink2)-  , ("light_pink3",             X11.light_pink3)-  , ("light_pink4",             X11.light_pink4)-  , ("light_salmon1",           X11.light_salmon1)-  , ("light_salmon2",           X11.light_salmon2)-  , ("light_salmon3",           X11.light_salmon3)-  , ("light_salmon4",           X11.light_salmon4)-  , ("light_sky_blue1",         X11.light_sky_blue1)-  , ("light_sky_blue2",         X11.light_sky_blue2)-  , ("light_sky_blue3",         X11.light_sky_blue3)-  , ("light_sky_blue4",         X11.light_sky_blue4)-  , ("light_steel_blue1",       X11.light_steel_blue1)-  , ("light_steel_blue2",       X11.light_steel_blue2)-  , ("light_steel_blue3",       X11.light_steel_blue3)-  , ("light_steel_blue4",       X11.light_steel_blue4)-  , ("light_yellow1",           X11.light_yellow1)-  , ("light_yellow2",           X11.light_yellow2)-  , ("light_yellow3",           X11.light_yellow3)-  , ("light_yellow4",           X11.light_yellow4)-  , ("magenta1",                X11.magenta1)-  , ("magenta2",                X11.magenta2)-  , ("magenta3",                X11.magenta3)-  , ("magenta4",                X11.magenta4)-  , ("maroon1",                 X11.maroon1)-  , ("maroon2",                 X11.maroon2)-  , ("maroon3",                 X11.maroon3)-  , ("maroon4",                 X11.maroon4)-  , ("medium_orchid1",          X11.medium_orchid1)-  , ("medium_orchid2",          X11.medium_orchid2)-  , ("medium_orchid3",          X11.medium_orchid3)-  , ("medium_orchid4",          X11.medium_orchid4)-  , ("medium_purple1",          X11.medium_purple1)-  , ("medium_purple2",          X11.medium_purple2)-  , ("medium_purple3",          X11.medium_purple3)-  , ("medium_purple4",          X11.medium_purple4)-  , ("misty_rose1",             X11.misty_rose1)-  , ("misty_rose2",             X11.misty_rose2)-  , ("misty_rose3",             X11.misty_rose3)-  , ("misty_rose4",             X11.misty_rose4)-  , ("navajo_white1",           X11.navajo_white1)-  , ("navajo_white2",           X11.navajo_white2)-  , ("navajo_white3",           X11.navajo_white3)-  , ("navajo_white4",           X11.navajo_white4)-  , ("olive_drab1",             X11.olive_drab1)-  , ("olive_drab2",             X11.olive_drab2)-  , ("olive_drab3",             X11.olive_drab3)-  , ("olive_drab4",             X11.olive_drab4)-  , ("orange1",                 X11.orange1)-  , ("orange2",                 X11.orange2)-  , ("orange3",                 X11.orange3)-  , ("orange4",                 X11.orange4)-  , ("orange_red1",             X11.orange_red1)-  , ("orange_red2",             X11.orange_red2)-  , ("orange_red3",             X11.orange_red3)-  , ("orange_red4",             X11.orange_red4)-  , ("orchid1",                 X11.orchid1)-  , ("orchid2",                 X11.orchid2)-  , ("orchid3",                 X11.orchid3)-  , ("orchid4",                 X11.orchid4)-  , ("pale_green1",             X11.pale_green1)-  , ("pale_green2",             X11.pale_green2)-  , ("pale_green3",             X11.pale_green3)-  , ("pale_green4",             X11.pale_green4)-  , ("pale_turquoise1",         X11.pale_turquoise1)-  , ("pale_turquoise2",         X11.pale_turquoise2)-  , ("pale_turquoise3",         X11.pale_turquoise3)-  , ("pale_turquoise4",         X11.pale_turquoise4)-  , ("pale_violet_red1",        X11.pale_violet_red1)-  , ("pale_violet_red2",        X11.pale_violet_red2)-  , ("pale_violet_red3",        X11.pale_violet_red3)-  , ("pale_Violet_red4",        X11.pale_violet_red4)-  , ("peach_puff1",             X11.peach_puff1)-  , ("peach_puff2",             X11.peach_puff2)-  , ("peach_puff3",             X11.peach_puff3)-  , ("peach_puff4",             X11.peach_puff4)-  , ("pink1",                   X11.pink1)-  , ("pink2",                   X11.pink2)-  , ("pink3",                   X11.pink3)-  , ("pink4",                   X11.pink4)-  , ("plum1",                   X11.plum1)-  , ("plum2",                   X11.plum2)-  , ("plum3",                   X11.plum3)-  , ("plum4",                   X11.plum4)-  , ("purple1",                 X11.purple1)-  , ("purple2",                 X11.purple2)-  , ("purple3",                 X11.purple3)-  , ("purple4",                 X11.purple4)-  , ("red1",                    X11.red1)-  , ("red2",                    X11.red2)-  , ("red3",                    X11.red3)-  , ("red4",                    X11.red4)-  , ("rosy_brown1",             X11.rosy_brown1)-  , ("rosy_brown2",             X11.rosy_brown2)-  , ("rosy_brown3",             X11.rosy_brown3)-  , ("rosy_brown4",             X11.rosy_brown4)-  , ("royal_blue1",             X11.royal_blue1)-  , ("royal_blue2",             X11.royal_blue2)-  , ("royal_blue3",             X11.royal_blue3)-  , ("royal_blue4",             X11.royal_blue4)-  , ("salmon1",                 X11.salmon1)-  , ("salmon2",                 X11.salmon2)-  , ("salmon3",                 X11.salmon3)-  , ("salmon4",                 X11.salmon4)-  , ("sea_green1",              X11.sea_green1)-  , ("sea_green2",              X11.sea_green2)-  , ("sea_green3",              X11.sea_green3)-  , ("sea_green4",              X11.sea_green4)-  , ("seashell1",               X11.seashell1)-  , ("seashell2",               X11.seashell2)-  , ("seashell3",               X11.seashell3)-  , ("seashell4",               X11.seashell4)-  , ("sienna1",                 X11.sienna1)-  , ("sienna2",                 X11.sienna2)-  , ("sienna3",                 X11.sienna3)-  , ("sienna4",                 X11.sienna4)-  , ("sky_blue1",               X11.sky_blue1)-  , ("sky_blue2",               X11.sky_blue2)-  , ("sky_blue3",               X11.sky_blue3)-  , ("sky_blue4",               X11.sky_blue4)-  , ("slate_blue1",             X11.slate_blue1)-  , ("slate_blue2",             X11.slate_blue2)-  , ("slate_blue3",             X11.slate_blue3)-  , ("slate_blue4",             X11.slate_blue4)-  , ("slate_gray1",             X11.slate_gray1)-  , ("slate_gray2",             X11.slate_gray2)-  , ("slate_gray3",             X11.slate_gray3)-  , ("slate_gray4",             X11.slate_gray4)-  , ("snow1",                   X11.snow1)-  , ("snow2",                   X11.snow2)-  , ("snow3",                   X11.snow3)-  , ("snow4",                   X11.snow4)-  , ("spring_green1",           X11.spring_green1)-  , ("spring_green2",           X11.spring_green2)-  , ("spring_green3",           X11.spring_green3)-  , ("spring_green4",           X11.spring_green4)-  , ("steel_blue1",             X11.steel_blue1)-  , ("steel_blue2",             X11.steel_blue2)-  , ("steel_blue3",             X11.steel_blue3)-  , ("steel_blue4",             X11.steel_blue4)-  , ("tan1",                    X11.tan1)-  , ("tan2",                    X11.tan2)-  , ("tan3",                    X11.tan3)-  , ("tan4",                    X11.tan4)-  , ("thistle1",                X11.thistle1)-  , ("thistle2",                X11.thistle2)-  , ("thistle3",                X11.thistle3)-  , ("thistle4",                X11.thistle4)-  , ("tomato1",                 X11.tomato1)-  , ("tomato2",                 X11.tomato2)-  , ("tomato3",                 X11.tomato3)-  , ("tomato4",                 X11.tomato4)-  , ("turquoise1",              X11.turquoise1)-  , ("turquoise2",              X11.turquoise2)-  , ("turquoise3",              X11.turquoise3)-  , ("turquoise4",              X11.turquoise4)-  , ("violet_red1",             X11.violet_red1)-  , ("violet_red2",             X11.violet_red2)-  , ("violet_red3",             X11.violet_red3)-  , ("violet_red4",             X11.violet_red4)-  , ("wheat1",                  X11.wheat1)-  , ("wheat2",                  X11.wheat2)-  , ("wheat3",                  X11.wheat3)-  , ("wheat4",                  X11.wheat4)-  , ("yellow1",                 X11.yellow1)-  , ("yellow2",                 X11.yellow2)-  , ("yellow3",                 X11.yellow3)-  , ("yellow4",                 X11.yellow4)-  ]----
demo/Connectors.hs view
@@ -19,19 +19,14 @@ main :: IO () main = do      createDirectoryIfMissing True "./out/"-    demo01+    let pic1 = runDrawingU std_ctx conn_drawing+    writeEPS "./out/connectors01.eps" pic1+    writeSVG "./out/connectors01.svg" pic1 -pt2 :: Point2 Double-pt2 = P2 100 10  -demo01 :: IO ()-demo01 = do -    writeEPS_latin1 "./out/connectors01.eps" pic1-    writeSVG_latin1 "./out/connectors01.svg" pic1--pic1 :: Picture Double-pic1 = liftToPictureU $ execDrawing std_ctx $ tableGraphic $ conntable+conn_drawing :: Drawing Double+conn_drawing = drawTracing $ tableGraphic $ conntable  conntable :: [ConnectorPath Double] conntable = @@ -57,7 +52,7 @@     ]  tableGraphic :: (Real u, Floating u, FromPtSize u) -             => [ConnectorPath u] -> Drawing u ()+             => [ConnectorPath u] -> TraceDrawing u () tableGraphic conns = zipWithM_ makeConnDrawing conns ps   where     ps = unchain (coordinateScalingContext 120 52) $ tableDown 10 6@@ -70,9 +65,9 @@   makeConnDrawing :: (Real u, Floating u, FromPtSize u) -                 => ConnectorPath u -> Point2 u -> Drawing u ()+                 => ConnectorPath u -> Point2 u -> TraceDrawing u () makeConnDrawing conn p0 = -    drawi_ $ strokeConnector (dblArrow conn curveTip) p0 p1+    drawi_ $ situ2 (strokeConnector (dblArrow conn curveTip)) p0 p1   where     p1 = p0 .+^ vec 100 40   
demo/DotPic.hs view
@@ -6,8 +6,13 @@ import Wumpus.Basic.Chains import Wumpus.Basic.Colour.SVGColours import Wumpus.Basic.Dots.AnchorDots+import Wumpus.Basic.FontLoader.AfmLoader+import Wumpus.Basic.FontLoader.GSLoader import Wumpus.Basic.Graphic+import Wumpus.Basic.SafeFonts +import FontLoaderUtils+ import Wumpus.Core                              -- package: wumpus-core  import Data.AffineSpace                         -- package: vector-space@@ -15,22 +20,44 @@ import Control.Monad import System.Directory ++ main :: IO () main = do +    (mb_gs, mb_afm) <- processCmdLine default_font_loader_help     createDirectoryIfMissing True "./out/"-    demo01+    maybe gs_failk  makeGSPicture  $ mb_gs+    maybe afm_failk makeAfmPicture $ mb_afm+  where+    gs_failk  = putStrLn "No GhostScript font path supplied..."+    afm_failk = putStrLn "No AFM v4.1 font path supplied..." -pt2 :: Point2 Double-pt2 = P2 100 10 +makeGSPicture :: FilePath -> IO ()+makeGSPicture font_dir = do +    putStrLn "Using GhostScript metrics..."+    base_metrics <- loadGSMetrics font_dir ["Helvetica"]+    let pic1 = runDrawingU (makeCtx base_metrics) dot_drawing +    writeEPS "./out/dots01.eps" pic1+    writeSVG "./out/dots01.svg" pic1 -demo01 :: IO ()-demo01 = do -    writeEPS_latin1 "./out/dots01.eps" pic1-    writeSVG_latin1 "./out/dots01.svg" pic1+  -pic1 :: Picture Double-pic1 = liftToPictureU $ execDrawing std_ctx $ tableGraphic $ +makeAfmPicture :: FilePath -> IO ()+makeAfmPicture font_dir = do +    putStrLn "Using AFM 4.1 metrics..."+    base_metrics <- loadAfmMetrics font_dir ["Helvetica"]+    let pic1 = runDrawingU (makeCtx base_metrics) dot_drawing +    writeEPS "./out/dots02.eps" pic1+    writeSVG "./out/dots02.svg" pic1++ +makeCtx :: BaseGlyphMetrics -> DrawingContext+makeCtx = fillColour peru . fontface helvetica . metricsContext 24+++dot_drawing :: Drawing Double+dot_drawing = drawTracing $ tableGraphic $      [ dotHLine     , dotVLine     , dotX@@ -52,20 +79,15 @@   tableGraphic :: (Real u, Floating u, FromPtSize u) -             => [DotLocImage u] -> Drawing u ()+             => [DotLocImage u] -> TraceDrawing u () tableGraphic imgs = zipWithM_ makeDotDrawing imgs ps   where     ps = unchain (coordinateScalingContext 1 36) $ tableDown (length imgs) 1  - -std_ctx :: DrawingContext-std_ctx = fillColour peru $ standardContext 24 -- makeDotDrawing :: (Real u, Floating u, FromPtSize u) -              => DotLocImage u -> Point2 u -> Drawing u ()+               => DotLocImage u -> Point2 u -> TraceDrawing u () makeDotDrawing dotF pt = do      dashline     mapM_ (\v -> drawi $ dotF `at` pt .+^ v) displacements
+ demo/DrawingCompo.hs view
@@ -0,0 +1,152 @@+{-# OPTIONS -Wall #-}++module DrawingCompo where++import Wumpus.Basic.Colour.SVGColours+import Wumpus.Basic.DrawingComposition+import Wumpus.Basic.Graphic++import Wumpus.Core                              -- package: wumpus-core++import System.Directory+++main :: IO ()+main = do +    createDirectoryIfMissing True "./out/"+    let out1 = runDrawingU pic_drawing_ctx pictures+    writeEPS "./out/drawing_composition.eps" out1+    writeSVG "./out/drawing_composition.svg" out1+++pic_drawing_ctx :: DrawingContext+pic_drawing_ctx = standardContext 14+++pictures :: DDrawing+pictures = vsep 12 [ pic1,  pic2,  pic3,  pic4+                   , pic5,  pic6,  pic7,  pic8+                   , pic9,  pic10, pic11, pic12 ]+++drawBlueBounds :: (Real u, Floating u, FromPtSize u) +               => Drawing u -> Drawing u+drawBlueBounds = modifyDrawing (illustrateBounds blue)++pic1 :: DDrawing+pic1 = picAnno pic "red `over` green `over` blue"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ rect_red `over` rect_green `over` rect_blue++pic2 :: DDrawing+pic2 = picAnno pic "red `under` green `under` blue"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ rect_red `under` rect_green `under` rect_blue+++pic3 :: DDrawing +pic3 = picAnno pic "red `centric` green `centric` blue"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            rect_red `centric` rect_green `centric` rect_blue++-- Note - nextToH only moves pictures in the horizontal.+--+pic4 :: DDrawing +pic4 = picAnno pic "red `nextToH` green `nextToH` blue"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            rect_red `nextToH` rect_green `nextToH` rect_blue++-- Note - nextToV only moves pictures in the vertical.+--+pic5 :: DDrawing +pic5 = picAnno pic "red `nextToV` green `nextToV` blue"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            rect_red `nextToV` rect_green `nextToV` rect_blue+++pic6 :: DDrawing+pic6 = picAnno pic "zconcat [red, green, blue]"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            zconcat [rect_red, rect_green, rect_blue]+++pic7 :: DDrawing+pic7 = picAnno pic "hcat [red, green, blue]"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            hcat [rect_red, rect_green, rect_blue]++pic8 :: DDrawing+pic8 = picAnno pic "vcat [red, green, blue]"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            vcat [rect_red, rect_green, rect_blue]++pic9 :: DDrawing+pic9 = picAnno pic "hsep 20 [red, green, blue]"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            hsep 20 [rect_red, rect_green, rect_blue]++pic10 :: DDrawing+pic10 = picAnno pic "vsep 20 [red, green, blue]"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            vsep 20 [rect_red, rect_green, rect_blue]+++pic11 :: DDrawing+pic11 = picAnno pic "hcatA HTop [red, green, blue]"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            hcatA HTop [rect_red, rect_green, rect_blue]+++pic12 :: DDrawing+pic12 = picAnno pic "vcatA VCenter [red, green, blue]"+  where+    pic :: DDrawing+    pic = drawBlueBounds $ +            vcatA VCenter [rect_red, rect_green, rect_blue]+++--------------------------------------------------------------------------------+++picAnno :: DDrawing -> String -> DDrawing+picAnno pic msg = alignHSep HCenter 30 pic lbl+  where+    lbl = drawTracing $ draw $ textline msg `at` zeroPt+++rect_red :: DDrawing+rect_red = drawTracing $ +    localize (fillColour indian_red)+             (draw $ borderedRectangle 30 10 `at` (P2 0 10))+                 +rect_green :: DDrawing+rect_green = drawTracing $ +    localize (fillColour olive_drab)+             (draw $ borderedRectangle 15 15 `at` (P2 10 10))+++rect_blue :: DDrawing+rect_blue = drawTracing $ +    localize (fillColour powder_blue)+             (draw $ borderedRectangle 20 30 `at` (P2 10 0))+
+ demo/FeatureModel.hs view
@@ -0,0 +1,130 @@+{-# LANGUAGE TypeFamilies               #-}+{-# OPTIONS -Wall #-}++++module FeatureModel where++import Wumpus.Basic.Arrows+import Wumpus.Basic.FontLoader.AfmLoader+import Wumpus.Basic.FontLoader.GSLoader+import Wumpus.Basic.Graphic+import Wumpus.Basic.Paths +import Wumpus.Basic.SafeFonts+import Wumpus.Basic.Shapes+import Wumpus.Basic.Text.LRText++import Wumpus.Core                      -- package: wumpus-core++import FontLoaderUtils+++import System.Directory+++main :: IO ()+main = do +    (mb_gs, mb_afm) <- processCmdLine default_font_loader_help+    createDirectoryIfMissing True "./out/"+    maybe gs_failk  makeGSPicture  $ mb_gs+    maybe afm_failk makeAfmPicture $ mb_afm+  where+    gs_failk  = putStrLn "No GhostScript font path supplied..."+    afm_failk = putStrLn "No AFM v4.1 font path supplied..."++makeGSPicture :: FilePath -> IO ()+makeGSPicture font_dir = do +    putStrLn "Using GhostScript metrics..."+    base_metrics <- loadGSMetrics font_dir ["Courier-Bold"]+    let pic1 = runDrawingU (makeCtx base_metrics) feature_model +    writeEPS "./out/feature_model01.eps" pic1+    writeSVG "./out/feature_model01.svg" pic1 ++makeAfmPicture :: FilePath -> IO ()+makeAfmPicture font_dir = do +    putStrLn "Using AFM 4.1 metrics..."+    base_metrics <- loadAfmMetrics font_dir ["Courier-Bold"]+    let pic1 = runDrawingU (makeCtx base_metrics) feature_model +    writeEPS "./out/feature_model02.eps" pic1+    writeSVG "./out/feature_model02.svg" pic1 ++makeCtx :: BaseGlyphMetrics -> DrawingContext+makeCtx = fontface courier_bold . metricsContext 18+++-- Note - I haven't worked out how to do @alternative@, @or@ and+-- @repetitions@ yet.+--+         +feature_model :: Drawing Double +feature_model = drawTracing $ do+    lea <- widebox "e" $ P2 150 160    +    lra <- widebox "r" $ P2  60  80+    lsa <- widebox "s" $ P2 240  80+    cmandatory_ lea lra+    cmandatory_ lea lsa++    uGa <- box "G" $ P2   0 0+    uHa <- box "H" $ P2  60 0+    uIa <- box "I" $ P2 120 0++    uAa <- box "A" $ P2 180 0+    uBa <- box "B" $ P2 240 0+    uCa <- box "C" $ P2 300 0++    cmandatory_ lra uGa+    cmandatory_ lra uHa+    cmandatory_ lra uIa++    cmandatory_ lsa uAa+    coptional_  lsa uBa+    cmandatory_ lsa uCa++    return ()+++type Box u = Rectangle u+++makeBox :: (Real u, Floating u, FromPtSize u) +        => u -> String -> Point2 u -> TraceDrawing u (Box u)+makeBox w ss pt = do +    a <- drawi $ strokedShape $ rectangle w 20 $ pt+    drawi_ $ singleLineCC ss `at` center a+    return a++box :: (Real u, Floating u, FromPtSize u) +    => String -> Point2 u -> TraceDrawing u (Box u)+box = makeBox 40++widebox :: (Real u, Floating u, FromPtSize u) +        => String -> Point2 u -> TraceDrawing u (Box u)+widebox = makeBox 60+++connWith :: ( Real u, Floating u, FromPtSize u ) +         => Arrowhead u -> Box u -> Box u -> TraceDrawing u (Path u)+connWith arrh b0 b1 = do+   lw <- lineWidth+   let p0 = south b0+   let p1 = northwards (realToFrac lw) b1+   drawi $ situ2 (strokeConnector (rightArrow connLine arrh)) p0 p1++infixr 4 `cmandatory`, `coptional`, `cmandatory_`, `coptional_`++cmandatory :: ( Real u, Floating u, FromPtSize u ) +           => Box u -> Box u -> TraceDrawing u (Path u)+cmandatory = connWith diskTip++coptional :: ( Real u, Floating u, FromPtSize u ) +          => Box u -> Box u -> TraceDrawing u (Path u)+coptional = connWith odiskTip+++cmandatory_ :: ( Real u, Floating u, FromPtSize u ) +            => Box u -> Box u -> TraceDrawing u ()+cmandatory_ p0 p1 = connWith diskTip p0 p1 >> return ()++coptional_ :: ( Real u, Floating u, FromPtSize u ) +           => Box u -> Box u -> TraceDrawing u ()+coptional_ p0 p1 = connWith odiskTip p0 p1 >> return ()
+ demo/FontLoaderUtils.hs view
@@ -0,0 +1,95 @@+{-# OPTIONS -Wall #-}+++module FontLoaderUtils+  (+    processCmdLine+  , default_font_loader_help+  ) where+++import Control.Applicative+import Control.Monad+import System.Directory+import System.Console.GetOpt+import System.Environment+import System.IO.Error+++wumpus_gs_font_dir :: String+wumpus_gs_font_dir = "WUMPUS_GS_FONT_DIR"++wumpus_afm_font_dir :: String+wumpus_afm_font_dir = "WUMPUS_AFM_FONT_DIR"+++default_font_loader_help :: String+default_font_loader_help = unlines $ +    [ "This example uses glyph metrics loaded at runtime."+    , "It can use either the metrics files supplied with GhostScript,"+    , "or the AFM v4.1 metrics for the Core 14 fonts available from"+    , "Adobe's website."+    , "" +    , "To use GhostScripts font metrics set the environemt variable"+    , wumpus_gs_font_dir ++ " to point to the GhostScript fonts"+    , "directory (e.g. /usr/share/ghostscript/fonts) or use the command"+    , "line flag --gs=PATH_TO_GHOSTSCRIPT_FONTS"+    , ""+    , "To use the Adode Core 14 font metrics download the archive from"+    , "the Adobe website and set the environment variable "+    , wumpus_afm_font_dir ++ " to point to it, or use the command line"+    , "flag -- afm=PATH_TO_AFM_CORE14_FONTS"+    ]+++data CmdLineFlag = Help+                 | GS_FontDir  String+                 | AFM_FontDir String+  deriving (Eq,Ord,Show)++processCmdLine :: String -> IO (Maybe FilePath, Maybe FilePath)+processCmdLine help_message = +    let options = makeCmdLineOptions help_message in do+        args <- getArgs+        let (opts, _, _) = getOpt Permute options args+        if Help `elem` opts then failk help_message+                            else succk opts+  where+    failk msg   = putStr msg >> return (Nothing,Nothing) +    succk flags = (,) <$> gsFontDirectory flags <*> afmFontDirectory flags +       ++makeCmdLineOptions :: String -> [OptDescr CmdLineFlag]+makeCmdLineOptions help_message =+    [ Option ['h'] ["help"]   (NoArg Help)                help_message+    , Option []    ["afm"]    (ReqArg AFM_FontDir "DIR")  "AFM v4.1 metrics dir"+    , Option []    ["gs"]     (ReqArg GS_FontDir  "DIR")  "GhoshScript font dir"+    ]+++gsFontDirectory :: [CmdLineFlag] -> IO (Maybe FilePath)+gsFontDirectory = step +  where+    step (GS_FontDir p:xs)  = doesDirectoryExist p >>= \check -> +                              if check then return (Just p) else step xs++    step (_:xs)             = step xs+    step []                 = envLookup wumpus_gs_font_dir+ ++afmFontDirectory :: [CmdLineFlag] -> IO (Maybe FilePath)+afmFontDirectory = step +  where+    step (AFM_FontDir p:xs) = doesDirectoryExist p >>= \check -> +                              if check then return (Just p) else step xs++    step (_:xs)             = step xs+    step []                 = envLookup wumpus_afm_font_dir+++envLookup :: String -> IO (Maybe String)+envLookup name = liftM fn $ try $ getEnv name+  where+    fn (Left _)  = Nothing+    fn (Right a) = Just a+
demo/FontPic.hs view
@@ -17,24 +17,32 @@ main :: IO () main = do      createDirectoryIfMissing True "./out/"-    writeEPS_latin1 "./out/font_courier.eps"   courier_pic-    writeSVG_latin1 "./out/font_courier.svg"   courier_pic-    writeEPS_latin1 "./out/font_times.eps"     times_pic-    writeSVG_latin1 "./out/font_times.svg"     times_pic-    writeEPS_latin1 "./out/font_helvetica.eps" helvetica_pic-    writeSVG_latin1 "./out/font_helvetica.svg" helvetica_pic-    writeEPS_latin1 "./out/font_symbol.eps"    symbol_pic-    writeSVG_latin1 "./out/font_symbol.svg"    symbol_pic+    --+    let courier_pic = runDrawingU std_ctx courier_drawing+    writeEPS "./out/font_courier.eps"   courier_pic+    writeSVG "./out/font_courier.svg"   courier_pic+    --+    let times_pic = runDrawingU std_ctx times_drawing+    writeEPS "./out/font_times.eps"     times_pic+    writeSVG "./out/font_times.svg"     times_pic+    --+    let helvetica_pic = runDrawingU std_ctx helvetica_drawing+    writeEPS "./out/font_helvetica.eps" helvetica_pic+    writeSVG "./out/font_helvetica.svg" helvetica_pic+    --+    let symbol_pic = runDrawingU std_ctx symbol_drawing+    writeEPS "./out/font_symbol.eps"    symbol_pic+    writeSVG "./out/font_symbol.svg"    symbol_pic   fontMsg :: FontFace -> Int -> String fontMsg ff sz = msgF []   where-    msgF = showString (font_name ff) . showChar ' ' . shows sz . showString "pt"+    msgF = showString (ps_font_name ff) . showChar ' ' . shows sz . showString "pt"   makeLabel :: RGBi -> FontFace -> Int -> DLocGraphic-makeLabel rgb ff sz = localize upd . (textline $ fontMsg ff sz)+makeLabel rgb ff sz = localize upd (textline $ fontMsg ff sz)   where     upd = fillColour rgb . fontsize sz . fontface ff @@ -51,7 +59,7 @@ pointChain :: LocChain Int Int Double pointChain = verticals positions -fontGraphic :: RGBi -> FontFace -> DPoint2 -> Drawing Double ()+fontGraphic :: RGBi -> FontFace -> DPoint2 -> TraceDrawing Double () fontGraphic rgb ff pt =      let ps = unchain (coordinateScalingContext 1 1) $ pointChain pt in        zipWithM_ (\p1 sz -> draw $ makeLabel rgb ff sz `at` p1) ps point_sizes@@ -61,9 +69,9 @@ std_ctx = standardContext 10  -fontPicture :: [(RGBi,FontFace)] -> DPicture-fontPicture xs = liftToPictureU $ execDrawing std_ctx $  -                   zipWithM (\(rgb,ff) pt -> fontGraphic rgb ff pt) xs ps+fontDrawing :: [(RGBi,FontFace)] -> DDrawing+fontDrawing xs = drawTracing $  +    zipWithM (\(rgb,ff) pt -> fontGraphic rgb ff pt) xs ps   where     ps = unchain (coordinateScalingContext 1 180) $ tableDown 4 1 @@ -72,17 +80,17 @@ -------------------------------------------------------------------------------- -- Times -times_pic :: Picture Double-times_pic = -    fontPicture [ (steel_blue,  times_roman)+times_drawing :: Drawing Double+times_drawing = +    fontDrawing [ (steel_blue,  times_roman)                 , (indian_red1, times_italic)                 , (steel_blue,  times_bold)                 , (indian_red1, times_bold_italic)                 ]  -helvetica_pic :: Picture Double-helvetica_pic = -    fontPicture [ (steel_blue,  helvetica)+helvetica_drawing :: Drawing Double+helvetica_drawing = +    fontDrawing [ (steel_blue,  helvetica)                 , (indian_red1, helvetica_oblique)                 , (steel_blue,  helvetica_bold)                 , (indian_red1, helvetica_bold_oblique)@@ -92,9 +100,9 @@  -------------------------------------------------------------------------------- -courier_pic :: Picture Double-courier_pic = -    fontPicture [ (steel_blue,  courier)+courier_drawing :: Drawing Double+courier_drawing = +    fontDrawing [ (steel_blue,  courier)                 , (indian_red1, courier_oblique)                 , (steel_blue,  courier_bold)                 , (indian_red1, courier_bold_oblique)@@ -104,6 +112,6 @@ --------------------------------------------------------------------------------      -symbol_pic :: Picture Double-symbol_pic = -    fontPicture [ (steel_blue, symbol) ]+symbol_drawing :: Drawing Double+symbol_drawing = +    fontDrawing [ (steel_blue, symbol) ]
+ demo/LeftRightText.hs view
@@ -0,0 +1,124 @@+{-# OPTIONS -Wall #-}++-- Note - @main@ is more convoluted than would normally be +-- expected as it supports both sources of glyph metrics - the +-- GhostScript distribution or the Core 14 metrics from Adobe.+-- +-- \"Real\" applications would be expected to choose one source. +--+-- I-am-not-a-lawyer, but it does look as though the Adobe font+-- metrics are redistributable, the GhostScript metrics are +-- seemingly redistributable under the same terms as the larger+-- GhostScript distribution.+-- +++module LeftRightText where+++import Wumpus.Basic.Colour.SVGColours+import Wumpus.Basic.Dots.Marks+import Wumpus.Basic.FontLoader.GSLoader+import Wumpus.Basic.FontLoader.AfmLoader+import Wumpus.Basic.Graphic+import Wumpus.Basic.SafeFonts+import Wumpus.Basic.Text.LRText++import FontLoaderUtils+++import Wumpus.Core                      -- package: wumpus-core++import System.Directory++++main :: IO ()+main = do +    (mb_gs, mb_afm) <- processCmdLine default_font_loader_help+    createDirectoryIfMissing True "./out/"+    maybe gs_failk  makeGSPicture  $ mb_gs+    maybe afm_failk makeAfmPicture $ mb_afm+  where+    gs_failk  = putStrLn "No GhostScript font path supplied..."+    afm_failk = putStrLn "No AFM v4.1 font path supplied..."+++makeGSPicture :: FilePath -> IO ()+makeGSPicture font_dir = do+    putStrLn "Using GhostScript metrics..."+    gs_metrics <- loadGSMetrics font_dir ["Helvetica"]+    let pic1 = runDrawingU (makeCtx gs_metrics) text_drawing +    writeEPS "./out/new_text01.eps" pic1+    writeSVG "./out/new_text01.svg" pic1++makeAfmPicture :: FilePath -> IO ()+makeAfmPicture font_dir = do+    putStrLn "Using AFM 4.1 metrics..."+    afm_metrics <- loadAfmMetrics font_dir ["Helvetica"]+    let pic2 = runDrawingU (makeCtx afm_metrics) text_drawing +    writeEPS "./out/new_text02.eps" pic2+    writeSVG "./out/new_text02.svg" pic2+++++makeCtx :: BaseGlyphMetrics -> DrawingContext+makeCtx = fontface helvetica . metricsContext 18+++text_drawing :: Drawing Double+text_drawing = drawTracing $ do +    drawi_ $ (fn left_text)   `at` P2   0 100+    drawi_ $ (fn center_text) `at` P2 200 100+    drawi_ $ (fn right_text)  `at` P2 400 100+    drawi_ $ (fn blank_text)  `at` P2   0   0+    drawi_ $ (fn bl_oneline)  `at` P2 200   0+    drawi_ $ (fn cc_oneline)  `at` P2 400   0+    +    draw $ redPlus            `at` P2   0 100+    draw $ redPlus            `at` P2 200 100+    draw $ redPlus            `at` P2 400 100+    draw $ redPlus            `at` P2   0   0  +    draw $ redPlus            `at` P2 200   0 +    draw $ redPlus            `at` P2 400   0 +       +  where+    fn = illustrateBoundedLocGraphic++redPlus :: (Fractional u, FromPtSize u) => LocGraphic u+redPlus = localize (strokeColour red) markPlus++bl_oneline :: BoundedLocGraphic Double+bl_oneline = +    localize (strokeColour dark_slate_gray) $ singleLineBL "Baseline-left..."+++cc_oneline :: BoundedLocGraphic Double+cc_oneline = +    localize (strokeColour dark_slate_gray) $ singleLineCC "Center-center..."++blank_text :: BoundedLocGraphic Double+blank_text = +    localize (strokeColour dark_slate_gray) $ multiAlignCenter ""+++left_text :: BoundedLocGraphic Double+left_text = +    localize (strokeColour dark_slate_gray) $ multiAlignLeft dummy_text+++right_text :: BoundedLocGraphic Double+right_text = +    localize (strokeColour dark_slate_gray) $ multiAlignRight dummy_text++center_text :: BoundedLocGraphic Double+center_text = +    localize (strokeColour dark_slate_gray) $ multiAlignCenter dummy_text+++dummy_text :: String +dummy_text = unlines $ [ "The quick brown"+                       , "fox jumps over"+                       , "the lazy dog."+                       ]
demo/PetriNet.hs view
@@ -7,7 +7,6 @@  module PetriNet where -import Wumpus.Basic.Anchors import Wumpus.Basic.Arrows import Wumpus.Basic.Colour.SVGColours import Wumpus.Basic.Graphic                     -- package: wumpus-basic@@ -26,67 +25,68 @@ main :: IO () main = do      createDirectoryIfMissing True "./out/"-    writeEPS_latin1 "./out/petri_net.eps" petri_net-    writeSVG_latin1 "./out/petri_net.svg" petri_net+    let pic1 = runDrawingU (standardContext 14) petri_net+    writeEPS "./out/petri_net.eps" pic1+    writeSVG "./out/petri_net.svg" pic1       -petri_net :: DPicture-petri_net = liftToPictureU $ execDrawing (standardContext 14) $ do-              pw     <- place 0 140-              tu1    <- transition 70 140-              rtw    <- place 140 140-              tu2    <- transition 210 140-              w      <- place 280 140-              tu3    <- transition 350 140-              res    <- place 280 70-              pr     <- place 0 0-              tl1    <- transition 70 0-              rtr    <- place 140 0-              tl2    <- transition 210 0-              r      <- place 280 0-              tl3    <- transition 350 0-              connector' (east pw)  (west tu1)              -              connector' (east tu1) (west rtw)-              connector' (east rtw) (west tu2)-              connector' (east tu2) (west w)-              connector' (east w)   (west tu3)-              connectorC 32 (north tu3) (north pw)-              connector' (east pr)  (west tl1)              -              connector' (east tl1) (west rtr)-              connector' (east rtr) (west tl2)-              connector' (east tl2) (west r)-              connector' (east r)   (west tl3)-              connectorC (-32) (south tl3) (south pr)-              connector' (southwest res) (northeast tl2)-              connector' (northwest tl3) (southeast res)-              connectorD 6    (southwest tu3) (northeast res)-              connectorD (-6) (southwest tu3) (northeast res) -              connectorD 6    (northwest res) (southeast tu2)-              connectorD (-6) (northwest res) (southeast tu2) -              draw $ lblParensParens `at` (P2 (-36) 150)-              draw $ lblParensParens `at` (P2 300 60)-              draw $ lblParensParensParens `at` (P2 (-52) (-14))-              draw $ lblBold "processing_w"   `at` (southwards 12 pw)-              draw $ lblBold "ready_to_write" `at` (southwards 12 rtw)-              draw $ lblBold "writing"        `at` (southwards 12 w)-              draw $ lblBold' "resource"      `at` (P2 300 72)-              draw $ lblBold "processing_r"   `at` (northwards 12 pr)-              draw $ lblBold "ready_to_read"  `at` (northwards 12 rtr)-              draw $ lblBold "reading"        `at` (northwards 12 r)-              return ()+petri_net :: DDrawing+petri_net = drawTracing $ do+    pw     <- place 0 140+    tu1    <- transition 70 140+    rtw    <- place 140 140+    tu2    <- transition 210 140+    w      <- place 280 140+    tu3    <- transition 350 140+    res    <- place 280 70+    pr     <- place 0 0+    tl1    <- transition 70 0+    rtr    <- place 140 0+    tl2    <- transition 210 0+    r      <- place 280 0+    tl3    <- transition 350 0+    connector' (east pw)  (west tu1)              +    connector' (east tu1) (west rtw)+    connector' (east rtw) (west tu2)+    connector' (east tu2) (west w)+    connector' (east w)   (west tu3)+    connectorC 32 (north tu3) (north pw)+    connector' (east pr)  (west tl1)              +    connector' (east tl1) (west rtr)+    connector' (east rtr) (west tl2)+    connector' (east tl2) (west r)+    connector' (east r)   (west tl3)+    connectorC (-32) (south tl3) (south pr)+    connector' (southwest res) (northeast tl2)+    connector' (northwest tl3) (southeast res)+    connectorD 6    (southwest tu3) (northeast res)+    connectorD (-6) (southwest tu3) (northeast res) +    connectorD 6    (northwest res) (southeast tu2)+    connectorD (-6) (northwest res) (southeast tu2) +    draw $ lblParensParens `at` (P2 (-36) 150)+    draw $ lblParensParens `at` (P2 300 60)+    draw $ lblParensParensParens `at` (P2 (-52) (-14))+    draw $ lblBold "processing_w"   `at` (southwards 12 pw)+    draw $ lblBold "ready_to_write" `at` (southwards 12 rtw)+    draw $ lblBold "writing"        `at` (southwards 12 w)+    draw $ lblBold' "resource"      `at` (P2 300 72)+    draw $ lblBold "processing_r"   `at` (northwards 12 pr)+    draw $ lblBold "ready_to_read"  `at` (northwards 12 rtr)+    draw $ lblBold "reading"        `at` (northwards 12 r)+    return ()  greenFill :: DrawingCtxM m => m a -> m a greenFill = localize (fillColour lime_green)  place :: (Real u, Floating u, DrawingCtxM m, TraceM m, u ~ MonUnit m)        => u -> u -> m (Circle u)-place x y = greenFill $ drawi $ borderedShape $ circle 14 `at` P2 x y+place x y = greenFill $ drawi $ borderedShape $ circle 14 $ P2 x y  transition :: (Real u, Floating u, DrawingCtxM m, TraceM m, u ~ MonUnit m)             => u -> u -> m (Rectangle u) transition x y = -    greenFill $ drawi $ borderedShape $ rectangle 32 22 `at` P2 x y+    greenFill $ drawi $ borderedShape $ rectangle 32 22 $ P2 x y   @@ -95,32 +95,32 @@          , Real u, Floating u, FromPtSize u )        => Point2 u -> Point2 u -> m () connector' p0 p1 = -    drawi_ $ strokeConnector (rightArrow connLine tri45) p0 p1+    drawi_ $ situ2 (strokeConnector (rightArrow connLine tri45)) p0 p1   connectorC :: ( Real u, Floating u, FromPtSize u              , DrawingCtxM m, TraceM m, u ~ MonUnit m )            => u -> Point2 u -> Point2 u -> m () connectorC v p0 p1 = -    drawi_ $ strokeConnector (rightArrow (connRightVHV v) tri45) p0 p1+    drawi_ $ situ2 (strokeConnector (rightArrow (connRightVHV v) tri45)) p0 p1  connectorD :: ( Real u, Floating u, FromPtSize u              , DrawingCtxM m, TraceM m, u ~ MonUnit m )            => u -> Point2 u -> Point2 u -> m () connectorD u p0 p1 = -    drawi_ $ strokeConnector (rightArrow (connIsosceles u) tri45) p0 p1+    drawi_ $ situ2 (strokeConnector (rightArrow (connIsosceles u) tri45)) p0 p1   lblParensParens :: Num u => LocGraphic u-lblParensParens = localize (fontface helvetica) . textline "(),()"+lblParensParens = localize (fontface helvetica) $ textline "(),()"  lblParensParensParens :: Num u => LocGraphic u-lblParensParensParens = localize (fontface helvetica) . textline "(),(),()"+lblParensParensParens = localize (fontface helvetica) $ textline "(),(),()"   lblBold' :: Num u => String -> LocGraphic u-lblBold' ss = localize (fontface helvetica_bold) . textline ss+lblBold' ss = localize (fontface helvetica_bold) $ textline ss   lblBold :: (Fractional u, Ord u, FromPtSize u) => String -> LocGraphic u-lblBold ss = localize (fontface helvetica_bold) . centermonoTextline ss+lblBold ss = localize (fontface helvetica_bold) $ centermonoTextline ss
− demo/Picture.hs
@@ -1,151 +0,0 @@-{-# OPTIONS -Wall #-}--module Picture where--import Wumpus.Basic.Colour.SVGColours-import Wumpus.Basic.Graphic-import Wumpus.Basic.PictureLanguage--import Wumpus.Core                              -- package: wumpus-core--import System.Directory---main :: IO ()-main = do -    createDirectoryIfMissing True "./out/"-    >> writeEPS_latin1 "./out/picture_lang.eps" pictures-    >> writeSVG_latin1 "./out/picture_lang.svg" pictures--pictures :: DPicture-pictures = vsep 12 pic1 [ pic2,  pic3,  pic4,  pic5-                        , pic6,  pic7,  pic8,  pic9-                        , pic10, pic11, pic12, pic13 ]--pic1 :: DPicture-pic1 = picAnno pic "red `over` green `over` blue"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ rect_red `over` rect_green `over` rect_blue--pic2 :: DPicture-pic2 = picAnno pic "red `under` green `under` blue"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ rect_red `under` rect_green `under` rect_blue---pic3 :: DPicture -pic3 = picAnno pic "red `centerOver` green `centerOver` blue"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            rect_red `centerOver` rect_green `centerOver` rect_blue---- Note - nextToH only moves pictures in the horizontal.----pic4 :: DPicture -pic4 = picAnno pic "red `nextToH` green `nextToH` blue"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            rect_red `nextToH` rect_green `nextToH` rect_blue---- Note - nextToV only moves pictures in the vertical.----pic5 :: DPicture -pic5 = picAnno pic "red `nextToV` green `nextToV` blue"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            rect_red `nextToV` rect_green `nextToV` rect_blue---pic6 :: DPicture-pic6 = picAnno pic "[red, green] `stackOver` blue"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            [rect_red, rect_green] `stackOver` rect_blue--pic7 :: DPicture-pic7 = picAnno pic "zconcat red [green, blue]"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            zconcat rect_red [rect_green, rect_blue]---pic8 :: DPicture-pic8 = picAnno pic "hcat red [green, blue]"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            hcat rect_red [rect_green, rect_blue]--pic9 :: DPicture-pic9 = picAnno pic "vcat red [green, blue]"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            vcat rect_red [rect_green, rect_blue]--pic10 :: DPicture-pic10 = picAnno pic "hsep 20 red [green, blue]"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            hsep 20 rect_red [rect_green, rect_blue]--pic11 :: DPicture-pic11 = picAnno pic "vsep 20 red [green, blue]"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            vsep 20 rect_red [rect_green, rect_blue]---pic12 :: DPicture-pic12 = picAnno pic "hcatA HTop red [green, blue]"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            hcatA HTop rect_red [rect_green, rect_blue]---pic13 :: DPicture-pic13 = picAnno pic "vcatA VCenter red [green, blue]"-  where-    pic :: DPicture-    pic = illustrateBounds blue $ -            vcatA VCenter rect_red [rect_green, rect_blue]-------------------------------------------------------------------------------------pic_drawing_ctx :: DrawingContext-pic_drawing_ctx = standardContext 14--picAnno :: DPicture -> String -> DPicture-picAnno pic msg = alignHSep HCenter 30 pic lbl-  where-    lbl = liftToPictureU $ execDrawing pic_drawing_ctx $ -            draw $ textline msg `at` zeroPt---rect_red :: DPicture-rect_red = liftToPictureU $ execDrawing pic_drawing_ctx $ -              localize (fillColour indian_red)-                       (draw $ borderedRectangle 30 10 `at` (P2 0 10))-                 -rect_green :: DPicture-rect_green = liftToPictureU $ execDrawing pic_drawing_ctx $ -              localize (fillColour olive_drab)-                       (draw $ borderedRectangle 15 15 `at` (P2 10 10))---rect_blue :: DPicture-rect_blue = liftToPictureU $ execDrawing pic_drawing_ctx $ -              localize (fillColour powder_blue)-                       (draw $ borderedRectangle 20 30 `at` (P2 10 0))-
demo/Symbols.hs view
@@ -2,10 +2,9 @@  module Symbols where +import Wumpus.Basic.Chains import Wumpus.Basic.Graphic import Wumpus.Basic.SafeFonts-import Wumpus.Basic.Text.LRSymbol-import Wumpus.Basic.Text.LRText   import Wumpus.Core                              -- package: wumpus-core@@ -20,242 +19,205 @@ main :: IO () main = do      createDirectoryIfMissing True "./out/"-    demo01+    let pic1 = runDrawingU std_ctx symbols+    writeEPS "./out/symbols.eps" pic1+    writeSVG "./out/symbols.svg" pic1  -demo01 :: IO ()-demo01 = do -    writeEPS_latin1 "./out/symbols.eps" pic1-    writeSVG_latin1 "./out/symbols.svg" pic1- std_ctx :: DrawingContext std_ctx = fontface times_roman $ standardContext 12 -pic1 :: DPicture -pic1 = liftToPictureU $ execDrawing std_ctx $ do-         zipWithM_ mdraw letters_01 column_01-         zipWithM_ sdraw letters_01 column_01-         zipWithM_ mdraw letters_02 column_02-         zipWithM_ sdraw letters_02 column_02-         zipWithM_ mdraw letters_03 column_03-         zipWithM_ sdraw letters_03 column_03-         zipWithM_ mdraw letters_04 column_04-         zipWithM_ sdraw letters_04 column_04-         zipWithM_ mdraw letters_05 column_05-         zipWithM_ sdraw letters_05 column_05-         zipWithM_ mdraw letters_06 column_06-         zipWithM_ sdraw letters_06 column_06 +-- Because the font changes, we draw the all the symbols in one+-- run and all the labels in a second run. This helps Wumpus-Core +-- generate better PostScript as there are less changes to the +-- /graphics state/.+--+symbols :: DDrawing+symbols = drawTracing $ do+    localize (fontface symbol) $ zipWithM_ sdraw all_letters ps+    zipWithM_ ldraw all_letters ps   where-    mdraw (_,ma) pt = draw $ execLRText ma `at` pt-    sdraw (s,_)  pt = draw $ textline s `at` pt .+^ hvec 16--letters_01 :: [(String, LRText Double ())]-letters_01 = -    [ ("uAlpha",                uAlpha) -    , ("uBeta",                 uBeta)-    , ("uChi",                  uChi)-    , ("uDelta",                uDelta)-    , ("uEpsilon",              uEpsilon)-    , ("uEta",                  uEta)-    , ("uEuro",                 uEuro)-    , ("uGamma",                uGamma)-    , ("uIfraktur",             uIfraktur)-    , ("uIota",                 uIota)-    , ("uKappa",                uKappa)-    , ("uLambda",               uLambda)-    , ("uMu",                   uMu)-    , ("uNu",                   uNu)-    , ("uOmega",                uOmega)-    , ("uOmicron",              uOmicron)-    , ("uPhi",                  uPhi)-    , ("uPi",                   uPi)-    , ("uPsi",                  uPsi)-    , ("uRfraktur",             uRfraktur)-    , ("uRho",                  uRho)-    , ("uSigma",                uSigma)-    , ("uTau",                  uTau)-    , ("uTheta",                uTheta)-    , ("uUpsilon",              uUpsilon)-    , ("uUpsilon1",             uUpsilon1)-    , ("uXi",                   uXi)-    , ("uZeta",                 uZeta)-    , ("aleph",                 aleph)-    , ("alpha",                 alpha)-    , ("ampersand",             ampersand)-    , ("angle",                 angle)-    , ("angleleft",             angleleft)-    , ("angleright",            angleright)-    , ("approxequal",           approxequal)-    ]--letters_02 :: [(String, LRText Double ())]-letters_02 = -    [ ("arrowboth",             arrowboth) -    , ("arrowdblboth",          arrowdblboth)-    , ("arrowdbldown",          arrowdbldown)-    , ("arrowdblleft",          arrowdblleft)-    , ("arrowdblright",         arrowdblright)-    , ("arrowdblup",            arrowdblup)-    , ("arrowdown",             arrowdown)-    , ("arrowleft",             arrowleft)-    , ("arrowright",            arrowright)-    , ("arrowup",               arrowup)-    , ("asteriskmath",          asteriskmath)-    , ("bar",                   bar)-    , ("beta",                  beta)-    , ("braceleft",             braceleft)-    , ("braceright",            braceright)-    , ("bracketleft",           bracketleft)-    , ("bracketright",          bracketright)-    , ("bullet",                bullet)-    , ("carriagereturn",        carriagereturn)-    , ("chi",                   chi)-    ]+    sdraw (s,_)     pt = draw $ textline s `at` pt+    ldraw (_,name)  pt = draw $ textline name `at` pt .+^ hvec 16+    ps              = unchain (coordinateScalingContext 100 20) $ tableDown 30 6 -letters_03 :: [(String, LRText Double ())]-letters_03 = -    [ ("circlemultiply",        circlemultiply) -    , ("circleplus",            circleplus)-    , ("club",                  club)-    , ("colon",                 colon)-    , ("comma",                 comma)-    , ("congruent",             congruent)-    , ("copyrightsans",         copyrightsans)-    , ("copyrightserif",        copyrightserif)-    , ("degree",                degree)-    , ("delta",                 delta)-    , ("diamond",               diamond)-    , ("divide",                divide)-    , ("dotmath",               dotmath)-    , ("eight",                 eight)-    , ("element",               element)-    , ("ellipsis",              ellipsis)-    , ("emptyset",              emptyset)-    , ("epsilon",               epsilon)-    , ("equal",                 equal)-    , ("equivalence",           equivalence)-    , ("eta",                   eta)-    , ("exclam",                exclam)-    , ("existential",           existential)-    , ("five",                  five)-    , ("florin",                florin)-    , ("four",                  four)-    , ("fraction",              fraction)-    , ("gamma",                 gamma)-    , ("gradient",              gradient)-    , ("greater",               greater)-    , ("greaterequal",          greaterequal)-    , ("heart",                 heart)-    , ("infinity",              infinity)-    , ("integral",              integral)-    ]+all_letters :: [(String, String)]+all_letters = +    [ ("&Alpha;",               "Alpha") +    , ("&Beta;",                "Beta")+    , ("&Chi;",                 "Chi")+    , ("&Delta;",               "Delta")+    , ("&Epsilon;",             "Epsilon")+    , ("&Eta;",                 "Eta")+    , ("&Euro;",                "Euro")+    , ("&Gamma;",               "Gamma")+    , ("&Ifraktur;",            "Ifraktur")+    , ("&Iota;",                "Iota")+    , ("&Kappa;",               "Kappa")+    , ("&Lambda;",              "Lambda")+    , ("&Mu;",                  "Mu")+    , ("&Nu;",                  "Nu")+    , ("&Omega;",               "Omega")+    , ("&Omicron;",             "Omicron")+    , ("&Phi;",                 "Phi")+    , ("&Pi;",                  "Pi")+    , ("&Psi;",                 "Psi")+    , ("&Rfraktur;",            "Rfraktur")+    , ("&Rho;",                 "Rho")+    , ("&Sigma;",               "Sigma")+    , ("&Tau;",                 "Tau")+    , ("&Theta;",               "Theta")+    , ("&Upsilon;",             "Upsilon")+    , ("&Upsilon1;",            "Upsilon1")+    , ("&Xi;",                  "Xi")+    , ("&Zeta;",                "Zeta")+    , ("&aleph;",               "aleph")+    , ("&alpha;",               "alpha")+    , ("&ampersand;",           "ampersand")+    , ("&angle;",               "angle")+    , ("&angleleft;",           "angleleft")+    , ("&angleright;",          "angleright")+    , ("&approxequal;",         "approxequal") +    -- +    , ("&arrowboth;",           "arrowboth") +    , ("&arrowdblboth;",        "arrowdblboth")+    , ("&arrowdbldown;",        "arrowdbldown")+    , ("&arrowdblleft;",        "arrowdblleft")+    , ("&arrowdblright;",       "arrowdblright")+    , ("&arrowdblup;",          "arrowdblup")+    , ("&arrowdown;",           "arrowdown")+    , ("&arrowleft;",           "arrowleft")+    , ("&arrowright;",          "arrowright")+    , ("&arrowup;",             "arrowup")+    , ("&asteriskmath;",        "asteriskmath")+    , ("&bar;",                 "bar")+    , ("&beta;",                "beta")+    , ("&braceleft;",           "braceleft")+    , ("&braceright;",          "braceright")+    , ("&bracketleft;",         "bracketleft")+    , ("&bracketright;",        "bracketright")+    , ("&bullet;",              "bullet")+    , ("&carriagereturn;",      "carriagereturn")+    , ("&chi;",                 "chi") -letters_04 :: [(String, LRText Double ())]-letters_04 = -    [ ("intersection",          intersection)-    , ("iota",                  iota)-    , ("kappa",                 kappa)-    , ("lambda",                lambda)-    , ("less",                  less)-    , ("lessequal",             lessequal)-    , ("logicaland",            logicaland)-    , ("logicalnot",            logicalnot)-    , ("logicalor",             logicalor)-    , ("lozenge",               lozenge)-    , ("minus",                 minus)-    , ("minute",                minute)-    , ("mu",                    mu)-    , ("multiply",              multiply)-    , ("nine",                  nine)-    , ("notelement",            notelement)-    , ("notequal",              notequal)-    , ("notsubset",             notsubset)-    , ("nu",                    nu)-    , ("numbersign",            numbersign)-    , ("omega",                 omega)-    , ("omega1",                omega1)-    , ("omicron",               omicron)-    , ("one",                   one)-    , ("parenleft",             parenleft)-    , ("parenright",            parenright)-    ]+    --+    , ("&circlemultiply;",      "circlemultiply") +    , ("&circleplus;",          "circleplus")+    , ("&club;",                "club")+    , ("&colon;",               "colon")+    , ("&comma;",               "comma")+    , ("&congruent;",           "congruent")+    , ("&copyrightsans;",       "copyrightsans")+    , ("&copyrightserif;",      "copyrightserif")+    , ("&degree;",              "degree")+    , ("&delta;",               "delta")+    , ("&diamond;",             "diamond")+    , ("&divide;",              "divide")+    , ("&dotmath;",             "dotmath")+    , ("&eight;",               "eight")+    , ("&element;",             "element")+    , ("&ellipsis;",            "ellipsis")+    , ("&emptyset;",            "emptyset")+    , ("&epsilon;",             "epsilon")+    , ("&equal;",               "equal")+    , ("&equivalence;",         "equivalence")+    , ("&eta;",                 "eta")+    , ("&exclam;",              "exclam")+    , ("&existential;",         "existential")+    , ("&five;",                "five")+    , ("&florin;",              "florin")+    , ("&four;",                "four")+    , ("&fraction;",            "fraction")+    , ("&gamma;",               "gamma")+    , ("&gradient;",            "gradient")+    , ("&greater;",             "greater")+    , ("&greaterequal;",        "greaterequal")+    , ("&heart;",               "heart")+    , ("&infinity;",            "infinity")+    , ("&integral;",            "integral") -letters_05 :: [(String, LRText Double ())]-letters_05 = -    [ ("partialdiff",           partialdiff)-    , ("percent",               percent)-    , ("period",                period)-    , ("perpendicular",         perpendicular)-    , ("phi",                   phi)-    , ("phi1",                  phi1)-    , ("pi",                    pi)-    , ("plus",                  plus)-    , ("plusminus",             plusminus)-    , ("product",               product)-    , ("propersubset",          propersubset)-    , ("propersuperset",        propersuperset)-    , ("proportional",          proportional)-    , ("psi",                   psi)-    , ("question",              question)-    , ("radical",               radical)-    , ("radicalex",             radicalex)-    , ("reflexsubset",          reflexsubset)-    , ("reflexsuperset",        reflexsuperset)-    , ("registersans",          registersans)-    , ("registerserif",         registerserif)-    , ("rho",                   rho)-    ]+    -- +    , ("&intersection;",        "intersection")+    , ("&iota;",                "iota")+    , ("&kappa;",               "kappa")+    , ("&lambda;",              "lambda")+    , ("&less;",                "less")+    , ("&lessequal;",           "lessequal")+    , ("&logicaland;",          "logicaland")+    , ("&logicalnot;",          "logicalnot")+    , ("&logicalor;",           "logicalor")+    , ("&lozenge;",             "lozenge")+    , ("&minus;",               "minus")+    , ("&minute;",              "minute")+    , ("&mu;",                  "mu")+    , ("&multiply;",            "multiply")+    , ("&nine;",                "nine")+    , ("&notelement;",          "notelement")+    , ("&notequal;",            "notequal")+    , ("&notsubset;",           "notsubset")+    , ("&nu;",                  "nu")+    , ("&numbersign;",          "numbersign")+    , ("&omega;",               "omega")+    , ("&omega1;",              "omega1")+    , ("&omicron;",             "omicron")+    , ("&one;",                 "one")+    , ("&parenleft;",           "parenleft")+    , ("&parenright;",          "parenright") -letters_06 :: [(String, LRText Double ())]-letters_06 = -    [ ("second",                second)-    , ("semicolon",             semicolon)-    , ("seven",                 seven)-    , ("sigma",                 sigma)-    , ("sigma1",                sigma1)-    , ("similar",               similar)-    , ("six",                   six)-    , ("slash",                 slash)-    , ("space",                 space)-    , ("spade",                 spade)-    , ("suchthat",              suchthat)-    , ("summation",             summation)-    , ("tau",                   tau)-    , ("therefore",             therefore)-    , ("theta",                 theta)-    , ("theta1",                theta1)-    , ("three",                 three)-    , ("trademarksans",         trademarksans)-    , ("trademarkserif",        trademarkserif)-    , ("two",                   two)-    , ("underscore",            underscore)-    , ("union",                 union)-    , ("universal",             universal)-    , ("upsilon",               upsilon)-    , ("weierstrass",           weierstrass)-    , ("xi",                    xi)-    , ("zero",                  zero)-    , ("zeta",                  zeta)+    --+    , ("&partialdiff;",         "partialdiff")+    , ("&percent;",             "percent")+    , ("&period;",              "period")+    , ("&perpendicular;",       "perpendicular")+    , ("&phi;",                 "phi")+    , ("&phi1;",                "phi1")+    , ("&pi;",                  "pi")+    , ("&plus;",                "plus")+    , ("&plusminus;",           "plusminus")+    , ("&product;",             "product")+    , ("&propersubset;",        "propersubset")+    , ("&propersuperset;",      "propersuperset")+    , ("&proportional;",        "proportional")+    , ("&psi;",                 "psi")+    , ("&question;",            "question")+    , ("&radical;",             "radical")+    , ("&radicalex;",           "radicalex")+    , ("&reflexsubset;",        "reflexsubset")+    , ("&reflexsuperset;",      "reflexsuperset")+    , ("&registersans;",        "registersans")+    , ("&registerserif;",       "registerserif")+    , ("&rho;",                 "rho")+    +    -- +    , ("&second;",              "second")+    , ("&semicolon;",           "semicolon")+    , ("&seven;",               "seven")+    , ("&sigma;",               "sigma")+    , ("&sigma1;",              "sigma1")+    , ("&similar;",             "similar")+    , ("&six;",                 "six")+    , ("&slash;",               "slash")+    , ("&space;",               "space")+    , ("&spade;",               "spade")+    , ("&suchthat;",            "suchthat")+    , ("&summation;",           "summation")+    , ("&tau;",                 "tau")+    , ("&therefore;",           "therefore")+    , ("&theta;",               "theta")+    , ("&theta1;",              "theta1")+    , ("&three;",               "three")+    , ("&trademarksans;",       "trademarksans")+    , ("&trademarkserif;",      "trademarkserif")+    , ("&two;",                 "two")+    , ("&underscore;",          "underscore")+    , ("&union;",               "union")+    , ("&universal;",           "universal")+    , ("&upsilon;",             "upsilon")+    , ("&weierstrass;",         "weierstrass")+    , ("&xi;",                  "xi")+    , ("&zero;",                "zero")+    , ("&zeta;",                "zeta")     ] --- TODO - this should use a chain when the Chain API stablizes.--column_01 :: Num u => [Point2 u]-column_01 = iterate (.+^ vvec (-16)) (P2 0 600)--column_02 :: Num u => [Point2 u]-column_02 = iterate (.+^ vvec (-16)) (P2 100 600)--column_03 :: Num u => [Point2 u]-column_03 = iterate (.+^ vvec (-16)) (P2 200 600)--column_04 :: Num u => [Point2 u]-column_04 = iterate (.+^ vvec (-16)) (P2 300 600)--column_05 :: Num u => [Point2 u]-column_05 = iterate (.+^ vvec (-16)) (P2 400 600)--column_06 :: Num u => [Point2 u]-column_06 = iterate (.+^ vvec (-16)) (P2 500 600)
− src/Wumpus/Basic/Anchors.hs
@@ -1,138 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Anchors--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Anchor points on shapes.------ \*\* WARNING \*\* this module is an experiment, and may --- change significantly or even be dropped from future revisions.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Anchors-  ( --  -- * Anchors-    CenterAnchor(..)-  , CardinalAnchor(..)-  , CardinalAnchor2(..)-  , RadialAnchor(..)--  -- * extended anchor points-  , northwards-  , southwards-  , eastwards-  , westwards-  , northeastwards-  , southeastwards-  , southwestwards-  , northwestwards--  , radialConnectorPoints--  ) where--import Wumpus.Core                      -- package: wumpus-core--import Data.AffineSpace                 -- package: vector-space--class CenterAnchor t where-  center :: DUnit t ~ u => t -> Point2 u---- Note - in TikZ cardinal anchors are not necessarily at the--- equivalent radial position, for instance reactangle north-east--- is the top-right corner whether or not this is incident at --- 45deg.-----class CardinalAnchor t where-  north :: DUnit t ~ u => t -> Point2 u-  south :: DUnit t ~ u => t -> Point2 u-  east  :: DUnit t ~ u => t -> Point2 u-  west  :: DUnit t ~ u => t -> Point2 u--class CardinalAnchor2 t where-  northeast :: DUnit t ~ u => t -> Point2 u-  southeast :: DUnit t ~ u => t -> Point2 u-  southwest :: DUnit t ~ u => t -> Point2 u-  northwest :: DUnit t ~ u => t -> Point2 u----- | Anchor on a border that can be identified with and angle.----class RadialAnchor t where-  radialAnchor :: DUnit t ~ u => Radian -> t -> Point2 u---extendPtDist :: (Real u, Floating u) => u -> Point2 u -> Point2 u -> Point2 u-extendPtDist d p1 p2 = let v   = pvec p1 p2-                           ang = direction v-                           len = vlength v-                       in p1 .+^ avec ang (len+d)----northwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor t-              , u ~ DUnit t ) -           => u -> t -> Point2 u-northwards u a = extendPtDist u (center a) (north a)---southwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor t-              , u ~ DUnit t ) -           => u -> t -> Point2 u-southwards u a = extendPtDist u (center a) (south a)--eastwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor t-             , u ~ DUnit t ) -          => u -> t -> Point2 u-eastwards u a = extendPtDist u (center a) (east a)--westwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor t-             , u ~ DUnit t ) -          => u -> t -> Point2 u-westwards u a = extendPtDist u (center a) (west a)---northeastwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor2 t-                  , u ~ DUnit t ) -               => u -> t -> Point2 u-northeastwards u a = extendPtDist u (center a) (northeast a)---southeastwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor2 t-                  , u ~ DUnit t ) -               => u -> t -> Point2 u-southeastwards u a = extendPtDist u (center a) (southeast a)--southwestwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor2 t-                  , u ~ DUnit t ) -               => u -> t -> Point2 u-southwestwards u a = extendPtDist u (center a) (southwest a)--northwestwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor2 t-                  , u ~ DUnit t ) -               => u -> t -> Point2 u-northwestwards u a = extendPtDist u (center a) (northwest a)-------------------------------------------------------------------------------------radialConnectorPoints :: ( Real u, Floating u-                         , CenterAnchor t1, RadialAnchor t1-                         , CenterAnchor t2, RadialAnchor t2-                         , u ~ DUnit t1, DUnit t1 ~ DUnit t2 ) -                      => t1 -> t2 -> (Point2 u, Point2 u) -radialConnectorPoints a b = (radialAnchor theta a, radialAnchor (theta+pi) b)-  where-    theta = direction $ pvec (center a) (center b)-    
src/Wumpus/Basic/Arrows/Connectors.hs view
@@ -93,23 +93,25 @@   - strokeConnector :: (Real u, Floating u)                  => Connector u -> ConnectorImage u (Path u)-strokeConnector (Connector cpF opt_la opt_ra) p0 p1 =-    tipEval opt_la (directionL pathc) p0 >>= \(dl,gfL) -> -    tipEval opt_ra (directionR pathc) p1 >>= \(dr,gfR) ->-    intoImage (pure pathc) (gfR $ gfL $ drawP $ shortenPath dl dr pathc) +strokeConnector (Connector cpF opt_la opt_ra) =+    promote2 $ \p0 p1 -> let pathc = cpF p0 p1 in +       tipEval opt_la p0 (directionL pathc) >>= \(dl,gfL) -> +       tipEval opt_ra p1 (directionR pathc) >>= \(dr,gfR) ->+       intoImage (pure pathc) (postpro (gfR . gfL) $ drawP $ shortenPath dl dr pathc)    where-    pathc       = cpF p0 p1     drawP       = openStroke . toPrimPath    + -- for Paths.Base ? ---shortenPath :: (Real u , Floating u) =>  u  -> u -> Path u -> Path u+shortenPath :: (Real u , Floating u) => u  -> u -> Path u -> Path u shortenPath l r = shortenL l .  shortenR r  +type ArrowMark u = PrimGraphic u -> PrimGraphic u + -- 'tipEval' is a bit of an oddity. It has to evaluate the  -- Arrowhead / Image in the DrawingCtx to get the retract  -- distance. But doing so evaluates the tips to PrimGraphics, thus @@ -129,18 +131,18 @@ --  tipEval :: Num u -        => Maybe (Arrowhead u) -> Radian -> Point2 u -        -> DrawingR (u, GraphicTrafoF u)-tipEval Nothing    _     _  = return (0,unmarked)-tipEval (Just arw) theta pt = getArrowhead arw theta pt >>= \(dx,prim) -> -                              return (dx, superior $ pure prim)-+        => Maybe (Arrowhead u) -> Point2 u -> Radian+        -> CF (u, ArrowMark u)+tipEval Nothing    _  _     = return (0,unmarked)+tipEval (Just arw) pt theta = makeMark $ unCF2 pt theta (getArrowhead arw)  -unmarked :: GraphicTrafoF u+unmarked :: ArrowMark u unmarked = id  +makeMark :: Image u a -> CF (a, ArrowMark u)+makeMark = postpro (\(a,prim) -> (a, superior prim))   
src/Wumpus/Basic/Arrows/Tips.hs view
@@ -22,6 +22,7 @@       Arrowhead(..)+     , tri90   , tri60@@ -62,7 +63,6 @@  import Wumpus.Basic.Graphic import Wumpus.Basic.Paths-import Wumpus.Basic.Utils.Combinators  import Wumpus.Core                      -- package: wumpus-core @@ -78,7 +78,7 @@ -- the markHeight (or halfMarkHeight) so it has to be calculated -- w.r.t. the DrawingCtx. ---newtype Arrowhead u = Arrowhead { getArrowhead :: ThetaLocImage u u }+newtype Arrowhead u = Arrowhead { getArrowhead :: LocThetaImage u u }   @@ -144,7 +144,7 @@ -}  -markHeightLessLineWidth :: (Fractional u, FromPtSize u) => DrawingR u+markHeightLessLineWidth :: (Fractional u, FromPtSize u) => CF u markHeightLessLineWidth =      (\h lw -> h - realToFrac lw) <$> markHeight <*> lineWidth @@ -154,13 +154,16 @@ -- Its common for the rectraction not to care about the angle or  -- the point and only care about the DrawingCtx. ---noRetract :: Num u => ThetaLocDrawingR u u-noRetract = rlift2 $ pure 0 +noRetract :: Num u => LocThetaCF u u+noRetract = wrap2 0    + -------------------------------------------------------------------------------- ++ -- | Tripoints takes the \*tip length\* is the mark height. -- -- This means that the 90deg tip has a tip width greater-than the@@ -168,236 +171,269 @@ -- does it). -- tripointsByAngle :: (Floating u, FromPtSize u)-                 => Radian ->  ThetaLocDrawingR u (Point2 u, Point2 u)-tripointsByAngle triang theta pt = -    (\h -> let (vupper,vlower) = triVecsByAngle h (0.5*triang) theta-           in  (pt .+^ vupper, pt .+^ vlower))-      <$> markHeight-+                 => Radian ->  LocThetaCF u (Point2 u, Point2 u)+tripointsByAngle triang = markHeight >>= \h -> +    raise2 $ \pt theta -> let (vup,vlo) = triVecsByAngle h (0.5*triang) theta+                          in  (pt .+^ vup, pt .+^ vlo)+      revtripointsByAngle :: (Floating u, FromPtSize u)                     => Radian -                    -> ThetaLocDrawingR u (Point2 u, Point2 u, Point2 u)-revtripointsByAngle triang theta pt = -    (\h -> let theta'          = circularModulo $ pi+theta -               (vupper,vlower) = triVecsByAngle h (0.5*triang) theta'-               back_tip        = pt .-^ avec theta h -           in (back_tip .+^ vupper, back_tip, back_tip .+^ vlower) )-      <$> markHeight+                    -> LocThetaCF u (Point2 u, Point2 u, Point2 u)+revtripointsByAngle triang = markHeight >>= \h -> +    raise2 $ \pt theta -> let theta'    = circularModulo $ pi+theta +                              (vup,vlo) = triVecsByAngle h (0.5*triang) theta'+                              back_tip  = pt .-^ avec theta h +                          in (back_tip .+^ vup, back_tip, back_tip .+^ vlo)  + tripointsByDist :: (Real u, Floating u, FromPtSize u)-                => ThetaLocDrawingR u (Point2 u, Point2 u)-tripointsByDist theta pt = -    (\h -> let (vup,vlo) = triVecsByDist h (0.5*h) theta-           in  (pt .+^ vup, pt .+^ vlo))-      <$> markHeight+                => LocThetaCF u (Point2 u, Point2 u)+tripointsByDist = markHeight >>= \h ->+    raise2 $ \pt theta -> let (vup,vlo) = triVecsByDist h (0.5*h) theta+                          in  (pt .+^ vup, pt .+^ vlo)+     revtripointsByDist :: (Real u, Floating u, FromPtSize u)-                   => ThetaLocDrawingR u (Point2 u, Point2 u, Point2 u)-revtripointsByDist theta pt = -    (\h -> let theta'    = circularModulo $ pi+theta -               (vup,vlo) = triVecsByDist h (0.5*h) theta'-               back_tip  = pt .-^ avec theta h -           in  (back_tip .+^ vup, back_tip, back_tip .+^ vlo))-      <$> markHeight+                   => LocThetaCF u (Point2 u, Point2 u, Point2 u)+revtripointsByDist = markHeight >>= \h -> +    raise2 $ \pt theta -> let theta'    = circularModulo $ pi+theta +                              (vup,vlo) = triVecsByDist h (0.5*h) theta'+                              back_tip  = pt .-^ avec theta h +                          in  (back_tip .+^ vup, back_tip, back_tip .+^ vlo)   ++bindLocTip :: LocThetaCF u a -> (a -> LocGraphic u) -> LocThetaGraphic u+bindLocTip df da = bind2 df (\a -> static2 $ da a) ++bindLocThetaTip :: LocThetaCF u a -> (a -> LocThetaGraphic u) +                -> LocThetaGraphic u+bindLocThetaTip = bind2 +++ -- width = xchar_height -- filled with stroke colour!  triTLG :: (Floating u, Real u, FromPtSize u)-       => Radian -> (PrimPath u -> Graphic u) -> ThetaLocGraphic u-triTLG triang drawF = tripointsByAngle triang `bindR2` \(u,v) -> -    rlift1 $ \pt -> localize bothStrokeColour $ drawF $ vertexPath [pt,u,v]--+       => Radian -> (PrimPath u -> Graphic u) -> LocThetaGraphic u+triTLG triang drawF = localize bothStrokeColour $ +    bindLocTip (tripointsByAngle triang) +               (\(u,v) -> promote1 $ \pt -> drawF $ vertexPath [pt,u,v])    tri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u tri90 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeight) (triTLG (pi/2) filledPath)+    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/2) filledPath)   tri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u tri60 = Arrowhead $-    intoThetaLocImage (rlift2 markHeight) (triTLG (pi/3) filledPath)+    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/3) filledPath)   tri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u tri45 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeight) (triTLG (pi/4) filledPath)+    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/4) filledPath)  otri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u otri90 = Arrowhead $-    intoThetaLocImage (rlift2 markHeight) (triTLG (pi/2) closedStroke)+    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/2) closedStroke)  otri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u otri60 = Arrowhead $   -    intoThetaLocImage (rlift2 markHeight) (triTLG (pi/3) closedStroke)+    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/3) closedStroke)  otri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u otri45 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeight) (triTLG (pi/4) closedStroke)-+    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/4) closedStroke)   -- width = xchar_height -- filled with stroke colour!  revtriTLG :: (Floating u, Real u, FromPtSize u)-          => Radian -> (PrimPath u -> Graphic u) -> ThetaLocGraphic u-revtriTLG triang drawF = revtripointsByAngle triang `bindR2` \(u,pt,v) -> -    rlift2 $ localize bothStrokeColour $ drawF $ vertexPath [u,pt,v]+          => Radian -> (PrimPath u -> Graphic u) -> LocThetaGraphic u+revtriTLG triang drawF = localize bothStrokeColour $ +    bindLocTip (revtripointsByAngle triang) +               (\(u,pt,v) -> static1 $ drawF $ vertexPath [u,pt,v])  + revtri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u revtri90 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeightLessLineWidth) +    intoLocThetaImage (dblstatic markHeightLessLineWidth)                        (revtriTLG (pi/2) filledPath)  revtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u revtri60 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeightLessLineWidth) +    intoLocThetaImage (dblstatic markHeightLessLineWidth)                        (revtriTLG (pi/3) filledPath)  revtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u revtri45 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeightLessLineWidth) +    intoLocThetaImage (dblstatic markHeightLessLineWidth)                        (revtriTLG (pi/4) filledPath)   orevtri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u orevtri90 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeightLessLineWidth) +    intoLocThetaImage (dblstatic markHeightLessLineWidth)                        (revtriTLG (pi/2) closedStroke)  orevtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u orevtri60 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeightLessLineWidth) +    intoLocThetaImage (dblstatic markHeightLessLineWidth)                        (revtriTLG (pi/3) closedStroke)  orevtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u orevtri45 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeightLessLineWidth) +    intoLocThetaImage (dblstatic markHeightLessLineWidth)                        (revtriTLG (pi/4) closedStroke)  -barbTLG :: (Floating u, Real u, FromPtSize u) => Radian -> ThetaLocGraphic u-barbTLG ang = tripointsByAngle ang `bindR2` \(u,v) -> -    rlift1 $ \pt -> openStroke $ vertexPath [u,pt,v] +barbTLG :: (Floating u, Real u, FromPtSize u) => Radian -> LocThetaGraphic u+barbTLG ang =  +    bindLocTip (tripointsByAngle ang) +               (\(u,v) -> promote1 $ \pt -> openStroke $ vertexPath [u,pt,v]) ++ barb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-barb90 = Arrowhead $ intoThetaLocImage noRetract (barbTLG (pi/2))+barb90 = Arrowhead $ intoLocThetaImage noRetract (barbTLG (pi/2))  barb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-barb60 = Arrowhead $ intoThetaLocImage noRetract (barbTLG (pi/3))+barb60 = Arrowhead $ intoLocThetaImage noRetract (barbTLG (pi/3))   barb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-barb45 = Arrowhead $ intoThetaLocImage noRetract (barbTLG (pi/4))+barb45 = Arrowhead $ intoLocThetaImage noRetract (barbTLG (pi/4))   -revbarbTLG :: (Floating u, Real u, FromPtSize u) => Radian -> ThetaLocGraphic u-revbarbTLG ang = revtripointsByAngle ang `bindR2` \(u,pt,v) -> -    rlift2 $ openStroke $ vertexPath [u,pt,v]+revbarbTLG :: (Floating u, Real u, FromPtSize u) => Radian -> LocThetaGraphic u+revbarbTLG ang = +    bindLocTip (revtripointsByAngle ang)+               (\(u,pt,v) -> static1 $ openStroke $ vertexPath [u,pt,v])  revbarb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u revbarb90 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeight) (revbarbTLG (pi/2))+    intoLocThetaImage (dblstatic markHeight) (revbarbTLG (pi/2))   revbarb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u revbarb60 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeight) (revbarbTLG (pi/3))+    intoLocThetaImage (dblstatic markHeight) (revbarbTLG (pi/3))  revbarb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u revbarb45 = Arrowhead $ -    intoThetaLocImage (rlift2 markHeight) (revbarbTLG (pi/4))+    intoLocThetaImage (dblstatic markHeight) (revbarbTLG (pi/4))  -perpTLG :: (Floating u, FromPtSize u) => ThetaLocGraphic u-perpTLG = bindAskR2 markHalfHeight $ \hh ->-    \theta pt -> let p0 = displacePerpendicular   hh  theta pt-                     p1 = displacePerpendicular (-hh) theta pt  -                 in straightLineBetween p0 p1+perpTLG :: (Floating u, FromPtSize u) => LocThetaGraphic u+perpTLG = bindLocThetaTip (dblstatic markHalfHeight) fn+  where+    fn hh = promote2 $ \pt theta -> openStroke $ perpPath hh pt theta  +perpPath :: Floating u => u -> Point2 u -> Radian -> PrimPath u+perpPath hh ctr theta = primPath p0 [lineTo p1]+  where+    p0 = displacePerpendicular   hh  theta ctr+    p1 = displacePerpendicular (-hh) theta ctr +             ++ perp :: (Floating u, FromPtSize u) => Arrowhead u-perp = Arrowhead $ intoThetaLocImage noRetract perpTLG+perp = Arrowhead $ intoLocThetaImage noRetract perpTLG   -bracketTLG :: (Floating u, FromPtSize u) => ThetaLocGraphic u-bracketTLG = bindAskR2 markHalfHeight $ \hh -> -    \theta pt -> let p1 = displacePerpendicular   hh  theta pt-                     p0 = displaceParallel      (-hh) theta p1-                     p2 = displacePerpendicular (-hh) theta pt-                     p3 = displaceParallel      (-hh) theta p2-                 in openStroke $ vertexPath [p0,p1,p2,p3]+bracketTLG :: (Floating u, FromPtSize u) => LocThetaGraphic u+bracketTLG = bindLocThetaTip (dblstatic markHalfHeight) fn+  where+    fn hh = promote2 $ \pt theta -> openStroke $ bracketPath hh pt theta  +bracketPath :: Floating u => u -> Point2 u -> Radian -> PrimPath u+bracketPath hh pt theta = vertexPath [p0,p1,p2,p3]+  where+    p1 = displacePerpendicular   hh  theta pt+    p0 = displaceParallel      (-hh) theta p1+    p2 = displacePerpendicular (-hh) theta pt+    p3 = displaceParallel      (-hh) theta p2+          + bracket :: (Floating u, FromPtSize u) => Arrowhead u-bracket = Arrowhead $ intoThetaLocImage noRetract bracketTLG+bracket = Arrowhead $ intoLocThetaImage noRetract bracketTLG + diskTLG :: (Floating u, FromPtSize u) -        => (u -> Point2 u -> Graphic u) -> ThetaLocGraphic u-diskTLG drawF = bindAskR2 markHalfHeight $ \hh ->-    \theta pt -> let ctr = pt .-^ avec theta hh-                 in drawF hh ctr+        => (u -> Point2 u -> Graphic u) -> LocThetaGraphic u+diskTLG drawF = bindLocThetaTip (dblstatic markHalfHeight) fn +  where+   fn hh = promote2 $ \pt theta -> let ctr = pt .-^ avec theta hh+                                   in drawF hh ctr + diskTip :: (Floating u, FromPtSize u) => Arrowhead u-diskTip = Arrowhead $ intoThetaLocImage (rlift2 markHeight) (diskTLG drawF)+diskTip = Arrowhead $ intoLocThetaImage (dblstatic markHeight) (diskTLG drawF)   where-    drawF r pt = localize bothStrokeColour $ filledDisk r pt+    drawF r pt = localize bothStrokeColour $ filledDisk r `at` pt   odiskTip :: (Floating u, FromPtSize u) => Arrowhead u-odiskTip = Arrowhead $ intoThetaLocImage (rlift2 markHeight) (diskTLG drawF)+odiskTip = Arrowhead $ intoLocThetaImage (dblstatic markHeight) (diskTLG drawF)   where-    drawF r pt = strokedDisk r pt+    drawF r pt = strokedDisk r `at` pt   squareTLG :: (Floating u, FromPtSize u) -        => (PrimPath u -> Graphic u) -> ThetaLocGraphic u-squareTLG drawF = bindAskR2 markHalfHeight $ \hh ->-    \theta pt -> let p0 = displacePerpendicular     hh  theta pt-                     p3 = displacePerpendicular   (-hh) theta pt-                     p1 = displaceParallel      (-2*hh) theta p0-                     p2 = displaceParallel      (-2*hh) theta p3-                 in drawF $ vertexPath [p0,p1,p2,p3]+        => (PrimPath u -> Graphic u) -> LocThetaGraphic u+squareTLG drawF = bindLocThetaTip (dblstatic markHalfHeight) fn+  where+    fn hh = promote2 $ \pt theta -> +              let p0 = displacePerpendicular     hh  theta pt+                  p3 = displacePerpendicular   (-hh) theta pt+                  p1 = displaceParallel      (-2*hh) theta p0+                  p2 = displaceParallel      (-2*hh) theta p3+              in drawF $ vertexPath [p0,p1,p2,p3] + squareTip :: (Floating u, FromPtSize u) => Arrowhead u-squareTip = Arrowhead $ intoThetaLocImage (rlift2 markHeight) (squareTLG drawF)+squareTip = Arrowhead $ intoLocThetaImage (dblstatic markHeight) (squareTLG drawF)   where     drawF = localize bothStrokeColour . filledPath   osquareTip :: (Floating u, FromPtSize u) => Arrowhead u osquareTip = Arrowhead $ -    intoThetaLocImage (rlift2 markHeight) (squareTLG closedStroke)+    intoLocThetaImage (dblstatic markHeight) (squareTLG closedStroke)   diamondTLG :: (Floating u, FromPtSize u) -           => (PrimPath u -> Graphic u) -> ThetaLocGraphic u-diamondTLG drawF = bindAskR2 markHalfHeight $ \hh ->-    \theta pt -> let ctr = displaceParallel       (-2*hh) theta pt-                     p1  = displacePerpendicular     hh   theta ctr-                     p3  = displacePerpendicular   (-hh)  theta ctr-                     p2  = displaceParallel       (-4*hh) theta pt-                 in drawF $ vertexPath [pt,p1,p2,p3]+           => (PrimPath u -> Graphic u) -> LocThetaGraphic u+diamondTLG drawF = bindLocThetaTip (dblstatic markHalfHeight) fn+  where+    fn hh = promote2 $ \pt theta -> +              let ctr = displaceParallel       (-2*hh) theta pt+                  p1  = displacePerpendicular     hh   theta ctr+                  p3  = displacePerpendicular   (-hh)  theta ctr+                  p2  = displaceParallel       (-4*hh) theta pt+              in drawF $ vertexPath [pt,p1,p2,p3]   diamondTip :: (Floating u, FromPtSize u) => Arrowhead u diamondTip = Arrowhead $ -    intoThetaLocImage (rlift2 $ fmap (2*) markHeightLessLineWidth) +    intoLocThetaImage (dblstatic $ fmap (2*) markHeightLessLineWidth)                        (diamondTLG drawF)   where     drawF = localize bothStrokeColour . filledPath@@ -405,40 +441,45 @@  odiamondTip :: (Floating u, FromPtSize u) => Arrowhead u odiamondTip = Arrowhead $ -    intoThetaLocImage (rlift2 $ fmap (2*) markHeight) (diamondTLG closedStroke)+    intoLocThetaImage (dblstatic $ fmap (2*) markHeight) (diamondTLG closedStroke)  + -- Note - points flipped to get the second trapezium to  -- draw /underneath/. ---curveTLG :: (Real u, Floating u, FromPtSize u) => ThetaLocGraphic u-curveTLG theta pt = -    markHalfHeight           >>= \hh        -> -    tripointsByDist theta pt >>= \(tup,tlo) -> -    let (u1,u2) = trapezoidFromBasePoints (0.25*hh) 0.5 pt tup-        (l2,l1) = trapezoidFromBasePoints (0.25*hh) 0.5 tlo pt -        tpath   = curve tup u2 u1 pt `append` curve pt l1 l2 tlo-    in localize (joinRound . capRound) -                (openStroke $ toPrimPath $ tpath)+curveTLG :: (Real u, Floating u, FromPtSize u) => LocThetaGraphic u+curveTLG = bindLocThetaTip (dblstatic markHalfHeight) fn+  where+    fn hh = promote2 $ \pt theta -> +              unLocTheta pt theta tripointsByDist >>= \(tup,tlo) -> +              let (u1,u2) = trapezoidFromBasePoints (0.25*hh) 0.5 pt tup+                  (l2,l1) = trapezoidFromBasePoints (0.25*hh) 0.5 tlo pt +                  tpath   = curve tup u2 u1 pt `append` curve pt l1 l2 tlo+              in localize (joinRound . capRound) +                          (openStroke $ toPrimPath $ tpath) + curveTip :: (Real u, Floating u, FromPtSize u) => Arrowhead u curveTip = Arrowhead $ -    intoThetaLocImage (rlift2 $ fmap realToFrac lineWidth) curveTLG+    intoLocThetaImage (dblstatic $ fmap realToFrac lineWidth) curveTLG   -- Note - points flipped to get the second trapezium to  -- draw /underneath/. ---revcurveTLG :: (Real u, Floating u, FromPtSize u) => ThetaLocGraphic u-revcurveTLG theta pt = -    markHalfHeight              >>= \hh           -> -    revtripointsByDist theta pt >>= \(tup,p1,tlo) -> -    let (u1,u2) = trapezoidFromBasePoints (0.25*hh) 0.5 p1 tup-        (l2,l1) = trapezoidFromBasePoints (0.25*hh) 0.5 tlo p1-        tpath   = curve tup u2 u1 p1 `append` curve p1 l1 l2 tlo-    in localize (joinRound . capRound) -                (openStroke $ toPrimPath $ tpath)+revcurveTLG :: (Real u, Floating u, FromPtSize u) => LocThetaGraphic u+revcurveTLG = bindLocThetaTip (dblstatic markHalfHeight) fn +  where+   fn hh = promote2 $ \pt theta ->+             unLocTheta pt theta revtripointsByDist >>= \(tup,p1,tlo) -> +             let (u1,u2) = trapezoidFromBasePoints (0.25*hh) 0.5 p1 tup+                 (l2,l1) = trapezoidFromBasePoints (0.25*hh) 0.5 tlo p1+                 tpath   = curve tup u2 u1 p1 `append` curve p1 l1 l2 tlo+             in localize (joinRound . capRound) +                         (openStroke $ toPrimPath $ tpath)  revcurveTip :: (Real u, Floating u, FromPtSize u) => Arrowhead u revcurveTip = Arrowhead $ -    intoThetaLocImage (rlift2 markHeight) revcurveTLG+    intoLocThetaImage (dblstatic markHeight) revcurveTLG+
src/Wumpus/Basic/Dots/AnchorDots.hs view
@@ -54,17 +54,15 @@    ) where -import Wumpus.Basic.Anchors import Wumpus.Basic.Dots.Marks import Wumpus.Basic.Graphic-import Wumpus.Basic.Utils.Combinators+import Wumpus.Basic.Text.LRText import Wumpus.Basic.Utils.Intersection  import Wumpus.Core                              -- package: wumpus-core  import Data.AffineSpace                         -- package: vector-space -import Control.Applicative   -- An existential thing that supports anchors.@@ -139,9 +137,15 @@     fn theta =  maybe ctr id $ findIntersect ctr theta                               $ rectangleLines ctr hw hh +bboxRectAnchor  :: (Real u, Floating u) => BoundingBox u -> DotAnchor u+bboxRectAnchor (BBox bl@(P2 x1 y1) (P2 x2 y2)) =+   let hw = 0.5 * (x2 - x1)+       hh = 0.5 * (y2 - y1)+   in rectangleAnchor hw hh (bl .+^ vec hw hh)+ rectangleLDO :: (Real u, Floating u) -             => u -> u -> LocDrawingR u (DotAnchor u)-rectangleLDO w h pt = pure $ rectangleAnchor (w*0.5) (h*0.5) pt+             => u -> u -> LocDrawingInfo u (DotAnchor u)+rectangleLDO w h = promote1 $ \pt -> wrap $ rectangleAnchor (w*0.5) (h*0.5) pt   circleAnchor :: Floating u => u -> Point2 u -> DotAnchor u@@ -149,8 +153,9 @@                                  (\theta -> ctr .+^ (avec theta rad))                                  (radialCardinal rad ctr) -circleLDO :: (Floating u, FromPtSize u) => LocDrawingR u (DotAnchor u)-circleLDO pt = (\diam -> circleAnchor (diam * 0.5) pt) <$> markHeight +circleLDO :: (Floating u, FromPtSize u) => LocDrawingInfo u (DotAnchor u)+circleLDO = bind1 (static1 markHeight) $ \diam -> +    promote1 $ \pt -> wrap $ circleAnchor (diam * 0.5) pt   @@ -162,16 +167,23 @@  dotChar :: (Floating u, Real u, FromPtSize u)          => Char -> DotLocImage u-dotChar ch = bindAsk (monoTextDimensions [ch]) $  \(w,h) -> -    intoLocImage (rectangleLDO w h) (markChar ch)+dotChar ch = dotText [ch]  +-- | Note - dots now use font metrics...+-- dotText :: (Floating u, Real u, FromPtSize u)          => String -> DotLocImage u -dotText ss = bindAsk (monoTextDimensions ss) $ \(w,h) -> -    intoLocImage (rectangleLDO w h) (markText ss) +dotText ss = locImageMapL bboxRectAnchor (singleLineCC ss)  +-- Is this generally useful? ...+--+locImageMapL :: (a -> b) -> LocImage u a -> LocImage u b+locImageMapL f = postpro1 $ \(a,prim) -> (f a, prim)+++ dotHLine :: (Floating u, FromPtSize u) => DotLocImage u dotHLine = intoLocImage circleLDO markHLine @@ -202,7 +214,7 @@   dotSquare :: (Floating u, Real u, FromPtSize u) => DotLocImage u-dotSquare = bindAsk markHeight $ \ h ->+dotSquare = bind1 (static1 markHeight) $ \ h ->     intoLocImage (rectangleLDO h h) markSquare  
src/Wumpus/Basic/Dots/Marks.hs view
@@ -48,7 +48,7 @@   import Wumpus.Basic.Graphic-import Wumpus.Basic.Utils.Combinators+import Wumpus.Basic.Text.LRText  import Wumpus.Core                      -- package: wumpus-core @@ -81,7 +81,7 @@   shiftOrigin :: Num u => u -> u -> LocGraphic u -> LocGraphic u-shiftOrigin dx dy f = \pt -> f (displace dx dy pt)+shiftOrigin dx dy = prepro1 (displace dx dy)  markChar :: (Fractional u, Ord u, FromPtSize u) => Char -> LocGraphic u markChar ch = markText [ch]@@ -90,7 +90,7 @@   markText :: (Fractional u, Ord u, FromPtSize u) => String -> LocGraphic u-markText ss = centermonoTextline ss+markText ss = postpro1 (\(_,b) -> b) $ singleLineCC ss   @@ -103,15 +103,15 @@   markHLine :: (Fractional u, FromPtSize u) => LocGraphic u -markHLine = bindAsk markHeight $ \h -> axialLine (hvec h)+markHLine = bind1 (static1 markHeight) $ \h -> axialLine (hvec h)   markVLine :: (Fractional u, FromPtSize u) => LocGraphic u -markVLine = bindAsk markHeight $ \h -> axialLine (vvec h) +markVLine = bind1 (static1 markHeight) $ \h -> axialLine (vvec h)    markX :: (Fractional u, FromPtSize u) => LocGraphic u-markX = bindAsk markHeight $ \h -> +markX = bind1 (static1 markHeight) $ \h ->      let w = 0.75 * h in axialLine (vec w h) `oplus` axialLine (vec (-w) h)  @@ -121,7 +121,7 @@   markCross :: (Floating u, FromPtSize u) =>  LocGraphic u-markCross = bindAsk markHeight $ \h ->  +markCross = bind1 (static1 markHeight) $ \h ->       (axialLine $ avec ang h) `oplus` (axialLine $ avec (-ang) h)   where     ang = pi*0.25  @@ -129,23 +129,25 @@ -- needs horizontal pinch...  pathDiamond :: (Fractional u, FromPtSize u) -            => Point2 u -> DrawingR (PrimPath u)-pathDiamond pt = (\h -> let hh    = 0.66 * h; hw = 0.5 * h -                        in vertexPath [dvs hh, dve hw,dvn hh, dvw hw])-                   <$> markHeight-  where-    dvs hh = pt .+^ vvec (-hh)-    dve hw = pt .+^ hvec hw-    dvn hh = pt .+^ vvec hh-    dvw hw = pt .+^ hvec (-hw)+            => LocCF u (PrimPath u)+pathDiamond = bind1 (static1 markHeight) $ \h -> promote1 $ \pt ->+    let hh    = 0.66 * h; hw = 0.5 * h +        s     = pt .+^ vvec (-hh)+        e     = pt .+^ hvec hw+        n     = pt .+^ vvec hh+        w     = pt .+^ hvec (-hw)+    in pure $ vertexPath [s,e,n,w]  +-- closedStroke :: (a -> ctx -> prim) +-- pathDiamond  :: (ctx -> pt -> a)+-- ans          :: (ctx -> pt -> prim)  markDiamond :: (Fractional u, FromPtSize u) => LocGraphic u-markDiamond = pathDiamond `bindInto` closedStroke  +markDiamond = pathDiamond `bind1` (static1 . closedStroke)  markFDiamond :: (Fractional u, FromPtSize u) => LocGraphic u-markFDiamond = pathDiamond `bindInto` filledPath+markFDiamond = pathDiamond `bind1` (static1 . filledPath)   -- Note - the (const . fn) composition doesn\'t /tell/ much about@@ -156,43 +158,43 @@ --  markBDiamond :: (Fractional u, FromPtSize u) => LocGraphic u-markBDiamond = pathDiamond `bindInto` borderedPath+markBDiamond = pathDiamond `bind1` (static1 . borderedPath)   -- | Note disk is filled. -- markDisk :: (Fractional u, FromPtSize u) => LocGraphic u-markDisk = bindAsk markHalfHeight filledDisk +markDisk = bind1 (static1 markHalfHeight) filledDisk     markSquare :: (Fractional u, FromPtSize u) => LocGraphic u-markSquare = bindAsk markHeight $ \h -> +markSquare = bind1 (static1 markHeight) $ \h ->      let d = 0.5*(-h) in shiftOrigin d d $ strokedRectangle h h        markCircle :: (Fractional u, FromPtSize u) => LocGraphic u-markCircle = bindAsk markHalfHeight strokedDisk +markCircle = bind1 (static1 markHalfHeight) strokedDisk    markBCircle :: (Fractional u, FromPtSize u) => LocGraphic u-markBCircle = bindAsk markHalfHeight borderedDisk +markBCircle = bind1 (static1 markHalfHeight) borderedDisk     markPentagon :: (Floating u, FromPtSize u) => LocGraphic u-markPentagon = bindAsk markHeight $ \h ->-    closedStroke . vertexPath . polygonPoints 5 (0.5*h)+markPentagon = bind1 (static1 markHeight) $ \h ->+    promote1 $ \pt -> closedStroke $ vertexPath $ polygonPoints 5 (0.5*h) pt      markStar :: (Floating u, FromPtSize u) => LocGraphic u -markStar pt = markHeight >>= \h -> -              let ps = polygonPoints 5 (0.5*h) pt in step $ map fn ps+markStar = bind1 (static1 markHeight) $ \h -> +    promote1 $ \pt -> let ps = polygonPoints 5 (0.5*h) pt in step $ map (fn pt) ps   where-    fn p1       = openStroke $ path pt [lineTo p1] +    fn st p1    = openStroke $ primPath st [lineTo p1]      step (x:xs) = oconcat x xs     step _      = error "markStar - unreachable" @@ -200,7 +202,7 @@ -- Note - relies on the functional instance of OPlus  markAsterisk :: (Floating u, FromPtSize u) => LocGraphic u-markAsterisk = bindAsk markHeight $ \h -> +markAsterisk = bind1 (static1 markHeight) $ \h ->      lineF1 h `oplus` lineF2 h `oplus` lineF3 h   where     ang       = (pi*2) / 6
+ src/Wumpus/Basic/DrawingComposition.hs view
@@ -0,0 +1,458 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.DrawingComposition+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC+--+-- Composition operators for Drawings.+--+-- Note - some operations can produce empty drawings...+--+--------------------------------------------------------------------------------++module Wumpus.Basic.DrawingComposition+  (+  -- * Composition+    over +  , under++  , centric+  , nextToH+  , nextToV+  +  , atPoint +  , centeredAt++  , zconcat++  , hcat +  , vcat+++  , hspace+  , vspace+  , hsep+  , vsep+ +  -- * Compose with alignment+  , alignH+  , alignV+  , alignHSep+  , alignVSep+  , hcatA+  , vcatA+  , hsepA+  , vsepA+++  ) where++import Wumpus.Basic.Graphic++import Wumpus.Core                              -- package: wumpus-core++import Data.AdditiveGroup+import Data.AffineSpace++import Data.List ( foldl' )++++--------------------------------------------------------------------------------+-- Extract anchors++boundaryExtr :: (BoundingBox u -> a) -> Picture u -> a+boundaryExtr f = f . boundary++-- Operations on bounds++-- | The center of a picture.+--+boundaryCenter :: Fractional u => Picture u -> Point2 u+boundaryCenter = boundaryExtr center++++-- | Extract the mid point of the top edge.+--+boundaryN :: Fractional u => Picture u -> Point2 u+boundaryN = boundaryExtr north++-- | Extract the mid point of the bottom edge.+--+boundaryS :: Fractional u => Picture u -> Point2 u+boundaryS = boundaryExtr south++-- | Extract the mid point of the left edge.+--+boundaryE :: Fractional u => Picture u -> Point2 u+boundaryE = boundaryExtr east++-- | Extract the mid point of the right edge.+--+boundaryW :: Fractional u => Picture u -> Point2 u+boundaryW = boundaryExtr west+++-- | Extract the top-left corner.+--+boundaryNW :: Fractional u => Picture u -> Point2 u+boundaryNW = boundaryExtr northwest++-- | Extract the top-right corner.+--+boundaryNE :: Picture u -> Point2 u+boundaryNE = boundaryExtr ur_corner++-- | Extract the bottom-left corner.+--+boundarySW :: Picture u -> Point2 u+boundarySW = boundaryExtr ll_corner++-- | Extract the bottom-right corner.+--+boundarySE :: Fractional u => Picture u -> Point2 u+boundarySE = boundaryExtr southeast+++boundaryLeftEdge :: Picture u -> u+boundaryLeftEdge = boundaryExtr (point_x . ll_corner)++boundaryRightEdge :: Picture u -> u+boundaryRightEdge = boundaryExtr (point_x . ur_corner)++boundaryBottomEdge :: Picture u -> u+boundaryBottomEdge = boundaryExtr (point_y . ll_corner)+++boundaryTopEdge :: Picture u -> u+boundaryTopEdge = boundaryExtr (point_y . ur_corner)+++++  +-- Note - do not export the empty drawing. It is easier to +-- pretend it doesn't exist.+-- +empty_drawing :: (Real u, Floating u, FromPtSize u) => Drawing u+empty_drawing = drawTracing $ return ()++++--------------------------------------------------------------------------------+-- Composition operators++-- Note - the megaCombR operator is in some way an+-- /anti-combinator/. It seems easier to think about composing +-- drawings if we do work on the result Pictures directly rather +-- than build combinators to manipulate Drawings.+--+-- The idea of combining pre- and post- operating combinators+-- makes me worry about circular programs even though I know +-- lazy evaluation allows me to write them (in some cicumstances).+--+++-- Picture /mega-combiner/ - moves only the second argument aka the +-- right picture.+--+megaCombR :: (Num u, Ord u)+          => (Picture u -> a) -> (Picture u -> a) +          -> (a -> a -> Picture u -> Picture u) +          -> Drawing u -> Drawing u+          -> Drawing u+megaCombR qL qR trafoR = drawingConcat fn+  where+    fn pic1 pic2 = let a    = qL pic1+                       b    = qR pic2+                       p2   = trafoR a b pic2+                   in pic1 `picOver` p2+++++-- | > a `over` b+-- +-- Place \'drawing\' a over b. The idea of @over@ here is in +-- terms z-ordering, nither picture a or b are actually moved.+--+over    :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u+over    = drawingConcat picOver++++-- | > a `under` b+--+-- Similarly @under@ draws the first drawing behind +-- the second but move neither.+--+under :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u+under = flip over++++-- | Move in both the horizontal and vertical.+--+move :: (Num u, Ord u) => Vec2 u -> Drawing u -> Drawing u+move v = modifyDrawing (\p -> p `picMoveBy` v)+++++--------------------------------------------------------------------------------+-- Composition++infixr 5 `nextToV`+infixr 6 `nextToH`, `centric`+++++-- | Draw @a@, move @b@ so its center is at the same center as +-- @a@, @b@ is drawn over underneath in the zorder.+--+-- > a `centeric` b +--+--+centric :: (Fractional u, Ord u) => Drawing u -> Drawing u -> Drawing u+centric = megaCombR boundaryCenter boundaryCenter moveFun+  where+    moveFun p1 p2 pic =  let v = p1 .-. p2 in pic `picMoveBy` v++++-- | > a `nextToH` b+-- +-- Horizontal composition - move @b@, placing it to the right +-- of @a@.+-- +nextToH :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u+nextToH = megaCombR boundaryRightEdge boundaryLeftEdge moveFun+  where +    moveFun a b pic = pic `picMoveBy` hvec (a - b)++++-- | > a `nextToV` b+--+-- Vertical composition - move @b@, placing it below @a@.+--+nextToV :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u+nextToV = megaCombR boundaryBottomEdge boundaryTopEdge moveFun+  where +    moveFun a b drw = drw `picMoveBy` vvec (a - b)+++-- | Place the picture at the supplied point.+--+-- `atPoint` was previous the `at` operator.+-- +atPoint :: (Num u, Ord u) => Drawing u -> Point2 u  -> Drawing u+p `atPoint` (P2 x y) = move (V2 x y) p++++-- | Center the picture at the supplied point.+--+centeredAt :: (Fractional u, Ord u) => Drawing u -> Point2 u -> Drawing u+centeredAt d (P2 x y) = modifyDrawing fn d+  where+    fn p = let bb = boundary p+               dx = x - (boundaryWidth  bb * 0.5)+               dy = y - (boundaryHeight bb * 0.5)+           in p `picMoveBy` vec dx dy+++-- | Concatenate the list of drawings. +--+-- No pictures are moved. +--+zconcat :: (Real u, Floating u, FromPtSize u) => [Drawing u] -> Drawing u+zconcat []     = empty_drawing+zconcat (d:ds) = foldl' over d ds+++++-- | Concatenate the list pictures @xs@ horizontally.+-- +hcat :: (Real u, Floating u, FromPtSize u) => [Drawing u] -> Drawing u+hcat []     = empty_drawing+hcat (d:ds) = foldl' nextToH d ds+++-- | Concatenate the list of pictures @xs@ vertically.+--+vcat :: (Real u, Floating u, FromPtSize u) => [Drawing u] -> Drawing u+vcat []     = empty_drawing+vcat (d:ds) = foldl' nextToV d ds+++++--------------------------------------------------------------------------------+++++-- | > hspace n a b+--+-- Horizontal composition - move @b@, placing it to the right +-- of @a@ with a horizontal gap of @n@ separating the pictures.+--+hspace :: (Num u, Ord u) => u -> Drawing u -> Drawing u -> Drawing u+hspace n = megaCombR boundaryRightEdge boundaryLeftEdge moveFun+  where+    moveFun a b pic = pic `picMoveBy` hvec (n + a - b)++    ++++-- | > vspace n a b+--+-- Vertical composition - move @b@, placing it below @a@ with a+-- vertical gap of @n@ separating the pictures.+--+vspace :: (Num u, Ord u) => u -> Drawing u -> Drawing u -> Drawing u+vspace n = megaCombR boundaryBottomEdge boundaryTopEdge moveFun+  where +    moveFun a b pic = pic `picMoveBy`  vvec (a - b - n)++++-- | > hsep n xs+--+-- Concatenate the list of pictures @xs@ horizontally with +-- @hspace@ starting at @x@. The pictures are interspersed with +-- spaces of @n@ units.+--+hsep :: (Real u, Floating u, FromPtSize u) => u -> [Drawing u] -> Drawing u+hsep _ []     = empty_drawing+hsep n (d:ds) = foldl' (hspace n) d ds++++-- | > vsep n xs+--+-- Concatenate the list of pictures @xs@ vertically with +-- @vspace@ starting at @x@. The pictures are interspersed with +-- spaces of @n@ units.+--+vsep :: (Real u, Floating u, FromPtSize u) => u -> [Drawing u] -> Drawing u+vsep _ []     = empty_drawing+vsep n (d:ds) = foldl' (vspace n) d ds+++--------------------------------------------------------------------------------+-- Aligning pictures++alignMove :: (Num u, Ord u) => Point2 u -> Point2 u -> Picture u -> Picture u+alignMove p1 p2 pic = pic `picMoveBy` (p1 .-. p2)++++-- | > alignH align a b+-- +-- Horizontal composition - move @b@, placing it to the right +-- of @a@ and align it with the top, center or bottom of @a@.+-- +alignH :: (Fractional u, Ord u) +       =>  HAlign -> Drawing u -> Drawing u -> Drawing u+alignH HTop     = megaCombR boundaryNE    boundaryNW     alignMove+alignH HCenter  = megaCombR boundaryE    boundaryW     alignMove+alignH HBottom  = megaCombR boundarySE boundarySW  alignMove+++-- | > alignV align a b+-- +-- Vertical composition - move @b@, placing it below @a@ +-- and align it with the left, center or right of @a@.+-- +alignV :: (Fractional u, Ord u) +       => VAlign -> Drawing u -> Drawing u -> Drawing u+alignV VLeft    = megaCombR boundarySW  boundaryNW   alignMove+alignV VCenter  = megaCombR boundaryS   boundaryN    alignMove+alignV VRight   = megaCombR boundarySE boundaryNE  alignMove++++alignMove2 :: (Num u, Ord u) +           => Vec2 u ->  Point2 u -> Point2 u -> Picture u -> Picture u+alignMove2 v p1 p2 pic = pic `picMoveBy` (v ^+^ (p1 .-. p2))++++-- | > alignHSep align sep a b+-- +-- Spacing version of alignH - move @b@ to the right of @a@ +-- separated by @sep@ units, align @b@ according to @align@.+-- +alignHSep :: (Fractional u, Ord u) +          => HAlign -> u -> Drawing u -> Drawing u -> Drawing u+alignHSep HTop    dx = megaCombR boundaryNE boundaryNW (alignMove2 (hvec dx))+alignHSep HCenter dx = megaCombR boundaryE  boundaryW  (alignMove2 (hvec dx))+alignHSep HBottom dx = megaCombR boundarySE boundarySW (alignMove2 (hvec dx))+++-- | > alignVSep align sep a b+-- +-- Spacing version of alignV - move @b@ below @a@ +-- separated by @sep@ units, align @b@ according to @align@.+-- +alignVSep :: (Fractional u, Ord u) +          => VAlign -> u -> Drawing u -> Drawing u -> Drawing u+alignVSep VLeft   dy = megaCombR boundarySW boundaryNW (alignMove2 $ vvec (-dy)) +alignVSep VCenter dy = megaCombR boundaryS  boundaryN  (alignMove2 $ vvec (-dy)) +alignVSep VRight  dy = megaCombR boundarySE boundaryNE (alignMove2 $ vvec (-dy))+++-- | Variant of 'hcat' that aligns the pictures as well as+-- concatenating them.+--+hcatA :: (Real u, Floating u, FromPtSize u) +      => HAlign -> [Drawing u] -> Drawing u+hcatA _  []     = empty_drawing+hcatA ha (d:ds) = foldl' (alignH ha) d ds++++-- | Variant of 'vcat' that aligns the pictures as well as+-- concatenating them.+--+vcatA :: (Real u, Floating u, FromPtSize u) +      => VAlign -> [Drawing u] -> Drawing u+vcatA _  []     = empty_drawing+vcatA va (d:ds) = foldl' (alignV va) d ds+++-- | Variant of @hsep@ that aligns the pictures as well as+-- concatenating and spacing them.+--+hsepA :: (Real u, Floating u, FromPtSize u) +      => HAlign -> u -> [Drawing u] -> Drawing u+hsepA _  _ []     = empty_drawing+hsepA ha n (d:ds) = foldl' op d ds+  where +    a `op` b = alignHSep ha n a b +++-- | Variant of @vsep@ that aligns the pictures as well as+-- concatenating and spacing them.+--+vsepA :: (Real u, Floating u, FromPtSize u) +      => VAlign -> u -> [Drawing u] -> Drawing u+vsepA _  _ []     = empty_drawing+vsepA va n (d:ds) = foldl' op d ds+  where +    a `op` b = alignVSep va n a b +++
+ src/Wumpus/Basic/FontLoader/AfmLoader.hs view
@@ -0,0 +1,62 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.FontLoader.AfmLoader+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Font loader for the Adobe \"Core 14\" glyph metrics.+--+-- Use this loader if you have the Adode glyph metrics set+-- (AFM v4.1). This metrics set is avaiable from the Adobe +-- website.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.FontLoader.AfmLoader+  ( ++    module Wumpus.Basic.FontLoader.Base+  , module Wumpus.Basic.FontLoader.AfmV4Dot1Parser  ++  , loadAfmMetrics+  , afmV4Dot1Loader+  ++  +  ) where++import Wumpus.Basic.FontLoader.AfmV4Dot1Parser+import Wumpus.Basic.FontLoader.Base+import Wumpus.Basic.Graphic++import Wumpus.Core                              -- package: wumpus-core++++loadAfmMetrics :: FilePath -> [FontName] -> IO BaseGlyphMetrics+loadAfmMetrics font_dir_path ns = +    loadBaseGlyphMetrics (afmV4Dot1Loader font_dir_path) ns+++afmV4Dot1Loader :: FilePath -> FontLoader AfmUnit+afmV4Dot1Loader font_dir_path = +    FontLoader +      { unit_scale_fun      = afmUnitScale+      , path_to_font_dir    = font_dir_path+      , file_name_locator   = buildName+      , font_parser         = parseAfmV4Dot1File+      , post_process        = buildGlyphMetricsTable bbox (V2 600 0) 1000+      }+  where+    buildName :: FontName -> FilePath+    buildName font = font ++ ".afm"++    bbox           = BBox (P2 (-23) (-250)) (P2 715 805)++
+ src/Wumpus/Basic/FontLoader/AfmParserBase.hs view
@@ -0,0 +1,215 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.FontLoader.AfmParserBase+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Common parsers for AFM files.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.FontLoader.AfmParserBase+  ( ++    afmFileParser+  , runQuery+  , textQuery++  , getFontBBox+  , getEncodingScheme+  , getCapHeight+  +  , charBBox+  , metric+  , keyStringPair+  , versionNumber  +  , startCharMetrics++  , keyName+  , newlineOrEOF+  , name+  , name1+  , semi+  , uptoNewline+  , number+  , cint+  , hexInt+  , octInt++  , lexeme+  , symbol+  , integer+  , int+  , double++  ) where++import Wumpus.Basic.FontLoader.Base+import Wumpus.Basic.Utils.ParserCombinators+import qualified Wumpus.Basic.Utils.TokenParsers as P++import Wumpus.Core                              -- package: wumpus-core++import Control.Applicative++import Data.Char+import qualified Data.Map               as Map++++afmFileParser :: CharParser AfmGlyphMetrics -> CharParser AfmFile+afmFileParser pgm = do +    info <- (versionNumber    *> globalInfo) +    cms  <- (startCharMetrics *> many pgm)+    let mb_encoding = getEncodingScheme info+    let mb_cap      = getCapHeight      info+    let mb_bbox     = getFontBBox       info+    case mb_bbox of+      Nothing -> throwError "No FontBBox field in the AFM file."+      Just bb -> return $ AfmFile +                            { afm_encoding        = mb_encoding+                            , afm_font_bbox       = bb+                            , afm_cap_height      = mb_cap+                            , afm_glyph_metrics   = cms+                            }++globalInfo :: CharParser GlobalInfo+globalInfo = (foldr (\(k,v) a -> Map.insert k v a) Map.empty) +               <$> manyTill keyStringPair (peek startCharMetrics)+++ +runQuery :: String -> CharParser a -> GlobalInfo -> Maybe a+runQuery field_name p table = +    Map.lookup field_name table >>= extr . runParser p+  where+    extr (Okay a _) = Just a+    extr _          = Nothing++textQuery :: String -> GlobalInfo -> Maybe String+textQuery = Map.lookup+++-- | Strictly speaking a fontBBox is measured in integer units.+--+getFontBBox            :: GlobalInfo -> Maybe AfmBoundingBox+getFontBBox            = runQuery "FontBBox" fontBBox++getEncodingScheme      :: GlobalInfo -> Maybe String+getEncodingScheme      = textQuery "EncodingScheme"++getCapHeight           :: GlobalInfo -> Maybe AfmUnit+getCapHeight           = runQuery "CapHeight" number+++charBBox :: CharParser AfmBoundingBox+charBBox = symbol "B" *> fontBBox <* semi++fontBBox :: CharParser AfmBoundingBox+fontBBox = (\llx lly urx ury -> boundingBox (P2 llx lly) (P2 urx ury))+              <$> number <*> number <*> number <*> number++++metric :: String -> a -> CharParser a -> CharParser a+metric iden dfault p = option dfault go+  where+    go = symbol iden *> p <* semi++++keyStringPair :: CharParser (AfmKey,String)+keyStringPair = (,) <$> keyName <*> uptoNewline <* newlineOrEOF +             <?> "key-value line"++versionNumber :: CharParser String+versionNumber = +    symbol "StartFontMetrics" *> many1 (digit <|> char '.') <* newlineOrEOF+      <?> "StartFontMetrics"+++startCharMetrics :: CharParser Int+startCharMetrics = symbol "StartCharMetrics" *> int <* newlineOrEOF+                <?> "StartCharMetrics failed"++++--------------------------------------------------------------------------------+++keyName :: CharParser AfmKey+keyName = lexeme (many1 $ satisfy isAlphaNum) +++newlineOrEOF :: CharParser ()+newlineOrEOF = skipOne (lexeme newline) <|> eof+++uptoNewline :: CharParser String+uptoNewline = many1 (noneOf ['\n'])+++name :: CharParser String+name = lexeme $ many (noneOf ";\n")++name1 :: CharParser String+name1 = lexeme $ many (noneOf "; \t\n")++++semi :: CharParser Char+semi = lexeme $ char ';'+++++number :: CharParser AfmUnit+number = liftA realToFrac double+++cint :: CharParser Int+cint = hexInt <|> octInt <|> int+++hexInt :: CharParser Int+hexInt = lexeme $ between (char '<') (char '>') P.hexBase+++octInt :: CharParser Int+octInt = lexeme $ char '\\' *> P.octBase++++--------------------------------------------------------------------------------++-- no newline in whitespace+++lp :: P.LexemeParser+lp = P.commentLineLexemeParser "Comment" [' ', '\t']+++lexeme          :: CharParser a -> CharParser a+lexeme          = P.lexeme lp++symbol          :: String -> CharParser String+symbol          = lexeme . string++-- whiteSpace      :: CharParser ()+-- whiteSpace      = P.whiteSpace lp+++integer         :: CharParser Integer+integer         = lexeme P.integer++int             :: CharParser Int+int             = fromIntegral <$> integer++double          :: CharParser Double+double          = lexeme P.double
+ src/Wumpus/Basic/FontLoader/AfmV2Parser.hs view
@@ -0,0 +1,67 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.FontLoader.AfmV2+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- AFM file parser for Version 2.0.+--+-- Note - AFM Version 2.0 used by GhostScript and Version 3.0++-- have numerous differences. +-- +--------------------------------------------------------------------------------++module Wumpus.Basic.FontLoader.AfmV2Parser+  ( ++     parseAfmV2File+  +  ) where++import Wumpus.Basic.FontLoader.AfmParserBase+import Wumpus.Basic.FontLoader.Base+import Wumpus.Basic.Utils.ParserCombinators++import Wumpus.Core                              -- package: wumpus-core++import Control.Applicative+++++--------------------------------------------------------------------------------+-- parser++parseAfmV2File :: FilePath -> IO (Either ParseError AfmFile)+parseAfmV2File filepath = runParserEither p <$> readFile filepath+  where+    p = afmFileParser charMetricsV2+++charMetricsV2 :: CharParser AfmGlyphMetrics+charMetricsV2 = AfmGlyphMetrics <$>+        metric "C" (-1) cint+    <*> widthVector+    <*> metric "N" "" name1+    <*  charBBox+    <*  many (symbol "L" *> ligature_body <* semi)+    <*  newlineOrEOF+  where+    ligature_body = ((,) <$> name <*> name)+    +widthVector :: CharParser (Vec2 AfmUnit)+widthVector =  (symbol "WX" *> ((\w -> vec w 0) <$> number) <* semi)+           <|> (symbol "W"  *> (vec <$> number <*> number)  <* semi)+++--------------------------------------------------------------------------------++++
+ src/Wumpus/Basic/FontLoader/AfmV4Dot1Parser.hs view
@@ -0,0 +1,67 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.FontLoader.AfmV4Dot1Parser+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- AFM file parser for Version 4.1.+--+-- Adobe distributes font metrics for the /Core 14/ fonts as+-- AFM Version 4.1 files.  +--+--------------------------------------------------------------------------------++module Wumpus.Basic.FontLoader.AfmV4Dot1Parser+  ( +    +    parseAfmV4Dot1File+  +  ) where++import Wumpus.Basic.FontLoader.AfmParserBase+import Wumpus.Basic.FontLoader.Base+import Wumpus.Basic.Utils.ParserCombinators++import Wumpus.Core                              -- package: wumpus-core++import Control.Applicative+++parseAfmV4Dot1File :: FilePath -> IO (Either ParseError AfmFile)+parseAfmV4Dot1File filepath = runParserEither p <$> readFile filepath+  where+    p = afmFileParser charMetricsV4Dot1++++charMetricsV4Dot1 :: CharParser AfmGlyphMetrics+charMetricsV4Dot1 = AfmGlyphMetrics <$>+        characterCode+    <*> widthVector+    <*> metric "N" "" name1+    <*  charBBox+    <*  many (symbol "L" *> ligature_body <* semi)+    <*  newlineOrEOF+  where+    ligature_body = ((,) <$> name <*> name)+++-- Note - there are many variants for width vectors in in 4.1.+-- Wumpus needs some thought about what to do for them, it also+-- needs some facility to tell how successful the parse has been.+    +widthVector :: CharParser (Vec2 AfmUnit)+widthVector =  (symbol "WX" *> ((\w -> vec w 0) <$> number) <* semi)+           <|> (symbol "W"  *> (vec <$> number <*> number)  <* semi)+++-- V4.1 allows C int or CH \<hex\>+--+characterCode :: CharParser Int+characterCode = metric "CH" (-1) hexInt <|> metric "C" (-1) cint  
+ src/Wumpus/Basic/FontLoader/Base.hs view
@@ -0,0 +1,222 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE ExistentialQuantification  #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.FontLoader.AfmV2+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- AFM file parser.+--+-- Note - AFM Version 2.0 used by GhostScript and Version 3.0++-- have numerous differences. +-- +--------------------------------------------------------------------------------++module Wumpus.Basic.FontLoader.Base+  (++  -- * Afm Unit+    AfmUnit+  , afmValue+  , afmUnitScale+  +  -- * Glyph metrics++  , PSCharCode+  , PSEncodingScheme+  , AfmBoundingBox++  , AfmKey+  , GlobalInfo+  , AfmFile(..)+  , AfmGlyphMetrics(..)++  -- * Font loading+  , FontLoadErr+  , FontLoadResult+  , FontLoader(..)+  , loadFont++  , BaseGlyphMetrics+  , loadBaseGlyphMetrics++  , buildGlyphMetricsTable++  ) where++import Wumpus.Basic.Graphic+++import Wumpus.Core                              -- package: wumpus-core+import Wumpus.Core.Text.GlyphIndices++import Data.Foldable ( foldrM )+import qualified Data.IntMap            as IntMap+import qualified Data.Map as Map+import Data.Maybe++import System.Directory+import System.FilePath++++-- | Wrapped Double representing 1\/1000 of the scale factor+-- (Point size) of a font. AFM files encode all measurements +-- as these units. +-- +newtype AfmUnit = AfmUnit { getAfmUnit :: Double } +  deriving (Eq,Ord,Num,Floating,Fractional,Real,RealFrac,RealFloat)++instance Show AfmUnit where+  showsPrec p d = showsPrec p (getAfmUnit d)+++-- | Compute the size of a measurement in Afm units scaled by the+-- point size of the font.+--+afmValue :: FromPtSize u => AfmUnit -> PtSize -> u+afmValue u pt = fromPtSize $ (realToFrac $ getAfmUnit u) * (pt / 1000)++afmUnitScale :: AfmUnit -> PtSize +afmUnitScale u = (realToFrac $ getAfmUnit u / 1000)+++--------------------------------------------------------------------------------++-- | Afm files index glyphs by /PostScript character code/. This +-- is not the same as Unicode, ASCII...+--+-- It is expected to be determined by @EncodingScheme@ in the+-- Global Font Information Section.+--+type PSCharCode         = Int++type PSEncodingScheme   = String++type AfmBoundingBox     = BoundingBox AfmUnit++type AfmKey         = String+type GlobalInfo     = Map.Map AfmKey String++++-- | Wumpus needs a very small subset of AFM files, common to both+-- version 2.0 and version 4.1.+--+-- Note - Bounding Box is mandatory for AFM versions 3.0 and 4.1+-- +-- Cap Height is optional in AFM versions 3.0 and 4.1. As Wumpus +-- uses cap height in calculations, glyph metrics must be build +-- with an arbitrary value if it is not present.+--+-- Encoding Scheme is optional in AFM files.+--+data AfmFile = AfmFile +      { afm_encoding        :: Maybe String+      , afm_font_bbox       :: AfmBoundingBox+      , afm_cap_height      :: Maybe AfmUnit+      , afm_glyph_metrics   :: [AfmGlyphMetrics]+      }+  deriving (Show) ++-- Note BBox is a required field for version 4.1.+++data AfmGlyphMetrics = AfmGlyphMetrics+      { afm_char_code       :: !PSCharCode+      , afm_width_vector    :: !(Vec2 AfmUnit)+      , afm_char_name       :: !String+      }+  deriving (Eq,Show)++++-- Maybe the CharMetricsTable should be scaled to Wumpus units as +-- the last part of the parsing process...+--+-- No it shouldn\'t - this would disallow drawings in centimeters+-- ++type FontLoadErr        = String+type FontLoadResult cu  = Either FontLoadErr (GlyphMetricsTable cu)++data FontLoader cu = forall interim. FontLoader +      { unit_scale_fun      :: cu -> PtSize+      , path_to_font_dir    :: FilePath+      , file_name_locator   :: FontName -> FilePath+      , font_parser         :: FilePath -> IO (Either String interim)+      , post_process        :: interim -> GlyphMetricsTable cu+      }+++loadFont :: FontLoader cu -> FontName -> IO (FontLoadResult cu)+loadFont loader font_name = +    locateStep loader font_name >>= \ans -> case ans of+      Nothing        -> return $ Left $ "Cannot find font " ++ font_name+      Just full_path -> parseStep loader full_path++locateStep :: FontLoader cu -> FontName -> IO (Maybe FilePath)+locateStep loader font_name = +    doesFileExist full_path >>= \check -> +    if check then return $ Just full_path+             else return $ Nothing+  where+    full_path = normalise $ path_to_font_dir loader +                             </> file_name_locator loader font_name+++parseStep :: FontLoader cu -> FilePath -> IO (FontLoadResult cu)+parseStep (FontLoader _ _ _ parser post) valid_path = +    fmap (either Left (Right . post)) $ parser valid_path++--------------------------------------------------------------------------------++++loadBaseGlyphMetrics :: FontLoader u -> [FontName] -> IO BaseGlyphMetrics+loadBaseGlyphMetrics loader xs = foldrM fn Map.empty xs+  where+    fn font_name acc = loadFont loader font_name >>= \ans -> +                       case ans of+                         Left err -> reportBaseError font_name err >> return acc+                         Right table -> return $ +                             Map.insert font_name (tableToGM table) acc++    tableToGM = buildMetrics (unit_scale_fun loader)  +    +reportBaseError :: FontName -> FontLoadErr -> IO ()+reportBaseError font_name err = do +    putStrLn $ "The font " ++ font_name ++ " failed to load, with the error:"+    putStrLn $ err+++++buildGlyphMetricsTable :: BoundingBox AfmUnit +                       -> Vec2 AfmUnit +                       -> AfmUnit+                       -> AfmFile +                       -> GlyphMetricsTable AfmUnit+buildGlyphMetricsTable bbox dflt_vec dflt_cap_height afm = +    GlyphMetricsTable +      { glyph_bounding_box    = bbox+      , glyph_default_adv_vec = dflt_vec+      , glyph_adv_vecs        = makeAdvVecs $ afm_glyph_metrics afm+      , glyph_cap_height      = fromMaybe dflt_cap_height $ afm_cap_height afm+      }  +++makeAdvVecs :: [AfmGlyphMetrics] -> IntMap.IntMap (Vec2 AfmUnit)+makeAdvVecs  = foldr fn IntMap.empty+  where+    fn (AfmGlyphMetrics _ v ss) table = case Map.lookup ss ps_glyph_indices of+        Nothing -> table+        Just i  -> IntMap.insert i v table+
+ src/Wumpus/Basic/FontLoader/GSFontMap.hs view
@@ -0,0 +1,87 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.FontLoader.GSFontMap+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- GhostScript Font map.+--+-- GhostScript aliases the /Core 14/ PostScript fonts to fonts+-- it can freely distribute. This module provides aliases to +-- Wumpus so the font loader can find the equivalent GhostScript+-- files to the Core 14 set.+--+-- The data in this file matches GhostScript 8.63. Other versions+-- of GhostScript may need different aliases.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.FontLoader.GSFontMap+  (+   +    ghostscript_version  ++  , GSFontMap+  , gsMetricsFile+  , gsFontAlias+  , core14_alias_table++  ) where+++import Data.Map ( Map )+import qualified Data.Map as Map+++-- | GhostScript version that the aliases were derived from.+-- +ghostscript_version :: String+ghostscript_version = "gs8.54"++type GSFontMap = Map String (String, FilePath)+++-- | Get the @.afm@ metrics file.+--+-- Note this return only the file name and not the path to it.+-- The full path must be resolved in client code.+--+gsMetricsFile :: GSFontMap -> String -> Maybe FilePath+gsMetricsFile mp name = fmap snd $ Map.lookup name mp++-- | Get the GhostScript font name alias.+--+gsFontAlias :: GSFontMap -> String -> Maybe String+gsFontAlias mp name = fmap fst $ Map.lookup name mp++-- | Map from PostScript font name to the corresponding +-- GhostScript name and file.+--+core14_alias_table :: GSFontMap+core14_alias_table = Map.fromList $ +  [ ("Courier",                 ("NimbusMonL-Regu",         "n022003l.afm"))+  , ("Courier-Oblique",         ("NimbusMonL-ReguObli",     "n022023l.afm"))+  , ("Courier-Bold",            ("NimbusMonL-Bold",         "n022004l.afm"))+  , ("Courier-BoldOblique",     ("NimbusMonL-BoldObli",     "n022024l.afm"))+  +  , ("Helvetica",               ("NimbusSanL-Regu",         "n019003l.afm"))+  , ("Helvetica-Oblique",       ("NimbusSanL-ReguItal",     "n019023l.afm"))+  , ("Helvetica-Bold",          ("NimbusSanL-Bold",         "n019004l.afm"))+  , ("Helvetica-BoldOblique",   ("NimbusSanL-BoldItal",     "n019024l.afm"))++  , ("Times-Roman",             ("NimbusRomNo9L-Regu",      "n021003l.afm"))+  , ("Times-Italic",            ("NimbusRomNo9L-ReguItal",  "n021023l.afm"))+  , ("Times-Bold",              ("NimbusRomNo9L-Medi",      "n021004l.afm"))+  , ("Times-BoldItalic",        ("NimbusRomNo9L-MediItal",  "n021024l.afm"))++  , ("Symbol",                  ("StandardSymL",            "s050000l.afm"))++  , ("ZapfDingbats",            ("Dingbats",                "d050000l.afm"))+  ]+
+ src/Wumpus/Basic/FontLoader/GSLoader.hs view
@@ -0,0 +1,63 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.FontLoader.GSLoader+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Font loader for GhostScript glyph metrics.+--+-- Use this loader if you have GhostScript installed and you want +-- to use the (AFM v2.0) metrics that are distributed with +-- GhostScript.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.FontLoader.GSLoader+  ( ++    module Wumpus.Basic.FontLoader.Base+  , module Wumpus.Basic.FontLoader.AfmV2Parser  ++  , loadGSMetrics+  , gsFontLoader+  ++  +  ) where++import Wumpus.Basic.FontLoader.AfmV2Parser+import Wumpus.Basic.FontLoader.Base+import Wumpus.Basic.FontLoader.GSFontMap+import Wumpus.Basic.Graphic++import Wumpus.Core                              -- package: wumpus-core++import Data.Maybe+++loadGSMetrics :: FilePath -> [FontName] -> IO BaseGlyphMetrics+loadGSMetrics font_dir_path ns = +    loadBaseGlyphMetrics (gsFontLoader font_dir_path) ns+    ++gsFontLoader :: FilePath -> FontLoader AfmUnit+gsFontLoader font_dir_path = FontLoader+      { unit_scale_fun      = afmUnitScale+      , path_to_font_dir    = font_dir_path+      , file_name_locator   = buildName+      , font_parser         = parseAfmV2File+      , post_process        = buildGlyphMetricsTable bbox (V2 600 0) 1000+      }+  where+    buildName :: FontName -> FilePath+    buildName font = fromMaybe font $ gsMetricsFile core14_alias_table font++    bbox           = BBox (P2 (-23) (-250)) (P2 715 805)++
src/Wumpus/Basic/Graphic.hs view
@@ -17,17 +17,27 @@  module Wumpus.Basic.Graphic   (-    module Wumpus.Basic.Graphic.Base+    module Wumpus.Basic.Graphic.Anchors+  , module Wumpus.Basic.Graphic.Base+  , module Wumpus.Basic.Graphic.ContextFunction   , module Wumpus.Basic.Graphic.Drawing   , module Wumpus.Basic.Graphic.DrawingContext-  , module Wumpus.Basic.Graphic.PrimGraphic+  , module Wumpus.Basic.Graphic.GlyphMetrics+  , module Wumpus.Basic.Graphic.GraphicOperations+  , module Wumpus.Basic.Graphic.GraphicTypes   , module Wumpus.Basic.Graphic.Query   , module Wumpus.Basic.Graphic.ScalingContext+  , module Wumpus.Basic.Graphic.TraceDrawing   ) where  import Wumpus.Basic.Graphic.Base+import Wumpus.Basic.Graphic.Anchors+import Wumpus.Basic.Graphic.ContextFunction import Wumpus.Basic.Graphic.Drawing import Wumpus.Basic.Graphic.DrawingContext-import Wumpus.Basic.Graphic.PrimGraphic+import Wumpus.Basic.Graphic.GlyphMetrics+import Wumpus.Basic.Graphic.GraphicOperations+import Wumpus.Basic.Graphic.GraphicTypes import Wumpus.Basic.Graphic.Query import Wumpus.Basic.Graphic.ScalingContext+import Wumpus.Basic.Graphic.TraceDrawing
+ src/Wumpus/Basic/Graphic/Anchors.hs view
@@ -0,0 +1,158 @@+{-# LANGUAGE TypeFamilies               #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Graphic.Anchors+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Anchor points on shapes.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Graphic.Anchors+  ( ++  -- * Anchors+    CenterAnchor(..)+  , CardinalAnchor(..)+  , CardinalAnchor2(..)+  , RadialAnchor(..)++  -- * Extended anchor points+  , northwards+  , southwards+  , eastwards+  , westwards+  , northeastwards+  , southeastwards+  , southwestwards+  , northwestwards++  , radialConnectorPoints++  ) where++import Wumpus.Core                      -- package: wumpus-core++import Data.AffineSpace                 -- package: vector-space++class CenterAnchor t where+  center :: DUnit t ~ u => t -> Point2 u++-- | Note - in TikZ cardinal anchors are not necessarily at the+-- equivalent radial position, for instance reactangle north-east+-- is the top-right corner whether or not this is incident at +-- 45deg.+--+class CardinalAnchor t where+  north :: DUnit t ~ u => t -> Point2 u+  south :: DUnit t ~ u => t -> Point2 u+  east  :: DUnit t ~ u => t -> Point2 u+  west  :: DUnit t ~ u => t -> Point2 u++class CardinalAnchor2 t where+  northeast :: DUnit t ~ u => t -> Point2 u+  southeast :: DUnit t ~ u => t -> Point2 u+  southwest :: DUnit t ~ u => t -> Point2 u+  northwest :: DUnit t ~ u => t -> Point2 u+++-- | Anchor on a border that can be identified with and angle.+--+class RadialAnchor t where+  radialAnchor :: DUnit t ~ u => Radian -> t -> Point2 u+++extendPtDist :: (Real u, Floating u) => u -> Point2 u -> Point2 u -> Point2 u+extendPtDist d p1 p2 = let v   = pvec p1 p2+                           ang = direction v+                           len = vlength v+                       in p1 .+^ avec ang (len+d)++++northwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor t+              , u ~ DUnit t ) +           => u -> t -> Point2 u+northwards u a = extendPtDist u (center a) (north a)+++southwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor t+              , u ~ DUnit t ) +           => u -> t -> Point2 u+southwards u a = extendPtDist u (center a) (south a)++eastwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor t+             , u ~ DUnit t ) +          => u -> t -> Point2 u+eastwards u a = extendPtDist u (center a) (east a)++westwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor t+             , u ~ DUnit t ) +          => u -> t -> Point2 u+westwards u a = extendPtDist u (center a) (west a)+++northeastwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor2 t+                  , u ~ DUnit t ) +               => u -> t -> Point2 u+northeastwards u a = extendPtDist u (center a) (northeast a)+++southeastwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor2 t+                  , u ~ DUnit t ) +               => u -> t -> Point2 u+southeastwards u a = extendPtDist u (center a) (southeast a)++southwestwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor2 t+                  , u ~ DUnit t ) +               => u -> t -> Point2 u+southwestwards u a = extendPtDist u (center a) (southwest a)++northwestwards :: ( Real u, Floating u, CenterAnchor t, CardinalAnchor2 t+                  , u ~ DUnit t ) +               => u -> t -> Point2 u+northwestwards u a = extendPtDist u (center a) (northwest a)+++--------------------------------------------------------------------------------++radialConnectorPoints :: ( Real u, Floating u+                         , CenterAnchor t1, RadialAnchor t1+                         , CenterAnchor t2, RadialAnchor t2+                         , u ~ DUnit t1, DUnit t1 ~ DUnit t2 ) +                      => t1 -> t2 -> (Point2 u, Point2 u) +radialConnectorPoints a b = (radialAnchor theta a, radialAnchor (theta+pi) b)+  where+    theta = direction $ pvec (center a) (center b)+    ++--------------------------------------------------------------------------------+-- Instances ++instance Fractional u => CenterAnchor (BoundingBox u) where+  center (BBox (P2 xl ylo) (P2 xr yhi)) = P2 x y +     where+       x = xl+0.5*(xr-xl)+       y = ylo+0.5*(yhi-ylo)+       ++instance Fractional u => CardinalAnchor (BoundingBox u) where+  north (BBox (P2 xl _  ) (P2 xr yhi)) = P2 (xl+0.5*(xr-xl)) yhi+  south (BBox (P2 xl ylo) (P2 xr _  )) = P2 (xl+0.5*(xr-xl)) ylo+  east  (BBox (P2 _  ylo) (P2 xr yhi)) = P2 xr (ylo+0.5*(yhi-ylo))+  west  (BBox (P2 xl ylo) (P2 _  yhi)) = P2 xl (ylo+0.5*(yhi-ylo))+++instance Fractional u => CardinalAnchor2 (BoundingBox u) where+  northeast (BBox _ ur)                 = ur+  southeast (BBox (P2 _ ylo) (P2 xr _)) = P2 xr ylo+  southwest (BBox ll _)                 = ll+  northwest (BBox (P2 xl _) (P2 _ yhi)) = P2 xl yhi +
src/Wumpus/Basic/Graphic/Base.hs view
@@ -13,32 +13,12 @@ -- Stability   :  highly unstable -- Portability :  GHC  ----- Base types for Drawing Objects, Graphics / Images (a Graphic --- that also returns an answer), etc.+-- The common base drawing objects in Wumpus-Basic - a +-- semigroup class, monad classes (TraceM analogue to Writer,+-- DrawingCtxM analogue to Reader), a wrapped Hughes list of+-- primitives.  -- --- Base classes for monadic drawing. ----- Notes on prefix and suffix names:------ Function types suffixed @F@ are functions from same-to-same, e.g.:------ > type Point2F u = Point2 u -> Point2 u------ Functional types subfixed @R@ are functions from some static --- context to the answer type (c.f the ReaderMonad), e.g.:------ > newtype DrawingR a = DrawingR { getDrawingR :: DrawingContext -> a }------ The suffix @M@ is used for classes defining monadic actions.------ The prefix @Loc@ indicates a functional type --- /from Point2 to something.../--- --- The prefix @ThetaLoc@ indicates a functional type --- /from Direction (radian) then Point to something.../------ \*\* WARNING \*\* - some names are expected to change.--- --------------------------------------------------------------------------------  module Wumpus.Basic.Graphic.Base@@ -50,6 +30,10 @@   , anterior       , superior +  -- * Alignment.+  , HAlign(..)+  , VAlign(..)  +   -- * Drawing monads.   , MonUnit   , TraceM(..)@@ -64,75 +48,14 @@   , hprimToList   , singleH -  , Point2F-  , DPoint2F--  , DrawingR-  , LocDrawingR-  , DLocDrawingR--  , DrawingTrafoF --  , runDrawingR-   , PrimGraphic   , getPrimGraphic-  , wrapPrim-+  , primGraphic   , collectH -  , Graphic-  , DGraphic-  , GraphicTrafoF--  , superiorGraphic-  , anteriorGraphic  --  , runGraphic-  , xlinkGraphic--  , LocGraphic-  , DLocGraphic--  , Image-  , DImage--  , ImageTrafoF-  , intoImageTrafo-  , imageTrafoDrawing-  , imageTrafoGraphic--  , LocImage-  , DLocImage--  , runImage-  , intoImage-  , intoLocImage-  , xlinkImage--  , ConnectorDrawingR-  , DConnectorDrawingR-  , ConnectorGraphic-  , DConnectorGraphic-  , ConnectorImage-  , DConnectorImage--  , intoConnectorImage--  , ThetaLocDrawingR-  , DThetaLocDrawingR-  , ThetaLocGraphic-  , DThetaLocGraphic-  , ThetaLocImage-  , DThetaLocImage--  , intoThetaLocImage--   ) where  import Wumpus.Basic.Graphic.DrawingContext-import Wumpus.Basic.Utils.Combinators import Wumpus.Basic.Utils.HList  import Wumpus.Core                      -- package: wumpus-core@@ -165,12 +88,8 @@   --- Note - this produces tall-skinny trees in Wumpus-core.--- This does not impact on the generated PostScript but it is --- (probably) inefficient for traversals in Wumpus.------ There is scope to modify the Primitive type in Wumpus-Core --- (make Group indepenent of XLink) so wider trees can be made.+instance Ord u => OPlus (BoundingBox u) where+  oplus = boundaryUnion  instance OPlus (Primitive u) where   a `oplus` b = primGroup [a,b]@@ -187,6 +106,21 @@   --------------------------------------------------------------------------------++-- Alignment++-- | Horizontal alignment - align to the top, center or bottom.+data HAlign = HTop | HCenter | HBottom+  deriving (Enum,Eq,Ord,Show)++-- | Vertical alignment - align to the left, center or bottom.+data VAlign = VLeft | VCenter | VRight+  deriving (Enum,Eq,Ord,Show)+++++-------------------------------------------------------------------------------- -- Monadic drawing  -- | DUnit is always for fully saturated type constructors, so @@ -214,9 +148,6 @@   --- -- | A monad that supplies points, e.g. a turtle monad.  -- class Monad m => PointSupplyM (m :: * -> *) where@@ -224,7 +155,7 @@    ----------------------------------------------------------------------------------- Base types+-- Lists of primitives...  -- | Graphics objects, even simple ones (line, arrow, dot) might  -- need more than one primitive (path or text label) for their@@ -257,86 +188,6 @@ singleH :: Primitive u -> HPrim u singleH = HPrim . wrapH  --- | Point transformation function.----type Point2F u = Point2 u -> Point2 u--type DPoint2F = Point2F Double----------------------------------------------------------------------------------------- | Drawings in Wumpus-Basic have an implicit /graphics state/ --- the @DrawingContext@, the most primitive building block is --- a function from the DrawingContext to some polymorphic answer.--- --- This functional type is represented concretely as @DrawingR@.--- --- > DrawingR :: DrawingContext -> a ----newtype DrawingR a = DrawingR { getDrawingR :: DrawingContext -> a }---instance Functor DrawingR where-  fmap f ma = DrawingR $ \ctx -> f $ getDrawingR ma ctx ---instance OPlus a => OPlus (DrawingR a)  where-  fa `oplus` fb = DrawingR $ \ctx -> -                      getDrawingR fa ctx `oplus` getDrawingR fb ctx---- The monoid instance seems sensible...----instance Monoid a => Monoid (DrawingR a) where -  mempty          = DrawingR $ \_   -> mempty-  fa `mappend` fb = DrawingR $ \ctx -> -                      getDrawingR fa ctx `mappend` getDrawingR fb ctx---- Applicative--instance Applicative DrawingR where-  pure a    = DrawingR $ \_   -> a-  mf <*> ma = DrawingR $ \ctx -> let f = getDrawingR mf ctx-                                     a = getDrawingR ma ctx-                                 in f a---- Monad --instance Monad DrawingR where-  return a  = DrawingR $ \_   -> a-  ma >>= k  = DrawingR $ \ctx -> let a = getDrawingR ma ctx-                                 in (getDrawingR . k) a ctx ---instance DrawingCtxM DrawingR where-  askDC           = DrawingR $ \ctx -> ctx-  localize upd df = DrawingR $ \ctx -> getDrawingR df (upd ctx)-  ---- | Run a /Drawing Function/ with the supplied /Drawing Context/.----runDrawingR :: DrawingContext -> DrawingR a -> a-runDrawingR ctx df = getDrawingR df ctx-----type LocDrawingR u a = Point2 u -> DrawingR a --type DLocDrawingR a = LocDrawingR Double a---type DrawingTrafoF a = DrawingR a -> DrawingR a------- Affine instances - cannot be manufactured. There is no --- DUnit @u@ to get a handle on.-------------------------------------------------------------------------------------- -- As of version 0.36.0, Wumpus-Core supports grouping primitives -- together (a common operation in vector drawing editors).  --@@ -373,204 +224,9 @@   translate dx dy = PrimGraphic . translate dx dy . getPrimGraphic  -wrapPrim :: Primitive u -> PrimGraphic u -wrapPrim = PrimGraphic+primGraphic :: Primitive u -> PrimGraphic u +primGraphic = PrimGraphic  collectH :: PrimGraphic u -> HPrim u collectH = singleH . getPrimGraphic-------------------------------------------------------------------------------------- Simple drawing - produce a primitive, access the DrawingContext--- if required.--type Graphic u = DrawingR (PrimGraphic u)--type DGraphic = Graphic Double--type instance DUnit (Graphic u) = u---runGraphic :: DrawingContext -> Graphic u -> PrimGraphic u-runGraphic ctx gf = (getDrawingR gf) ctx---xlinkGraphic :: XLink -> Graphic u -> Graphic u-xlinkGraphic xlink gf = DrawingR $ \ctx -> -    let a = runGraphic ctx gf -    in PrimGraphic $ xlinkGroup xlink [getPrimGraphic a]----- Affine instances--instance (Real u, Floating u) => Rotate (Graphic u) where-  rotate ang = liftA (rotate ang) ---instance (Real u, Floating u) => RotateAbout (Graphic u) where-  rotateAbout ang pt = liftA (rotateAbout ang pt)---instance Num u => Scale (Graphic u) where-  scale sx sy = liftA (scale sx sy)---instance Num u => Translate (Graphic u) where-  translate dx dy = liftA (translate dx dy)-----type GraphicTrafoF u = Graphic u -> Graphic u--anteriorGraphic :: Graphic u -> GraphicTrafoF u-anteriorGraphic = anterior--superiorGraphic :: Graphic u -> GraphicTrafoF u-superiorGraphic = superior------------------------------------------------------------------------------------------ | 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 = Point2 u -> Graphic u--type DLocGraphic = LocGraphic Double------------------------------------------------------------------------------------------ | 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 = DrawingR (a, PrimGraphic u)--type DImage a = Image Double a--type instance DUnit (Image u a) = u----runImage :: DrawingContext -> Image u a -> (a, PrimGraphic u)-runImage ctx img = (getDrawingR img) ctx---intoImage :: DrawingR a -> Graphic u -> Image u a-intoImage f g = forkA f g----- Affine instances--instance (Real u, Floating u, Rotate a, DUnit a ~ u) => -    Rotate (Image u a) where-  rotate ang = liftA (prod (rotate ang) (rotate ang))---instance (Real u, Floating u, RotateAbout a, DUnit a ~ u) => -    RotateAbout (Image u a) where-  rotateAbout ang pt = liftA (prod (rotateAbout ang pt) (rotateAbout ang pt))---instance (Num u, Scale a, DUnit a ~ u) => Scale (Image u a) where-  scale sx sy = liftA (prod (scale sx sy) (scale sx sy))---instance (Num u, Translate a, DUnit a ~ u) => Translate (Image u a) where-  translate dx dy = liftA (prod (translate dx dy) (translate dx dy))----type ImageTrafoF u a = Image u a -> Image u a-----intoImageTrafo :: DrawingTrafoF a -> GraphicTrafoF u -> ImageTrafoF u a-intoImageTrafo df gf img = img >>= \(a,prim) -> -    intoImage (df $ pure a) (gf $ pure prim)--imageTrafoDrawing :: DrawingTrafoF a -> ImageTrafoF u a-imageTrafoDrawing df = intoImageTrafo df id--imageTrafoGraphic :: GraphicTrafoF u -> ImageTrafoF u a-imageTrafoGraphic gf = intoImageTrafo id gf----type LocImage u a = Point2 u -> Image u a--type DLocImage a = LocImage Double a--intoLocImage :: LocDrawingR u a -> LocGraphic u -> LocImage u a-intoLocImage f g pt = forkA (f pt) (g pt)---xlinkImage :: XLink -> Image u a -> Image u a-xlinkImage xlink img = DrawingR $ \ctx -> -    let (a,pg) = runImage ctx img -    in (a, PrimGraphic $ xlinkGroup xlink [getPrimGraphic pg])---------------------------------------------------------------------------------------type ConnectorDrawingR u a = Point2 u -> Point2 u -> DrawingR a--type DConnectorDrawingR a = ConnectorDrawingR Double a---- | ConnectorGraphic is a connector drawn between two points --- contructing a Graphic.----type ConnectorGraphic u = Point2 u -> Point2 u -> Graphic u--type DConnectorGraphic = ConnectorGraphic Double---- | 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 = Point2 u -> Point2 u -> Image u a--type DConnectorImage a = ConnectorImage Double a---intoConnectorImage :: ConnectorDrawingR u a -                   -> ConnectorGraphic u -                   -> ConnectorImage u a-intoConnectorImage f g p1 p2 = forkA (f p1 p2) (g p1 p2)---type ThetaLocDrawingR u a = Radian -> LocDrawingR u a --type DThetaLocDrawingR a = ThetaLocDrawingR Double a---- | A function from /Radian -\> Point -\> Graphic/...----type ThetaLocGraphic u = Radian -> LocGraphic u--type DThetaLocGraphic = ThetaLocGraphic Double--type ThetaLocImage u a = Radian -> LocImage u a--type DThetaLocImage a = ThetaLocImage Double a ---intoThetaLocImage :: ThetaLocDrawingR u a -                  -> ThetaLocGraphic u -                  -> ThetaLocImage u a-intoThetaLocImage f g theta pt = forkA (f theta pt) (g theta pt) - 
+ src/Wumpus/Basic/Graphic/ContextFunction.hs view
@@ -0,0 +1,718 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Graphic.ContextFunction+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- The primary drawing type and base combinators to manipulate it. +--+--------------------------------------------------------------------------------++module Wumpus.Basic.Graphic.ContextFunction+  (++    CF++  , LocCF+  , LocThetaCF+  , ConnectorCF+  , DLocCF+  , DLocThetaCF+  , DConnectorCF++++  -- * Run functions+  , runCF++  -- * Extractors+  , drawingCtx+  , queryCtx+  , locCtx+  , locPoint+  , locThetaCtx+  , locThetaPoint+  , locThetaAng+  , connCtx+  , connStart+  , connEnd++  -- * Reducers+  , unLoc+  , unTheta+  , unLocTheta+  , unConnector++  , unCF1+  , unCF2++  -- * Combinators+  , wrap+  , wrap1+  , wrap2++  , promote1+  , promote2++  , raise+  , raise1+  , raise2++  , static1 +  , static2+  , dblstatic++  , bind+  , bind1+  , bind2+++  , situ1+  , situ2++  , apply+  , apply1+  , apply2++  -- * Pre-transformers+  , prepro1+  , prepro2+  , prepro2a+  , prepro2b++  -- * Post-transformers+  , postpro+  , postpro1+  , postpro2++  -- * Post-combiners+  , postcomb+  , postcomb1+  , postcomb2++  , accumulate1+  , accumulate2+++  ) where++-- import Wumpus.Basic.Graphic.Anchors+import Wumpus.Basic.Graphic.Base+import Wumpus.Basic.Graphic.DrawingContext++import Wumpus.Core                      -- package: wumpus-core+++import Control.Applicative+import Data.Monoid+++--------------------------------------------------------------------------------+--++-- | Most drawing operations in Wumpus-Basic have an implicit +-- /graphics state/ the @DrawingContext@, so the most primitive +-- building block is a function from the DrawingContext to some +-- polymorphic answer.+-- +-- This functional type is represented concretely as the initials +-- @CF@ for /contextual function/.+-- +-- > CF :: DrawingContext -> a +--+newtype CF a = CF { getCF :: DrawingContext -> a }+++type LocCF          u a = CF (Point2 u -> a)++type LocThetaCF     u a = LocCF u (Radian -> a)++type ConnectorCF    u a = LocCF u (Point2 u -> a)++++type DLocCF a           = LocCF       Double a+type DLocThetaCF a      = LocThetaCF  Double a+type DConnectorCF a     = ConnectorCF Double a++++--------------------------------------------------------------------------------+-- Drawing instances++instance Functor CF where+  fmap f ma = CF $ \ctx -> f $ getCF ma ctx +++instance OPlus a => OPlus (CF a)  where+  fa `oplus` fb = CF $ \ctx -> getCF fa ctx `oplus` getCF fb ctx++-- The monoid instance seems sensible...+--+instance Monoid a => Monoid (CF a) where +  mempty          = CF $ \_   -> mempty+  fa `mappend` fb = CF $ \ctx -> getCF fa ctx `mappend` getCF fb ctx++-- Applicative++instance Applicative CF where+  pure a    = CF $ \_   -> a+  mf <*> ma = CF $ \ctx -> let f = getCF mf ctx+                               a = getCF ma ctx+                           in f a+-- Monad ++instance Monad CF where+  return a  = CF $ \_   -> a+  ma >>= k  = CF $ \ctx -> let a = getCF ma ctx in (getCF . k) a ctx +++instance DrawingCtxM CF where+  askDC           = CF $ \ctx -> ctx+  localize upd df = CF $ \ctx -> getCF df (upd ctx)+  ++++--------------------------------------------------------------------------------+-- Run functions++++-- | Run a /CF/ (context function) with the supplied /DrawingContext/.+--+runCF :: DrawingContext -> CF a -> a+runCF ctx df = getCF df ctx+++--------------------------------------------------------------------------------+-- extractors ++-- | Extract the drawing context from a CtxFun.+--+-- > (ctx -> ctx)+-- +drawingCtx      :: CF DrawingContext+drawingCtx      = CF $ \ctx -> ctx++-- | Apply the projection function to the drawing context.+--+-- > (ctx -> a) -> (ctx -> a)+--+queryCtx        :: (DrawingContext -> a) -> CF a+queryCtx f      = CF $ \ctx -> f ctx+++-- | Extract the drawing context from a LocCF.+--+-- > (ctx -> pt -> ctx)+--+locCtx          :: LocCF u DrawingContext+locCtx          = CF $ \ctx _  -> ctx++-- | Extract the /start/ point from a LocCF.+--+-- > (ctx -> pt -> pt)+--+locPoint        :: LocCF u (Point2 u)+locPoint        = CF $ \_ pt -> pt+++-- | Extract the drawing context from a LocThetaCF.+--+-- > (ctx -> pt -> ang -> ctx)+--+locThetaCtx     :: LocThetaCF u DrawingContext+locThetaCtx     = CF $ \ctx _ _ -> ctx+++-- | Extract the /start/ point from a LocThetaCF.+--+-- > (ctx -> pt -> ang -> pt)+--+locThetaPoint   :: LocThetaCF u (Point2 u)+locThetaPoint   = CF $ \_ pt _ -> pt++-- | Extract the angle from a LocThetaCF.+--+-- > (ctx -> pt -> ang -> ang)+--+locThetaAng     :: LocThetaCF u Radian+locThetaAng     = CF $ \_ _ ang -> ang++-- | Extract the drawing context from a ConnectorCF.+--+-- > (ctx -> pt1 -> pt2 -> ctx)+--+connCtx         :: ConnectorCF u DrawingContext+connCtx         = CF $ \ctx _ _ -> ctx++-- | Extract the start point from a ConnectorCF.+--+-- > (ctx -> pt1 -> pt2 -> pt1)+--+connStart       :: ConnectorCF u (Point2 u) +connStart       = CF $ \_ pt _ -> pt++-- | Extract the end point from a ConnectorCF.+--+-- > (ctx -> pt1 -> pt2 -> pt2)+--+connEnd         :: ConnectorCF u (Point2 u) +connEnd         = CF $ \_ _ pt -> pt+++--------------------------------------------------------------------------------+-- /Reducers/++-- | This is unCF1 at a specific type.+--+unLoc :: Point2 u -> LocCF u a -> CF a+unLoc pt mf = CF $ \ctx -> getCF mf ctx pt++unTheta :: Radian -> LocThetaCF u a -> LocCF u a+unTheta theta mf = CF $ \ctx pt -> getCF mf ctx pt theta++unLocTheta :: Point2 u -> Radian -> LocThetaCF u a -> CF a+unLocTheta pt theta mf = CF $ \ctx -> getCF mf ctx pt theta++unConnector :: Point2 u -> Point2 u -> ConnectorCF u a -> CF a+unConnector p0 p1 mf = CF $ \ctx -> getCF mf ctx p0 p1+++unCF1 :: r1 -> CF (r1 -> a) -> CF a+unCF1 a mf = CF $ \ctx -> getCF mf ctx a++unCF2 :: r1 -> r2 ->  CF (r1 -> r2 -> a) -> CF a+unCF2 a b mf = CF $ \ctx -> getCF mf ctx a b+++++--------------------------------------------------------------------------------+-- Combinators++-- | Lift a pure value into a Context functional. The +-- DrawingContext is ignored.+--+-- > ans -> (ctx -> ans)+--+-- Without any other arguments, this is the same as the 'raise' +-- combinator for raising into the Context functional. However, +-- the /arity family/ of @wrap@ combinators is different.+--+wrap :: a -> CF a+wrap = pure+++-- | Lift a pure value into a Context functional, ignoring both +-- the DrawingContext and the /static/ argument, e.g. this would+-- ingnore start point for a @LocDrawing@).+--+-- > ans -> (ctx -> r1 -> ans)+--+wrap1 :: a -> CF (r1 -> a)+wrap1 = pure . pure++-- | Lift a pure value into a Context functional, ignoring both +-- the DrawingContext and the two /static/ arguments, e.g. this +-- would ignore the start point and angle for a @LocThetaDrawing@.+--+-- > ans -> (ctx -> r1 -> r2 -> ans)+--+wrap2 :: a -> CF (r1 -> r2 -> a)+wrap2 = pure . pure . pure++   ++-- | Promote a Context functional with one argument /outside/+-- the functional so that the the argument is /inside/ the +-- Context functional.+--+-- The type signature is probably more illustrative of the +-- operation than this description:+--+-- > (r1 -> ctx -> ans) -> (ctx -> r1 -> ans)+--+-- This is essentially the @cardinal@ combinator - @flip@+-- in Haskell.+--+promote1 :: (r1 -> CF ans) -> CF (r1 -> ans)+promote1 f = CF $ \ctx a -> getCF (f a) ctx+++-- | Promote a Context functional with two arguments /outside/+-- the functional so that the two arguments are /inside/ the +-- Context functional.+--+-- The type signature is probably more illustrative of the +-- operation than this description:+--+-- > (r1 -> r2 -> ctx -> ans) -> (ctx -> r1 -> r2 -> ans)+--+promote2 :: (r1 -> r2 -> CF ans) -> CF (r1 -> r2 -> ans)+promote2 df = CF $ \ctx a b -> getCF (df a b) ctx+++-- | Lift a value into a Context functional.+--+-- > ans -> (ctx -> ans)+--+-- Essentially this is the @kestrel@ combinator - @const@ in +-- Haskell, though due to newtype wrapping it is @pure@ from the+-- Applicative class.+--+raise :: a -> CF a+raise = pure+++-- | Lift a one argument function into a Context functional.+--+-- This is Applicative\'s 'pure' with a specialized type +-- signature. +--+raise1 :: (r1 -> ans) -> CF (r1 -> ans) +raise1 = pure++-- | Lift a two argument function into a Context functional.+--+-- This is Applicative\'s 'pure' with a specialized type +-- signature.+--+raise2 :: (r1 -> r2 -> ans) -> CF (r1 -> r2 -> ans) +raise2 = pure+++-- | Extend the arity of a /Context functional/, the original +-- function is oblivious to the added argument.+--+-- Typically this combinator is used to take a @Graphic@ to a+-- @LocGraphic@ ingoring the start point (figuratively a @Graphic@ +-- is not /coordinate free/). +--+-- > (ctx -> ans) -> (ctx -> r1 -> ans)+--+-- This was called the J-combinator by Joy, Rayward-Smith and+-- Burton (ref. /Compling Functional Languages/ by Antoni +-- Diller), however it is not the J combinator commonly in the +-- Literature. +--+static1 :: CF ans -> CF (r1 -> ans)+static1 df = CF $ \ctx _ -> getCF df ctx+++-- | Extend the arity of a /Context functional/, the original +-- function is oblivious to the added argument.+--+-- Typically this combinator is used to take a @LocGraphic@ to a+-- @LocThetaGraphic@ ingoring the angle of direction.+--+-- > (ctx -> r1 -> ans) -> (ctx -> r1 -> r2 -> ans)+--+-- This was called the J-Prime combinator by Joy, Rayward-Smith +-- and Burton (ref. /Compling Functional Languages/ by Antoni +-- Diller). +--+static2 :: CF (r1 -> ans) -> CF (r1 -> r2 -> ans)+static2 df = CF $ \ctx a _ -> getCF df ctx a+++-- | Complementary combinator to static2. +--+-- This combinator raises a function two levels rather than one.+--+-- > (ctx -> ans) -> (ctx -> r1 -> r2 -> ans)+--+dblstatic :: CF ans -> CF (r1 -> r2 -> ans)+dblstatic df = CF $ \ctx _ _ -> getCF df ctx+++infixl 1 `bind`, `bind1`, `bind2`+++-- | Supply the output from the first function to the second +-- function.+--+-- This is just monadic bind - specialized to the CF functional +-- type.+--+-- > (ctx -> a) -> (a -> ctx -> ans) -> (ctx -> ans)+-- +bind :: CF a -> (a -> CF ans) -> CF ans+bind df dk = CF $ \ctx -> let z = getCF df ctx in getCF (dk z) ctx+++-- | Supply the output from the first function to the second +-- function, /sharing/ the drawing context and the static +-- argument @r1@.+--+-- > (ctx -> r1 -> a) -> (a -> ctx -> -> r1 -> ans) -> (ctx -> r1 -> ans)+-- +bind1 :: CF (r1 -> a) -> (a -> CF (r1 -> ans)) -> CF (r1 -> ans)+bind1 df dk = CF $ \ctx a -> let z = getCF df ctx a in getCF (dk z) ctx a++-- | Supply the output from the first function to the second +-- function, /sharing/ the DrawingContext and the two static +-- arguments @r1@ and @r2@.+--+-- > (ctx -> r1 -> r2 -> a) -> (a -> ctx -> -> r1 -> r2 -> ans) -> (ctx -> r1 -> r2 -> ans)+-- +bind2 :: CF (r1 -> r2 -> a) -> (a -> CF (r1 -> r2 -> ans)) +      -> CF (r1 -> r2 -> ans)+bind2 df dk = CF $ \ctx a b -> +    let z = getCF df ctx a b in getCF (dk z) ctx a b+++-- idstar  :: (r1 -> r2 -> ans) -> r1 -> r2 -> ans++-- | Supply the arguments to an arity 1 Context functional so it +-- can be /situated/. Typically this is supplying the start point +-- to a @LocGraphic@ or @LocImage@.+--+-- > (ctx -> r1 -> ans) -> r1 -> (ctx -> ans)+--+-- This is equivalent to the @id**@ combinator.+--+situ1 :: CF (r1 -> ans) -> r1 -> CF ans+situ1 df a = CF $ \ctx -> getCF df ctx a++++-- | Supply the arguments to an arity 2 Conterxt functional so +-- it can be /situated/. Typically this is supplying the start +-- point and angle to a @LocThetaGraphic@ or @LocThetaImage@.+--+-- > (ctx -> r1 -> r2 -> ans) -> r1 -> r2 -> (ctx -> ans)+--+situ2 :: CF (r1 -> r2 -> ans) -> r1 -> r2 -> CF ans+situ2 df a b = CF $ \ctx -> getCF df ctx a b+++-- | Apply the the functional produced by the first argument to+-- the value produced by the second.+--+-- > (ctx -> a -> ans) -> (ctx -> a) -> (ctx -> ans) +--+apply :: CF (a -> ans) -> CF a -> CF ans+apply df da = CF $ \ctx -> getCF df ctx (getCF da ctx)+++-- | Apply the the functional produced by the first argument to+-- the value produced by the second /sharing/ the context of the +-- first functional argument @r1@ (usually a Point2) as well as +-- the DrawingContext.+--+-- > (ctx -> r1 -> a -> ans) -> (ctx -> r1 -> a) -> (ctx -> r1 -> ans) +--+apply1 :: CF (r1 -> a -> ans) -> CF (r1 -> a) -> CF (r1 -> ans)+apply1 df da = CF $ \ctx a -> getCF df ctx a (getCF da ctx a)+++-- | Apply the the functional produced by the first argument to+-- the value produced by the second /sharing/ the context of the +-- two functional arguments @r1@ and @r2@ as well as the +-- DrawingContext.+--+-- > (ctx -> r1 -> r2 -> a -> ans) -> (ctx -> r1 -> r2 -> a) -> (ctx -> r1 -> r2 -> ans) +--+apply2 :: CF (r1 -> r2 -> a -> ans) -> CF (r1 -> r2 -> a) +       -> CF (r1 -> r2 -> ans)+apply2 df da = CF $ \ctx a b -> getCF df ctx a b (getCF da ctx a b)+++--------------------------------------------------------------------------------+-- Pre-transformers++-- The primary /pre-transformation/ function is @localize@, here +-- it is without the newtype wrapper or the specific types:+--+-- > fn :: (ctx -> ctx) -> (ctx -> ans) -> ctx -> ans+-- > fn f g = \ctx -> g (f ctx)+--+-- This a a type restricted version of reverse appliction, the T+-- combinator sometimes called queer, sometings @(#)@ in Haskell.+-- In Wumpus-Basic it is @localize@ which is overloaded for the+-- CF newtype and TraceDrawing monads.+--+-- > localizeDR :: (DrawingContext -> DrawingContext) -> CF a -> CF a+-- > localizeDR = localize+--+-- Figuartively speaking this is an opposite of the fmap function +-- instance. Instead of (post-) transforming the output, ... +-- (pre-) transforms  the input.+-- +-- Due to Context functionals being stacked in a particular way+-- @localize@ always pre-transforms the DrawingContext regardless+-- of the arity of the functional:+--+-- > localizeDR2 :: (DrawingContext -> DrawingContext) +-- >             -> CF (r -> a) -> CF (r -> a)+-- > localizeDR2 = localize+-- +++-- | Apply the static argument transfomer @(r1 -> a)@ to the +-- static argument /before/ applying the Context functional.+--+-- > (r1 -> a) -> (ctx -> a -> ans) -> (ctx -> r1 -> ans)+-- +prepro1 :: (r1 -> a) -> CF (a -> ans) -> CF (r1 -> ans)+prepro1 f mf = CF $ \ctx a -> getCF mf ctx (f a)+++-- | Apply the static argument transfomers to their respective+-- static arguments /before/ applying the Context functional.+--+-- > (r1 -> a) -> (r2 -> b) -> (ctx -> a -> b -> ans) -> (ctx -> r1 -> r2 -> ans)+-- +prepro2 :: (r1 -> a) -> (r2 -> b) -> CF (a -> b -> ans) -> CF (r1 -> r2 -> ans)+prepro2 f g mf = CF $ \ctx a b -> getCF mf ctx (f a) (g b)+++-- | Apply the static argument transfomer to the first static+-- argument of a two static argument functional /before/ applying +-- the Context functional.+--+-- > (r1 -> a) -> (ctx -> a -> r2 -> ans) -> (ctx -> r1 -> r2 -> ans)+-- +prepro2a :: (r1 -> a) -> CF (a -> r2 -> ans) -> CF (r1 -> r2 -> ans)+prepro2a f mf = CF $ \ctx a b -> getCF mf ctx (f a) b++-- | Apply the static argument transfomer to the second static+-- argument of a two static argument functional /before/ applying +-- the Context functional.+--+-- > (r2 -> a) -> (ctx -> r1 -> a -> ans) -> (ctx -> r1 -> r2 -> ans)+-- +prepro2b :: (r2 -> a) -> CF (r1 -> a -> ans) -> CF (r1 -> r2 -> ans)+prepro2b f mf = CF $ \ctx a b -> getCF mf ctx a (f b)++------------------------------------------------------------------------------+-- Post-transfomers++-- | Apply the post-transformer to the result of the Context+-- functional.+--+-- > (a -> ans) -> (ctx -> a) -> (ctx -> ans) +--+postpro :: (a -> ans) -> CF a -> CF ans+postpro = fmap++-- | Apply the post-transformer to the result of the Context+-- functional. Version for one static argument.+--+-- Note - the DrawingContext is always present so it is never +-- counted as a static argument.+--+-- > (a -> ans) -> (ctx -> r1 -> a) -> (ctx -> r1 -> ans) +--+postpro1 :: (a -> ans) -> CF (r1 -> a) -> CF (r1 -> ans)+postpro1 = postpro . fmap  ++-- | Apply the post-transformer to the result of the Context+-- functional. Version for two static arguments.+--+-- Note - the DrawingContext is always present so it is never +-- counted as a static argument.+--+--+-- > (a -> ans) -> (ctx -> r1 -> r2 -> a) -> (ctx -> r1 -> r2 -> ans) +--+postpro2 :: (a -> ans) -> CF (r1 -> r2 -> a) -> CF (r1 -> r2 -> ans)+postpro2 = postpro1 . fmap  +++--------------------------------------------------------------------------------+-- Post-combiners++-- | Combine the results of the two Context Functions with the +-- supplied operator.+--+-- > (a -> b -> ans) -> (ctx -> a) -> (ctx -> b) -> (ctx -> ans)+--+postcomb :: (a -> b -> ans) -> CF a -> CF b -> CF ans+postcomb op df dg = CF $ \ctx ->  getCF df ctx `op` getCF dg ctx++-- | Combine the results of the two one-static-argument Context +-- Functions with the supplied operator.+--+-- > (a -> b -> ans) -> (ctx -> r1 -> a) -> (ctx -> r1 -> b) -> (ctx -> r1 -> ans)+--+postcomb1 :: (a -> b -> c) -> CF (r1 -> a) -> CF (r1 -> b) -> CF (r1 -> c)+postcomb1 op df dg = CF $ \ctx a -> getCF df ctx a `op` getCF dg ctx a+++-- | Combine the results of the two two-static-argument Context +-- Functions with the supplied operator.+--+-- > (a -> b -> ans) -> (ctx -> r1 -> a) -> (ctx -> r1 -> b) -> (ctx -> r1 -> ans)+--+postcomb2 :: (a -> b -> ans) -> CF (r1 -> r2 -> a) -> CF (r1 -> r2 -> b) +          -> CF (r1 -> r2 -> ans)+postcomb2 op df dg = CF $ \ctx a b -> +    getCF df ctx a b `op` getCF dg ctx a b++++-- | Iteration combinator - the initial argument @s1@ is not +-- shared bewteen the drawings.+--+-- Evaluate the first Context Function with the drawing context +-- and the /initial state/ @st0@. The result of the evaluation is +-- a new /state/ @st1@ and and answer @a1@. +--+-- Evaluate the second Context Function with the drawing context +-- and the new state @st1@, producing a new state @s2@ and an +-- answer @a2@.+--+-- Return the result of combining the answers with +-- @op :: (ans -> ans -> ans)@ and the second state @s2@.+--+-- @ (ans -> ans -> ans) -> (ctx -> s1 -> (s1,ans)) @+-- @                     -> (ctx -> s1 -> (s1,ans)) -> (ctx -> s1 -> (s1,ans)) @+--+-- This models chaining start points together, which is the model+-- PostScript uses for text output when succesively calling the +-- @show@ operator.+-- +accumulate1 :: (ans -> ans -> ans) +            -> CF (s1 -> (s1,ans)) -> CF (s1 -> (s1,ans)) +            -> CF (s1 -> (s1,ans)) +accumulate1 op f g = CF $ \ctx s -> +                        let (s1,a1) = getCF f ctx s+                            (s2,a2) = getCF g ctx s1+                        in (s2, a1 `op` a2)++++-- | Arity two version of accumulate1 - this is not expected to be+-- useful!+--+-- @ (ans -> ans -> ans) -> (ctx -> s1 -> -> s2 (s1,s2,ans)) @+-- @     -> (ctx -> s1 -> s2 -> (s1,s2,ans)) @+-- @     -> (ctx -> s1 -> s2 -> (s1,s2,ans)) @+--+accumulate2 :: (ans -> ans -> ans) +            -> CF (s1 -> s2 -> (s1,s2,ans)) +            -> CF (s1 -> s2 -> (s1,s2,ans)) +            -> CF (s1 -> s2 -> (s1,s2,ans)) +accumulate2 op f g = CF $ \ctx s t -> +                        let (s1,t1,a1) = getCF f ctx s t+                            (s2,t2,a2) = getCF g ctx s1 t1+                        in (s2, t2, a1 `op` a2)++++++--------------------------------------------------------------------------------+{-+instance CenterAnchor a => CenterAnchor (CF a) where+  center = postpro center+-}
src/Wumpus/Basic/Graphic/Drawing.hs view
@@ -1,7 +1,4 @@-{-# LANGUAGE MultiParamTypeClasses      #-} {-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE FlexibleInstances          #-} {-# OPTIONS -Wall #-}  --------------------------------------------------------------------------------@@ -14,353 +11,114 @@ -- Stability   :  unstable -- Portability :  GHC  ----- Drawing with /trace/ - a Writer like monad collecting --- intermediate graphics - and /drawing context/ - a reader monad--- of attributes - font_face, fill_colour etc.---+-- A Drawing object. +-- +-- This is the corresponding type to Picture in the Wumpus-Core.+-- +-- Drawing is a function from the DrawingContext to a Picture.+-- Internally the result is actually a (Maybe Picture) and not a +-- Picture, this is a trick to promote the extraction from +-- possibly empty drawings (created by TraceDrawing) to the +-- top-level of the type hierarchy where client code can deal +-- with empty drawings explicitly (empty Pictures cannot be +-- rendered by Wumpus-Core).+--  --------------------------------------------------------------------------------  module Wumpus.Basic.Graphic.Drawing   (      Drawing-  , DrawingT+  , DDrawing   , runDrawing-  , execDrawing-  , evalDrawing-  , runDrawingT-  , execDrawingT-  , evalDrawingT--  , runFdcDrawing-  , execFdcDrawing-  , runFdcDrawingT-  , execFdcDrawingT--  , liftToPictureU-  , liftToPictureMb-  , mbPictureU- -  , draw-  , xdraw-  , drawi-  , drawi_-  , xdrawi-  , xdrawi_--  , at+  , runDrawingU+  , drawTracing -  , node-  , nodei+  , clipDrawing+  , modifyDrawing+  , drawingConcat    ) where --import Wumpus.Basic.Graphic.Base+import Wumpus.Basic.Graphic.ContextFunction import Wumpus.Basic.Graphic.DrawingContext--- import Wumpus.Basic.Utils.HList +import Wumpus.Basic.Graphic.TraceDrawing  import Wumpus.Core                              -- package: wumpus-core -import Control.Applicative-import Control.Monad-import Data.Monoid+newtype Drawing u = Drawing { getDrawing :: CF (Maybe (Picture u)) } +type DDrawing = Drawing Double  --- Note - Drawing run \once\ - it is supplied with the starting--- environment (DrawingContext) and returns a Picture.------ Other Wumpus monads (e.g. Turtle) will typically be run inside--- the Drawing monad as a local effect, rather than built into a --- transformer stack.---+type instance DUnit (Drawing u) = u  -newtype Drawing u a   = Drawing { -          getDrawing :: DrawingContext -> (a, HPrim u) } -newtype DrawingT u m a = DrawingT { -          getDrawingT :: DrawingContext -> m (a, HPrim u) } ---type instance MonUnit (Drawing u) = u-type instance MonUnit (DrawingT u m) = u------ Functor--instance Functor (Drawing u) where-  fmap f ma = Drawing $ \ctx -> -                let (a,w) = getDrawing ma ctx in (f a,w)---instance Monad m => Functor (DrawingT u m) where-  fmap f ma = DrawingT $ \ctx -> -                getDrawingT ma ctx >>= \(a,w) -> return (f a,w)------ Applicative--instance Applicative (Drawing u) where-  pure a    = Drawing $ \_   -> (a, mempty)-  mf <*> ma = Drawing $ \ctx -> let (f,w1) = getDrawing mf ctx-                                    (a,w2) = getDrawing ma ctx-                                in (f a, w1 `mappend` w2)---instance Monad m => Applicative (DrawingT u m) where-  pure a    = DrawingT $ \_   -> return (a,mempty)-  mf <*> ma = DrawingT $ \ctx -> getDrawingT mf ctx >>= \(f,w1) ->-                                 getDrawingT ma ctx >>= \(a,w2) ->-                                 return (f a, w1 `mappend` w2)---- Monad--instance Monad (Drawing u) where-  return a  = Drawing $ \_   -> (a, mempty)-  ma >>= k  = Drawing $ \ctx -> let (a,w1) = getDrawing ma ctx-                                    (b,w2) = (getDrawing . k) a ctx-                                in (b,w1 `mappend` w2)-                               ----instance Monad m => Monad (DrawingT u m) where-  return a  = DrawingT $ \_   -> return (a, mempty)-  ma >>= k  = DrawingT $ \ctx -> getDrawingT ma ctx      >>= \(a,w1) ->-                                 (getDrawingT . k) a ctx >>= \(b,w2) -> -                                 return (b, w1 `mappend` w2)-                                 ------ TraceM ------ Note -  @ state `mappend` a @ means the first expression in a --- monadic drawing is the first element in the output file. It is--- also \*\* at the back \*\* in the the Z-Order.------ Some control over the Z-Order, possibly by adding /layers/ to --- the drawing model would be valuable. --- --instance TraceM (Drawing u) where-  trace a = Drawing $ \_ -> ((), a)---instance Monad m => TraceM (DrawingT u m) where-  trace a = DrawingT $ \_ -> return ((), a)------ DrawingCtxM--instance DrawingCtxM (Drawing u) where-  askDC           = Drawing $ \ctx -> (ctx, mempty)-  localize upd ma = Drawing $ \ctx -> getDrawing ma (upd ctx)----instance Monad m => DrawingCtxM (DrawingT u m) where-  askDC           = DrawingT $ \ctx -> return (ctx,mempty)-  localize upd ma = DrawingT $ \ctx -> getDrawingT ma (upd ctx)------ Note - the result type of runDrawing and friends needs more --- thought and may change. ------ Possibly a wrapped HPrim that only supports concat and safe--- extraction is best.------ Or it could generate a picture, but then separate drawings--- need the picture combinators to put them together. --- ---runDrawing :: DrawingContext -> Drawing u a -> (a, HPrim u)-runDrawing ctx ma = getDrawing ma ctx---- | Run the drawing returning only the output it produces, drop--- any answer from the monadic computation.----execDrawing :: DrawingContext -> Drawing u a -> HPrim u-execDrawing ctx ma = snd $ runDrawing ctx ma---- | Run the drawing ignoring the output it produces, return the --- answer from the monadic computation.------ Note - this useful for testing, generally one would want the --- opposite behaviour (return the drawing, ignore than the --- answer).--- -evalDrawing :: DrawingContext -> Drawing u a -> a-evalDrawing ctx ma = fst $ runDrawing ctx ma----runDrawingT :: Monad m => DrawingContext -> DrawingT u m a -> m (a, HPrim u) -runDrawingT ctx ma = getDrawingT ma ctx--execDrawingT :: Monad m => DrawingContext -> DrawingT u m a -> m (HPrim u)-execDrawingT ctx ma = liftM snd $ runDrawingT ctx ma---evalDrawingT :: Monad m => DrawingContext -> DrawingT u m a -> m a-evalDrawingT ctx ma = liftM fst $ runDrawingT ctx ma-+runDrawing :: DrawingContext -> Drawing u -> Maybe (Picture u)+runDrawing ctx drw = runCF ctx (getDrawing drw)    --- | Run the Drawing generating a Picture /within/ a --- \"font delta context\" using the font-family and font-size --- from the intial DrawingContext.------ Using a /font delta context/ can reduce the code size of the--- generated SVG file (PostScript ignores the FDC).----runFdcDrawing :: (Real u, Floating u, FromPtSize u)-             => DrawingContext -> Drawing u a -> (a, Maybe (Picture u))-runFdcDrawing ctx ma = -    let (a,hp) = runDrawing ctx ma-        ps     = hprimToList hp-        fdc    = font_props ctx-    in if null ps then (a, Nothing)-                 else (a, Just $ fontDeltaContext fdc $ frame ps)---- | /exec/ version of 'runFdcContext'.----execFdcDrawing :: (Real u, Floating u, FromPtSize u)-             => DrawingContext -> Drawing u a -> Maybe (Picture u)-execFdcDrawing ctx ma = snd $ runFdcDrawing ctx ma---- | Transformer version of 'runFdcDrawing'.----runFdcDrawingT :: (Real u, Floating u, FromPtSize u, Monad m)-             => DrawingContext -> DrawingT u m a -> m (a, Maybe (Picture u))-runFdcDrawingT ctx ma = -    runDrawingT ctx ma >>= \(a,hp) -> -    let ps     = hprimToList hp-        fdc    = font_props ctx-    in if null ps then return (a, Nothing)-                  else return (a, Just $ fontDeltaContext fdc $ frame ps)-  --- | Transformer version of 'execFdcDrawing'.---       -execFdcDrawingT :: (Real u, Floating u, FromPtSize u, Monad m)-             => DrawingContext -> DrawingT u m a -> m (Maybe (Picture u))-execFdcDrawingT ctx ma = liftM snd $ runFdcDrawingT ctx ma---- | /Unsafe/ promotion of @HPrim@ to @Picture@.------ If the HPrim is empty, a run-time error is thrown.--- -liftToPictureU :: (Real u, Floating u, FromPtSize u) => HPrim u -> Picture u-liftToPictureU hf = -    let prims = hprimToList hf in if null prims then errK else frame prims+runDrawingU :: DrawingContext -> Drawing u -> Picture u+runDrawingU ctx df = maybe fk id $ runDrawing ctx df   where-    errK = error "toPictureU - empty prims list."+    fk = error "runDrawingU - empty Drawing."    --- | /Safe/ promotion of @HPrim@ to @(Maybe Picture)@.------ If the HPrim is empty, then @Nothing@ is returned.--- -liftToPictureMb :: (Real u, Floating u, FromPtSize u) -               => HPrim u -> Maybe (Picture u)-liftToPictureMb hf = let prims = hprimToList hf in -    if null prims then Nothing else Just (frame prims)  +drawTracing :: (Real u, Floating u, FromPtSize u) +            => TraceDrawing u a -> Drawing u+drawTracing mf = Drawing $ +    drawingCtx >>= \ctx -> return (liftToPictureMb (execTraceDrawing ctx mf) ) --- | /Unsafe/ promotion of @(Maybe Picture)@ to @Picture@.++-- Note - cannot get an answer from a TraceDrawing with this +-- Drawing type. There is nowhere to put the answer in the type. ----- This is equivalent to:+-- If the type was extended: ----- > fromMaybe (error "empty") $ pic+-- > newtype Drawing u a = Drawing { getDrawing :: CF (a, Maybe (Picture u))) } ----- This function is solely a convenience, using it saves one --- import and a few characters.+-- It would make things difficult for the drawing composition +-- operators. @a@ could be monoidial but are there any types of +-- a where this would be useful (rather than just making things +-- more complicated)?  ----- If the supplied value is @Nothing@ a run-time error is thrown.--- -mbPictureU :: (Real u, Floating u, FromPtSize u) -           => Maybe (Picture u) -> Picture u-mbPictureU Nothing  = error "mbPictureU - empty picture."-mbPictureU (Just a) = a---- Note - need an equivalent to Parsec\`s parseTest that provides--- a very simple way to run graphics without concern for return --- type or initial drawing context.- -------------------------------------------------------------------------------- --- | Draw a Graphic taking the drawing style from the --- /drawing context/. ------ This operation is analogeous to @tell@ in a Writer monad.--- -draw :: (TraceM m, DrawingCtxM m, u ~ MonUnit m) => Graphic u -> m ()-draw gf = askDC >>= \ctx -> trace (collectH $ runGraphic ctx gf)+clipDrawing :: (Num u, Ord u) => (PrimPath u) -> Drawing u -> Drawing u+clipDrawing cpath = modifyDrawing (clip cpath) --- | Hyperlink version of 'draw'.----xdraw :: (TraceM m, DrawingCtxM m, u ~ MonUnit m) -      => XLink -> Graphic u -> m ()-xdraw xl gf = draw (xlinkGraphic xl gf) +modifyDrawing :: (Picture u -> Picture u) -> Drawing u -> Drawing u+modifyDrawing pf = Drawing . postpro (fmap pf) . getDrawing +instance (Real u, Floating u) => Rotate (Drawing u) where +  rotate ang = modifyDrawing (rotate ang) --- | Draw an Image taking the drawing style from the --- /drawing context/. ------ The graphic representation of the Image is drawn in the Trace --- monad, and the result is returned.--- -drawi ::  (TraceM m, DrawingCtxM m, u ~ MonUnit m) => Image u a -> m a-drawi img = askDC >>= \ctx -> -            let (a,o) = runImage ctx img in trace (collectH o) >> return a+instance (Real u, Floating u) => RotateAbout (Drawing u) where+  rotateAbout r pt = modifyDrawing (rotateAbout r pt) --- | Forgetful 'drawi'.----drawi_ ::  (TraceM m, DrawingCtxM m, u ~ MonUnit m) => Image u a -> m ()-drawi_ img = drawi img >> return ()+instance (Num u, Ord u) => Scale (Drawing u) where+  scale sx sy = modifyDrawing (scale sx sy) +instance (Num u, Ord u) => Translate (Drawing u) where+  translate dx dy = modifyDrawing (translate dx dy) --- | Hyperlink version of 'drawi'.----xdrawi ::  (TraceM m, DrawingCtxM m, u ~ MonUnit m) -       => XLink -> Image u a -> m a-xdrawi xl img = drawi (xlinkImage xl img)  --- | Forgetful 'xdrawi'.----xdrawi_ ::  (TraceM m, DrawingCtxM m, u ~ MonUnit m) -        => XLink -> Image u a -> m ()-xdrawi_ xl img = xdrawi xl img >> return ()  -infixr 1 `at`-at :: (Point2 u -> a) -> Point2 u -> a-at = ($)-+drawingConcat :: (Picture u -> Picture u -> Picture u) +              -> Drawing u -> Drawing u -> Drawing u+drawingConcat op a b = Drawing $ mbpostcomb op (getDrawing a) (getDrawing b)   -node :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ MonUnit m) -     => LocGraphic u -> m ()-node gfL = askDC    >>= \ctx -> -           position >>= \pt  -> -           trace (collectH $ runGraphic ctx $ gfL pt)---nodei :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ MonUnit m) -     => LocImage u a -> m a-nodei imgL = askDC   >>= \ctx -> -             position >>= \pt  -> -             let (a,o) = runImage ctx (imgL pt) -             in trace (collectH o) >> return a-+mbpostcomb :: (a -> a -> a) -> CF (Maybe a) -> CF (Maybe a) -> CF (Maybe a)+mbpostcomb op = postcomb fn+  where+    fn (Just a) (Just b) = Just $ a `op` b+    fn a        Nothing  = a+    fn Nothing  b        = b
src/Wumpus/Basic/Graphic/DrawingContext.hs view
@@ -28,6 +28,8 @@   , DrawingContextF    , standardContext+  , metricsContext+   , default_drawing_context    -- * Modifiers @@ -69,41 +71,78 @@   , strokeColour   , fillColour  -+  -- * Glyph metrics+  , withFontMetrics       ) where  -import Wumpus.Basic.SafeFonts-import Wumpus.Basic.Colour.SVGColours+import Wumpus.Basic.Graphic.GlyphMetrics -import Wumpus.Core                      -- package: wumpus-core+import Wumpus.Core                              -- package: wumpus-core+import Wumpus.Core.Text.StandardEncoding  import Control.Applicative+import qualified Data.Map as Map+import Data.Maybe + data DrawingContext = DrawingContext-      { stroke_props          :: StrokeAttr+      { glyph_tables          :: BaseGlyphMetrics+      , fallback_metrics      :: GlyphMetrics      +      , stroke_props          :: StrokeAttr       , font_props            :: FontAttr       , stroke_colour         :: RGBi      -- also text colour...       , fill_colour           :: RGBi             , line_spacing_factor   :: Double       }-  deriving (Eq,Show) +-- TODO - hand craft a Show instance + type DrawingContextF = DrawingContext -> DrawingContext   standardContext :: FontSize -> DrawingContext standardContext sz = -    DrawingContext { stroke_props         = default_stroke_attr-                   , font_props           = FontAttr sz courier-                   , stroke_colour        = black-                   , fill_colour          = light_gray+    DrawingContext { glyph_tables         = Map.empty+                   , fallback_metrics     = monospace_metrics+                   , stroke_props         = default_stroke_attr+                   , font_props           = FontAttr sz wumpus_courier+                   , stroke_colour        = wumpus_black+                   , fill_colour          = wumpus_light_gray                    , line_spacing_factor  = 1.2                      }  +metricsContext :: FontSize -> BaseGlyphMetrics -> DrawingContext+metricsContext sz bgm = +    DrawingContext { glyph_tables         = bgm+                   , fallback_metrics     = monospace_metrics+                   , stroke_props         = default_stroke_attr+                   , font_props           = FontAttr sz wumpus_courier+                   , stroke_colour        = wumpus_black+                   , fill_colour          = wumpus_light_gray+                   , line_spacing_factor  = 1.2  +                   }+++++wumpus_black            :: RGBi+wumpus_black            = RGBi 0 0 0 ++wumpus_light_gray       :: RGBi+wumpus_light_gray       = RGBi 200 200 200+++-- | Courier+-- +wumpus_courier :: FontFace+wumpus_courier = FontFace "Courier" "Courier New" SVG_REGULAR standard_encoding+++ default_drawing_context :: DrawingContext default_drawing_context =      standardContext (font_size wumpus_default_font)@@ -261,4 +300,25 @@  fillColour :: RGBi -> DrawingContextF fillColour rgb = \s -> s { fill_colour = rgb } ++++++--------------------------------------------------------------------------------+-- Glyph metrics++-- These are directly on the DrawingContext /for efficiency/.++++withFontMetrics :: (GlyphMetrics -> PtSize -> u) -> DrawingContext -> u+withFontMetrics fn ctx@(DrawingContext { font_props = font_stats }) = +      fn metric_set point_sz+  where +    ps_name     = ps_font_name $ font_face font_stats+    point_sz    = fromIntegral $ font_size font_stats +    metric_set  = fromMaybe (fallback_metrics ctx) $ +                    Map.lookup ps_name (glyph_tables ctx) + 
+ src/Wumpus/Basic/Graphic/GlyphMetrics.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE RankNTypes                 #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Graphic.GlyphMetrics+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Data types representing glyph metrics loaded from font files.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Graphic.GlyphMetrics+  ( ++    FontName+  , CodePoint+  , GlyphMetricsTable(..)+  , GlyphMetrics(..)+  , buildMetrics+  , BaseGlyphMetrics+  , monospace_metrics++  +  ) where++import Wumpus.Core                              -- package: wumpus-core++import qualified Data.IntMap   as IntMap+import qualified Data.Map      as Map++type FontName = String++-- | A Unicode code-point.+--+type CodePoint = Int+++-- | NOTE - GlyphMetrics table is parametric on @cu@ - +-- /Character unit/ and not on the usual @u@.+--+data GlyphMetricsTable cu = GlyphMetricsTable+       { glyph_bounding_box     :: BoundingBox cu +       , glyph_default_adv_vec  :: Vec2 cu+       , glyph_adv_vecs         :: IntMap.IntMap (Vec2 cu)+       , glyph_cap_height       :: cu+       }+++-- unit_scale_fun     :: PtSize -> cu -> u+--++-- afmValue  :: FromPtSize u => AfmUnit -> PtSize -> u+--++data GlyphMetrics = GlyphMetrics +      { get_bounding_box  :: forall u. FromPtSize u => PtSize -> BoundingBox u +      , get_av_lookup     :: forall u. FromPtSize u => PtSize -> (CodePoint -> Vec2 u)+      , get_cap_height    :: forall u. FromPtSize u => PtSize -> u+      }+++type BaseGlyphMetrics = Map.Map FontName GlyphMetrics++-- | This ignores the Char code lookup and just returns the +-- default advance vector.+--+monospace_metrics :: GlyphMetrics+monospace_metrics = GlyphMetrics+      { get_bounding_box  = \sz -> BBox (lowerLeft sz) (upperRight sz)+      , get_av_lookup     = \sz _ -> hvec (upscale sz width_vec) +      , get_cap_height    = \sz -> upscale sz cap_height+      }+  where+    llx           = (-23)  / 1000+    lly           = (-250) / 1000+    urx           = 715    / 1000+    ury           = 805    / 1000+    width_vec     = 600    / 1000+    cap_height    = 562    / 1000++    upscale sz d  = fromPtSize $ sz * d+    lowerLeft sz  = P2 (upscale sz llx) (upscale sz lly) +    upperRight sz = P2 (upscale sz urx) (upscale sz ury) +++buildMetrics :: (cu -> PtSize) -> GlyphMetricsTable cu -> GlyphMetrics++buildMetrics fn (GlyphMetricsTable (BBox ll ur) (V2 vx vy) +                                   vec_table    cap_height) = +    GlyphMetrics+      { get_bounding_box  = \sz -> BBox (scalePt sz ll) (scalePt sz ur)+      , get_av_lookup     = \sz i -> +            maybe (defaultAV sz) (scaleVec sz) $ IntMap.lookup i vec_table +      , get_cap_height    = \sz -> upscale sz (fn cap_height)+      }+  where+    upscale sz d            = fromPtSize $ sz * d + +    defaultAV sz            = V2 (upscale sz $ fn vx) (upscale sz $ fn vy) +    scalePt  sz (P2 cx cy)  = P2 (upscale sz $ fn cx) (upscale sz $ fn cy) +    scaleVec sz (V2 cx cy)  = V2 (upscale sz $ fn cx) (upscale sz $ fn cy) +++
+ src/Wumpus/Basic/Graphic/GraphicOperations.hs view
@@ -0,0 +1,399 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Graphic.GraphicOperations+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- Elementary functions for the Graphic and LocGraphic types.+--+-- The functions here are generally analogeous to the Picture +-- API in @Wumpus.Core@, but here they exploit the implicit +-- @DrawingContext@.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Graphic.GraphicOperations+  (+    drawGraphic++  , openStroke+  , closedStroke+  , filledPath+  , borderedPath++  +  , textline+  , rtextline+  , centermonoTextline+  , escapedline+  , rescapedline++  , textlineMulti+  , hkernline+  , vkernline+++  , strokedEllipse+  , filledEllipse  +  , borderedEllipse++  , supplyPt+  , localPoint+  , vecdisplace+  , displace+  , hdisplace+  , vdisplace+  , parallelvec+  , perpendicularvec+  , displaceParallel+  , displacePerpendicular+++  , straightLine+  , straightLineBetween+  , curveBetween+++  , strokedRectangle+  , filledRectangle+  , borderedRectangle+++  , strokedCircle+  , filledCircle+  , borderedCircle+  +  , strokedDisk+  , filledDisk+  , borderedDisk+  ++  , illustrateBoundedGraphic+  , illustrateBoundedLocGraphic++  ) where++import Wumpus.Basic.Graphic.Base+import Wumpus.Basic.Graphic.ContextFunction+import Wumpus.Basic.Graphic.DrawingContext+import Wumpus.Basic.Graphic.GraphicTypes+import Wumpus.Basic.Graphic.Query++import Wumpus.Core                              -- package: wumpus-core+import Wumpus.Core.Colour++import Data.AffineSpace                         -- package: vector-space+import Data.VectorSpace++++drawGraphic :: (Real u, Floating u, FromPtSize u) +            => DrawingContext -> Graphic u -> Picture u+drawGraphic ctx gf = frame [getPrimGraphic $ runGraphic ctx gf]+++++openStroke :: Num u => PrimPath u -> Graphic u+openStroke pp = +    withStrokeAttr $ \rgb attr -> primGraphic $ ostroke rgb attr pp++closedStroke :: Num u => PrimPath u -> Graphic u+closedStroke pp = +    withStrokeAttr $ \rgb attr -> primGraphic $ cstroke rgb attr pp++filledPath :: Num u => PrimPath u -> Graphic u+filledPath pp = withFillAttr $ \rgb -> primGraphic $ fill rgb pp+                 +++borderedPath :: Num u => PrimPath u -> Graphic u+borderedPath pp =+    withBorderedAttr $ \frgb attr srgb -> +                           primGraphic $ fillStroke frgb attr srgb pp+++-- Note - clipping needs a picture as well as a path, so there is+-- no analogous @clippedPath@ function.+++--------------------------------------------------------------------------------+-- ++locPrimGraphic :: (Point2 u -> Primitive u) -> (Point2 u -> PrimGraphic u)+locPrimGraphic fn = primGraphic . fn++thetaLocPrimGraphic :: (Point2 u -> Radian -> Primitive u) +                    -> (Point2 u -> Radian -> PrimGraphic u) +thetaLocPrimGraphic fn = \pt theta -> primGraphic (fn pt theta)+++++textline :: Num u => String -> LocGraphic u+textline ss =+    withTextAttr $ \rgb attr -> locPrimGraphic (textlabel rgb attr ss)++++rtextline :: Num u => String -> LocThetaGraphic u+rtextline ss = +    withTextAttr $ \rgb attr -> thetaLocPrimGraphic +                                  (\pt ang -> rtextlabel rgb attr ss pt ang)+++++-- | As 'textline' but the supplied point is the /center/.+--+-- Centered is inexact - it is calculated with monospaced font+-- metrics.+-- +centermonoTextline :: (Fractional u, Ord u, FromPtSize u) +                   => String -> LocGraphic u+centermonoTextline ss = monoVecToCenter ss >>= \v ->+                          moveLoc (vecdisplace (negateV v)) (textline ss)++++escapedline :: Num u => EscapedText -> LocGraphic u+escapedline ss =+    withTextAttr $ \rgb attr -> locPrimGraphic (escapedlabel rgb attr ss)+++rescapedline :: Num u => EscapedText -> LocThetaGraphic u+rescapedline ss = +    withTextAttr $ \rgb attr -> thetaLocPrimGraphic +                                  (\pt ang -> rescapedlabel rgb attr ss pt ang)++++-- | Point is the baseline left of the bottom line, text is +-- left-aligned.+--+textlineMulti :: Fractional u => [String] -> LocGraphic u+textlineMulti xs = baselineSpacing >>= \dy -> +    extrLocGraphic $ go (tmStep dy) xs+  where+    -- go /starts/ at the end of the list and works back.+    go fn []      = fn ""       -- not ideal, better than error+    go fn [s]     = fn s+    go fn (s:ss)  = let ans = go fn ss in ans `feedPt` fn s++-- LocImage u (Point2 u) deserved to be a new type synonym+-- as it models PostScript\'s @show@ +++tmStep :: Num u => u -> String -> LocImage u (Point2 u) +tmStep dy str = intoLocImage (raise $ \pt -> pt .+^ vvec dy) (textline str)++feedPt :: LocImage u (Point2 u) -> LocImage u (Point2 u) -> LocImage u (Point2 u) +feedPt = accumulate1 oplus++hkernline :: Num u => [KerningChar u] -> LocGraphic u+hkernline ks = +    withTextAttr $ \rgb attr -> locPrimGraphic (hkernlabel rgb attr ks)+      ++vkernline :: Num u => [KerningChar u] -> LocGraphic u+vkernline ks = +    withTextAttr $ \rgb attr -> locPrimGraphic (vkernlabel rgb attr ks)+  +++--------------------------------------------------------------------------------+++strokedEllipse :: Num u => u -> u -> LocGraphic u+strokedEllipse hw hh =  +    withStrokeAttr $ \rgb attr -> locPrimGraphic (strokeEllipse rgb attr hw hh)+   ++filledEllipse :: Num u => u -> u -> LocGraphic u+filledEllipse hw hh =  +    withFillAttr $ \rgb -> locPrimGraphic (fillEllipse rgb hw hh)+  ++borderedEllipse :: Num u => u -> u -> LocGraphic u+borderedEllipse hw hh = +    withBorderedAttr $ \frgb attr srgb -> +      locPrimGraphic (fillStrokeEllipse frgb attr srgb hw hh)++--------------------------------------------------------------------------------+++-- | Supplying a point to a 'CFGraphic' takes it to a regular +-- 'Graphic'.+--+supplyPt :: Point2 u -> LocGraphic u -> Graphic u+supplyPt pt gf = fmap ($ pt) gf ++++vecdisplace :: Num u => Vec2 u -> PointDisplace u+vecdisplace (V2 dx dy) (P2 x y) = P2 (x+dx) (y+dy)+++displace :: Num u => u -> u -> PointDisplace u+displace dx dy (P2 x y) = P2 (x+dx) (y+dy)++hdisplace :: Num u => u -> PointDisplace u+hdisplace dx (P2 x y) = P2 (x+dx) y++vdisplace :: Num u => u -> PointDisplace u+vdisplace dy (P2 x y) = P2 x (y+dy)+++++parallelvec :: Floating u => u -> Radian -> Vec2 u+parallelvec d r         = avec (circularModulo r) d++perpendicularvec :: Floating u => u -> Radian -> Vec2 u+perpendicularvec d r    = avec (circularModulo $ (0.5*pi) + r) d++displaceParallel :: Floating u => u -> Radian -> PointDisplace u+displaceParallel d r pt = pt .+^ parallelvec d r++displacePerpendicular :: Floating u => u -> Radian -> PointDisplace u+displacePerpendicular d r pt = pt .+^ perpendicularvec d r+++localPoint :: (Point2 u -> Point2 u) -> LocGraphic u -> LocGraphic u+localPoint = moveLoc++++--------------------------------------------------------------------------------+++straightLine :: Fractional u => Vec2 u -> LocGraphic u+straightLine v = +    promote1 $ \pt -> openStroke $ primPath pt [lineTo $ pt .+^ v]+          ++straightLineBetween :: Fractional u => Point2 u -> Point2 u -> Graphic u+straightLineBetween p1 p2 = openStroke $ primPath p1 [lineTo p2]++++curveBetween :: Fractional u +             => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Graphic u+curveBetween sp cp1 cp2 ep = openStroke $ primPath sp [curveTo cp1 cp2 ep]++++-- | Supplied point is /bottom-left/.+--+rectangle :: Num u => u -> u -> Point2 u -> PrimPath u+rectangle w h bl = primPath bl [ lineTo br, lineTo tr, lineTo tl ]+  where+    br = bl .+^ hvec w+    tr = br .+^ vvec h+    tl = bl .+^ vvec h ++-- This is basically the cardinal-prime combinator with arguments +-- at specific types +-- +-- > cardinal'  :: (a -> r1 -> ans) -> (r2 -> a) -> (r1 -> r2 -> ans)+--++drawWith :: (PrimPath u -> Graphic u) -> (Point2 u -> PrimPath u) -> LocGraphic u +drawWith mf g = promote1 $ \pt -> (mf $ g pt)++-- | Supplied point is /bottom left/.+--+strokedRectangle :: Fractional u => u -> u -> LocGraphic u+strokedRectangle w h = drawWith closedStroke (rectangle w h)+++-- | Supplied point is /bottom left/.+--+filledRectangle :: Fractional u => u -> u -> LocGraphic u+filledRectangle w h = drawWith borderedPath (rectangle w h) ++-- | Supplied point is /bottom left/.+--+borderedRectangle :: Fractional u => u -> u -> LocGraphic u+borderedRectangle w h = drawWith borderedPath (rectangle w h) +++++--------------------------------------------------------------------------------+++-- | Supplied point is center. Circle is drawn with Bezier +-- curves. +--+strokedCircle :: Floating u => Int -> u -> LocGraphic u+strokedCircle n r = drawWith closedStroke (curvedPath . bezierCircle n r)++++-- | Supplied point is center. Circle is drawn with Bezier +-- curves. +--+filledCircle :: Floating u => Int -> u -> LocGraphic u+filledCircle n r = drawWith filledPath (curvedPath . bezierCircle n r)++++-- | Supplied point is center. Circle is drawn with Bezier +-- curves. +--+borderedCircle :: Floating u => Int -> u -> LocGraphic u+borderedCircle n r = drawWith borderedPath (curvedPath . bezierCircle n r)++++-- | 'disk' is drawn with Wumpus-Core\'s @ellipse@ primitive.+--+-- This is a efficient representation of circles using +-- PostScript\'s @arc@ or SVG\'s @circle@ in the generated +-- output. However, stroked-circles do not draw well after +-- non-uniform scaling - the line width is scaled as well as +-- the shape.+--+-- For stroked circles that can be scaled, consider making the +-- circle from Bezier curves.+--+strokedDisk :: Num u => u -> LocGraphic u+strokedDisk radius = strokedEllipse radius radius+++filledDisk :: Num u => u -> LocGraphic u+filledDisk radius = filledEllipse radius radius++borderedDisk :: Num u => u -> LocGraphic u+borderedDisk radius = borderedEllipse radius radius++--------------------------------------------------------------------------------+-- ++illustrateBoundedGraphic :: Fractional u => BoundedGraphic u -> BoundedGraphic u+illustrateBoundedGraphic mf = mf >>= \(bb,g1) -> +                      bbrectangle bb >>= \g2 -> +                      return (bb, g2 `oplus` g1)  +++illustrateBoundedLocGraphic :: Fractional u +                            => BoundedLocGraphic u -> BoundedLocGraphic u+illustrateBoundedLocGraphic mf = +    promote1 $ \pt -> illustrateBoundedGraphic (unLoc pt mf)+++bbrectangle :: Fractional u => BoundingBox u -> Graphic u+bbrectangle (BBox p1@(P2 llx lly) p2@(P2 urx ury)) = +    localize drawing_props $ rect1 `oplus` cross+  where+    drawing_props = strokeColour blue . capRound . dashPattern (Dash 0 [(1,2)])+    rect1         = strokedRectangle (urx-llx) (ury-lly) `at` p1+    cross         = straightLineBetween p1 p2 +                      `oplus` straightLineBetween (P2 llx ury) (P2 urx lly)
+ src/Wumpus/Basic/Graphic/GraphicTypes.hs view
@@ -0,0 +1,441 @@+{-# 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+++++
− src/Wumpus/Basic/Graphic/PrimGraphic.hs
@@ -1,319 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Graphic.PrimGraphic--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  highly unstable--- Portability :  GHC ------ Elementary functions for the Graphic and LocGraphic types.------ The functions here are generally analogeous to the Picture --- API in @Wumpus.Core@, but here they exploit the implicit --- @DrawingContext@.--------------------------------------------------------------------------------------module Wumpus.Basic.Graphic.PrimGraphic-  (-    drawGraphic--  , openStroke-  , closedStroke-  , filledPath-  , borderedPath-  -  , textline-  , rtextline-  , centermonoTextline-  , textlineMulti-  , hkernline-  , vkernline---  , strokedEllipse-  , filledEllipse  -  , borderedEllipse--  , supplyPt-  , localPoint-  , vecdisplace-  , displace-  , hdisplace-  , vdisplace-  , parallelvec-  , perpendicularvec-  , displaceParallel-  , displacePerpendicular---  , straightLine-  , straightLineBetween-  , curveBetween--  , strokedRectangle-  , filledRectangle-  , borderedRectangle---  , strokedCircle-  , filledCircle-  , borderedCircle-  -  , strokedDisk-  , filledDisk-  , borderedDisk-  --  ) where--import Wumpus.Basic.Graphic.Base-import Wumpus.Basic.Graphic.DrawingContext-import Wumpus.Basic.Graphic.Query--import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace                         -- package: vector-space-import Data.VectorSpace--import Control.Applicative-import Data.Foldable ( foldrM )---drawGraphic :: (Real u, Floating u, FromPtSize u) -            => DrawingContext -> Graphic u -> Picture u-drawGraphic ctx gf = frame [getPrimGraphic $ runGraphic ctx gf]------- having the same names is actually not so useful...--openStroke :: Num u => PrimPath u -> Graphic u-openStroke pp = -    withStrokeAttr $ \rgb attr -> wrapPrim $ ostroke rgb attr pp--closedStroke :: Num u => PrimPath u -> Graphic u-closedStroke pp = -    withStrokeAttr $ \rgb attr -> wrapPrim $ cstroke rgb attr pp--filledPath :: Num u => PrimPath u -> Graphic u-filledPath pp = withFillAttr $ \rgb -> wrapPrim $ fill rgb pp-                 ---borderedPath :: Num u => PrimPath u -> Graphic u-borderedPath pp = -    withBorderedAttr $ \frgb attr srgb -> wrapPrim $ fillStroke frgb attr srgb pp----- Note - clipping needs a picture as well as a path, so there is--- no analogous @clippedPath@ function.-------------------------------------------------------------------------------------- ----textline :: Num u => String -> LocGraphic u-textline ss baseline_left =-    withTextAttr $ \rgb attr -> wrapPrim $ textlabel rgb attr ss baseline_left--rtextline :: Num u => String -> ThetaLocGraphic u-rtextline ss theta baseline_left =-    withTextAttr $ \rgb attr -> -      wrapPrim $ rtextlabel rgb attr ss theta baseline_left---- | As 'textline' but the supplied point is the /center/.------ Centered is inexact - it is calculated with monospaced font--- metrics.--- -centermonoTextline :: (Fractional u, Ord u, FromPtSize u) -                   => String -> LocGraphic u-centermonoTextline ss pt = monoVecToCenter ss  >>= \v ->-                           textline ss (vecdisplace (negateV v) pt)-------- | Point is the baseline left of the bottom line, text is --- left-aligned.----textlineMulti :: Fractional u => [String] -> LocGraphic u-textlineMulti xs baseline_left =  -    baselineSpacing >>= \dy -> -    foldrM (foldStep dy) (baseline_left,[]) xs >>= \(_,gs) ->-    return (wrapPrim $ primGroup gs)-  where-    foldStep dy str (pt,ac) = (\a -> (pt .+^ vvec dy, (getPrimGraphic a) : ac)) -                                <$> textline str pt-                                ---hkernline :: Num u => [KerningChar u] -> LocGraphic u-hkernline ks baseline_left = -    withTextAttr $ \rgb attr -> wrapPrim $ hkernlabel rgb attr ks baseline_left-      --vkernline :: Num u => [KerningChar u] -> LocGraphic u-vkernline ks baseline_left = -    withTextAttr $ \rgb attr -> wrapPrim $ vkernlabel rgb attr ks baseline_left-  --------------------------------------------------------------------------------------strokedEllipse :: Num u => u -> u -> LocGraphic u-strokedEllipse hw hh pt =  -    withStrokeAttr $ \rgb attr -> wrapPrim $ strokeEllipse rgb attr hw hh pt-   --filledEllipse :: Num u => u -> u -> LocGraphic u-filledEllipse hw hh pt =  -    withFillAttr $ \rgb -> wrapPrim $ fillEllipse rgb hw hh pt-  --borderedEllipse :: Num u => u -> u -> LocGraphic u-borderedEllipse hw hh pt = -    withBorderedAttr $ \frgb attr srgb -> -      wrapPrim $ fillStrokeEllipse frgb attr srgb hw hh pt--------------------------------------------------------------------------------------- | Supplying a point to a 'CFGraphic' takes it to a regular --- 'Graphic'.----supplyPt :: Point2 u -> LocGraphic u -> Graphic u-supplyPt pt gf = gf pt --vecdisplace :: Num u => Vec2 u -> Point2 u -> Point2 u-vecdisplace (V2 dx dy) (P2 x y) = P2 (x+dx) (y+dy)---displace :: Num u => u -> u -> Point2 u -> Point2 u-displace dx dy (P2 x y) = P2 (x+dx) (y+dy)--hdisplace :: Num u => u -> Point2 u -> Point2 u-hdisplace dx (P2 x y) = P2 (x+dx) y--vdisplace :: Num u => u -> Point2 u -> Point2 u-vdisplace dy (P2 x y) = P2 x (y+dy)----parallelvec :: Floating u => u -> Radian -> Vec2 u-parallelvec d r         = avec (circularModulo r) d--perpendicularvec :: Floating u => u -> Radian -> Vec2 u-perpendicularvec d r    = avec (circularModulo $ (0.5*pi) + r) d--displaceParallel :: Floating u => u -> Radian -> Point2F u-displaceParallel d r pt = pt .+^ parallelvec d r--displacePerpendicular :: Floating u => u -> Radian -> Point2F u-displacePerpendicular d r pt = pt .+^ perpendicularvec d r---localPoint :: (Point2 u -> Point2 u) -> LocGraphic u -> LocGraphic u-localPoint upd gf = \pt -> gf (upd pt)--------------------------------------------------------------------------------------straightLine :: Fractional u => Vec2 u -> LocGraphic u-straightLine v = \pt -> openStroke $ path pt [lineTo $ pt .+^ v]-          --straightLineBetween :: Fractional u => Point2 u -> Point2 u -> Graphic u-straightLineBetween p1 p2 = openStroke $ path p1 [lineTo p2]--curveBetween :: Fractional u -             => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Graphic u-curveBetween sp cp1 cp2 ep = openStroke $ path sp [curveTo cp1 cp2 ep]------ | Supplied point is /bottom-left/.----rectangle :: Num u => u -> u -> Point2 u -> PrimPath u-rectangle w h bl = path bl [ lineTo br, lineTo tr, lineTo tl ]-  where-    br = bl .+^ hvec w-    tr = br .+^ vvec h-    tl = bl .+^ vvec h ------ | Supplied point is /bottom left/.----strokedRectangle :: Fractional u => u -> u -> LocGraphic u-strokedRectangle w h = closedStroke . rectangle w h------ | Supplied point is /bottom left/.----filledRectangle :: Fractional u => u -> u -> LocGraphic u-filledRectangle w h = filledPath . rectangle w h-  ---- | Supplied point is /bottom left/.----borderedRectangle :: Fractional u => u -> u -> LocGraphic u-borderedRectangle w h = borderedPath . rectangle w h--------------------------------------------------------------------------------------- | Supplied point is center. Circle is drawn with Bezier --- curves. ----strokedCircle :: Floating u => Int -> u -> LocGraphic u-strokedCircle n r = closedStroke . curvedPath . bezierCircle n r------ | Supplied point is center. Circle is drawn with Bezier --- curves. ----filledCircle :: Floating u => Int -> u -> LocGraphic u-filledCircle n r = filledPath . curvedPath . bezierCircle n r----- | Supplied point is center. Circle is drawn with Bezier --- curves. ----borderedCircle :: Floating u => Int -> u -> LocGraphic u-borderedCircle n r = borderedPath . curvedPath . bezierCircle n r----- | 'disk' is drawn with Wumpus-Core\'s @ellipse@ primitive.------ This is a efficient representation of circles using --- PostScript\'s @arc@ or SVG\'s @circle@ in the generated --- output. However, stroked-circles do not draw well after --- non-uniform scaling - the line width is scaled as well as --- the shape.------ For stroked circles that can be scaled, consider making the --- circle from Bezier curves.----strokedDisk :: Num u => u -> LocGraphic u-strokedDisk radius = strokedEllipse radius radius---filledDisk :: Num u => u -> LocGraphic u-filledDisk radius = filledEllipse radius radius--borderedDisk :: Num u => u -> LocGraphic u-borderedDisk radius = borderedEllipse radius radius
src/Wumpus/Basic/Graphic/Query.hs view
@@ -32,31 +32,43 @@    , lineWidth   , fontSize+  , fontFace+  , fontAttr   , markHeight   , markHalfHeight   , baselineSpacing -  -- +  -- * Glyph metrics+  , glyphBoundingBox+  , glyphHeightRange+  , glyphHeight+  , glyphCapHeight++  , avLookupTable++  -- * Default monospace metrics++  , monoFontPointSize   , monoCharWidth-  , monoSpacerWidth   , monoTextWidth   , monoTextLength-  , monoTextHeight-  , monoNumeralHeight+  , monoCapHeight   , monoLowerxHeight   , monoDescenderDepth+  , monoAscenderHeight   , monoTextDimensions-  , monoMultiLineTextHeight+  , monoMultiLineHeight   , monoDefaultPadding   , monoVecToCenter     ) where  import Wumpus.Basic.Graphic.Base import Wumpus.Basic.Graphic.DrawingContext---import Wumpus.Core                      -- package: wumpus-core+import Wumpus.Basic.Graphic.GlyphMetrics +import Wumpus.Core                              -- package: wumpus-core+import qualified Wumpus.Core.FontSize   as FS+  import Control.Applicative  @@ -98,9 +110,14 @@ lineWidth :: DrawingCtxM m => m Double lineWidth = line_width <$> asksDC stroke_props +fontAttr :: DrawingCtxM m => m FontAttr+fontAttr = asksDC font_props+ fontSize :: DrawingCtxM m => m Int fontSize = font_size <$> asksDC font_props +fontFace :: DrawingCtxM m => m FontFace+fontFace = font_face <$> asksDC font_props   @@ -120,7 +137,7 @@ -- height. --  markHeight :: (DrawingCtxM m, FromPtSize u) => m u-markHeight = (fromPtSize . xcharHeight . font_size) <$> asksDC font_props+markHeight = (fromPtSize . FS.xcharHeight . font_size) <$> asksDC font_props   markHalfHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u@@ -131,48 +148,79 @@ -- markHeight to merit a withMarkHeight function.  +-------------------------------------------------------------------------------- +glyphQuery :: DrawingCtxM m => (GlyphMetrics -> PtSize -> u) -> m u+glyphQuery fn = (\ctx -> withFontMetrics fn ctx) <$> askDC +glyphBoundingBox :: (FromPtSize u, DrawingCtxM m) => m (BoundingBox u)+glyphBoundingBox = glyphQuery get_bounding_box  +glyphHeightRange :: (FromPtSize u, DrawingCtxM m) => m (u,u)+glyphHeightRange = fn <$> glyphBoundingBox+  where+    fn (BBox (P2 _ ymin) (P2 _ ymax)) = (ymin,ymax)+++glyphHeight :: (FromPtSize u, DrawingCtxM m) => m u+glyphHeight = (\(ymax,ymin) -> ymax - ymin) <$> glyphHeightRange+++glyphCapHeight :: (FromPtSize u, DrawingCtxM m) => m u+glyphCapHeight = glyphQuery get_cap_height++avLookupTable :: (FromPtSize u, DrawingCtxM m) => m (Int -> Vec2 u)+avLookupTable = glyphQuery get_av_lookup++ --------------------------------------------------------------------------------  withFontSize :: DrawingCtxM m => (FontSize -> u) -> m u withFontSize fn = (fn . font_size) <$> asksDC font_props -monoCharWidth :: (DrawingCtxM m, FromPtSize u) => m u-monoCharWidth = withFontSize (fromPtSize . charWidth) -monoSpacerWidth :: (DrawingCtxM m, FromPtSize u) => m u-monoSpacerWidth = withFontSize (fromPtSize . spacerWidth)+-- NOTE - textHeight in Wumpus-Core should be renamed as it is+-- (probably) more indiactive of Cap height than /font point size/+-- +monoFontPointSize :: (DrawingCtxM m, FromPtSize u) => m u+monoFontPointSize = withFontSize (fromPtSize . fromIntegral) +monoCharWidth :: (DrawingCtxM m, FromPtSize u) => m u+monoCharWidth = withFontSize (fromPtSize . FS.charWidth)++ monoTextWidth :: (DrawingCtxM m, FromPtSize u) => Int -> m u-monoTextWidth n = withFontSize $ \sz -> fromPtSize $ textWidth sz n+monoTextWidth n = withFontSize $ \sz -> fromPtSize $ FS.textWidth sz n   monoTextLength :: (DrawingCtxM m, FromPtSize u) => String -> m u monoTextLength ss = monoTextWidth $ charCount ss  -monoTextHeight :: (DrawingCtxM m, FromPtSize u) => m u-monoTextHeight = withFontSize (fromPtSize . textHeight)+monoCapHeight :: (DrawingCtxM m, FromPtSize u) => m u+monoCapHeight = withFontSize (fromPtSize . FS.capHeight) -monoNumeralHeight :: (DrawingCtxM m, FromPtSize u) => m u-monoNumeralHeight = withFontSize (fromPtSize . numeralHeight)+monoTotalCharHeight :: (DrawingCtxM m, FromPtSize u) => m u+monoTotalCharHeight = withFontSize (fromPtSize . FS.totalCharHeight)  + -- | Height of a lower case \'x\' in Courier. --   -- \'x\' has no ascenders or descenders.  --  monoLowerxHeight :: (DrawingCtxM m, FromPtSize u) => m u-monoLowerxHeight = withFontSize (fromPtSize . xcharHeight)+monoLowerxHeight = withFontSize (fromPtSize . FS.xcharHeight)  monoDescenderDepth :: (DrawingCtxM m, FromPtSize u) => m u-monoDescenderDepth = withFontSize (fromPtSize . descenderDepth)+monoDescenderDepth = withFontSize (fromPtSize . FS.descenderDepth) +monoAscenderHeight :: (DrawingCtxM m, FromPtSize u) => m u+monoAscenderHeight = withFontSize (fromPtSize . FS.ascenderHeight) + -- | Query the dimensions of the text using the current font size -- but using metrics derived from Courier. --@@ -188,12 +236,19 @@     post bb = (boundaryWidth bb, boundaryHeight bb)  -monoMultiLineTextHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) +-- | The heigth of @n@ lines of text, which is +-- @n lines + n-1 line spacers@+--+monoMultiLineHeight :: (DrawingCtxM m, Fractional u, FromPtSize u)                          => Int -> m u-monoMultiLineTextHeight n | n < 0   = pure 0-monoMultiLineTextHeight n           = +monoMultiLineHeight n | n < 0   = pure 0+monoMultiLineHeight n           =      (\h lsf -> h + (fromIntegral $ n-1) * (h * realToFrac lsf))-      <$> monoTextHeight <*> asksDC line_spacing_factor+      <$> monoTotalCharHeight <*> asksDC line_spacing_factor+ +    -- Note as the height calculation has changed in Wumpus-Core this+    -- no longer quite works... +    -- | The default padding is half of the /char width/.
+ src/Wumpus/Basic/Graphic/TraceDrawing.hs view
@@ -0,0 +1,329 @@+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Graphic.TraceDrawing+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC +--+-- Drawing with /trace/ - a Writer like monad collecting +-- intermediate graphics - and /drawing context/ - a reader monad+-- of attributes - font_face, fill_colour etc.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Graphic.TraceDrawing+  (++    TraceDrawing+  , TraceDrawingT+  , runTraceDrawing+  , execTraceDrawing+  , evalTraceDrawing+  , runTraceDrawingT+  , execTraceDrawingT+  , evalTraceDrawingT++  , liftToPictureU+  , liftToPictureMb+  , mbPictureU+ ++  , query+  , draw+  , xdraw+  , drawi+  , drawi_+  , xdrawi+  , xdrawi_++  , node+  , nodei++  ) where+++import Wumpus.Basic.Graphic.Base+import Wumpus.Basic.Graphic.ContextFunction+import Wumpus.Basic.Graphic.DrawingContext+import Wumpus.Basic.Graphic.GraphicTypes++import Wumpus.Core                              -- package: wumpus-core++import Control.Applicative+import Control.Monad+import Data.Monoid++++-- Note - TraceDrawing run \once\ - it is supplied with the starting+-- environment (DrawingContext) and returns a Picture.+--+-- Other Wumpus monads (e.g. Turtle) will typically be run inside+-- the TraceDrawing monad as a local effect, rather than built into a +-- transformer stack.+--+++newtype TraceDrawing u a   = TraceDrawing { +          getTraceDrawing :: DrawingContext -> (a, HPrim u) }++newtype TraceDrawingT u m a = TraceDrawingT { +          getTraceDrawingT :: DrawingContext -> m (a, HPrim u) }++++type instance MonUnit (TraceDrawing u) = u+type instance MonUnit (TraceDrawingT u m) = u++++-- Functor++instance Functor (TraceDrawing u) where+  fmap f ma = TraceDrawing $ \ctx -> +                let (a,w) = getTraceDrawing ma ctx in (f a,w)+++instance Monad m => Functor (TraceDrawingT u m) where+  fmap f ma = TraceDrawingT $ \ctx -> +                getTraceDrawingT ma ctx >>= \(a,w) -> return (f a,w)++++-- Applicative++instance Applicative (TraceDrawing u) where+  pure a    = TraceDrawing $ \_   -> (a, mempty)+  mf <*> ma = TraceDrawing $ \ctx -> +                let (f,w1) = getTraceDrawing mf ctx+                    (a,w2) = getTraceDrawing ma ctx+                in (f a, w1 `mappend` w2)+++instance Monad m => Applicative (TraceDrawingT u m) where+  pure a    = TraceDrawingT $ \_   -> return (a,mempty)+  mf <*> ma = TraceDrawingT $ \ctx -> +                getTraceDrawingT mf ctx >>= \(f,w1) ->+                getTraceDrawingT ma ctx >>= \(a,w2) ->+                return (f a, w1 `mappend` w2)++-- Monad++instance Monad (TraceDrawing u) where+  return a  = TraceDrawing $ \_   -> (a, mempty)+  ma >>= k  = TraceDrawing $ \ctx -> +                let (a,w1) = getTraceDrawing ma ctx+                    (b,w2) = (getTraceDrawing . k) a ctx+                in (b,w1 `mappend` w2)+                               ++++instance Monad m => Monad (TraceDrawingT u m) where+  return a  = TraceDrawingT $ \_   -> return (a, mempty)+  ma >>= k  = TraceDrawingT $ \ctx -> +                getTraceDrawingT ma ctx      >>= \(a,w1) ->+                (getTraceDrawingT . k) a ctx >>= \(b,w2) -> +                return (b, w1 `mappend` w2)+                                 ++++-- TraceM +--+-- Note -  @ state `mappend` a @ means the first expression in a +-- monadic drawing is the first element in the output file. It is+-- also \*\* at the back \*\* in the the Z-Order.+--+-- Some control over the Z-Order, possibly by adding /layers/ to +-- the drawing model would be valuable. +-- ++instance TraceM (TraceDrawing u) where+  trace a = TraceDrawing $ \_ -> ((), a)+++instance Monad m => TraceM (TraceDrawingT u m) where+  trace a = TraceDrawingT $ \_ -> return ((), a)++++-- DrawingCtxM++instance DrawingCtxM (TraceDrawing u) where+  askDC           = TraceDrawing $ \ctx -> (ctx, mempty)+  localize upd ma = TraceDrawing $ \ctx -> getTraceDrawing ma (upd ctx)++++instance Monad m => DrawingCtxM (TraceDrawingT u m) where+  askDC           = TraceDrawingT $ \ctx -> return (ctx,mempty)+  localize upd ma = TraceDrawingT $ \ctx -> getTraceDrawingT ma (upd ctx)++++-- Note - the result type of runTraceDrawing and friends needs more +-- thought and may change. +--+-- Possibly a wrapped HPrim that only supports concat and safe+-- extraction is best.+--+-- Or it could generate a picture, but then separate drawings+-- need the picture combinators to put them together. +-- +++runTraceDrawing :: DrawingContext -> TraceDrawing u a -> (a, HPrim u)+runTraceDrawing ctx ma = getTraceDrawing ma ctx++-- | Run the drawing returning only the output it produces, drop+-- any answer from the monadic computation.+--+execTraceDrawing :: DrawingContext -> TraceDrawing u a -> HPrim u+execTraceDrawing ctx ma = snd $ runTraceDrawing ctx ma++-- | Run the drawing ignoring the output it produces, return the +-- answer from the monadic computation.+--+-- Note - this useful for testing, generally one would want the +-- opposite behaviour (return the drawing, ignore than the +-- answer).+-- +evalTraceDrawing :: DrawingContext -> TraceDrawing u a -> a+evalTraceDrawing ctx ma = fst $ runTraceDrawing ctx ma++++runTraceDrawingT :: Monad m +                 => DrawingContext -> TraceDrawingT u m a -> m (a, HPrim u) +runTraceDrawingT ctx ma = getTraceDrawingT ma ctx++execTraceDrawingT :: Monad m +                  => DrawingContext -> TraceDrawingT u m a -> m (HPrim u)+execTraceDrawingT ctx ma = liftM snd $ runTraceDrawingT ctx ma+++evalTraceDrawingT :: Monad m +                  => DrawingContext -> TraceDrawingT u m a -> m a+evalTraceDrawingT ctx ma = liftM fst $ runTraceDrawingT ctx ma++++-- | /Unsafe/ promotion of @HPrim@ to @Picture@.+--+-- If the HPrim is empty, a run-time error is thrown.+-- +liftToPictureU :: (Real u, Floating u, FromPtSize u) => HPrim u -> Picture u+liftToPictureU hf = +    let prims = hprimToList hf in if null prims then errK else frame prims+  where+    errK = error "toPictureU - empty prims list."++-- | /Safe/ promotion of @HPrim@ to @(Maybe Picture)@.+--+-- If the HPrim is empty, then @Nothing@ is returned.+-- +liftToPictureMb :: (Real u, Floating u, FromPtSize u) +                => HPrim u -> Maybe (Picture u)+liftToPictureMb hf = let prims = hprimToList hf in +    if null prims then Nothing else Just (frame prims)++++-- | /Unsafe/ promotion of @(Maybe Picture)@ to @Picture@.+--+-- This is equivalent to:+--+-- > fromMaybe (error "empty") $ pic+--+-- This function is solely a convenience, using it saves one +-- import and a few characters.+--+-- If the supplied value is @Nothing@ a run-time error is thrown.+-- +mbPictureU :: (Real u, Floating u, FromPtSize u) +           => Maybe (Picture u) -> Picture u+mbPictureU Nothing  = error "mbPictureU - empty picture."+mbPictureU (Just a) = a++-- Note - need an equivalent to Parsec\`s parseTest that provides+-- a very simple way to run graphics without concern for return +-- type or initial drawing context.++--------------------------------------------------------------------------------++query :: DrawingCtxM m => CF a -> m a+query df = askDC >>= \ctx -> return $ runCF ctx df+++-- | Draw a Graphic taking the drawing style from the +-- /drawing context/. +--+-- This operation is analogeous to @tell@ in a Writer monad.+-- +draw :: (TraceM m, DrawingCtxM m, u ~ MonUnit m) => Graphic u -> m ()+draw gf = askDC >>= \ctx -> trace (collectH $ runGraphic ctx gf)++-- | Hyperlink version of 'draw'.+--+xdraw :: (TraceM m, DrawingCtxM m, u ~ MonUnit m) +      => XLink -> Graphic u -> m ()+xdraw xl gf = draw (xlinkGraphic xl gf)++++-- | Draw an Image taking the drawing style from the +-- /drawing context/. +--+-- The graphic representation of the Image is drawn in the Trace +-- monad, and the result is returned.+-- +drawi :: (TraceM m, DrawingCtxM m, u ~ MonUnit m) => Image u a -> m a+drawi img = askDC >>= \ctx -> +            let (a,o) = runImage ctx img in trace (collectH o) >> return a++-- | Forgetful 'drawi'.+--+drawi_ ::  (TraceM m, DrawingCtxM m, u ~ MonUnit m) => Image u a -> m ()+drawi_ img = drawi img >> return ()+++-- | Hyperlink version of 'drawi'.+--+xdrawi ::  (TraceM m, DrawingCtxM m, u ~ MonUnit m) +       => XLink -> Image u a -> m a+xdrawi xl img = drawi (xlinkImage xl img)+++-- | Forgetful 'xdrawi'.+--+xdrawi_ ::  (TraceM m, DrawingCtxM m, u ~ MonUnit m) +        => XLink -> Image u a -> m ()+xdrawi_ xl img = xdrawi xl img >> return ()+++++node :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ MonUnit m) +     => LocGraphic u -> m ()+node gf = askDC    >>= \ctx -> +          position >>= \pt  -> +          let f    = runCF ctx gf in trace (collectH $ f pt)+++nodei :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ MonUnit m) +     => LocImage u a -> m a+nodei imgL = askDC    >>= \ctx -> +             position >>= \pt  -> +             let (a,o) = runLocImage ctx pt imgL+             in trace (collectH o) >> return a+
src/Wumpus/Basic/Paths/Base.hs view
@@ -217,12 +217,12 @@ -- segment is the same point as the start point of the next -- segment. ---toPrimPath :: Path u -> PrimPath u+toPrimPath :: Num u => Path u -> PrimPath u toPrimPath (Path _ _ segs _) = step1 $ viewl segs   where     step1 EmptyL                  = error "toPrimPath - (not) unreachable."     step1 (e :< se)               = let (start,a) = seg1 e in -                                    path start $ a : step2 (viewl se)+                                    primPath start $ a : step2 (viewl se)      step2 EmptyL                  = []     step2 (e :< se)               = seg2 e : step2 (viewl se)
src/Wumpus/Basic/Paths/RoundCorners.hs view
@@ -96,6 +96,9 @@ drawPathBoth pa@(Line1 p1 _)      = drawPath1 pa `oplus` pathPoint p1 drawPathBoth pa@(Curve1 p1 _ _ _) = drawPath1 pa `oplus` pathPoint p1 +++ drawPath1 :: Fractional u => PathSegment u -> Graphic u drawPath1 (Line1 p1 p2)        =      straightLineBetween p1 p2 `oplus` pathPoint p2@@ -105,12 +108,14 @@                                , pathPoint p4 ]  +-- WARNING - This indicates that straightLineBetween is not +-- consistent with other prim graphics...+ bezierCtrl :: Fractional u => Point2 u -> Point2 u -> Graphic u-bezierCtrl p1 p2 = -    localize (strokeColour light_steel_blue . fillColour red) $-      straightLineBetween p1 p2 `oplus` filledDisk 1 p2+bezierCtrl p1 p2 = localize (strokeColour light_steel_blue . fillColour red) $+      straightLineBetween p1 p2 `oplus` (filledDisk 1 `at` p2)   pathPoint :: Num u => Point2 u -> Graphic u-pathPoint = localize bothStrokeColour . filledDisk 1+pathPoint pt = localize bothStrokeColour (filledDisk 1 `at` pt) 
− src/Wumpus/Basic/PictureLanguage.hs
@@ -1,481 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.PictureLanguage--- Copyright   :  (c) Stephen Tetley 2009-2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC------ Composition operators for Pictures.------ Note - empty pictures cannot exist in Wumpus hence the /list/ --- functions in this module are always supplied with an initial --- picture, as well as the (possibly empty) list.--------------------------------------------------------------------------------------module Wumpus.Basic.PictureLanguage -  (-  -- * Data types for alignment -    HAlign(..)-  , VAlign(..)--  -- * Operations on boundary-  , centerPoint--  -- * Composition-  , over -  , under--  , centerOver-  , nextToH-  , nextToV-  -  , atPoint -  , centeredAt--  , stackOver-  , zconcat--  , hcat -  , vcat-  , stackOverCenter---  , hspace-  , vspace-  , hsep-  , vsep- -  -- * Compose with alignment-  , alignH-  , alignV-  , alignHSep-  , alignVSep-  , hcatA-  , vcatA-  , hsepA-  , vsepA--  ) where--import Wumpus.Core--import Data.AdditiveGroup-import Data.AffineSpace--import Data.List ( foldl' )-------------------------------------------------------------------------------------- Data types---- Alignment---- | Horizontal alignment - align to the top, center or bottom.-data HAlign = HTop | HCenter | HBottom-  deriving (Eq,Show)---- | Vertical alignment - align to the left, center or bottom.-data VAlign = VLeft | VCenter | VRight-  deriving (Eq,Show)--------------------------------------------------------------------------------------- Operations on bounds---- Corresponding operations are available on bounding boxes - the --- definitions here have different type class obligations.---- | The center of a picture.-centerPoint :: Fractional u => Picture u -> Point2 u-centerPoint = fn . boundary-  where  -    fn (BBox (P2 x0 y0) (P2 x1 y1)) = P2 (x0 + ((x1-x0)*0.5)) -                                         (y0 + ((y1-y0)*0.5))--rightBound :: Picture u -> u-rightBound = fn . ur_corner . boundary-  where-    fn (P2 x _) = x---leftBound :: Picture u -> u-leftBound = fn . ll_corner . boundary-  where-    fn (P2 x _) = x--bottomBound :: Picture u -> u-bottomBound = fn . ll_corner . boundary-  where-    fn (P2 _ y) = y--topBound :: Picture u -> u-topBound = fn . ur_corner . boundary-  where-    fn (P2 _ y) = y--------------------------------------------------------------------------------------- Composition operators---- | > a `over` b--- --- Place \'picture\' a over b. The idea of @over@ here is in --- terms z-ordering, nither picture a or b are actually moved.----over    :: (Num u, Ord u) => Picture u -> Picture u -> Picture u-over = picOver----- | > a `under` b------ Similarly @under@ draws the first picture behind --- the second but move neither.------ @under@ was previously @beneath@.----under :: (Num u, Ord u) => Picture u -> Picture u -> Picture u--under = flip over---  --- | Move in both the horizontal and vertical.----move :: (Num u, Ord u) => Vec2 u -> Picture u -> Picture u-move = flip picMoveBy---------- | Extract the top-left corner.----topleft       :: Picture u -> Point2 u-topleft       = fn . boundary -  where-    fn (BBox (P2 x0 _) (P2 _ y1)) = P2 x0 y1---- | Extract the top-right corner.----topright      :: Picture u -> Point2 u-topright      = ur_corner . boundary---- | Extract the bottom-left corner.----bottomleft    :: Picture u -> Point2 u-bottomleft    = ll_corner . boundary---- | Extract the bottom-right corner.----bottomright   :: Picture u -> Point2 u-bottomright   = fn . boundary-  where-    fn (BBox (P2 _ y0) (P2 x1 _)) = P2 x1 y0-------------------------------------------------------------------------------------- Internal helpers--leftmid       :: Fractional u => Picture u -> Point2 u-leftmid a     = P2 (leftBound a) (midpt (bottomBound a) (topBound a))--rightmid      :: Fractional u => Picture u -> Point2 u-rightmid a    = P2 (rightBound a) (midpt (bottomBound a) (topBound a))---topmid        :: Fractional u => Picture u -> Point2 u-topmid a      = P2 (midpt (leftBound a) (rightBound a)) (topBound a)--bottommid     :: Fractional u => Picture u -> Point2 u-bottommid a   = P2 (midpt (leftBound a) (rightBound a)) (bottomBound a)---midpt :: Fractional a => a -> a -> a-midpt a b = a + 0.5*(b-a)-------------------------------------------------------------------------------------- Composition--infixr 5 `nextToV`-infixr 6 `nextToH`, `centerOver`----- Note - `centerOver` moves the first argument, whereas other --- functions move the second...---- | Draw a centered over b - a is moved, b is static.------ > a `centerOver` b ------ 'centerOver' was previously the (-\@-) operator.--- -centerOver :: (Fractional u, Ord u) => Picture u -> Picture u -> Picture u-p1 `centerOver` p2 = (move v p1) `over` p2 -  where -    v = centerPoint p2 .-. centerPoint p1----- | > a `nextToH` b--- --- Horizontal composition - move @b@, placing it to the right --- of @a@.--- --- 'nextToH' was previously the (->-) operator.----nextToH :: (Num u, Ord u) => Picture u -> Picture u -> Picture u-a `nextToH` b = a `over` move hv b -  where -    hv = hvec $ rightBound a - leftBound b ------ | > a `nextToV` b------ Vertical composition - move @b@, placing it below @a@.------ nextToV  was previously the (-//-) operator.----nextToV :: (Num u, Ord u) => Picture u -> Picture u -> Picture u-a `nextToV` b = a `over` move vv b -  where -    vv = vvec $ bottomBound a - topBound b ----- | Place the picture at the supplied point.------ `atPoint` was previous the `at` operator.--- -atPoint :: (Num u, Ord u) => Picture u -> Point2 u  -> Picture u-p `atPoint` (P2 x y) = move (V2 x y) p----- | Center the picture at the supplied point.----centeredAt :: (Fractional u, Ord u) => Picture u -> Point2 u ->Picture u-centeredAt p (P2 x y) = move (vec dx dy) p -  where-    bb = boundary p-    dx = x - (boundaryWidth  bb * 0.5)-    dy = y - (boundaryHeight bb * 0.5)------ | > xs `stackOver` x--- --- Stack the list of pictures @xs@ 'over' @x@.------ Note, the first picture in the list is drawn at the top, all --- the pictures in the list are drawn \'over\' @x@. No pictures--- are moved ------ @ [p1,p2,p3] `stackOver` p4 => [p1,p2,p3,p4] @----stackOver :: (Num u, Ord u) => [Picture u] -> Picture u -> Picture u-stackOver = flip (foldr over)------ | > x `zconcat` xs--- --- Concatenate @x@ over the list of pictures @xs@. ------ @x@ is drawn at the top. No pictures are moved. ------ @ p1 `zconcat` [p2,p3,p4] => [p1,p2,p3,p4] @----zconcat :: (Num u, Ord u) => Picture u -> [Picture u] -> Picture u-zconcat = foldl' over-------- | Concatenate the list pictures @xs@ horizontally with @nextToH@ --- starting at @x@.--- -hcat :: (Num u, Ord u) => Picture u -> [Picture u] -> Picture u-hcat = foldl' nextToH----- | Concatenate the list of pictures @xs@ vertically with @nextToV@ --- starting at @x@.----vcat :: (Num u, Ord u) => Picture u -> [Picture u] -> Picture u-vcat = foldl' nextToV------ | Stack pictures centered ontop of each other - the first --- picture in the list is drawn at the top, last picture is on --- drawn at the bottom.----stackOverCenter :: (Fractional u, Ord u) -                => [Picture u] -> Picture u -> Picture u-stackOverCenter = flip $ foldr centerOver------------------------------------------------------------------------------------------- | > hspace n a b------ Horizontal composition - move @b@, placing it to the right --- of @a@ with a horizontal gap of @n@ separating the pictures.----hspace :: (Num u, Ord u) => u -> Picture u -> Picture u -> Picture u-hspace n a b = a `over` move hv b-  where-    hv = hvec $ n + rightBound a - leftBound b --    ------ | > vspace n a b------ Vertical composition - move @b@, placing it below @a@ with a--- vertical gap of @n@ separating the pictures.----vspace :: (Num u, Ord u) => u -> Picture u -> Picture u -> Picture u-vspace n a b = a `over` move vv b -  where -    vv = vvec $ bottomBound a - topBound b - n------ | > hsep n x xs------ Concatenate the list of pictures @xs@ horizontally with --- @hspace@ starting at @x@. The pictures are interspersed with --- spaces of @n@ units.----hsep :: (Num u, Ord u) => u -> Picture u -> [Picture u] -> Picture u-hsep n = foldl' (hspace n)------ | > vsep n x xs------ Concatenate the list of pictures @xs@ vertically with --- @vspace@ starting at @x@. The pictures are interspersed with --- spaces of @n@ units.----vsep :: (Num u, Ord u) => u -> Picture u -> [Picture u] -> Picture u-vsep n = foldl' (vspace n)-------------------------------------------------------------------------------------- Aligning pictures--vecMove :: (Num u, Ord u) => Picture u -> Picture u -> (Vec2 u) -> Picture u -vecMove a b v = a `over` (move v b)------ | > alignH align a b--- --- Horizontal composition - move @b@, placing it to the right --- of @a@ and align it with the top, center or bottom of @a@.--- -alignH :: (Fractional u, Ord u) -       =>  HAlign -> Picture u -> Picture u -> Picture u-alignH align p1 p2 = vecMove p1 p2 $ fn align-  where-    fn HTop    = topright p1    .-. topleft p2-    fn HCenter = rightmid p1    .-. leftmid p2-    fn HBottom = bottomright p1 .-. bottomleft p2----- | > alignV align a b--- --- Vertical composition - move @b@, placing it below @a@ --- and align it with the left, center or right of @a@.--- -alignV :: (Fractional u, Ord u) -           => VAlign -> Picture u -> Picture u -> Picture u-alignV align p1 p2 = vecMove p1 p2 $ fn align-  where-    fn VLeft   = bottomleft p1  .-. topleft p2-    fn VCenter = bottommid p1   .-. topmid p2-    fn VRight  = bottomright p1 .-. topright p2------ | > alignHSep align sep a b--- --- Spacing version of alignH - move @b@ to the right of @a@ --- separated by @sep@ units, align @b@ according to @align@.--- -alignHSep :: (Fractional u, Ord u) -              =>  HAlign -> u -> Picture u -> Picture u -> Picture u-alignHSep align dx p1 p2 = vecMove p1 p2 $ hvec dx ^+^ fn align-  where-    fn HTop    = topright p1    .-. topleft p2-    fn HCenter = rightmid p1    .-. leftmid p2-    fn HBottom = bottomright p1 .-. bottomleft p2---- | > alignHSep align sep a b--- --- Spacing version of alignV - move @b@ below @a@ --- separated by @sep@ units, align @b@ according to @align@.--- -alignVSep :: (Fractional u, Ord u) -           => VAlign -> u -> Picture u -> Picture u -> Picture u-alignVSep align dy p1 p2 = vecMove p1 p2 $ vvec (-dy) ^+^ fn align-  where-    fn VLeft   = bottomleft p1  .-. topleft p2-    fn VCenter = bottommid p1   .-. topmid p2-    fn VRight  = bottomright p1 .-. topright p2------ | Variant of 'hcat' that aligns the pictures as well as--- concatenating them.----hcatA :: (Fractional u, Ord u) -      => HAlign -> Picture u -> [Picture u] -> Picture u-hcatA ha = foldl' (alignH ha)---- | Variant of 'vcat' that aligns the pictures as well as--- concatenating them.----vcatA :: (Fractional u, Ord u) -      => VAlign -> Picture u -> [Picture u] -> Picture u-vcatA va = foldl' (alignV va)----- | Variant of @hsep@ that aligns the pictures as well as--- concatenating and spacing them.----hsepA :: (Fractional u, Ord u) -      => HAlign -> u -> Picture u -> [Picture u] -> Picture u-hsepA ha n = foldl' op -  where -    a `op` b = alignHSep ha n a b ----- | Variant of @vsep@ that aligns the pictures as well as--- concatenating and spacing them.----vsepA :: (Fractional u, Ord u) -      => VAlign -> u -> Picture u -> [Picture u] -> Picture u-vsepA va n = foldl' op -  where -    a `op` b = alignVSep va n a b ---
src/Wumpus/Basic/SafeFonts.hs view
@@ -10,9 +10,15 @@ -- Stability   :  highly unstable -- Portability :  GHC ----- Safe to use fonts.+-- Safe to use \"Core 13\" fonts that are expected to be present+-- for any PostScript interpreter. --+-- Note - regrettably Symbol is not safe to use for SVG. --+-- \*\* WARNING \*\* - this module is in flux due to changes to +-- Text encoding in Wumpus-Core and adding font metrics to +-- Wumpus-Basic. The code here is likely to be revised.+-- --------------------------------------------------------------------------------  module Wumpus.Basic.SafeFonts@@ -43,6 +49,8 @@   import Wumpus.Core+import Wumpus.Core.Text.StandardEncoding+import Wumpus.Core.Text.Symbol  -- Supported fonts are: --@@ -58,19 +66,19 @@ --  times_roman :: FontFace times_roman = -    FontFace "Times-Roman" "Times New Roman" SVG_REGULAR latin1_font_encoder+    FontFace "Times-Roman" "Times New Roman" SVG_REGULAR standard_encoding  -- | Times Italic -- times_italic :: FontFace times_italic = -    FontFace "Times-Italic" "Times New Roman" SVG_ITALIC latin1_font_encoder+    FontFace "Times-Italic" "Times New Roman" SVG_ITALIC standard_encoding                         -- | Times Bold -- times_bold :: FontFace times_bold = -    FontFace "Times-Bold" "Times New Roman" SVG_BOLD latin1_font_encoder+    FontFace "Times-Bold" "Times New Roman" SVG_BOLD standard_encoding  -- | Times Bold Italic --@@ -78,7 +86,7 @@ times_bold_italic = FontFace "Times-BoldItalic"                               "Times New Roman"                               SVG_BOLD_ITALIC -                             latin1_font_encoder+                             standard_encoding   --------------------------------------------------------------------------------@@ -87,20 +95,20 @@ -- | Helvetica  -- helvetica :: FontFace-helvetica = FontFace "Helvetica" "Helvetica" SVG_REGULAR latin1_font_encoder+helvetica = FontFace "Helvetica" "Helvetica" SVG_REGULAR standard_encoding   -- | Helvetica Oblique -- helvetica_oblique :: FontFace helvetica_oblique = -    FontFace "Helvetica-Oblique" "Helvetica" SVG_OBLIQUE latin1_font_encoder+    FontFace "Helvetica-Oblique" "Helvetica" SVG_OBLIQUE standard_encoding  -- | Helvetica Bold --  helvetica_bold :: FontFace helvetica_bold = -    FontFace "Helvetica-Bold" "Helvetica" SVG_BOLD latin1_font_encoder+    FontFace "Helvetica-Bold" "Helvetica" SVG_BOLD standard_encoding   -- | Helvetica Bold Oblique@@ -109,7 +117,7 @@ helvetica_bold_oblique = FontFace "Helvetica-Bold-Oblique"                                    "Helvetica"                                    SVG_BOLD_OBLIQUE -                                  latin1_font_encoder+                                  standard_encoding   @@ -118,19 +126,19 @@ -- | Courier --  courier :: FontFace-courier = FontFace "Courier" "Courier New" SVG_REGULAR latin1_font_encoder+courier = FontFace "Courier" "Courier New" SVG_REGULAR standard_encoding  -- | Courier Oblique --  courier_oblique :: FontFace courier_oblique = -    FontFace "Courier-Oblique" "Courier New" SVG_OBLIQUE latin1_font_encoder+    FontFace "Courier-Oblique" "Courier New" SVG_OBLIQUE standard_encoding  -- | Courier Bold --  courier_bold :: FontFace courier_bold = -    FontFace "Courier-Bold" "Courier New" SVG_BOLD latin1_font_encoder+    FontFace "Courier-Bold" "Courier New" SVG_BOLD standard_encoding   -- | Courier Bold Oblique@@ -139,19 +147,19 @@ courier_bold_oblique = FontFace "Courier-Bold-Oblique"                                  "Courier New"                                  SVG_BOLD_OBLIQUE -                                latin1_font_encoder+                                standard_encoding  -------------------------------------------------------------------------------- -- Symbol  -- | Symbol ----- Note - Symbol does not appear to be well supported by some SVG--- renders. Seemingly Chrome is fine but Firefox defaults to some--- serif font.+-- Note - Symbol is intentionally not supported for SVG by some +-- renderers (Firefox). Chrome is fine, but the use of symbol +-- should be still be avoided for web graphics. --  symbol :: FontFace-symbol = FontFace "Symbol" "Symbol" SVG_REGULAR symbol_font_encoder+symbol = FontFace "Symbol" "Symbol" SVG_REGULAR symbol_encoding   
src/Wumpus/Basic/Shapes.hs view
@@ -19,11 +19,9 @@     module Wumpus.Basic.Shapes.Base   , module Wumpus.Basic.Shapes.Coordinate   , module Wumpus.Basic.Shapes.Derived-  , module Wumpus.Basic.Shapes.Plaintext    ) where  import Wumpus.Basic.Shapes.Base import Wumpus.Basic.Shapes.Coordinate import Wumpus.Basic.Shapes.Derived hiding ( mkRectangle )-import Wumpus.Basic.Shapes.Plaintext
src/Wumpus/Basic/Shapes/Base.hs view
@@ -14,8 +14,8 @@ -- -- Common core for shapes -- --- \*\* WARNING \*\* - the types of Shapes and Plaintext are not--- ideal and are pending revision.+-- \*\* WARNING \*\* - the types of Shapes are not ideal and are +-- pending revision. -- -------------------------------------------------------------------------------- @@ -42,6 +42,7 @@   , askCTM   , projectPoint   , shapeCenter+  , shapeAngle    ) where @@ -207,9 +208,11 @@ askCTM :: ShapeGeom u (ShapeCTM u) askCTM = ShapeGeom $ \ctm -> ctm -shapeCenter :: (Real u, Floating u) => ShapeGeom u (Point2 u)-shapeCenter = ShapeGeom $ \r -> ctm_center r+shapeCenter :: ShapeGeom u (Point2 u)+shapeCenter = ShapeGeom $ \ctm -> ctm_center ctm +shapeAngle :: ShapeGeom u Radian+shapeAngle = ShapeGeom $ \ctm -> ctm_rotation ctm   @@ -220,5 +223,4 @@                , ctm_scale_y  = sy                , ctm_rotation = theta }) ->      translate dx dy $ rotate theta $ P2 (sx*x) (sy*y)- 
src/Wumpus/Basic/Shapes/Coordinate.hs view
@@ -11,12 +11,16 @@ -- Stability   :  highly unstable -- Portability :  GHC ----- Coordinate is a bit like a shape but does not generate a path --- and cannot be scaled or rotated (it can be translated).--- --- \*\* WARNING \*\* - the types of Shapes and Coordinate are not--- ideal and are pending revision.+-- A Coordinate is operationally like a shape but it can only be +-- drawn as a dot or a cross and it only supports @CenterAnchor@.  --+-- Coordinates support affine transformations, however +-- transfomations only displace a coordinate\'s origin they do +-- not change how it is drawn (one cannot elongate the drawing of +-- a coordinate with a scale). This is why coordinates are not +-- Shapes, though one major use of coordinates is to illustrate +-- anchor points on Shapes.+--  --------------------------------------------------------------------------------  module Wumpus.Basic.Shapes.Coordinate@@ -27,26 +31,31 @@   , DCoordinate   , coordinate -  , coordinateMark+  , coordinateDot+  , coordinateX    ) where -import Wumpus.Basic.Anchors import Wumpus.Basic.Graphic+import Wumpus.Basic.Shapes.Base  import Wumpus.Core                              -- package: wumpus-core -+import Control.Monad +-- Note - a CoordinateAnchor should _NOT_ have affine instances.+-- +-- However, a coordinate supports affine transformations. This +-- follows the logic where Shapes transform but representations +-- of their anchors (i.e. the concrete types Rectangle, Circle...)+-- do not transform. +--    -------------------------------------------------------------------------------- -- | Coordinate -data CoordinateAnchor u = CoordinateAnchor-      { coord_x   :: !u-      , coord_y   :: !u-      }+newtype CoordinateAnchor u = CoordinateAnchor { getCoordAnchor :: ShapeCTM u }   deriving (Eq,Ord,Show)  type DCoordinateAnchor = CoordinateAnchor Double@@ -60,29 +69,68 @@  type instance DUnit (Coordinate u) = u +type LocCoordinate u = Point2 u -> Coordinate u +++runCoordinate :: ShapeGeom u a -> CoordinateAnchor u -> a+runCoordinate mf a = runShapeGeom (getCoordAnchor a) mf ++ instance (Real u, Floating u) => CenterAnchor (CoordinateAnchor u) where-  center (CoordinateAnchor x y) = P2 x y+  center = runCoordinate shapeCenter +cMap :: (ShapeCTM u -> ShapeCTM u) -> Coordinate u -> Coordinate u+cMap fn = Coordinate . CoordinateAnchor . fn . getCoordAnchor . getCoordinate+++-- Affine instances++instance (Real u, Floating u) => Rotate (Coordinate u) where+  rotate r = cMap (rotate r)++instance (Real u, Floating u) => RotateAbout (Coordinate u) where+  rotateAbout r pt = cMap (rotateAbout r pt)++instance Num u => Scale (Coordinate u) where+  scale sx sy = cMap (scale sx sy)+ instance Num u => Translate (Coordinate u) where-  translate dx dy = Coordinate . fn . getCoordinate -    where -      fn (CoordinateAnchor x y) = CoordinateAnchor (x+dx) (y+dy)+  translate dx dy = cMap (translate dx dy) --- Need a differentiation at the type level between a coord--- that can be translated (moved) and a coord that anchors... -coordinate :: Num u => Point2 u -> Coordinate u-coordinate (P2 x y) = Coordinate $ CoordinateAnchor { coord_x = x, coord_y = y } --- Note - should @coordinate@ take a point, Shapes don\'t.+coordinate :: Num u => LocCoordinate u+coordinate = Coordinate . CoordinateAnchor . makeShapeCTM  -coordinateMark :: (Real u, Floating u) -               => Coordinate u -> Image u (CoordinateAnchor u)-coordinateMark x = intoImage (return $ getCoordinate x) (drawCoord x)+coordinateDot :: (Real u, Floating u, FromPtSize u) +              => Coordinate u -> Image u (CoordinateAnchor u)+coordinateDot x = intoImage (return $ getCoordinate x) (drawDot x) -drawCoord :: (Real u, Floating u) => Coordinate u -> Graphic u-drawCoord coord = -   localize bothStrokeColour $ filledEllipse 2 2 (center $ getCoordinate coord)+++-- | Note - the @x@ is drawn /regardless/ of any scaling or rotation.+--+coordinateX :: (Real u, Floating u, FromPtSize u) +            => Coordinate u -> Image u (CoordinateAnchor u)+coordinateX x = intoImage (return $ getCoordinate x) (drawX x)++++quarterMarkHeight :: (Fractional u, FromPtSize u) => CF u+quarterMarkHeight = liftM (0.25*) markHeight++drawDot :: (Real u, Floating u, FromPtSize u) => Coordinate u -> Graphic u+drawDot coord = quarterMarkHeight >>= \qh -> +    localize bothStrokeColour (filledEllipse qh qh `at` ctr)+  where+    ctr = center $ getCoordinate coord++drawX :: (Real u, Floating u, FromPtSize u) => Coordinate u -> Graphic u+drawX coord = quarterMarkHeight >>= \qh -> line1 qh `oplus` line2 qh+  where+    P2 x y  = center $ getCoordinate coord+    line1 h = straightLineBetween (P2 (x-h) (y-h)) (P2 (x+h) (y+h))+    line2 h = straightLineBetween (P2 (x+h) (y-h)) (P2 (x-h) (y+h)) 
src/Wumpus/Basic/Shapes/Derived.hs view
@@ -15,9 +15,6 @@ -- -- Simple shapes - rectangle, circle diamond, ellipse. -- --- \*\* WARNING \*\* - the types of Shapes and Plaintext are not--- ideal and are pending revision.---  --------------------------------------------------------------------------------  module Wumpus.Basic.Shapes.Derived@@ -45,7 +42,7 @@    ) where -import Wumpus.Basic.Anchors+import Wumpus.Basic.Graphic import Wumpus.Basic.Paths import Wumpus.Basic.Paths.RoundCorners import Wumpus.Basic.Shapes.Base@@ -85,7 +82,7 @@   runRectangle :: (u -> u -> ShapeGeom u a) -> Rectangle u -> a-runRectangle mf (Rectangle { rect_ctm =ctm, rect_hw = hw, rect_hh = hh }) = +runRectangle mf (Rectangle { rect_ctm = ctm, rect_hw = hw, rect_hh = hh }) =     runShapeGeom ctm $ mf hw hh   instance (Real u, Floating u) => CenterAnchor (Rectangle u) where
− src/Wumpus/Basic/Shapes/Plaintext.hs
@@ -1,149 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Shapes.Plaintext--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Plaintext is a bit like a shape but does not generate a path --- and cannot be scaled (it can be rotated or translated).------ \*\* WARNING \*\* - the types of Shapes and Plaintext are not--- ideal and are pending revision.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Shapes.Plaintext-  (--    PlaintextAnchor-  , DPlaintextAnchor-  , Plaintext-  , DPlaintext--  , plaintext-  , drawText--  ) where--import Wumpus.Basic.Anchors-import Wumpus.Basic.Graphic-import Wumpus.Basic.Shapes.Base-import Wumpus.Basic.Shapes.Derived--import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace                         -- package: vector-space--import Control.Applicative---------------------------------------------------------------------------------------- Free label---- Free label is a rectangle that /is not drawn/, the --- constructor should always create some text.--newtype PlaintextAnchor u = PlaintextAnchor  { getPlaintext :: Rectangle u }---type DPlaintextAnchor = PlaintextAnchor Double--type instance DUnit (PlaintextAnchor u) = u---data Plaintext u = Plaintext-      { text_text :: String     -- Note - generalize this for multi-line...-      , text_x    :: !u-      , text_y    :: !u-      , text_ang  :: !Radian-      }-  deriving (Eq,Ord,Show)--type DPlaintext = Plaintext Double--type instance DUnit (Plaintext u) = u---instance (Real u, Floating u) => CenterAnchor (PlaintextAnchor u) where-  center = center . getPlaintext---instance (Real u, Floating u) => CardinalAnchor (PlaintextAnchor u) where-  north = north . getPlaintext-  south = south . getPlaintext-  east  = east . getPlaintext-  west  = west . getPlaintext--instance (Real u, Floating u) => CardinalAnchor2 (PlaintextAnchor u) where-  northeast = northeast . getPlaintext-  southeast = southeast . getPlaintext-  southwest = southwest . getPlaintext-  northwest = northwest . getPlaintext--instance (Real u, Floating u) => RadialAnchor (PlaintextAnchor u) where-  radialAnchor theta = radialAnchor theta . getPlaintext----instance Rotate (Plaintext u) where-  rotate dr = (\s i -> s { text_ang = i+dr }) <*> text_ang---- Note - cannot scale Plaintext---instance Num u => Translate (Plaintext u) where-  translate dx dy = (\s x y -> s { text_x = x+dx, text_y = y+dy }) -                      <*> text_x <*> text_y----plaintext :: Num u => String -> Plaintext u-plaintext ss = Plaintext { text_text  = ss-                         , text_x     = 0-                         , text_y     = 0-                         , text_ang   = 0 }-----drawText :: (Real u, Floating u, FromPtSize u)-         => Plaintext u -> Image u (PlaintextAnchor u)-drawText x = intoImage (oneLineRect x) (drawOneLine x)----textCTM :: Num u => u -> u -> Radian -> ShapeCTM u-textCTM x y theta = rotate theta $ makeShapeCTM (P2 x y)--oneLineRect :: (Fractional u, Ord u, FromPtSize u) -        => Plaintext u -> DrawingR (PlaintextAnchor u)-oneLineRect ptext = -    monoTextDimensions (text_text ptext) >>= \(w,h) -> -    return (PlaintextAnchor $ mkRectangle (0.5*w) (0.5*h) ctm)-  where-    ctm = textCTM (text_x ptext) (text_y ptext) (text_ang ptext)-                   --drawOneLine :: (Real u, Floating u, FromPtSize u) -            => Plaintext u -> Graphic u -drawOneLine (Plaintext { text_text = ss, text_x=dx, text_y=dy-                       , text_ang = ang }) =-    monoVecToCenter ss >>= \v -> -    let ctr = P2 dx dy; bl = ctr .-^ v in -    rotTextline ang ss (rotateAbout ang ctr bl)----rotTextline :: (Real u, Floating u) => Radian -> String -> LocGraphic u-rotTextline theta ss baseline_left = -    withTextAttr $ \rgb attr -> -        wrapPrim $ rtextlabel rgb attr ss theta baseline_left
− src/Wumpus/Basic/Text/LRSymbol.hs
@@ -1,746 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Text.LRSymbol--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Named literals from Symbol font, drawn with the LRText monad.--- --- Note - Symbol font handling and precise letter placing in SVG --- viewers is mixed. Chrome works well good, Firefox (3.6.3) and --- Safari (5.0.1) are unsatisfactory.---  ---   --------------------------------------------------------------------------------------module Wumpus.Basic.Text.LRSymbol-  ( ---  -- * Upper case letters and upper case Greek letters-    uAlpha-  , uBeta-  , uChi-  , uDelta-  , uEpsilon-  , uEta-  , uEuro-  , uGamma-  , uIfraktur-  , uIota-  , uKappa-  , uLambda-  , uMu-  , uNu-  , uOmega-  , uOmicron-  , uPhi-  , uPi-  , uPsi-  , uRfraktur-  , uRho-  , uSigma-  , uTau-  , uTheta-  , uUpsilon-  , uUpsilon1-  , uXi-  , uZeta-  ---  -- * Lower case Greek letters--  , alpha-  , beta-  , gamma-  , delta-  , epsilon-  , zeta-  , eta-  , theta-  , iota-  , kappa-  , lambda-  , mu-  , nu-  , xi-  , pi-  , rho-  , sigma-  , tau-  , upsilon-  , phi-  , chi-  , psi-  , omega--  -- * Miscellaneous chars-  , aleph-  , ampersand-  , angle-  , angleleft-  , angleright-  , approxequal-  , arrowboth-  , arrowdblboth-  , arrowdbldown-  , arrowdblleft-  , arrowdblright-  , arrowdblup-  , arrowdown-  , arrowleft-  , arrowright-  , arrowup-  , asteriskmath-  , bar-  , braceleft-  , braceright-  , bracketleft-  , bracketright-  , bullet-  , carriagereturn-  , circlemultiply-  , circleplus-  , club -  , colon-  , comma-  , congruent-  , copyrightsans-  , copyrightserif-  , degree-  , diamond-  , divide-  , dotmath-  , eight-  , element-  , ellipsis-  , emptyset-  , equal-  , equivalence-  , exclam-  , existential-  , five-  , florin-  , four-  , fraction-  , gradient-  , greater-  , greaterequal-  , heart-  , infinity-  , integral-  , intersection-  , less-  , lessequal-  , logicaland-  , logicalnot-  , logicalor-  , lozenge-  , minus-  , minute-  , multiply-  , nine-  , notelement-  , notequal-  , notsubset-  , numbersign-  , omega1-  , omicron-  , one-  , parenleft-  , parenright-  , partialdiff-  , percent-  , period-  , perpendicular-  , phi1-  , plus-  , plusminus-  , product-  , propersubset-  , propersuperset-  , proportional-  , question-  , radical-  , radicalex-  , reflexsubset-  , reflexsuperset-  , registersans-  , registerserif-  , second-  , semicolon-  , seven-  , sigma1-  , similar-  , six-  , slash-  , space-  , spade-  , suchthat-  , summation-  , therefore-  , theta1-  , three-  , trademarksans-  , trademarkserif-  , two-  , underscore-  , union-  , universal-  , weierstrass-  , zero--  ) where---import Wumpus.Basic.Text.LRText---import Prelude hiding ( pi, product )--------------------------------------------------------------------------------------- upper case---- | Note - prints as \'A\'.----uAlpha          :: Num u => LRText u ()-uAlpha          = symb 'A'---- | Note - prints as \'B\'.----uBeta           :: Num u => LRText u ()-uBeta           = symb 'B'---- | Note - prints as \'X\'.----uChi            :: Num u => LRText u ()-uChi            = symb 'C'--uDelta          :: Num u => LRText u ()-uDelta          = symb 'D'---- | Note - prints as \'E\'.----uEpsilon        :: Num u => LRText u ()-uEpsilon        = symb 'E'---- | Note - prints as \'H\'.----uEta            :: Num u => LRText u ()-uEta            = symb 'H'----- | Note - does not appear to print in Chrome.----uEuro           :: Num u => LRText u ()-uEuro           = symbEscInt 0o240--uGamma          :: Num u => LRText u ()-uGamma          = symb 'G'--uIfraktur       :: Num u => LRText u ()-uIfraktur       = symbEscInt 0o301---- | Note - prints as \'I\'.----uIota           :: Num u => LRText u ()-uIota           = symb 'I'---- | Note - prints as \'K\'.----uKappa          :: Num u => LRText u ()-uKappa          = symb 'K'--uLambda         :: Num u => LRText u ()-uLambda         = symb 'L'---- | Note - prints as \'M\'.----uMu             :: Num u => LRText u ()-uMu             = symb 'M'---- | Note - prints as \'N\'.----uNu             :: Num u => LRText u ()-uNu             = symb 'N'--uOmega          :: Num u => LRText u ()-uOmega          = symbEscInt 0o127--uOmicron        :: Num u => LRText u ()-uOmicron        = symbEscInt 0o117--uPhi            :: Num u => LRText u ()-uPhi            = symbEscInt 0o106--uPi             :: Num u => LRText u ()-uPi             = symb 'P'--uPsi            :: Num u => LRText u ()-uPsi            = symbEscInt 0o131--uRfraktur       :: Num u => LRText u ()-uRfraktur       = symbEscInt 0o302--uRho            :: Num u => LRText u ()-uRho            = symbEscInt 0o122--uSigma          :: Num u => LRText u ()-uSigma          = symb 'S'--uTau            :: Num u => LRText u ()-uTau            = symb 'T'---uTheta          :: Num u => LRText u ()-uTheta          = symb 'Q'---- | Note - prints as \'Y\'.----uUpsilon        :: Num u => LRText u ()-uUpsilon        = symbEscInt 0o125---- | Note - this is the /pretty/ Upsilon.----uUpsilon1       :: Num u => LRText u ()-uUpsilon1       = symbEscInt 0o241--uXi             :: Num u => LRText u ()-uXi             = symb 'X'--uZeta           :: Num u => LRText u ()-uZeta           = symb 'Z'-------------------------------------------------------------------------------------- lower case Greek letters---alpha           :: Num u => LRText u ()-alpha           = symb 'a'--beta            :: Num u => LRText u ()-beta            = symb 'b'--gamma           :: Num u => LRText u ()-gamma           = symb 'g'--delta           :: Num u => LRText u ()-delta           = symb 'd'--epsilon         :: Num u => LRText u ()-epsilon         = symb 'e'--zeta            :: Num u => LRText u ()-zeta            = symb 'z'--eta             :: Num u => LRText u ()-eta             = symb 'h'--theta           :: Num u => LRText u ()-theta           = symb 'q'--iota            :: Num u => LRText u ()-iota            = symb 'i'--kappa           :: Num u => LRText u ()-kappa           = symb 'k'--lambda          :: Num u => LRText u ()-lambda          = symb 'l'--mu              :: Num u => LRText u ()-mu              = symb 'm'--nu              :: Num u => LRText u ()-nu              = symb 'n'--xi              :: Num u => LRText u ()-xi              = symb 'x'--pi              :: Num u => LRText u ()-pi              = symb 'p'--rho             :: Num u => LRText u ()-rho             = symb 'r'--sigma           :: Num u => LRText u ()-sigma           = symb 's'--tau             :: Num u => LRText u ()-tau             = symb 't'--upsilon         :: Num u => LRText u ()-upsilon         = symb 'u'--phi             :: Num u => LRText u ()-phi             = symb 'j'--chi             :: Num u => LRText u ()-chi             = symb 'c'--psi             :: Num u => LRText u ()-psi             = symb 'y'--omega           :: Num u => LRText u ()-omega           = symb 'w'--------------------------------------------------------------------------------------- Miscellaneous chars--aleph           :: Num u => LRText u ()-aleph           = symbEscInt 0o300--ampersand       :: Num u => LRText u ()-ampersand       = symbEscInt 0o046--angle           :: Num u => LRText u ()-angle           = symbEscInt 0o320--angleleft       :: Num u => LRText u ()-angleleft       = symbEscInt 0o341--angleright      :: Num u => LRText u ()-angleright      = symbEscInt 0o361--approxequal     :: Num u => LRText u ()-approxequal     = symbEscInt 0o273--arrowboth       :: Num u => LRText u ()-arrowboth       = symbEscInt 0o253--arrowdblboth    :: Num u => LRText u ()-arrowdblboth    = symbEscInt 0o333--arrowdbldown    :: Num u => LRText u ()-arrowdbldown    = symbEscInt 0o337--arrowdblleft    :: Num u => LRText u ()-arrowdblleft    = symbEscInt 0o334--arrowdblright   :: Num u => LRText u ()-arrowdblright   = symbEscInt 0o336--arrowdblup      :: Num u => LRText u ()-arrowdblup      = symbEscInt 0o335--arrowdown       :: Num u => LRText u ()-arrowdown       = symbEscInt 0o257--arrowleft       :: Num u => LRText u ()-arrowleft       = symbEscInt 0o254--arrowright      :: Num u => LRText u ()-arrowright      = symbEscInt 0o256--arrowup         :: Num u => LRText u ()-arrowup         = symbEscInt 0o255--asteriskmath    :: Num u => LRText u ()-asteriskmath    = symbEscInt 0o052--bar             :: Num u => LRText u ()-bar             = symbEscInt 0o174--braceleft       :: Num u => LRText u ()-braceleft       = symbEscInt 0o173--braceright      :: Num u => LRText u ()-braceright      = symbEscInt 0o175--bracketleft     :: Num u => LRText u ()-bracketleft     = symbEscInt 0o133--bracketright    :: Num u => LRText u ()-bracketright    = symbEscInt 0o135--bullet          :: Num u => LRText u ()-bullet          = symbEscInt 0o267--carriagereturn  :: Num u => LRText u ()-carriagereturn  = symbEscInt 0o277---circlemultiply  :: Num u => LRText u ()-circlemultiply  = symbEscInt 0o304--circleplus      :: Num u => LRText u ()-circleplus      = symbEscInt 0o305--club            :: Num u => LRText u ()-club            = symbEscInt 0o247--colon           :: Num u => LRText u ()-colon           = symbEscInt 0o072--comma           :: Num u => LRText u ()-comma           = symbEscInt 0o054--congruent       :: Num u => LRText u ()-congruent             = symbEscInt 0o100--copyrightsans   :: Num u => LRText u ()-copyrightsans   = symbEscInt 0o343--copyrightserif  :: Num u => LRText u ()-copyrightserif  = symbEscInt 0o323--degree          :: Num u => LRText u ()-degree          = symbEscInt 0o260--diamond         :: Num u => LRText u ()-diamond         = symbEscInt 0o250--divide          :: Num u => LRText u ()-divide          = symbEscInt 0o270--dotmath         :: Num u => LRText u ()-dotmath         = symbEscInt 0o327--eight           :: Num u => LRText u ()-eight           = symbEscInt 0o070--element         :: Num u => LRText u ()-element         = symbEscInt 0o316--ellipsis        :: Num u => LRText u ()-ellipsis        = symbEscInt 0o274--emptyset        :: Num u => LRText u ()-emptyset        = symbEscInt 0o306--equal           :: Num u => LRText u ()-equal           = symbEscInt 0o075--equivalence     :: Num u => LRText u ()-equivalence     = symbEscInt 0o272--exclam          :: Num u => LRText u ()-exclam          = symbEscInt 0o041--existential     :: Num u => LRText u ()-existential     = symbEscInt 0o044--five            :: Num u => LRText u ()-five            = symbEscInt 0o065--florin          :: Num u => LRText u ()-florin          = symbEscInt 0o246--four            :: Num u => LRText u ()-four            = symbEscInt 0o064--fraction        :: Num u => LRText u ()-fraction        = symbEscInt 0o244--gradient        :: Num u => LRText u ()-gradient        = symbEscInt 0o321--greater         :: Num u => LRText u ()-greater         = symbEscInt 0o076--greaterequal    :: Num u => LRText u ()-greaterequal    = symbEscInt 0o263--heart           :: Num u => LRText u ()-heart           = symbEscInt 0o251--infinity        :: Num u => LRText u ()-infinity        = symbEscInt 0o245--integral        :: Num u => LRText u ()-integral        = symbEscInt 0o362--intersection    :: Num u => LRText u ()-intersection    = symbEscInt 0o307--less            :: Num u => LRText u ()-less            = symbEscInt 0o074--lessequal       :: Num u => LRText u ()-lessequal       = symbEscInt 0o243--logicaland      :: Num u => LRText u ()-logicaland      = symbEscInt 0o331--logicalnot      :: Num u => LRText u ()-logicalnot      = symbEscInt 0o330--logicalor       :: Num u => LRText u ()-logicalor       = symbEscInt 0o332--lozenge         :: Num u => LRText u ()-lozenge         = symbEscInt 0o340--minus           :: Num u => LRText u ()-minus           = symbEscInt 0o055--minute          :: Num u => LRText u ()-minute          = symbEscInt 0o242--multiply        :: Num u => LRText u ()-multiply        = symbEscInt 0o264--nine            :: Num u => LRText u ()-nine            = symbEscInt 0o071--notelement      :: Num u => LRText u ()-notelement      = symbEscInt 0o317--notequal        :: Num u => LRText u ()-notequal        = symbEscInt 0o271--notsubset       :: Num u => LRText u ()-notsubset       = symbEscInt 0o313--numbersign      :: Num u => LRText u ()-numbersign      = symbEscInt 0o043--omega1          :: Num u => LRText u ()-omega1          = symbEscInt 0o166--omicron         :: Num u => LRText u ()-omicron         = symbEscInt 0o157--one             :: Num u => LRText u ()-one             = symbEscInt 0o061--parenleft       :: Num u => LRText u ()-parenleft       = symbEscInt 0o050--parenright      :: Num u => LRText u ()-parenright      = symbEscInt 0o051--partialdiff     :: Num u => LRText u ()-partialdiff     = symbEscInt 0o266--percent         :: Num u => LRText u ()-percent         = symbEscInt 0o045--period          :: Num u => LRText u ()-period          = symbEscInt 0o056--perpendicular   :: Num u => LRText u ()-perpendicular   = symbEscInt 0o136--phi1            :: Num u => LRText u ()-phi1            = symbEscInt 0o152--plus            :: Num u => LRText u ()-plus            = symbEscInt 0o053--plusminus       :: Num u => LRText u ()-plusminus       = symbEscInt 0o261--product         :: Num u => LRText u ()-product         = symbEscInt 0o325--propersubset    :: Num u => LRText u ()-propersubset    = symbEscInt 0o314--propersuperset  :: Num u => LRText u ()-propersuperset  = symbEscInt 0o311--proportional    :: Num u => LRText u ()-proportional    = symbEscInt 0o265--question        :: Num u => LRText u ()-question        = symbEscInt 0o077--radical         :: Num u => LRText u ()-radical         = symbEscInt 0o326--radicalex       :: Num u => LRText u ()-radicalex       = symbEscInt 0o140--reflexsubset    :: Num u => LRText u ()-reflexsubset    = symbEscInt 0o315--reflexsuperset  :: Num u => LRText u ()-reflexsuperset  = symbEscInt 0o312--registersans    :: Num u => LRText u ()-registersans    = symbEscInt 0o342--registerserif   :: Num u => LRText u ()-registerserif   = symbEscInt 0o322--second          :: Num u => LRText u ()-second          = symbEscInt 0o262--semicolon       :: Num u => LRText u ()-semicolon       = symbEscInt 0o073--seven           :: Num u => LRText u ()-seven           = symbEscInt 0o067--sigma1          :: Num u => LRText u ()-sigma1          = symbEscInt 0o126--similar         :: Num u => LRText u ()-similar         = symbEscInt 0o176--six             :: Num u => LRText u ()-six             = symbEscInt 0o066--slash           :: Num u => LRText u ()-slash           = symbEscInt 0o057--space           :: Num u => LRText u ()-space           = symbEscInt 0o040--spade           :: Num u => LRText u ()-spade           = symbEscInt 0o252--suchthat        :: Num u => LRText u ()-suchthat        = symbEscInt 0o047--summation       :: Num u => LRText u ()-summation       = symbEscInt 0o345--therefore       :: Num u => LRText u ()-therefore       = symbEscInt 0o134--theta1          :: Num u => LRText u ()-theta1          = symbEscInt 0o112--three           :: Num u => LRText u ()-three           = symbEscInt 0o063--trademarksans   :: Num u => LRText u ()-trademarksans   = symbEscInt 0o344--trademarkserif  :: Num u => LRText u ()-trademarkserif  = symbEscInt 0o324--two             :: Num u => LRText u ()-two             = symbEscInt 0o062--underscore      :: Num u => LRText u ()-underscore      = symbEscInt 0o137--union           :: Num u => LRText u ()-union           = symbEscInt 0o310--universal       :: Num u => LRText u ()-universal       = symbEscInt 0o042--weierstrass     :: Num u => LRText u ()-weierstrass     = symbEscInt 0o303--zero            :: Num u => LRText u ()-zero            = symbEscInt 0o060--
src/Wumpus/Basic/Text/LRText.hs view
@@ -7,191 +7,233 @@ -- Copyright   :  (c) Stephen Tetley 2010 -- License     :  BSD3 ----- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable -- Portability :  GHC ----- LRText monad - left-to-right text, with kerning.--- --- Note - because Wumpus has no access to the metrics data inside--- a font file, the default spacing is not good and it is --- expected that kerning will need to be added per-letter for--- variable width fonts.------ This module makes precise horizontal text spacing \*possible\*, --- it does not make it \*easy\*.+-- Left-to-right measured text. The text uses glyph metrics so it +-- can be positioned accurately. --  --------------------------------------------------------------------------------  module Wumpus.Basic.Text.LRText   (  +   +    singleLineBL+  , singleLineCC -    LRText+  , multiAlignLeft+  , multiAlignCenter+  , multiAlignRight -  , runLRText-  , execLRText -  , kern-  , char-  , escInt-  , escName-  , symb-  , symbEscInt-  , symbEscName-   ) where + import Wumpus.Basic.Graphic-import Wumpus.Basic.SafeFonts-import Wumpus.Basic.Utils.HList  import Wumpus.Core                              -- package: wumpus-core+import Wumpus.Core.Text.GlyphIndices -import Control.Applicative-import Control.Monad+import Data.AffineSpace                         -- package: vector-space+import Data.VectorSpace +import Data.Char+import Data.Foldable ( foldrM )+import qualified Data.Map               as Map+import Data.Maybe   +-- One line of multiline text+--+data InterimText1 u = InterimText1+      { text1_escaped   :: EscapedText+      , text1_advance   :: (AdvanceVec u)+      } +  deriving (Eq,Show) --- Need a note in wumpus-core and here about space:preserve --- Note - if we have font change (e.g. to symbol font) then we --- have to generate more than one hkernline.--- --- Apropos /optimization/ we have two two simultaneous and --- overlayed lines - one in the regular font, and one in Symbol. +singleLineBL :: (Ord u, FromPtSize u) +             => String -> BoundedLocGraphic u+singleLineBL ss = interimText1 ss >>= singleLRText id ++singleLineCC :: (Fractional u, Ord u, FromPtSize u) +             => String -> BoundedLocGraphic u+singleLineCC ss = glyphCapHeight  >>= \cap_h   -> +                  interimText1 ss >>= \interim -> +                  let hw = 0.5 * advanceH (text1_advance interim)+                  in singleLRText (.-^ vec hw (0.5 * cap_h)) interim++-- | Draw multi-line text, aligned to the left.  ----- Result should be a LocGraphic (so cannot do a trace as we go). +-- The input string is split on newline with the Prelude function +-- @lines@. The supplied point is the center of the text. --+multiAlignLeft      :: (Fractional u, Ord u, FromPtSize u) +                    => String -> BoundedLocGraphic u+multiAlignLeft      = +    multiAligned drawLeftAligned1 (\wv pt -> pt .-^ hvec (0.5 * advanceH wv)) --- Note - the the state tracks two kernlines: one for symbols,   -data St u = St -      { delta_chr       :: !u-      , delta_sym       :: !u-      , acc_chr         :: H (KerningChar u)-      , acc_sym         :: H (KerningChar u)-      }+-- | Draw multi-line text, aligned on the horizontal center. +--+-- The input string is split on newline with the Prelude function +-- @lines@. The supplied point is the center of the text.+--+multiAlignCenter    :: (Fractional u, Ord u, FromPtSize u) +                    => String -> BoundedLocGraphic u+multiAlignCenter    = +    multiAligned drawCenterAligned1 (\_ pt -> pt) +-- | Draw multi-line text, aligned to the right. +--+-- The input string is split on newline with the Prelude function +-- @lines@. The supplied point is the center of the text.+--+multiAlignRight     :: (Fractional u, Ord u, FromPtSize u) +                    => String -> BoundedLocGraphic u+multiAlignRight     = +    multiAligned drawRightAligned1 (\wv pt -> pt .+^ hvec (0.5 * advanceH wv)) -data Env u = Env -      { char_width      :: !u-      , spacer_width    :: !u-      } --- Note - unlike Turtle for example, Text is a monad not a --- transformer.+-- Build multi-line aligned text.  ----- The rationale for this is to avoid complications percolating --- from the Drawing monad. It Text were built over the Drawing--- monad what would it do on a font change, a colour change...--- --- That say Text must still be run /within/ the Drawing so it --- can take the initial font size, stroke colour etc.+-- The drawF functions regard the supplied point differently, for+-- instance @drawRightAligned1@ regards the point as +-- baseline-right. --+-- The dispF are applied to a point which is initially in the +-- center of the drawing - for right aligned text it is displaced +-- to the right (half the max width vectoer), for left aligned +-- text it is displaced to the left. Center aligned text is not +-- displaced.+--+multiAligned :: (Fractional u, Ord u, FromPtSize u) +             => (InterimText1 u -> Point2 u -> BoundedGraphic u)+             -> (AdvanceVec u -> Point2 u -> Point2 u)+             -> String -> BoundedLocGraphic u+multiAligned drawF dispF ss = +    linesToInterims ss >>= \(wv,xs)   ->+    glyphCapHeight     >>= \cap_h     -> +    baselineSpacing    >>= \base_span ->   +    promote1 $ \p0 -> let p1  = dispF wv p0+                          axs = annotateStartPoints cap_h base_span p1 xs+                      in mergeLines drawF p1 axs -newtype LRText u a = LRText { getLRText :: Env u -> St u -> (a, St u) }+-- This needs sorting out so as not to throw an error+--+mergeLines :: (Num u, Ord u)+           => (InterimText1 u -> Point2 u -> BoundedGraphic u)+           -> Point2 u+           -> [(InterimText1 u, Point2 u)] -> BoundedGraphic u +mergeLines fn fallback_pt = step+  where+    step [(x,pt)]    = fn x pt+    step ((x,pt):ys) = fn x pt `oplus` step ys  +    step _           = fn empty_fallback fallback_pt  -type instance MonUnit (LRText u) = u+    empty_fallback   = InterimText1 (escapeString "") (hvec 0) -instance Functor (LRText u) where-  fmap f mf = LRText $ \r s -> let (a,s') = getLRText mf r s in (f a,s')  -instance Applicative (LRText u) where-  pure a    = LRText $ \_ s -> (a,s)-  mf <*> ma = LRText $ \r s -> let (f,s')  = getLRText mf r s-                                   (a,s'') = getLRText ma r s'-                               in (f a,s'') -instance Monad (LRText u) where-  return a  = LRText $ \_ s -> (a,s)-  m >>= k   = LRText $ \r s -> let (a,s')  = getLRText m r s -                               in (getLRText . k) a r s'+singleLRText :: (Ord u, FromPtSize u) +             => (Point2 u -> Point2 u) -> InterimText1 u +             -> BoundedLocGraphic u+singleLRText dispF (InterimText1 esc av) =+    glyphHeightRange >>= \(ymin, ymax)  ->+    promote1 $ \p0 -> let pt  = dispF p0+                          w   = advanceH av+                          ll  = pt .+^ vvec ymin+                          ur  = pt .+^ vec w ymax+                          bb  = boundingBox ll ur +                      in (escapedline esc `at` pt) >>= \prim ->+                         return (bb, prim)   +-- Point is baseline-left+--+drawLeftAligned1 :: (Ord u, FromPtSize u) +                 => InterimText1 u -> Point2 u -> BoundedGraphic u+drawLeftAligned1 itext pt = singleLRText id itext `at` pt -runLRText :: (Num u, FromPtSize u) => LRText u a -> LocImage u a-runLRText ma = \pt -> envZero >>= \e1 -> -    let (a,st) = getLRText ma e1 st_zero -    in mkline pt (acc_chr st) >>= \g1 ->-       localize (fontface symbol) (mkline pt (acc_sym st)) >>= \g2 ->-       return (a, g1 `oplus` g2)-  where-    mkline pt h = hkernline (toListH h) pt+-- Point is baseline-center+--+drawCenterAligned1 :: (Fractional u, Ord u, FromPtSize u)+                   => InterimText1 u -> Point2 u -> BoundedGraphic u+drawCenterAligned1 itext pt = +    let hw = 0.5 * advanceH (text1_advance itext)    +    in singleLRText (.-^ hvec hw) itext `at` pt  +-- Point is baseline-right+--+drawRightAligned1 :: (Fractional u, Ord u, FromPtSize u)+                  => InterimText1 u -> Point2 u -> BoundedGraphic u+drawRightAligned1 itext pt = +    let w = advanceH (text1_advance itext)+    in singleLRText (.-^ hvec w) itext `at` pt -execLRText :: (Num u, FromPtSize u) => LRText u a -> LocGraphic u-execLRText ma = \pt -> liftM snd (runLRText ma pt)  -st_zero :: Num u => St u-st_zero = St { delta_chr       = 0-             , delta_sym       = 0-             , acc_chr         = emptyH-             , acc_sym         = emptyH }-  -envZero :: FromPtSize u => DrawingR (Env u)-envZero = (\sz -> Env { char_width   = fromPtSize $ charWidth sz-                      , spacer_width = fromPtSize $ spacerWidth sz })-            <$> fontSize --gets :: (St u -> a) -> LRText u a-gets fn = LRText $ \_ s -> (fn s, s)+-- This isn't worth the complexity  to get to one traversal... -charMove :: Num u => LRText u ()-charMove = LRText $ \(Env {char_width=cw, spacer_width=sw}) s -> -             let step_width = cw + sw    -                 d_sym      = (delta_sym s) + step_width-             in ((), s { delta_chr = step_width, delta_sym = d_sym }) +linesToInterims :: (FromPtSize u, Ord u) +                => String -> DrawingInfo (AdvanceVec u, [InterimText1 u])+linesToInterims = fmap post . mapM interimText1 . lines+  where+    post xs   = let vmax = foldr fn (hvec 0) xs in (vmax,xs)+    fn a vmax = avMaxWidth (text1_advance a) vmax -symbMove :: Num u => LRText u ()-symbMove = LRText $ \(Env {char_width=cw, spacer_width=sw}) s -> -             let step_width = cw + sw-                 d_chr      = (delta_chr s) + step_width-             in ((), s { delta_chr = d_chr, delta_sym = step_width }) +avMaxWidth :: Ord u => AdvanceVec u -> AdvanceVec u -> AdvanceVec u+avMaxWidth a@(V2 w1 _) b@(V2 w2 _) = if w2 > w1 then b else a -snocSymb :: KerningChar u -> LRText u ()-snocSymb kc = LRText $ \_ s -> ((), upd s)+interimText1 :: FromPtSize u => String -> DrawingInfo (InterimText1 u)+interimText1 ss = let esc = escapeString ss in +    postpro (mk esc) $ textVector esc   where-    upd = (\s a -> s { acc_sym = a `snocH` kc}) <*> acc_sym+    mk a b = InterimText1 { text1_escaped = a+                          , text1_advance = b } -snocChar :: KerningChar u -> LRText u ()-snocChar kc = LRText $ \_ s -> ((), upd s)-  where-    upd = (\s a -> s { acc_chr = a `snocH` kc}) <*> acc_chr -kern :: Num u => u -> LRText u ()-kern dx = LRText $ \_ s -> ((), upd s)-  where-    upd = (\s a b -> s { delta_chr = a+dx, delta_sym = b+dx}) -            <*> delta_chr <*> delta_sym+textVector :: FromPtSize u => EscapedText -> DrawingInfo (AdvanceVec u)+textVector esc = let cs = getEscapedText esc in +   foldrM (\c v -> charVector c >>= \cv -> return  (v ^+^ cv)) (vec 0 0) cs -char :: Num u => Char -> LRText u ()-char ch = gets delta_chr           >>= \u -> -          snocChar (kernchar u ch) >> charMove -escInt ::  Num u => Int -> LRText u ()-escInt i = gets delta_chr            >>= \u -> -           snocChar (kernEscInt u i) >> charMove+charVector :: FromPtSize u => EscapedChar -> DrawingInfo (AdvanceVec u)+charVector (CharLiteral c) = unCF1 (ord c) avLookupTable+charVector (CharEscInt i)  = unCF1 i       avLookupTable+charVector (CharEscName s) = unCF1 ix      avLookupTable+  where+    ix = fromMaybe (-1) $ Map.lookup s ps_glyph_indices -escName ::  Num u => String -> LRText u ()-escName s = gets delta_chr             >>= \u -> -            snocChar (kernEscName u s) >> charMove  -symb :: Num u => Char -> LRText u ()-symb sy = gets delta_sym           >>= \u -> -          snocSymb (kernchar u sy) >> symbMove+-- baseline_span is the vertical distance from one baseline to+-- the next it is not /gap_height/.+-- +annotateStartPoints :: Fractional u +                 => u -> u -> Point2 u -> [InterimText1 u] +                 -> [(InterimText1 u, Point2 u)]+annotateStartPoints _          _             _        []     = []+annotateStartPoints cap_height baseline_span (P2 x y) (z:rest) = +    let y0 = if odd list_len then odd_start_y else even_start_y+        p0 = P2 x y0+    in (z,p0) : step (moveDown1 p0) rest+  where+    list_len        = 1 + length rest+    halfn           = fromIntegral $ list_len `div` 2+    center_to_bl    = 0.5 * cap_height+    half_gap_height = 0.5 * (baseline_span - cap_height)+    odd_start_y     = y - center_to_bl + halfn * baseline_span+    even_start_y    = y - half_gap_height - cap_height + halfn * baseline_span -symbEscInt :: Num u => Int -> LRText u ()-symbEscInt i = gets delta_sym            >>= \u -> -               snocSymb (kernEscInt u i) >> symbMove+    moveDown1       = \pt -> pt .-^ vvec baseline_span -symbEscName :: Num u => String -> LRText u ()-symbEscName s = gets delta_sym             >>= \u -> -                snocSymb (kernEscName u s) >> symbMove+    step _  []      = []+    step pt (a:as)  = (a,pt) : step (moveDown1 pt) as+
− src/Wumpus/Basic/Utils/Combinators.hs
@@ -1,92 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Utils.Combinators--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC------ Combiantors - pairing, /static argument/ functions, ...--------------------------------------------------------------------------------------module Wumpus.Basic.Utils.Combinators-  (--  -- * Combinators-    fork-  , prod-  , forkA--  , bindR-  , bindAsk-  , bindInto-  , rlift1--  , bindR2-  , bindAskR2-  , rlift2---  ) where--import Control.Applicative--fork :: (a -> b) -> (a -> c) -> a -> (b,c) -fork f g a = (f a, g a)--prod :: (a -> c) -> (b -> d) -> (a,b) -> (c,d) -prod f g (a,b) = (f a, g b)---forkA :: Applicative f => f a -> f b -> f (a,b)-forkA af ab = (,) <$> af <*> ab ----infixl 1 `bindR`, `bindR2`---- Monadic bind with 1 static argument.----bindR :: Monad m => (r -> m a) -> (a -> r -> m b) -> r -> m b-bindR cxma cxmf = \x -> cxma x >>= \a -> cxmf a x---- 'bindAsk' takes a monadic function oblivious to R1 upto bindR.--- (lift and bind).----bindAsk :: Monad m => m a -> (a -> r1 -> m b) -> r1 -> m b -bindAsk ma cxmf r1 = ma >>= \a -> cxmf a r1----- 'bindInto' takes a monadic action dependent on R1 and binds--- it into a mondic function oblivious to R1. ----bindInto :: Monad m => (r1 -> m a) -> (a -> m b) -> r1 -> m b -bindInto cxma mf r1 = cxma r1 >>= \a -> mf a--rlift1 :: Monad m => m a -> (r -> m a)-rlift1 ma = \_ -> ma------ Monadic bind with 2 static arguments.----bindR2 :: Monad m -       => (r1 -> r2 -> m a) -> (a -> r1 -> r2 -> m b) -> r1 -> r2 -> m b-bindR2 cxma cxmf = \x y -> cxma x y >>= \a -> cxmf a x y----- 'bindAskR2' takes a monadic function oblivious to R1 and R2 upto bindR2.--- (lift and bind).----bindAskR2 :: Monad m => m a -> (a -> r1 -> r2 -> m b) -> r1 -> r2 -> m b -bindAskR2 ma cxmf r1 r2 = ma >>= \a -> cxmf a r1 r2---rlift2 :: Monad m => m a -> (r1 -> r2 -> m a)-rlift2 ma = \_ _ -> ma-
+ src/Wumpus/Basic/Utils/FormatCombinators.hs view
@@ -0,0 +1,430 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Utils.FormatCombinators+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Formatting combinators - pretty printers without the fitting.+--+-- Note - indentation support is very limited. Generally one +-- should use a proper pretty printing library.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Utils.FormatCombinators+  (+    Doc+  , DocS+  , Format(..)+  , empty+  , showsDoc+  , (<>)+  , (<+>)  +  , vconcat+  , separate+  , hcat+  , hsep+  , vcat++  , text+  , char+  , int+  , integer+  , integral+  , float+  , double+  , hex4++  , space+  , comma+  , semicolon+  , line++  , fill+  , fillStringR+  , fillStringL++  , punctuate+  , enclose+  , squotes+  , dquotes+  , parens+  , brackets+  , braces+  , angles++  , lparen+  , rparen+  , lbracket+  , rbracket+  , lbrace+  , rbrace+  , langle+  , rangle++  , list+  , tupled+  , semiBraces++  , indent++  , writeDoc+    +  ) where++import Data.Monoid+import Numeric++-- | Doc is a Join List ...+--+data Doc = Doc1   ShowS +         | Join   Doc   Doc+         | Line+         | Indent !Int  Doc +++type DocS = Doc -> Doc+++-- Join could be improved...+--+unDoc :: Doc -> ShowS+unDoc = step 0 id+  where+   step _ acc (Doc1 sf)    = acc . sf+   step n acc (Join a b)   = let acc' = step n acc a in step n acc' b+   step n acc Line         = acc . showChar '\n' . indentS n+   step n acc (Indent i d) = step (n+i) (acc . (indentS i)) d+++indentS :: Int -> ShowS+indentS i | i < 1     = id+          | otherwise = showString $ replicate i ' '++runDoc :: Doc -> String+runDoc = ($ "") . unDoc+++instance Show Doc where+  show = runDoc++instance Monoid Doc where+  mempty = empty+  mappend = (<>)+++class Format a where format :: a -> Doc++--------------------------------------------------------------------------------+        +infixr 6 <>, <+>++++-- | Create an empty, zero length document.+--+empty :: Doc+empty = Doc1 id++-- | Create a document from a ShowS function.+--+showsDoc :: ShowS -> Doc+showsDoc = Doc1+++-- | Horizontally concatenate two documents with no space +-- between them.+-- +(<>) :: Doc -> Doc -> Doc+a <> b = Join a b +++-- | Horizontally concatenate two documents with a single space +-- between them.+-- +(<+>) :: Doc -> Doc -> Doc+a <+> b = Join a (Join space b)++-- | Vertical concatenate two documents with a line break.+-- +vconcat :: Doc -> Doc -> Doc+vconcat a b = a <> Line <> b++++separate :: Doc -> [Doc] -> Doc+separate _   []     = empty+separate sep (a:as) = step a as+  where+    step acc []     = acc+    step acc (x:xs) = step (acc <> sep <> x) xs++-- | Horizontally concatenate a list of documents with @(\<\>)@.+--+hcat :: [Doc] -> Doc+hcat = foldr (<>) empty++-- | Horizontally concatenate a list of documents with @(\<+\>)@.+--+hsep :: [Doc] -> Doc+hsep = separate space++-- | Vertically concatenate a list of documents, with a line +-- break between each doc.+--+vcat :: [Doc] -> Doc+vcat []     = empty+vcat (x:xs) = step x xs +  where+    step acc (z:zs) = step (acc `vconcat` z) zs+    step acc []     = acc++-- | Create a document from a literal string.+-- +-- The string should not contain newlines (though this is not +-- enforced). +--+text :: String -> Doc+text = Doc1 . showString+++-- | Create a document from a literal character.+--+-- The char should not be a tab or newline. +--+char :: Char -> Doc+char = Doc1 . showChar++-- | Show the Int as a Doc.+--+-- > int  = text . show+--+int :: Int -> Doc+int  = Doc1 . showInt++-- | Show the Integer as a Doc.+--+integer :: Integer -> Doc+integer = Doc1 . showInt++-- | Show an \"integral value\" as a Doc via 'fromIntegral'.+--+integral :: Integral a => a -> Doc+integral = Doc1 . showInt++-- | Show the Float as a Doc.+--+float :: Double -> Doc+float = Doc1 . showFloat++-- | Show the Double as a Doc.+--+double :: Double -> Doc+double = Doc1 . showFloat++-- | Show the Int as hexadecimal, padding up to 4 digits if +-- necessary.+--+-- No trucation occurs if the value has more than 4 digits.+--+hex4 :: Int -> Doc+hex4 n | n < 0x0010 = text "000" <> showsDoc (showHex n)+       | n < 0x0100 = text "00"  <> showsDoc (showHex n)+       | n < 0x1000 = text "0"   <> showsDoc (showHex n)+       | otherwise  = showsDoc (showHex n)+ +-- | Create a Doc containing a single space character.+--+space :: Doc+space = char ' '++-- | Create a Doc containing a comma, \",\".+--+comma :: Doc+comma = char ','++-- | Create a Doc containing a semi colon, \";\".+--+semicolon :: Doc+semicolon = char ';'++-- | Create a Doc containing newline, \"\\n\".+--+line :: Doc +line = char '\n'+++--------------------------------------------------------------------------------++-- | Fill a doc to the supplied length, padding the right-hand+-- side with spaces.+--+-- Note - this function is expensive - it unrolls the functional+-- representation of the String. +-- +-- Also it should only be used for single line Doc\'s.+-- +fill :: Int -> Doc -> Doc+fill i d = Doc1 (padr i ' ' $ unDoc d) ++padr :: Int -> Char -> ShowS -> ShowS+padr i c df = step (length $ df []) +  where+    step len | len >= i  = df+             | otherwise = df . showString (replicate (i-len) c)++-- | String version of 'fill'.+--+-- This is more efficient than 'fill' as the input is a string+-- so its length is more accesible.+--+-- Padding is the space character appended to the right.+-- +fillStringR :: Int -> String -> Doc+fillStringR i s = step (length s)+  where+    step n | n >= i = text s+    step n          = text s <> text (replicate (i-n) ' ')++-- | Left-padding version of 'fillStringR'.+--+fillStringL :: Int -> String -> Doc+fillStringL i s = step (length s)+  where+    step n | n >= i = text s+    step n          = text (replicate (i-n) ' ') <> text s++--------------------------------------------------------------------------------++-- | Punctuate the Doc list with the separator, producing a Doc. +--+punctuate :: Doc -> [Doc] -> Doc+punctuate _ []     = empty+punctuate _ [x]    = x+punctuate s (x:xs) = x <> s <> punctuate s xs+++-- | Enclose the final Doc within the first two.+--+-- There are no spaces between the documents:+--+-- > enclose l r d = l <> d <> r+--+enclose :: Doc -> Doc -> Doc -> Doc+enclose l r d = l <> d <> r++++-- | Enclose the Doc within single quotes.+--+squotes :: Doc -> Doc+squotes = enclose (char '\'') (char '\'')++-- | Enclose the Doc within double quotes.+--+dquotes :: Doc -> Doc+dquotes = enclose (char '"') (char '"')++-- | Enclose the Doc within parens @()@.+--+parens :: Doc -> Doc+parens = enclose lparen rparen++-- | Enclose the Doc within square brackets @[]@.+--+brackets :: Doc -> Doc+brackets = enclose lbracket rbracket++-- | Enclose the Doc within curly braces @{}@.+--+braces :: Doc -> Doc+braces = enclose lbrace rbrace++-- | Enclose the Doc within angle brackets @\<\>@.+--+angles :: Doc -> Doc+angles = enclose langle rangle++++-- | Create a Doc containing a left paren, \'(\'.+--+lparen :: Doc+lparen = char '('++-- | Create a Doc containing a right paren, \')\'.+--+rparen :: Doc+rparen = char ')'++-- | Create a Doc containing a left square bracket, \'[\'.+--+lbracket :: Doc+lbracket = char '['++-- | Create a Doc containing a right square bracket, \']\'.+--+rbracket :: Doc+rbracket = char ']'++-- | Create a Doc containing a left curly brace, \'{\'.+--+lbrace :: Doc+lbrace = char '{'++-- | Create a Doc containing a right curly brace, \'}\'.+--+rbrace :: Doc+rbrace = char '}'++-- | Create a Doc containing a left angle bracket, \'\<\'.+--+langle :: Doc+langle = char '<'++-- | Create a Doc containing a right angle bracket, \'\>\'.+--+rangle :: Doc+rangle = char '>'++-- | Comma separate the list of documents and enclose in square+-- brackets.+--+list :: [Doc] -> Doc+list = brackets . punctuate comma++-- | Comma separate the list of documents and enclose in parens.+--+tupled :: [Doc] -> Doc+tupled = parens . punctuate comma++-- | Separate the list with a semicolon and enclose in curly +-- braces.+--+semiBraces :: [Doc] -> Doc+semiBraces = braces . punctuate semicolon+++-- | Horizontally indent a Doc.+--+-- Note - this space-prefixes the Doc on /the current line/. It+-- does not indent subsequent lines if the Doc spans multiple +-- lines.+--+indent :: Int -> Doc -> Doc+indent i d | i < 1     = d+           | otherwise = Indent i d++--------------------------------------------------------------------------------+++-- | Write a Doc to file.+--+writeDoc :: FilePath -> Doc -> IO ()+writeDoc filepath d = writeFile filepath $ show d 
+ src/Wumpus/Basic/Utils/ParserCombinators.hs view
@@ -0,0 +1,376 @@+{-# LANGUAGE RankNTypes                 #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Utils.ParserCombinators+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Two continuation parser combinators.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Utils.ParserCombinators+  (+    Parser+  , Result(..)+  , CharParser+  , CharResult+  , ParseError++  , runParser+  , runParserEither+  , apply+  , failure+  , throwError+  , (<?>)+  , lookahead+  , peek+  , eof+  , equals+  , satisfy+  , oneOf+  , noneOf++  , chainl1+  , chainr1+  , chainl+  , chainr+  , choice+  , count+  , between+  , option+  , optionMaybe+  , optionUnit+  , skipOne+  , skipMany+  , skipMany1+  , many1+  , sepBy+  , sepBy1+  , sepEndBy+  , sepEndBy1+  , manyTill  +  , manyTill1++  -- * Char parsers+  , char+  , string+  , anyChar+  , upper+  , lower+  , letter+  , alphaNum+  , digit+  , hexDigit+  , octDigit+  , newline+  , tab+  , space++++  ) where++import Control.Applicative+import Control.Monad+import Data.Char+++data Result s ans = Fail String [s] | Okay ans [s]+  deriving (Eq,Ord,Show)+++type SK s r ans = r -> FK s ans -> [s] -> Result s ans+type FK s ans   = Result s ans+++newtype Parser s r = Parser { +          getParser :: forall ans. SK s r ans -> FK s ans -> [s] -> Result s ans }+++type CharParser a = Parser Char a+type CharResult a = Result Char a+type ParseError   = String++runParser :: Parser s a -> [s] -> Result s a+runParser p = getParser p skZero fkZero+  where+    skZero = \ans _ ss -> Okay ans ss+    fkZero = Fail "" []+++runParserEither :: Show s => Parser s a -> [s] -> Either ParseError a+runParserEither p = post . runParser p+  where    +    post (Okay a _)    = Right a+    post (Fail err []) = Left $ err ++ "\nUnexpected EOF"+    post (Fail err ss) = Left $ err ++ "\n" ++ (take 20 $ show ss)+++-- @return@ of Monad, @pure@ of Applicative+--+yield  :: a -> Parser s a+yield a = Parser $ \sk fk ss -> sk a fk ss++-- mplus of MonadPlus, (<|>) of Applicative.+--+alt :: Parser s a -> Parser s a -> Parser s a+alt p1 p2 = Parser $ \sk fk ss -> getParser p1 sk (getParser p2 sk fk ss) ss++infixl 5 `apply`++apply :: Functor f => f a -> (a -> b) -> f b+apply = flip fmap+++failure :: Parser s a+failure = Parser $ \_ fk _ -> fk+++-- eager-many / zero-or-more (many of Applicative)+--+eagerMany :: Parser s a -> Parser s [a]+eagerMany p = (p >>= \r -> eagerMany p `apply` \rs -> (r:rs)) <|> return [] ++-- eager-some / one-or-more (some of Applicative)+--+eagerSome :: Parser s a -> Parser s [a]+eagerSome p = p >>= \r -> eagerMany p `apply` \rs -> (r:rs)+++instance Functor (Parser s) where+  fmap f mf = Parser $ \sk -> getParser mf $ \a -> (sk . f) a+     +++instance Applicative (Parser s) where+  pure = yield+  (<*>) = ap++instance Alternative (Parser s) where+  empty = failure+  (<|>) = alt+  many  = eagerMany+  some  = eagerSome+ +instance Monad (Parser s) where+  return  = yield+  m >>= k = Parser $ \sk -> getParser m $ \a -> getParser (k a) sk++instance MonadPlus (Parser s) where+  mzero = failure+  mplus = alt++++--------------------------------------------------------------------------------+-- Combinators+++throwError :: String -> Parser s a+throwError err_msg = Parser $ \_ _ ss -> Fail err_msg ss+++infixr 0 <?>++(<?>) :: Parser s a -> String -> Parser s a+p <?> err_msg = Parser $ \sk fk ss -> getParser p sk (swapMsg fk) ss+  where+    swapMsg (Fail _ ss) = Fail err_msg ss+    swapMsg okay        = okay++-- | This one is from Chris Okasaki\'s \"Even Higher-Order +-- Functions for Parsing\".+--+lookahead :: Parser s a -> (a -> Parser s b) -> Parser s b +lookahead p mf  = Parser $ \sk fk -> +    getParser p (\a fk2 -> getParser (mf a) sk fk2) fk+++-- | Peek tries the supplied parse, but does not consume input +-- \*\* even when the parse succeeds \*\*.+--+peek :: Parser s a -> Parser s a+peek p = Parser $ \sk fk ss -> +    getParser p (\a fk2 _ -> sk a fk2 ss) fk ss+++eof :: Parser s ()+eof = Parser go+  where+    go sk fk [] = sk () fk []+    go _  fk _  = fk++equals :: Eq s => s -> Parser s s+equals sym = Parser go+  where+    go sk fk (s:ss) | s == sym = sk s fk ss+    go _  fk _                 = fk+++satisfy :: (s -> Bool) -> Parser s s+satisfy test = Parser go+  where+    go sk fk (s:ss) | test s = sk s fk ss +    go _  fk _               = fk+++oneOf           :: Eq s => [s] -> Parser s s+oneOf cs        = satisfy (`elem` cs)++noneOf          :: Eq s => [s] -> Parser s s+noneOf cs       = satisfy (`notElem` cs)++++-- Note - the type sigs of the chain parsers can be generalized +-- to any MonadPlus.+--++chainl1 :: MonadPlus m => m a -> m (a -> a -> a) -> m a+chainl1 p op = p >>= rest +  where +    rest x = mplus (op >>= \f -> p >>= \a -> rest (f x a)) (return x) +               ++chainr1 :: MonadPlus m => m a -> m (a -> a -> a) -> m a+chainr1 p op = scan +   where +     scan   = p >>= rest +     rest x = mplus (op >>= \f -> scan >>= \a -> rest (f x a)) (return x) ++chainl :: MonadPlus m => m a -> m (a -> a -> a) -> a -> m a+chainl p op v = mplus (chainl1 p op) (return v)++chainr :: MonadPlus m => m a -> m (a -> a -> a) -> a -> m a+chainr p op v = mplus (chainr1 p op) (return v)+++infixr 5 <:> + +-- | Applicative cons.+--+(<:>) :: Applicative f => f a -> f [a] -> f [a]+(<:>) p1 p2 = (:) <$> p1 <*> p2+++choice :: Alternative f => [f a] -> f a+choice = foldr (<|>) empty +   +count :: Applicative f => Int -> f a -> f [a]+count i p | i <= 0    = pure []+          | otherwise = p <:> count (i-1) p +          +between :: Applicative f => f open -> f close -> f a -> f a+between o c a = o *> a <* c++          +option :: Alternative f => a -> f a -> f a+option x p          = p <|> pure x++optionMaybe :: Alternative f => f a -> f (Maybe a)+optionMaybe = optional++-- aka Parsecs /optional/+optionUnit :: Alternative f => f a -> f ()+optionUnit p = () <$ p <|> pure ()++skipOne :: Applicative f => f a -> f ()+skipOne p = p *> pure ()++skipMany :: Alternative f => f a -> f ()+skipMany p = many_p+  where +    many_p = some_p <|> pure ()+    some_p = p       *> many_p++skipMany1 :: Alternative f => f a -> f ()+skipMany1 p = p *> skipMany p++-- | 'many1' an alias for Control.Applicative 'some'. +--+many1 :: Alternative f => f a -> f [a]+many1 = some++sepBy :: Alternative f => f a -> f b -> f [a]+sepBy p sep = sepBy1 p sep <|> pure []++sepBy1 :: Alternative f => f a -> f b -> f [a]+sepBy1 p sep = p <:> step +  where +    step = (sep *> p) <:> step <|> pure []++sepEndBy :: Alternative f => f a -> f b -> f [a]+sepEndBy p sep = sepEndBy1 p sep <|> pure []++sepEndBy1 :: Alternative f => f a -> f b -> f [a]+sepEndBy1 p sep = (p <* sep) <:> step +  where+    step = (p <* sep) <:> step <|> pure []+    +manyTill :: Alternative f => f a -> f b -> f [a]+manyTill p end = step <|> pure [] +  where+    step  = p <:> (final <|> step)+    final = [] <$ end ++manyTill1 :: Alternative f => f a -> f b -> f [a]+manyTill1 p end = p <:> step +  where+    step  = final <|> (p <:> step)+    final = [] <$ end+++--------------------------------------------------------------------------------+-- Char parsers+++char :: Char -> CharParser Char+char ch = satisfy (==ch)++string :: String -> CharParser String+string ss = mapM char ss++anyChar :: CharParser Char+anyChar = Parser go+  where+   go sk fk (s:ss) = sk s fk ss+   go _  fk _      = fk+++upper       :: CharParser Char+upper       = satisfy isUpper++lower       :: CharParser Char+lower       = satisfy isLower++letter      :: CharParser Char+letter      = satisfy isAlpha++alphaNum    :: CharParser Char+alphaNum    = satisfy isAlphaNum++digit       :: CharParser Char+digit       = satisfy isDigit ++hexDigit    :: CharParser Char+hexDigit    = satisfy isHexDigit++octDigit    :: CharParser Char+octDigit    = satisfy isOctDigit++newline     :: CharParser Char+newline     = equals '\n'++tab         :: CharParser Char+tab         = equals '\t'++space       :: CharParser Char+space       = satisfy isSpace+
+ src/Wumpus/Basic/Utils/TokenParsers.hs view
@@ -0,0 +1,175 @@+{-# LANGUAGE RankNTypes                 #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Utils.TokenParsers+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Generally you should expect to import this module qualified +-- and define versions to consume trailing white-space.+--+-- > lexDef   :: P.LexemeParser+-- > lexDef   = P.commentLineLexemeParser "Comment" [' ', '\t']+-- >+-- > lexeme   :: CharParser a -> CharParser a+-- > lexeme   = P.lexeme lexDef+-- >+-- > integer  :: CharParser Int+-- > integer  = lexeme P.integer+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Utils.TokenParsers+  (++    LexemeParser+  , spaceLexemeParser+  , spaceCharLexemeParser+  , commentLexemeParser+  , commentLineLexemeParser+  , commentMultiLexemeParser++  , lexeme+  , whiteSpace++  , octBase+  , octHask+  +  , hexBase++  , natural+  , integer+  , double++  ) where++import Wumpus.Basic.Utils.ParserCombinators++import Control.Applicative++-- | Opaque type representing a parser that consumes arbitrary +-- space.+--+-- Unlike Parsec\'s lexeme parser, this can be customized so that +-- e.g. newlines are not consumed as white space.+--+newtype LexemeParser = LexemeParser { getLexemeParser :: CharParser () }++-- | Build a lexeme parser that handles /space/.+--+-- /Space/ is zero or more elements matching the @isSpace@+-- predicate from @Data.Char@.+--+spaceLexemeParser :: LexemeParser+spaceLexemeParser = LexemeParser go +  where+    go = () <$ many space+++-- | Build a lexeme parser that handles arbitrary /space/.+--+-- /space/ is parametric, for instance this can manufacture a +-- lexeme parser that consumes space and tab chars but not +-- newline.+--+spaceCharLexemeParser :: [Char] -> LexemeParser+spaceCharLexemeParser cs = LexemeParser go +  where+    go = skipMany (oneOf cs)+++-- | Build a lexeme parser that handles start-and-end delimited+-- comments and arbitrary /space/.+--+commentLexemeParser :: String -> (String,String) -> [Char] -> LexemeParser+commentLexemeParser line (start,end) cs = LexemeParser go+  where+    go        = skipMany (whiteChar <|> lineComment line+                                    <|> spanComment start end)+    whiteChar = skipOne (oneOf cs)+++-- | Build a lexeme parser that handles line spanning comments +-- an arbitrary /space/.+--+commentLineLexemeParser :: String -> [Char] -> LexemeParser+commentLineLexemeParser start cs = LexemeParser go+  where+    go        = skipMany (whiteChar <|> lineComment start)+    whiteChar = skipOne (oneOf cs)+++-- | Build a lexeme parser that handles start-and-end delimited+-- comments, line comments and arbitrary /space/.+--+commentMultiLexemeParser :: String -> String -> [Char] -> LexemeParser+commentMultiLexemeParser start end cs = LexemeParser go+  where+    go        = skipMany (whiteChar <|> spanComment start end)+    whiteChar = skipOne (oneOf cs)++lineComment :: String -> CharParser ()+lineComment start  = +    skipOne (string start *> manyTill anyChar endLine)++spanComment :: String -> String -> CharParser ()+spanComment start end = +    string start *> manyTill anyChar (string end) *> return ()+++endLine :: CharParser ()+endLine = skipOne (char '\n') <|> eof+++-- | Wrap a CharParser with a lexeme parser, the CharParser will+-- consume trailing space according to the strategy of the +-- LexemeParser.+--+lexeme :: LexemeParser -> CharParser a -> CharParser a+lexeme trail p = p <* getLexemeParser trail++whiteSpace :: LexemeParser -> CharParser ()+whiteSpace = getLexemeParser++--------------------------------------------------------------------------------+++++octBase :: CharParser Int+octBase = (\cs -> read $ '0':'o':cs) <$> many1 octDigit++octHask :: CharParser Int+octHask = (string "0o" <|> string "0O") *> octBase+++hexBase :: CharParser Int+hexBase = (\xs -> read $ '0':'x':xs) <$> many1 hexDigit++++--------------------------------------------------------------------------------++natural :: CharParser Integer+natural = liftA read (many1 digit)+++integer :: CharParser Integer+integer = ($) <$> psign <*> natural+  where+    psign = option id (negate <$ char '-')+++double :: CharParser Double+double = (\signf intpart fracpart -> signf $ intpart + fracpart)+                  <$> psign <*> onatural <*> ofrac +  where+    psign     = option id (negate <$ char '-')+    onatural  = option 0  (fromIntegral <$> natural)+    ofrac     = option 0  ((\xs -> read $ '.':xs) <$> (char '.' *> (many1 digit)))
src/Wumpus/Basic/VersionNumber.hs view
@@ -23,7 +23,7 @@  -- | Version number ----- > (0,12,0)+-- > (0,13,0) -- wumpus_basic_version :: (Int,Int,Int)-wumpus_basic_version = (0,12,0)+wumpus_basic_version = (0,13,0)
wumpus-basic.cabal view
@@ -1,5 +1,5 @@ name:             wumpus-basic-version:          0.12.0+version:          0.13.0 license:          BSD3 license-file:     LICENSE copyright:        Stephen Tetley <stephen.tetley@gmail.com>@@ -9,87 +9,63 @@ synopsis:         Common drawing utilities built on wumpus-core. description:   .-  \*\* WARNING \*\* - this package is sub-alpha. It was released -  to Hackage prematurely - designing a higher-level drawing -  library turns out to be much more demanding than designing a -  low-level one (Wumpus-Core). -  .-  Some of the modules (SafeFonts, SVGColours, X11Colours) are-  relatively stable. The core modules of @Basic.Graphic@ (@Base@,-  @PrimGraphic@, @DrawingContext@) seem to support a good set-  primitive functions, but the exact types of drawing objects do -  not feel right at the moment. Other modules (Paths, Chains, -  Shapes) are still being worked out and may be substantially -  revised in subsequent updates.-  .-  Version 0.12.0 extends the sets of arrowheads and connectors.-  Unfortunately Shapes are still undercooked.-  .-  Changelog:-  .-  0.11.0 to 0.12.0:-  .-  * Changes Base types in  @Basic.Graphic@. The @Graphic@ and -    @Image@ types now produce (wrapped) @Primitives@, rather than -    Hughes lists of @Primitives@. This means they can now be -    transformed with the affine transformations. Removed the -    function @ati@, it is replaced by @at@.-  .-  * Added @Basic.Utils.Combinators@.+  \*\* WARNING \*\* - this package is sub-alpha, it was released+  to Hackage prematurely and while its capabilities have improved+  with subsequent updates it is arguably becoming even less stable +  and more experimental (unfortunately the only thing consistent +  about the API is that it consistently changes...).    .-  * Arrowheads and Connectors reworked - Arrowheads are now a -    functional type, Connectors use new Image combining -    operations from @Basic.Graphic.Base@.+  Version 0.13.0 significantly differs form the previous release +  as font metrics support has been added and the core graphic +  types have been redesigned. With these re-workings some modules +  that were previously fairly stable have changed substantially or +  are likely to change soon (@Basic.PictureLanguage@ has become +  @Basic.DrawingComposition@; @Basic.SafeFonts@ no longer seems +  very /SVG safe/ so it is marked as pending change).    .-  * Path connectors re-worked and renamed. +  NOTE - many of the demos now use font metrics. Font metrics for+  the \"Core 14\" PostScript fonts are distributed as @*.afm@ +  files with GhostScript in the @fonts@ directory. Wumpus expects+  the GhostScript font metrics to be AFM version 2.0 files (this+  matches GhostScript 8.63). Alternatively, metrics for the Core +  14 fonts are available from Adode (AFM version 4.1), see the +  links below. To run the demos properly you will need one of +  these sets of metrics.   .-  * Dot hierarchy changed - @Basic.Dots@ becomes -    @Basic.Dots.AnchorDots@; @Basic.Dots.Primitive@ becomes-    @Basic.Dots.Marks@.+  Adobe Font techinal notes:+  <https://www.adobe.com/devnet/font.html>   .-  * @Basic.Shapes@ - internals reworked.+  Core 14 AFM metrics:+  <https://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/Core14_AFMs.tar>   .-  0.10.0 to 0.11.0:-  . -  * Reworked arrowheads and connectors - connectors are now -    configurable: there are functions to make connectors with -    a left arrowhead, right arrowhead, none or both.  +  WARNING - the font metrics parsing in version 0.13.0 is +  essentially a proof-of-concept and is not very robust. +  Generally, if a font cannot be parsed, fallback metrics will be +  used. At the moment there no error logging, so there is little +  indication of whether Wumpus has used the correct metrics or the +  fallback for a requested font.   .-  * Reworked shapes - internally shapes now create a @Path@ rather -    than a @Graphic@ this means the path can be manipulated (e.g. -    round cornered rectangles, diamonds... can be constructed).-    @Coordinate@ is no longer a @Shape@ - it is now similar object -    but of a different type. Likewise, @FreeLabel@ has been -    replaced by @Plaintext@ which is not a @Shape@, but has some -    similar properties. Unfortunately, the Shape types are still -    difficult to work with and a larger reworking is still -    necessary.+  Changelog:   .-  * @Basic.Paths.Base@ - @Path@ type changed, @PathEmpty@ -    constructor removed so empty paths cannot be created. This -    allows a better API for taking points on a path. It also -    means @Path@ is no longer an instance of Monoid. Type changes -    to various functions (e.g. @tipR@, @tipL@) reflecting that as -    paths cannot now be empty, functions on them can generally be -    total. @toPrimPathU@ removed as converting to a PrimPath as -    now always /safe/. @tracePoints@ renamed @traceLinePoints@, -    @tracePointsCurve@ renamed @traceCurvePoints@, @midpoint@ -    renamed @midway@.+  0.12.0 to 0.13.0:   .-  * @Basic.Graphic@ - the types @ConnDrawingR@, @ConnGraphic@ etc.-    have had their names expanded to @ConnectorDrawingR@, -    @ConnectorGraphic@... +  * Major changes to @Basic.Graphic@ modules. @DrawingR@ is +    renamed @Drawing@ and is substantially re-worked. Graphic +    /functional/ types are now encapulated in the Drawing +    constructor @Drawing (ctx -> pt -> prim)@ rather than +    partially outside it @pt -> Drawing (ctx -> prim)@. +    @Drawing@ monad renamed @TraceDrawing@ and @DrawingT@ +    transformer renamed @TraceDrawingT@.   .-  * @Basic.SafeFont@ - font names changed to use underscore -    separators rather than camelCase. Wumpus generally uses -    underscored names for /constants/.+  * Rudimentary font loading added, only AFM files are supported.   .-  * Removed @conn@ from @Basic.Graphic.Drawing@. Connectors should -    be used instead.+  * @Basic.Shapes.Coordinate@ re-worked. The Coordinate type is +    now more like the Shapes types (excepting the intentional +    difference in drawing style).   .-  * The class @DrawingCtxM@ now has @Applicative@ as a superclass. +  * @Basic.Shapes.Plaintext@ removed.   .-  * @lineSpacing@ renamed @baselineSpacing@.+  * @Basic.Text.LRText@ completely redesigned.   .   . build-type:         Simple@@ -103,24 +79,28 @@   demo/Arrowheads.hs,   demo/ClipPic.hs,   demo/ColourCharts.hs,-  demo/ColourDefns.hs,+  demo/ColourChartUtils.hs,   demo/Connectors.hs   demo/DotPic.hs,+  demo/DrawingCompo.hs,+  demo/FeatureModel.hs,+  demo/FontLoaderUtils.hs,   demo/FontPic.hs,+  demo/LeftRightText.hs,   demo/PetriNet.hs,-  demo/Picture.hs,   demo/Symbols.hs  library   hs-source-dirs:     src   build-depends:      base            <  5, -                      containers      >= 0.3     && <= 0.4, -                      vector-space    >= 0.6,-                      wumpus-core     == 0.36.0+                      containers      >= 0.3     && <= 0.4,+                      directory       >= 1.0     && <  2.0, +                      filepath        >= 1.1     && <  2.0,+                      vector-space    >= 0.6     && <  1.0,+                      wumpus-core     == 0.40.0       exposed-modules:-    Wumpus.Basic.Anchors,     Wumpus.Basic.Arrows,     Wumpus.Basic.Arrows.Connectors,     Wumpus.Basic.Arrows.Tips,@@ -131,13 +111,26 @@     Wumpus.Basic.Colour.X11Colours,     Wumpus.Basic.Dots.AnchorDots,     Wumpus.Basic.Dots.Marks,+    Wumpus.Basic.DrawingComposition,+    Wumpus.Basic.FontLoader.AfmLoader,+    Wumpus.Basic.FontLoader.AfmParserBase,+    Wumpus.Basic.FontLoader.AfmV2Parser,+    Wumpus.Basic.FontLoader.AfmV4Dot1Parser,+    Wumpus.Basic.FontLoader.Base,+    Wumpus.Basic.FontLoader.GSFontMap,+    Wumpus.Basic.FontLoader.GSLoader,     Wumpus.Basic.Graphic,+    Wumpus.Basic.Graphic.Anchors,     Wumpus.Basic.Graphic.Base,+    Wumpus.Basic.Graphic.ContextFunction,     Wumpus.Basic.Graphic.Drawing,     Wumpus.Basic.Graphic.DrawingContext,-    Wumpus.Basic.Graphic.PrimGraphic,+    Wumpus.Basic.Graphic.GlyphMetrics+    Wumpus.Basic.Graphic.GraphicOperations,+    Wumpus.Basic.Graphic.GraphicTypes,     Wumpus.Basic.Graphic.Query,     Wumpus.Basic.Graphic.ScalingContext,+    Wumpus.Basic.Graphic.TraceDrawing,     Wumpus.Basic.Monads.TurtleClass,     Wumpus.Basic.Monads.TurtleMonad,     Wumpus.Basic.Paths,@@ -151,14 +144,13 @@     Wumpus.Basic.Shapes.Base,     Wumpus.Basic.Shapes.Coordinate,     Wumpus.Basic.Shapes.Derived,-    Wumpus.Basic.Shapes.Plaintext,-    Wumpus.Basic.Text.LRSymbol,     Wumpus.Basic.Text.LRText,-    Wumpus.Basic.Utils.Combinators,     Wumpus.Basic.Utils.HList,+    Wumpus.Basic.Utils.FormatCombinators,     Wumpus.Basic.Utils.Intersection,-    Wumpus.Basic.VersionNumber,-    Wumpus.Basic.PictureLanguage+    Wumpus.Basic.Utils.ParserCombinators,+    Wumpus.Basic.Utils.TokenParsers,+    Wumpus.Basic.VersionNumber    other-modules: