packages feed

wumpus-basic 0.13.0 → 0.14.0

raw patch · 111 files changed

+11962/−10938 lines, 111 filesdep ~containersdep ~wumpus-corePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: containers, wumpus-core

API changes (from Hackage documentation)

- Wumpus.Basic.Arrows.Connectors: connector :: ConnectorPath u -> Connector u
- Wumpus.Basic.Arrows.Connectors: data Connector u
- Wumpus.Basic.Arrows.Connectors: dblArrow :: ConnectorPath u -> Arrowhead u -> Connector u
- Wumpus.Basic.Arrows.Connectors: leftArrow :: ConnectorPath u -> Arrowhead u -> Connector u
- Wumpus.Basic.Arrows.Connectors: leftrightArrow :: ConnectorPath u -> Arrowhead u -> Arrowhead u -> Connector u
- Wumpus.Basic.Arrows.Connectors: rightArrow :: ConnectorPath u -> Arrowhead u -> Connector u
- Wumpus.Basic.Arrows.Connectors: strokeConnector :: (Real u, Floating u) => Connector u -> ConnectorImage u (Path u)
- Wumpus.Basic.Arrows.Tips: Arrowhead :: LocThetaImage u u -> Arrowhead u
- Wumpus.Basic.Arrows.Tips: barb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: barb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: barb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: bracket :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: curveTip :: (Real u, Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: diamondTip :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: diskTip :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: getArrowhead :: Arrowhead u -> LocThetaImage u u
- Wumpus.Basic.Arrows.Tips: newtype Arrowhead u
- Wumpus.Basic.Arrows.Tips: odiamondTip :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: odiskTip :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: orevtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: orevtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: orevtri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: osquareTip :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: otri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: otri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: otri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: perp :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: revbarb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: revbarb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: revbarb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: revcurveTip :: (Real u, Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: revtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: revtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: revtri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: squareTip :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: tri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: tri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: tri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Chains.Base: Done :: AnaAlg st a
- Wumpus.Basic.Chains.Base: IterStep :: a -> !st -> IterAlg st a
- Wumpus.Basic.Chains.Base: Step :: a -> !st -> AnaAlg st a
- Wumpus.Basic.Chains.Base: bivariate :: st -> (st -> AnaAlg st (ux, uy)) -> BivariateAlg ux uy
- Wumpus.Basic.Chains.Base: bounded :: Int -> SequenceAlg (ux, uy) -> BivariateAlg ux uy
- Wumpus.Basic.Chains.Base: chain :: BivariateAlg ux uy -> Chain ux uy u
- Wumpus.Basic.Chains.Base: chainFrom :: Num u => BivariateAlg ux uy -> LocChain ux uy u
- Wumpus.Basic.Chains.Base: data AnaAlg st a
- Wumpus.Basic.Chains.Base: data BivariateAlg ux uy
- Wumpus.Basic.Chains.Base: data Chain ux uy u
- Wumpus.Basic.Chains.Base: data IterAlg st a
- Wumpus.Basic.Chains.Base: data SequenceAlg a
- Wumpus.Basic.Chains.Base: iteration :: (a -> a) -> a -> SequenceAlg a
- Wumpus.Basic.Chains.Base: pairOnXs :: (ux -> uy) -> SequenceAlg ux -> SequenceAlg (ux, uy)
- Wumpus.Basic.Chains.Base: pairOnYs :: (r -> l) -> SequenceAlg r -> SequenceAlg (l, r)
- Wumpus.Basic.Chains.Base: type LocChain ux uy u = Point2 u -> Chain ux uy u
- Wumpus.Basic.Chains.Base: unchain :: ScalingContext ux uy u -> Chain ux uy u -> [Point2 u]
- Wumpus.Basic.Chains.Derived: horizontal :: Int -> Chain Int Int u
- Wumpus.Basic.Chains.Derived: horizontals :: (Num ua, Num u) => [ua] -> LocChain ua ua u
- Wumpus.Basic.Chains.Derived: rescale :: Fractional a => a -> a -> a -> a -> a -> a
- Wumpus.Basic.Chains.Derived: tableDown :: Int -> Int -> Chain Int Int u
- Wumpus.Basic.Chains.Derived: tableRight :: Num u => Int -> Int -> Chain Int Int u
- Wumpus.Basic.Chains.Derived: univariateX :: (Fractional uy, Num ux, Num u) => [ux] -> LocChain ux uy u
- Wumpus.Basic.Chains.Derived: univariateY :: (Fractional ux, Num uy, Num u) => [uy] -> LocChain ux uy u
- Wumpus.Basic.Chains.Derived: vertical :: Int -> Chain Int Int u
- Wumpus.Basic.Chains.Derived: verticals :: (Num ua, Num u) => [ua] -> LocChain ua ua u
- Wumpus.Basic.Colour.SVGColours: alice_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: antique_white :: RGBi
- Wumpus.Basic.Colour.SVGColours: aqua :: RGBi
- Wumpus.Basic.Colour.SVGColours: aquamarine :: RGBi
- Wumpus.Basic.Colour.SVGColours: azure :: RGBi
- Wumpus.Basic.Colour.SVGColours: beige :: RGBi
- Wumpus.Basic.Colour.SVGColours: bisque :: RGBi
- Wumpus.Basic.Colour.SVGColours: black :: RGBi
- Wumpus.Basic.Colour.SVGColours: blanched_almond :: RGBi
- Wumpus.Basic.Colour.SVGColours: blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: blue_violet :: RGBi
- Wumpus.Basic.Colour.SVGColours: brown :: RGBi
- Wumpus.Basic.Colour.SVGColours: burlywood :: RGBi
- Wumpus.Basic.Colour.SVGColours: cadet_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: chartreuse :: RGBi
- Wumpus.Basic.Colour.SVGColours: chocolate :: RGBi
- Wumpus.Basic.Colour.SVGColours: coral :: RGBi
- Wumpus.Basic.Colour.SVGColours: cornflower_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: cornsilk :: RGBi
- Wumpus.Basic.Colour.SVGColours: crimson :: RGBi
- Wumpus.Basic.Colour.SVGColours: cyan :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_cyan :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_goldenrod :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_gray :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_grey :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_khaki :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_magenta :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_olive_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_orange :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_orchid :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_red :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_salmon :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_sea_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_slate_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_slate_gray :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_slate_grey :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_turquoise :: RGBi
- Wumpus.Basic.Colour.SVGColours: dark_violet :: RGBi
- Wumpus.Basic.Colour.SVGColours: deep_pink :: RGBi
- Wumpus.Basic.Colour.SVGColours: deep_sky_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: dim_gray :: RGBi
- Wumpus.Basic.Colour.SVGColours: dim_grey :: RGBi
- Wumpus.Basic.Colour.SVGColours: dodger_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: firebrick :: RGBi
- Wumpus.Basic.Colour.SVGColours: floral_white :: RGBi
- Wumpus.Basic.Colour.SVGColours: forest_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: fuchsia :: RGBi
- Wumpus.Basic.Colour.SVGColours: gainsboro :: RGBi
- Wumpus.Basic.Colour.SVGColours: ghost_white :: RGBi
- Wumpus.Basic.Colour.SVGColours: gold :: RGBi
- Wumpus.Basic.Colour.SVGColours: goldenrod :: RGBi
- Wumpus.Basic.Colour.SVGColours: gray :: RGBi
- Wumpus.Basic.Colour.SVGColours: green :: RGBi
- Wumpus.Basic.Colour.SVGColours: green_yellow :: RGBi
- Wumpus.Basic.Colour.SVGColours: grey :: RGBi
- Wumpus.Basic.Colour.SVGColours: honeydew :: RGBi
- Wumpus.Basic.Colour.SVGColours: hot_pink :: RGBi
- Wumpus.Basic.Colour.SVGColours: indian_red :: RGBi
- Wumpus.Basic.Colour.SVGColours: indigo :: RGBi
- Wumpus.Basic.Colour.SVGColours: ivory :: RGBi
- Wumpus.Basic.Colour.SVGColours: khaki :: RGBi
- Wumpus.Basic.Colour.SVGColours: lavender :: RGBi
- Wumpus.Basic.Colour.SVGColours: lavender_blush :: RGBi
- Wumpus.Basic.Colour.SVGColours: lawn_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: lemon_chiffon :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_coral :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_cyan :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_goldenrod_yellow :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_gray :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_grey :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_pink :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_salmon :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_sea_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_sky_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_slate_gray :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_slate_grey :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_steel_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: light_yellow :: RGBi
- Wumpus.Basic.Colour.SVGColours: lime :: RGBi
- Wumpus.Basic.Colour.SVGColours: lime_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: linen :: RGBi
- Wumpus.Basic.Colour.SVGColours: magenta :: RGBi
- Wumpus.Basic.Colour.SVGColours: maroon :: RGBi
- Wumpus.Basic.Colour.SVGColours: medium_aquamarine :: RGBi
- Wumpus.Basic.Colour.SVGColours: medium_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: medium_orchid :: RGBi
- Wumpus.Basic.Colour.SVGColours: medium_purple :: RGBi
- Wumpus.Basic.Colour.SVGColours: medium_sea_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: medium_slate_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: medium_spring_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: medium_turquoise :: RGBi
- Wumpus.Basic.Colour.SVGColours: medium_violet_red :: RGBi
- Wumpus.Basic.Colour.SVGColours: midnight_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: mintcream :: RGBi
- Wumpus.Basic.Colour.SVGColours: mistyrose :: RGBi
- Wumpus.Basic.Colour.SVGColours: moccasin :: RGBi
- Wumpus.Basic.Colour.SVGColours: navajo_white :: RGBi
- Wumpus.Basic.Colour.SVGColours: navy :: RGBi
- Wumpus.Basic.Colour.SVGColours: old_lace :: RGBi
- Wumpus.Basic.Colour.SVGColours: olive :: RGBi
- Wumpus.Basic.Colour.SVGColours: olive_drab :: RGBi
- Wumpus.Basic.Colour.SVGColours: orange :: RGBi
- Wumpus.Basic.Colour.SVGColours: orange_red :: RGBi
- Wumpus.Basic.Colour.SVGColours: orchid :: RGBi
- Wumpus.Basic.Colour.SVGColours: pale_goldenrod :: RGBi
- Wumpus.Basic.Colour.SVGColours: pale_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: pale_turquoise :: RGBi
- Wumpus.Basic.Colour.SVGColours: pale_violet_red :: RGBi
- Wumpus.Basic.Colour.SVGColours: papaya_whip :: RGBi
- Wumpus.Basic.Colour.SVGColours: peach_puff :: RGBi
- Wumpus.Basic.Colour.SVGColours: peru :: RGBi
- Wumpus.Basic.Colour.SVGColours: pink :: RGBi
- Wumpus.Basic.Colour.SVGColours: plum :: RGBi
- Wumpus.Basic.Colour.SVGColours: powder_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: purple :: RGBi
- Wumpus.Basic.Colour.SVGColours: red :: RGBi
- Wumpus.Basic.Colour.SVGColours: rosy_brown :: RGBi
- Wumpus.Basic.Colour.SVGColours: royal_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: saddle_brown :: RGBi
- Wumpus.Basic.Colour.SVGColours: salmon :: RGBi
- Wumpus.Basic.Colour.SVGColours: sandy_brown :: RGBi
- Wumpus.Basic.Colour.SVGColours: sea_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: seashell :: RGBi
- Wumpus.Basic.Colour.SVGColours: sienna :: RGBi
- Wumpus.Basic.Colour.SVGColours: silver :: RGBi
- Wumpus.Basic.Colour.SVGColours: sky_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: slate_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: slate_gray :: RGBi
- Wumpus.Basic.Colour.SVGColours: slate_grey :: RGBi
- Wumpus.Basic.Colour.SVGColours: snow :: RGBi
- Wumpus.Basic.Colour.SVGColours: spring_green :: RGBi
- Wumpus.Basic.Colour.SVGColours: steel_blue :: RGBi
- Wumpus.Basic.Colour.SVGColours: tan :: RGBi
- Wumpus.Basic.Colour.SVGColours: teal :: RGBi
- Wumpus.Basic.Colour.SVGColours: thistle :: RGBi
- Wumpus.Basic.Colour.SVGColours: tomato :: RGBi
- Wumpus.Basic.Colour.SVGColours: turquoise :: RGBi
- Wumpus.Basic.Colour.SVGColours: violet :: RGBi
- Wumpus.Basic.Colour.SVGColours: wheat :: RGBi
- Wumpus.Basic.Colour.SVGColours: white :: RGBi
- Wumpus.Basic.Colour.SVGColours: whitesmoke :: RGBi
- Wumpus.Basic.Colour.SVGColours: yellow :: RGBi
- Wumpus.Basic.Colour.SVGColours: yellow_green :: RGBi
- Wumpus.Basic.Colour.X11Colours: antique_white1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: antique_white2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: antique_white3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: antique_white4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: aquamarine1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: aquamarine2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: aquamarine3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: aquamarine4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: azure1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: azure2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: azure3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: azure4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: bisque1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: bisque2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: bisque3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: bisque4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: brown1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: brown2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: brown3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: brown4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: burlywood1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: burlywood2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: burlywood3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: burlywood4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cadet_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cadet_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cadet_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cadet_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: chartreuse1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: chartreuse2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: chartreuse3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: chartreuse4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: chocolate1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: chocolate2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: chocolate3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: chocolate4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: coral1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: coral2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: coral3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: coral4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cornsilk1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cornsilk2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cornsilk3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cornsilk4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cyan1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cyan2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cyan3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: cyan4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_goldenrod1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_goldenrod2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_goldenrod3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_goldenrod4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_olive_green1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_olive_green2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_olive_green3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_olive_green4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_orange1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_orange2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_orange3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_orange4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_orchid1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_orchid2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_orchid3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_orchid4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_sea_green1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_sea_green2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_sea_green3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_sea_green4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_slate_gray1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_slate_gray2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_slate_gray3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dark_slate_gray4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: deep_pink1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: deep_pink2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: deep_pink3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: deep_pink4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: deep_sky_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: deep_sky_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: deep_sky_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: deep_sky_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dodger_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dodger_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dodger_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: dodger_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: firebrick1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: firebrick2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: firebrick3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: firebrick4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: gold1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: gold2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: gold3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: gold4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: goldenrod1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: goldenrod2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: goldenrod3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: goldenrod4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: green1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: green2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: green3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: green4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: honeydew1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: honeydew2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: honeydew3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: honeydew4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: hot_pink1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: hot_pink2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: hot_pink3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: hot_pink4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: indian_red1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: indian_red2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: indian_red3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: indian_red4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: ivory1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: ivory2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: ivory3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: ivory4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: khaki1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: khaki2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: khaki3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: khaki4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: lavender_blush1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: lavender_blush2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: lavender_blush3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: lavender_blush4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: lemon_chiffon1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: lemon_chiffon2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: lemon_chiffon3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: lemon_chiffon4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_cyan1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_cyan2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_cyan3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_cyan4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_goldenrod1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_goldenrod2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_goldenrod3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_goldenrod4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_pink1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_pink2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_pink3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_pink4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_salmon1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_salmon2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_salmon3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_salmon4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_sky_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_sky_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_sky_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_sky_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_steel_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_steel_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_steel_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_steel_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_yellow1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_yellow2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_yellow3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: light_yellow4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: magenta1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: magenta2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: magenta3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: magenta4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: maroon1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: maroon2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: maroon3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: maroon4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: medium_orchid1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: medium_orchid2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: medium_orchid3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: medium_orchid4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: medium_purple1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: medium_purple2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: medium_purple3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: medium_purple4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: misty_rose1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: misty_rose2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: misty_rose3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: misty_rose4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: navajo_white1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: navajo_white2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: navajo_white3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: navajo_white4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: olive_drab1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: olive_drab2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: olive_drab3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: olive_drab4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orange1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orange2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orange3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orange4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orange_red1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orange_red2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orange_red3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orange_red4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orchid1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orchid2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orchid3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: orchid4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_green1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_green2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_green3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_green4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_turquoise1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_turquoise2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_turquoise3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_turquoise4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_violet_red1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_violet_red2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_violet_red3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pale_violet_red4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: peach_puff1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: peach_puff2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: peach_puff3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: peach_puff4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pink1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pink2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pink3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: pink4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: plum1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: plum2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: plum3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: plum4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: purple1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: purple2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: purple3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: purple4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: red1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: red2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: red3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: red4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: rosy_brown1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: rosy_brown2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: rosy_brown3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: rosy_brown4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: royal_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: royal_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: royal_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: royal_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: salmon1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: salmon2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: salmon3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: salmon4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sea_green1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sea_green2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sea_green3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sea_green4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: seashell1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: seashell2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: seashell3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: seashell4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sienna1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sienna2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sienna3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sienna4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sky_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sky_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sky_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: sky_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: slate_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: slate_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: slate_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: slate_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: slate_gray1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: slate_gray2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: slate_gray3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: slate_gray4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: snow1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: snow2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: snow3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: snow4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: spring_green1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: spring_green2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: spring_green3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: spring_green4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: steel_blue1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: steel_blue2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: steel_blue3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: steel_blue4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: tan1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: tan2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: tan3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: tan4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: thistle1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: thistle2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: thistle3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: thistle4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: tomato1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: tomato2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: tomato3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: tomato4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: turquoise1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: turquoise2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: turquoise3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: turquoise4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: violet_red1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: violet_red2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: violet_red3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: violet_red4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: wheat1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: wheat2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: wheat3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: wheat4 :: RGBi
- Wumpus.Basic.Colour.X11Colours: yellow1 :: RGBi
- Wumpus.Basic.Colour.X11Colours: yellow2 :: RGBi
- Wumpus.Basic.Colour.X11Colours: yellow3 :: RGBi
- Wumpus.Basic.Colour.X11Colours: yellow4 :: RGBi
- Wumpus.Basic.Dots.AnchorDots: data DotAnchor u
- Wumpus.Basic.Dots.AnchorDots: dotAsterisk :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotChar :: (Floating u, Real u, FromPtSize u) => Char -> DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotCircle :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotCross :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotDiamond :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotDisk :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotFDiamond :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotFOCross :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotHLine :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotOCross :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotOPlus :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotPentagon :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotPlus :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotSquare :: (Floating u, Real u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotStar :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotText :: (Floating u, Real u, FromPtSize u) => String -> DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotVLine :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: dotX :: (Floating u, FromPtSize u) => DotLocImage u
- Wumpus.Basic.Dots.AnchorDots: instance CardinalAnchor (DotAnchor u)
- Wumpus.Basic.Dots.AnchorDots: instance CardinalAnchor2 (DotAnchor u)
- Wumpus.Basic.Dots.AnchorDots: instance CenterAnchor (DotAnchor u)
- Wumpus.Basic.Dots.AnchorDots: instance Eq Cardinal
- Wumpus.Basic.Dots.AnchorDots: instance RadialAnchor (DotAnchor u)
- Wumpus.Basic.Dots.AnchorDots: instance Show Cardinal
- Wumpus.Basic.Dots.AnchorDots: type DDotLocImage = DotLocImage Double
- Wumpus.Basic.Dots.AnchorDots: type DotLocImage u = LocImage u (DotAnchor u)
- Wumpus.Basic.Dots.Marks: markAsterisk :: (Floating u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markBDiamond :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markChar :: (Fractional u, Ord u, FromPtSize u) => Char -> LocGraphic u
- Wumpus.Basic.Dots.Marks: markCircle :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markCross :: (Floating u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markDiamond :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markDisk :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markFDiamond :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markFOCross :: (Floating u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markHLine :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markOCross :: (Floating u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markOPlus :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markPentagon :: (Floating u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markPlus :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markSquare :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markStar :: (Floating u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markText :: (Fractional u, Ord u, FromPtSize u) => String -> LocGraphic u
- Wumpus.Basic.Dots.Marks: markVLine :: (Fractional u, FromPtSize u) => LocGraphic u
- Wumpus.Basic.Dots.Marks: markX :: (Fractional u, FromPtSize u) => LocGraphic u
- 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: anterior :: OPlus t => t -> (t -> t)
- Wumpus.Basic.Graphic.Base: askDC :: DrawingCtxM m => m DrawingContext
- Wumpus.Basic.Graphic.Base: asksDC :: DrawingCtxM m => (DrawingContext -> a) -> m a
- Wumpus.Basic.Graphic.Base: class (Applicative m, Monad m) => DrawingCtxM m :: (* -> *)
- Wumpus.Basic.Graphic.Base: class OPlus t
- Wumpus.Basic.Graphic.Base: class Monad m => PointSupplyM m :: (* -> *)
- Wumpus.Basic.Graphic.Base: class Monad m => TraceM m :: (* -> *)
- Wumpus.Basic.Graphic.Base: collectH :: PrimGraphic u -> HPrim u
- Wumpus.Basic.Graphic.Base: data HAlign
- Wumpus.Basic.Graphic.Base: data HPrim u
- Wumpus.Basic.Graphic.Base: data PrimGraphic u
- Wumpus.Basic.Graphic.Base: data VAlign
- Wumpus.Basic.Graphic.Base: getPrimGraphic :: PrimGraphic u -> Primitive u
- Wumpus.Basic.Graphic.Base: hprimToList :: HPrim u -> [Primitive u]
- Wumpus.Basic.Graphic.Base: instance (OPlus a, OPlus b) => OPlus (a, b)
- Wumpus.Basic.Graphic.Base: instance (Real u, Floating u) => Rotate (PrimGraphic u)
- Wumpus.Basic.Graphic.Base: instance (Real u, Floating u) => RotateAbout (PrimGraphic u)
- 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 Eq u => Eq (PrimGraphic u)
- Wumpus.Basic.Graphic.Base: instance Monoid (HPrim u)
- Wumpus.Basic.Graphic.Base: instance Num u => Scale (PrimGraphic u)
- Wumpus.Basic.Graphic.Base: instance Num u => Translate (PrimGraphic u)
- Wumpus.Basic.Graphic.Base: instance OPlus (PrimGraphic u)
- Wumpus.Basic.Graphic.Base: instance OPlus (Primitive u)
- Wumpus.Basic.Graphic.Base: instance OPlus a => OPlus (r -> a)
- 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: instance Show u => Show (PrimGraphic u)
- Wumpus.Basic.Graphic.Base: localize :: DrawingCtxM m => (DrawingContext -> DrawingContext) -> m a -> m a
- Wumpus.Basic.Graphic.Base: oconcat :: OPlus t => t -> [t] -> t
- Wumpus.Basic.Graphic.Base: oplus :: OPlus t => t -> t -> t
- Wumpus.Basic.Graphic.Base: position :: (PointSupplyM m, u ~ (MonUnit m)) => m (Point2 u)
- Wumpus.Basic.Graphic.Base: primGraphic :: Primitive u -> PrimGraphic u
- Wumpus.Basic.Graphic.Base: singleH :: Primitive u -> HPrim u
- Wumpus.Basic.Graphic.Base: superior :: OPlus t => t -> (t -> t)
- Wumpus.Basic.Graphic.Base: trace :: TraceM m => HPrim (MonUnit m) -> m ()
- 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: data 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: runDrawing :: DrawingContext -> Drawing u -> Maybe (Picture u)
- Wumpus.Basic.Graphic.Drawing: runDrawingU :: DrawingContext -> Drawing u -> Picture u
- Wumpus.Basic.Graphic.Drawing: type DDrawing = Drawing Double
- Wumpus.Basic.Graphic.DrawingContext: DrawingContext :: BaseGlyphMetrics -> GlyphMetrics -> StrokeAttr -> FontAttr -> RGBi -> RGBi -> Double -> DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: bothFillColour :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: bothStrokeColour :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: capButt :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: capRound :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: capSquare :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: dashPattern :: DashPattern -> DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: data DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: default_drawing_context :: DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: doubledashes :: DashPattern -> DashPattern
- Wumpus.Basic.Graphic.DrawingContext: doublegaps :: DashPattern -> DashPattern
- Wumpus.Basic.Graphic.DrawingContext: doublesize :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: dphase :: Int -> DashPattern -> DashPattern
- Wumpus.Basic.Graphic.DrawingContext: fallback_metrics :: DrawingContext -> GlyphMetrics
- Wumpus.Basic.Graphic.DrawingContext: fillColour :: RGBi -> DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: fill_colour :: DrawingContext -> RGBi
- Wumpus.Basic.Graphic.DrawingContext: font_props :: DrawingContext -> FontAttr
- Wumpus.Basic.Graphic.DrawingContext: fontface :: FontFace -> DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: fontsize :: Int -> DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: glyph_tables :: DrawingContext -> BaseGlyphMetrics
- Wumpus.Basic.Graphic.DrawingContext: halfsize :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: joinBevel :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: joinMiter :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: joinRound :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: line_spacing_factor :: DrawingContext -> Double
- Wumpus.Basic.Graphic.DrawingContext: metricsContext :: FontSize -> BaseGlyphMetrics -> DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: phase :: Int -> DashPattern -> DashPattern
- Wumpus.Basic.Graphic.DrawingContext: standardContext :: FontSize -> DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: strokeColour :: RGBi -> DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: stroke_colour :: DrawingContext -> RGBi
- Wumpus.Basic.Graphic.DrawingContext: stroke_props :: DrawingContext -> StrokeAttr
- Wumpus.Basic.Graphic.DrawingContext: swapColours :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: thick :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: thin :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: type DrawingContextF = DrawingContext -> DrawingContext
- Wumpus.Basic.Graphic.DrawingContext: ultrathick :: DrawingContextF
- Wumpus.Basic.Graphic.DrawingContext: unit_dash_pattern :: DashPattern
- 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: baselineSpacing :: (DrawingCtxM m, Fractional u) => m u
- Wumpus.Basic.Graphic.Query: borderedAttr :: DrawingCtxM m => m (RGBi, StrokeAttr, RGBi)
- Wumpus.Basic.Graphic.Query: fillAttr :: DrawingCtxM m => m RGBi
- Wumpus.Basic.Graphic.Query: fontAttr :: DrawingCtxM m => m FontAttr
- Wumpus.Basic.Graphic.Query: fontFace :: DrawingCtxM m => m FontFace
- Wumpus.Basic.Graphic.Query: fontSize :: DrawingCtxM m => m Int
- 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: lineWidth :: DrawingCtxM m => m Double
- Wumpus.Basic.Graphic.Query: markHalfHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: markHeight :: (DrawingCtxM m, FromPtSize u) => m 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: monoCharWidth :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoDefaultPadding :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoDescenderDepth :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoFontPointSize :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoLowerxHeight :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoMultiLineHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => Int -> m u
- Wumpus.Basic.Graphic.Query: monoTextDimensions :: (DrawingCtxM m, Num u, Ord u, FromPtSize u) => String -> m (u, u)
- Wumpus.Basic.Graphic.Query: monoTextLength :: (DrawingCtxM m, FromPtSize u) => String -> m u
- Wumpus.Basic.Graphic.Query: monoTextWidth :: (DrawingCtxM m, FromPtSize u) => Int -> m u
- Wumpus.Basic.Graphic.Query: monoVecToCenter :: (DrawingCtxM m, Fractional u, Ord u, FromPtSize u) => String -> m (Vec2 u)
- Wumpus.Basic.Graphic.Query: strokeAttr :: DrawingCtxM m => m (RGBi, StrokeAttr)
- Wumpus.Basic.Graphic.Query: textAttr :: DrawingCtxM m => m (RGBi, FontAttr)
- Wumpus.Basic.Graphic.Query: withBorderedAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> RGBi -> a) -> m a
- Wumpus.Basic.Graphic.Query: withFillAttr :: DrawingCtxM m => (RGBi -> a) -> m a
- Wumpus.Basic.Graphic.Query: withStrokeAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> a) -> m a
- Wumpus.Basic.Graphic.Query: withTextAttr :: DrawingCtxM m => (RGBi -> FontAttr -> a) -> m a
- Wumpus.Basic.Graphic.ScalingContext: ScalingContext :: (ux -> u) -> (uy -> u) -> ScalingContext ux uy u
- Wumpus.Basic.Graphic.ScalingContext: class Monad m => ScalingM m where { type family XDim m :: *; type family YDim m :: *; }
- Wumpus.Basic.Graphic.ScalingContext: coordinateScalingContext :: Num u => u -> u -> ScalingContext Int Int u
- Wumpus.Basic.Graphic.ScalingContext: data Scaling ux uy u a
- Wumpus.Basic.Graphic.ScalingContext: data ScalingContext ux uy u
- Wumpus.Basic.Graphic.ScalingContext: data ScalingT ux uy u m a
- Wumpus.Basic.Graphic.ScalingContext: instance (u ~ MonUnit m, Monad m, TraceM m) => TraceM (ScalingT ux uy u m)
- Wumpus.Basic.Graphic.ScalingContext: instance Applicative (Scaling ux uy u)
- Wumpus.Basic.Graphic.ScalingContext: instance DrawingCtxM m => DrawingCtxM (ScalingT ux uy u m)
- Wumpus.Basic.Graphic.ScalingContext: instance Functor (Scaling ux uy u)
- Wumpus.Basic.Graphic.ScalingContext: instance Monad (Scaling ux uy u)
- Wumpus.Basic.Graphic.ScalingContext: instance Monad m => Applicative (ScalingT ux uy u m)
- Wumpus.Basic.Graphic.ScalingContext: instance Monad m => Functor (ScalingT ux uy u m)
- Wumpus.Basic.Graphic.ScalingContext: instance Monad m => Monad (ScalingT ux uy u m)
- Wumpus.Basic.Graphic.ScalingContext: instance Monad m => ScalingM (ScalingT ux uy u m)
- Wumpus.Basic.Graphic.ScalingContext: instance ScalingM (Scaling ux uy u)
- Wumpus.Basic.Graphic.ScalingContext: regularScalingContext :: Num u => u -> ScalingContext u u u
- Wumpus.Basic.Graphic.ScalingContext: runScaling :: ScalingContext ux uy u -> Scaling ux uy u a -> a
- Wumpus.Basic.Graphic.ScalingContext: runScalingT :: ScalingContext ux uy u -> ScalingT ux uy u m a -> m a
- Wumpus.Basic.Graphic.ScalingContext: scalePt :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m), uy ~ (YDim m)) => ux -> uy -> m (Point2 u)
- Wumpus.Basic.Graphic.ScalingContext: scaleVec :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m), uy ~ (YDim m)) => ux -> uy -> m (Vec2 u)
- Wumpus.Basic.Graphic.ScalingContext: scaleX :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m)) => ux -> m u
- Wumpus.Basic.Graphic.ScalingContext: scaleY :: (ScalingM m, u ~ (MonUnit m), uy ~ (YDim m)) => uy -> m u
- Wumpus.Basic.Graphic.ScalingContext: scale_in_x :: ScalingContext ux uy u -> ux -> u
- Wumpus.Basic.Graphic.ScalingContext: scale_in_y :: ScalingContext ux uy u -> uy -> u
- Wumpus.Basic.Graphic.ScalingContext: unitX :: (ScalingM m, Num ux, ux ~ (XDim m), u ~ (MonUnit m)) => m u
- Wumpus.Basic.Graphic.ScalingContext: unitY :: (ScalingM m, Num uy, uy ~ (YDim m), u ~ (MonUnit m)) => 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.Monads.TurtleClass: class Monad m => TurtleM m
- Wumpus.Basic.Monads.TurtleClass: getLoc :: TurtleM m => m (Int, Int)
- Wumpus.Basic.Monads.TurtleClass: getOrigin :: TurtleM m => m (Int, Int)
- Wumpus.Basic.Monads.TurtleClass: moveDown :: TurtleM m => m ()
- Wumpus.Basic.Monads.TurtleClass: moveLeft :: TurtleM m => m ()
- Wumpus.Basic.Monads.TurtleClass: moveRight :: TurtleM m => m ()
- Wumpus.Basic.Monads.TurtleClass: moveUp :: TurtleM m => m ()
- Wumpus.Basic.Monads.TurtleClass: nextLine :: TurtleM m => m ()
- Wumpus.Basic.Monads.TurtleClass: resetLoc :: TurtleM m => m ()
- Wumpus.Basic.Monads.TurtleClass: setLoc :: TurtleM m => (Int, Int) -> m ()
- Wumpus.Basic.Monads.TurtleClass: setOrigin :: TurtleM m => (Int, Int) -> m ()
- Wumpus.Basic.Monads.TurtleClass: setsLoc :: TurtleM m => (Coord -> (a, Coord)) -> m a
- Wumpus.Basic.Monads.TurtleClass: setsLoc_ :: TurtleM m => (Coord -> Coord) -> m ()
- Wumpus.Basic.Monads.TurtleClass: type Coord = (Int, Int)
- Wumpus.Basic.Monads.TurtleMonad: data TurtleT u m a
- Wumpus.Basic.Monads.TurtleMonad: instance (u ~ MonUnit m, Monad m, Num u) => PointSupplyM (TurtleT u m)
- Wumpus.Basic.Monads.TurtleMonad: instance (u ~ MonUnit m, Monad m, TraceM m) => TraceM (TurtleT u m)
- Wumpus.Basic.Monads.TurtleMonad: instance DrawingCtxM m => DrawingCtxM (TurtleT u m)
- Wumpus.Basic.Monads.TurtleMonad: instance Monad m => Applicative (TurtleT u m)
- Wumpus.Basic.Monads.TurtleMonad: instance Monad m => Functor (TurtleT u m)
- Wumpus.Basic.Monads.TurtleMonad: instance Monad m => Monad (TurtleT u m)
- Wumpus.Basic.Monads.TurtleMonad: instance Monad m => TurtleM (TurtleT u m)
- Wumpus.Basic.Monads.TurtleMonad: runTurtleT :: (Monad m, Num u) => (Int, Int) -> ScalingContext Int Int u -> TurtleT u m a -> m a
- Wumpus.Basic.Paths.Base: (:<<) :: PathSegment u -> Path u -> PathViewL u
- Wumpus.Basic.Paths.Base: (:>>) :: Path u -> PathSegment u -> PathViewR u
- Wumpus.Basic.Paths.Base: Curve1 :: (Point2 u) -> (Point2 u) -> (Point2 u) -> (Point2 u) -> PathSegment u
- Wumpus.Basic.Paths.Base: Line1 :: (Point2 u) -> (Point2 u) -> PathSegment u
- Wumpus.Basic.Paths.Base: PathOneL :: (PathSegment u) -> PathViewL u
- Wumpus.Basic.Paths.Base: PathOneR :: (PathSegment u) -> PathViewR u
- Wumpus.Basic.Paths.Base: append :: Floating u => Path u -> Path u -> Path u
- Wumpus.Basic.Paths.Base: atend :: (Real u, Floating u) => Path u -> (Point2 u, Radian)
- Wumpus.Basic.Paths.Base: atend_ :: Path u -> Point2 u
- Wumpus.Basic.Paths.Base: atstart :: (Real u, Floating u) => Path u -> (Point2 u, Radian)
- Wumpus.Basic.Paths.Base: atstart_ :: Path u -> Point2 u
- Wumpus.Basic.Paths.Base: curve :: (Floating u, Ord u) => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Path u
- Wumpus.Basic.Paths.Base: curveByAngles :: (Floating u, Ord u) => Point2 u -> Radian -> Radian -> Point2 u -> Path u
- Wumpus.Basic.Paths.Base: data Path u
- Wumpus.Basic.Paths.Base: data PathSegment u
- Wumpus.Basic.Paths.Base: data PathViewL u
- Wumpus.Basic.Paths.Base: data PathViewR u
- Wumpus.Basic.Paths.Base: directionL :: (Real u, Floating u) => Path u -> Radian
- Wumpus.Basic.Paths.Base: directionR :: (Real u, Floating u) => Path u -> Radian
- Wumpus.Basic.Paths.Base: instance Eq u => Eq (Path u)
- Wumpus.Basic.Paths.Base: instance Eq u => Eq (PathSeg u)
- Wumpus.Basic.Paths.Base: instance Eq u => Eq (PathSegment u)
- Wumpus.Basic.Paths.Base: instance Eq u => Eq (PathViewL u)
- Wumpus.Basic.Paths.Base: instance Eq u => Eq (PathViewR u)
- Wumpus.Basic.Paths.Base: instance Ord u => Ord (Path u)
- Wumpus.Basic.Paths.Base: instance Ord u => Ord (PathSeg u)
- Wumpus.Basic.Paths.Base: instance Ord u => Ord (PathSegment u)
- Wumpus.Basic.Paths.Base: instance Ord u => Ord (PathViewL u)
- Wumpus.Basic.Paths.Base: instance Ord u => Ord (PathViewR u)
- Wumpus.Basic.Paths.Base: instance Show u => Show (Path u)
- Wumpus.Basic.Paths.Base: instance Show u => Show (PathSeg u)
- Wumpus.Basic.Paths.Base: instance Show u => Show (PathSegment u)
- Wumpus.Basic.Paths.Base: instance Show u => Show (PathViewL u)
- Wumpus.Basic.Paths.Base: instance Show u => Show (PathViewR u)
- Wumpus.Basic.Paths.Base: length :: Num u => Path u -> u
- Wumpus.Basic.Paths.Base: line :: Floating u => Point2 u -> Point2 u -> Path u
- Wumpus.Basic.Paths.Base: midway :: (Real u, Floating u) => Path u -> (Point2 u, Radian)
- Wumpus.Basic.Paths.Base: midway_ :: (Real u, Floating u) => Path u -> Point2 u
- Wumpus.Basic.Paths.Base: pathViewL :: Num u => Path u -> PathViewL u
- Wumpus.Basic.Paths.Base: pathViewR :: Num u => Path u -> PathViewR u
- Wumpus.Basic.Paths.Base: pconcat :: Floating u => Path u -> [Path u] -> Path u
- Wumpus.Basic.Paths.Base: pivot :: Floating u => Point2 u -> Path u
- Wumpus.Basic.Paths.Base: shortenBoth :: (Real u, Floating u) => u -> Path u -> Path u
- Wumpus.Basic.Paths.Base: shortenL :: (Real u, Floating u) => u -> Path u -> Path u
- Wumpus.Basic.Paths.Base: shortenR :: (Real u, Floating u) => u -> Path u -> Path u
- Wumpus.Basic.Paths.Base: tipL :: Path u -> Point2 u
- Wumpus.Basic.Paths.Base: tipR :: Path u -> Point2 u
- Wumpus.Basic.Paths.Base: toPrimPath :: Num u => Path u -> PrimPath u
- Wumpus.Basic.Paths.Base: traceCurvePoints :: (Floating u, Ord u) => [Point2 u] -> Path u
- Wumpus.Basic.Paths.Base: traceLinePoints :: Floating u => [Point2 u] -> Path u
- Wumpus.Basic.Paths.Base: type DPath = Path Double
- Wumpus.Basic.Paths.Base: type DPathSegment = PathSegment Double
- Wumpus.Basic.Paths.Base: type DPathViewL = PathViewL Double
- Wumpus.Basic.Paths.Base: type DPathViewR = PathViewR Double
- Wumpus.Basic.Paths.Connectors: connIsosceles :: (Real u, Floating u) => u -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connIsosceles2 :: (Real u, Floating u) => u -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connIsoscelesCurve :: (Real u, Floating u) => u -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connLightningBolt :: (Real u, Floating u) => u -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connLine :: Floating u => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connRightHV :: Floating u => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connRightHVH :: Floating u => u -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connRightVH :: Floating u => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connRightVHV :: Floating u => u -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connSquareCurve :: (Real u, Floating u) => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connTrapezoidCurve :: (Real u, Floating u) => u -> u -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connUSquareCurve :: (Real u, Floating u) => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connUZSquareCurve :: (Real u, Floating u) => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: connZSquareCurve :: (Real u, Floating u) => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: type ConnectorPath u = Point2 u -> Point2 u -> Path u
- Wumpus.Basic.Paths.Connectors: type DConnectorPath = ConnectorPath Double
- Wumpus.Basic.Paths.Construction: bezierto :: (Floating u, Ord u) => Point2 u -> Point2 u -> Point2 u -> PathM u ()
- Wumpus.Basic.Paths.Construction: curveto :: (Floating u, Ord u) => Radian -> Radian -> Point2 u -> PathM u ()
- Wumpus.Basic.Paths.Construction: data PathM u a
- Wumpus.Basic.Paths.Construction: execPath :: Floating u => Point2 u -> PathM u a -> Path u
- Wumpus.Basic.Paths.Construction: hline :: Floating u => u -> PathM u ()
- Wumpus.Basic.Paths.Construction: horizontalVertical :: Floating u => Point2 u -> PathM u ()
- Wumpus.Basic.Paths.Construction: instance Applicative (PathM u)
- Wumpus.Basic.Paths.Construction: instance Functor (PathM u)
- Wumpus.Basic.Paths.Construction: instance Monad (PathM u)
- Wumpus.Basic.Paths.Construction: lineto :: Floating u => Point2 u -> PathM u ()
- Wumpus.Basic.Paths.Construction: rlineto :: Floating u => Vec2 u -> PathM u ()
- Wumpus.Basic.Paths.Construction: runPath :: Floating u => Point2 u -> PathM u a -> (a, Path u)
- Wumpus.Basic.Paths.Construction: tip :: PathM u (Point2 u)
- Wumpus.Basic.Paths.Construction: verticalHorizontal :: Floating u => Point2 u -> PathM u ()
- Wumpus.Basic.Paths.Construction: vline :: Floating u => u -> PathM u ()
- Wumpus.Basic.Paths.ControlPoints: dblpointIsosceles :: (Real u, Floating u) => u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)
- Wumpus.Basic.Paths.ControlPoints: midpointIsosceles :: (Real u, Floating u) => u -> Point2 u -> Point2 u -> Point2 u
- Wumpus.Basic.Paths.ControlPoints: rectangleFromBasePoints :: (Real u, Floating u) => u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)
- Wumpus.Basic.Paths.ControlPoints: squareFromBasePoints :: (Real u, Floating u) => Point2 u -> Point2 u -> (Point2 u, Point2 u)
- Wumpus.Basic.Paths.ControlPoints: squareFromCornerPoints :: (Real u, Floating u) => Point2 u -> Point2 u -> (Point2 u, Point2 u)
- Wumpus.Basic.Paths.ControlPoints: trapezoidFromBasePoints :: (Real u, Floating u) => u -> u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)
- Wumpus.Basic.Paths.ControlPoints: usquareFromBasePoints :: (Real u, Floating u) => Point2 u -> Point2 u -> (Point2 u, Point2 u)
- Wumpus.Basic.Paths.RoundCorners: cornerCurve :: (Real u, Floating u) => Point2 u -> Point2 u -> Point2 u -> Path u
- Wumpus.Basic.Paths.RoundCorners: illustratePath :: Fractional u => Path u -> Graphic u
- Wumpus.Basic.Paths.RoundCorners: roundEvery :: (Real u, Floating u) => u -> [Point2 u] -> Path u
- Wumpus.Basic.SafeFonts: courier :: FontFace
- Wumpus.Basic.SafeFonts: courier_bold :: FontFace
- Wumpus.Basic.SafeFonts: courier_bold_oblique :: FontFace
- Wumpus.Basic.SafeFonts: courier_oblique :: FontFace
- Wumpus.Basic.SafeFonts: helvetica :: FontFace
- Wumpus.Basic.SafeFonts: helvetica_bold :: FontFace
- Wumpus.Basic.SafeFonts: helvetica_bold_oblique :: FontFace
- Wumpus.Basic.SafeFonts: helvetica_oblique :: FontFace
- Wumpus.Basic.SafeFonts: symbol :: FontFace
- Wumpus.Basic.SafeFonts: times_bold :: FontFace
- Wumpus.Basic.SafeFonts: times_bold_italic :: FontFace
- Wumpus.Basic.SafeFonts: times_italic :: FontFace
- Wumpus.Basic.SafeFonts: times_roman :: FontFace
- Wumpus.Basic.Shapes.Base: askCTM :: ShapeGeom u (ShapeCTM u)
- Wumpus.Basic.Shapes.Base: borderedShape :: Num u => Shape u t -> Image u (t u)
- Wumpus.Basic.Shapes.Base: data Shape u t
- Wumpus.Basic.Shapes.Base: data ShapeCTM u
- Wumpus.Basic.Shapes.Base: data ShapeGeom u a
- Wumpus.Basic.Shapes.Base: filledShape :: Num u => Shape u t -> Image u (t u)
- Wumpus.Basic.Shapes.Base: instance (Real u, Floating u) => Rotate (Shape u sh)
- Wumpus.Basic.Shapes.Base: instance (Real u, Floating u) => RotateAbout (Shape u sh)
- Wumpus.Basic.Shapes.Base: instance (Real u, Floating u) => RotateAbout (ShapeCTM u)
- Wumpus.Basic.Shapes.Base: instance Applicative (ShapeGeom u)
- Wumpus.Basic.Shapes.Base: instance Eq u => Eq (ShapeCTM u)
- Wumpus.Basic.Shapes.Base: instance Functor (ShapeGeom u)
- Wumpus.Basic.Shapes.Base: instance Monad (ShapeGeom u)
- Wumpus.Basic.Shapes.Base: instance Num u => Scale (Shape u sh)
- Wumpus.Basic.Shapes.Base: instance Num u => Scale (ShapeCTM u)
- Wumpus.Basic.Shapes.Base: instance Num u => Translate (Shape u sh)
- Wumpus.Basic.Shapes.Base: instance Num u => Translate (ShapeCTM u)
- Wumpus.Basic.Shapes.Base: instance Ord u => Ord (ShapeCTM u)
- Wumpus.Basic.Shapes.Base: instance Rotate (ShapeCTM u)
- Wumpus.Basic.Shapes.Base: instance Show u => Show (ShapeCTM u)
- Wumpus.Basic.Shapes.Base: makeShape :: Num u => (ShapeCTM u -> Path u) -> (ShapeCTM u -> t u) -> LocShape u t
- Wumpus.Basic.Shapes.Base: makeShapeCTM :: Num u => Point2 u -> ShapeCTM u
- Wumpus.Basic.Shapes.Base: projectPoint :: (Real u, Floating u) => Point2 u -> ShapeGeom u (Point2 u)
- Wumpus.Basic.Shapes.Base: runShapeGeom :: ShapeCTM u -> ShapeGeom u a -> a
- Wumpus.Basic.Shapes.Base: shapeAngle :: ShapeGeom u Radian
- Wumpus.Basic.Shapes.Base: shapeCenter :: ShapeGeom u (Point2 u)
- Wumpus.Basic.Shapes.Base: strokedShape :: Num u => Shape u t -> Image u (t u)
- Wumpus.Basic.Shapes.Base: type LocShape u t = Point2 u -> Shape u t
- Wumpus.Basic.Shapes.Base: type ShapeConstructor u t = ShapeCTM u -> t u
- Wumpus.Basic.Shapes.Coordinate: coordinate :: Num u => LocCoordinate u
- 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: data Coordinate u
- Wumpus.Basic.Shapes.Coordinate: data CoordinateAnchor u
- Wumpus.Basic.Shapes.Coordinate: instance (Real u, Floating u) => CenterAnchor (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 Eq u => Eq (Coordinate u)
- Wumpus.Basic.Shapes.Coordinate: instance Eq u => Eq (CoordinateAnchor u)
- Wumpus.Basic.Shapes.Coordinate: instance Num u => Scale (Coordinate u)
- Wumpus.Basic.Shapes.Coordinate: instance Num u => Translate (Coordinate u)
- Wumpus.Basic.Shapes.Coordinate: instance Ord u => Ord (Coordinate u)
- Wumpus.Basic.Shapes.Coordinate: instance Ord u => Ord (CoordinateAnchor u)
- Wumpus.Basic.Shapes.Coordinate: instance Show u => Show (Coordinate u)
- Wumpus.Basic.Shapes.Coordinate: instance Show u => Show (CoordinateAnchor u)
- Wumpus.Basic.Shapes.Coordinate: type DCoordinate = Coordinate Double
- Wumpus.Basic.Shapes.Coordinate: type DCoordinateAnchor = CoordinateAnchor Double
- Wumpus.Basic.Shapes.Derived: circle :: (Real u, Floating u) => u -> LocShape u Circle
- Wumpus.Basic.Shapes.Derived: data Circle u
- Wumpus.Basic.Shapes.Derived: data Diamond u
- Wumpus.Basic.Shapes.Derived: data Ellipse u
- Wumpus.Basic.Shapes.Derived: data Rectangle u
- Wumpus.Basic.Shapes.Derived: diamond :: (Real u, Floating u) => u -> u -> LocShape u Diamond
- Wumpus.Basic.Shapes.Derived: ellipse :: (Real u, Floating u) => u -> u -> LocShape u Ellipse
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (Circle u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (Diamond u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (Ellipse u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (Rectangle u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor2 (Circle u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor2 (Ellipse u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor2 (Rectangle u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (Circle u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (Diamond u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (Ellipse u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (Rectangle u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (Circle u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (Diamond u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (Ellipse u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (Rectangle u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u, Fractional u) => CardinalAnchor2 (Diamond u)
- Wumpus.Basic.Shapes.Derived: instance Eq u => Eq (Circle u)
- Wumpus.Basic.Shapes.Derived: instance Eq u => Eq (Rectangle u)
- Wumpus.Basic.Shapes.Derived: instance Ord u => Ord (Rectangle u)
- Wumpus.Basic.Shapes.Derived: instance Show u => Show (Circle u)
- Wumpus.Basic.Shapes.Derived: instance Show u => Show (Rectangle u)
- Wumpus.Basic.Shapes.Derived: mkRectangle :: u -> u -> ShapeConstructor u Rectangle
- Wumpus.Basic.Shapes.Derived: rdiamond :: (Real u, Floating u) => u -> u -> u -> LocShape u Diamond
- Wumpus.Basic.Shapes.Derived: rectangle :: (Real u, Floating u) => u -> u -> LocShape u Rectangle
- Wumpus.Basic.Shapes.Derived: rrectangle :: (Real u, Floating u) => u -> u -> u -> LocShape u Rectangle
- Wumpus.Basic.Shapes.Derived: type DCircle = Circle Double
- Wumpus.Basic.Shapes.Derived: type DDiamond = Diamond Double
- Wumpus.Basic.Shapes.Derived: type DEllipse = Ellipse Double
- Wumpus.Basic.Shapes.Derived: type DRectangle = Rectangle Double
- 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.Intersection: LS :: (Point2 u) -> (Point2 u) -> LineSegment u
- Wumpus.Basic.Utils.Intersection: data LineEqn u
- Wumpus.Basic.Utils.Intersection: data LineSegment u
- Wumpus.Basic.Utils.Intersection: data PointSlope u
- Wumpus.Basic.Utils.Intersection: findIntersect :: (Floating u, Real u, Ord u) => Point2 u -> Radian -> [LineSegment u] -> Maybe (Point2 u)
- Wumpus.Basic.Utils.Intersection: instance Eq u => Eq (IntersectionResult u)
- Wumpus.Basic.Utils.Intersection: instance Eq u => Eq (LineEqn u)
- Wumpus.Basic.Utils.Intersection: instance Eq u => Eq (LineSegment u)
- Wumpus.Basic.Utils.Intersection: instance Eq u => Eq (PointSlope u)
- Wumpus.Basic.Utils.Intersection: instance Ord u => Ord (LineSegment u)
- Wumpus.Basic.Utils.Intersection: instance Show u => Show (IntersectionResult u)
- Wumpus.Basic.Utils.Intersection: instance Show u => Show (LineEqn u)
- Wumpus.Basic.Utils.Intersection: instance Show u => Show (LineSegment u)
- Wumpus.Basic.Utils.Intersection: instance Show u => Show (PointSlope u)
- Wumpus.Basic.Utils.Intersection: intersection :: (Fractional u, Ord u) => LineSegment u -> LineEqn u -> Maybe (Point2 u)
- Wumpus.Basic.Utils.Intersection: langle :: (Floating u, Real u) => Point2 u -> Point2 u -> Radian
- Wumpus.Basic.Utils.Intersection: lineEqn :: Num u => Point2 u -> Point2 u -> LineEqn u
- Wumpus.Basic.Utils.Intersection: pointSlope :: Fractional u => Point2 u -> Radian -> PointSlope u
- Wumpus.Basic.Utils.Intersection: polygonLines :: [Point2 u] -> [LineSegment u]
- Wumpus.Basic.Utils.Intersection: rectangleLines :: Num u => Point2 u -> u -> u -> [LineSegment u]
- Wumpus.Basic.Utils.Intersection: toLineEqn :: Num u => PointSlope u -> LineEqn u
+ Wumpus.Basic.Kernel.Base.Anchors: center :: (CenterAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: class CardinalAnchor t
+ Wumpus.Basic.Kernel.Base.Anchors: class CardinalAnchor2 t
+ Wumpus.Basic.Kernel.Base.Anchors: class CenterAnchor t
+ Wumpus.Basic.Kernel.Base.Anchors: class RadialAnchor t
+ Wumpus.Basic.Kernel.Base.Anchors: east :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: eastwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: instance Fractional u => CardinalAnchor (BoundingBox u)
+ Wumpus.Basic.Kernel.Base.Anchors: instance Fractional u => CardinalAnchor2 (BoundingBox u)
+ Wumpus.Basic.Kernel.Base.Anchors: instance Fractional u => CenterAnchor (BoundingBox u)
+ Wumpus.Basic.Kernel.Base.Anchors: north :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: northeast :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: northeastwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: northwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: northwest :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: northwestwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: radialAnchor :: (RadialAnchor t, (DUnit t) ~ u) => Radian -> t -> Point2 u
+ Wumpus.Basic.Kernel.Base.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.Kernel.Base.Anchors: south :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: southeast :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: southeastwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: southwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: southwest :: (CardinalAnchor2 t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: southwestwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor2 t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: west :: (CardinalAnchor t, (DUnit t) ~ u) => t -> Point2 u
+ Wumpus.Basic.Kernel.Base.Anchors: westwards :: (Real u, Floating u, CenterAnchor t, CardinalAnchor t, u ~ (DUnit t)) => u -> t -> Point2 u
+ Wumpus.Basic.Kernel.Base.BaseDefs: HBottom :: HAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: HCenter :: HAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: HTop :: HAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: VCenter :: VAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: VLeft :: VAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: VRight :: VAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: advanceH :: AdvanceVec u -> u
+ Wumpus.Basic.Kernel.Base.BaseDefs: advanceV :: AdvanceVec u -> u
+ Wumpus.Basic.Kernel.Base.BaseDefs: bimap :: Bimap f => (a -> p) -> (b -> q) -> f a b -> f p q
+ Wumpus.Basic.Kernel.Base.BaseDefs: bimapL :: Bimap f => (a -> p) -> f a b -> f p b
+ Wumpus.Basic.Kernel.Base.BaseDefs: bimapR :: Bimap f => (b -> q) -> f a b -> f a q
+ Wumpus.Basic.Kernel.Base.BaseDefs: class Bimap f
+ Wumpus.Basic.Kernel.Base.BaseDefs: class OPlus t
+ Wumpus.Basic.Kernel.Base.BaseDefs: class Monad m => PointSupplyM m :: (* -> *)
+ Wumpus.Basic.Kernel.Base.BaseDefs: data HAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: data VAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: displace :: Num u => u -> u -> PointDisplace u
+ Wumpus.Basic.Kernel.Base.BaseDefs: displaceH :: Num u => u -> PointDisplace u
+ Wumpus.Basic.Kernel.Base.BaseDefs: displaceParallel :: Floating u => u -> ThetaPointDisplace u
+ Wumpus.Basic.Kernel.Base.BaseDefs: displacePerpendicular :: Floating u => u -> ThetaPointDisplace u
+ Wumpus.Basic.Kernel.Base.BaseDefs: displaceV :: Num u => u -> PointDisplace u
+ Wumpus.Basic.Kernel.Base.BaseDefs: displaceVec :: Num u => Vec2 u -> PointDisplace u
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance (OPlus a, OPlus b) => OPlus (a, b)
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Bimap (,)
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Bimap Either
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Enum HAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Enum VAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Eq HAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Eq VAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance OPlus ()
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance OPlus (Primitive u)
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance OPlus (UNil u)
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance OPlus a => OPlus (r -> a)
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Ord HAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Ord VAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Ord u => OPlus (BoundingBox u)
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Show HAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: instance Show VAlign
+ Wumpus.Basic.Kernel.Base.BaseDefs: oconcat :: OPlus t => t -> [t] -> t
+ Wumpus.Basic.Kernel.Base.BaseDefs: oplus :: OPlus t => t -> t -> t
+ Wumpus.Basic.Kernel.Base.BaseDefs: position :: (PointSupplyM m, (MonUnit m) ~ u) => m (Point2 u)
+ Wumpus.Basic.Kernel.Base.BaseDefs: replaceL :: Bimap f => p -> f a b -> f p b
+ Wumpus.Basic.Kernel.Base.BaseDefs: replaceR :: Bimap f => q -> f a b -> f a q
+ Wumpus.Basic.Kernel.Base.BaseDefs: type AdvanceVec u = Vec2 u
+ Wumpus.Basic.Kernel.Base.BaseDefs: type PointDisplace u = Point2 u -> Point2 u
+ Wumpus.Basic.Kernel.Base.BaseDefs: type ThetaPointDisplace u = Radian -> PointDisplace u
+ Wumpus.Basic.Kernel.Base.ContextFun: apply1R1 :: CF1 r1 a -> r1 -> CF a
+ Wumpus.Basic.Kernel.Base.ContextFun: apply1R2 :: CF2 r1 r2 a -> r2 -> CF1 r1 a
+ Wumpus.Basic.Kernel.Base.ContextFun: apply2R2 :: CF2 r1 r2 a -> r1 -> r2 -> CF a
+ Wumpus.Basic.Kernel.Base.ContextFun: at :: LocCF u a -> Point2 u -> CF a
+ Wumpus.Basic.Kernel.Base.ContextFun: chain1 :: OPlus w => CF1 s1 (s1, w) -> CF1 s1 (s1, w) -> CF1 s1 (s1, w)
+ Wumpus.Basic.Kernel.Base.ContextFun: connCtx :: ConnectorCF u DrawingContext
+ Wumpus.Basic.Kernel.Base.ContextFun: connEnd :: ConnectorCF u (Point2 u)
+ Wumpus.Basic.Kernel.Base.ContextFun: connStart :: ConnectorCF u (Point2 u)
+ Wumpus.Basic.Kernel.Base.ContextFun: connect :: ConnectorCF u a -> Point2 u -> Point2 u -> CF a
+ Wumpus.Basic.Kernel.Base.ContextFun: data CF a
+ Wumpus.Basic.Kernel.Base.ContextFun: data CF1 r1 a
+ Wumpus.Basic.Kernel.Base.ContextFun: data CF2 r1 r2 a
+ Wumpus.Basic.Kernel.Base.ContextFun: drawingCtx :: CF DrawingContext
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Applicative (CF1 r1)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Applicative (CF2 r1 r2)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Applicative CF
+ Wumpus.Basic.Kernel.Base.ContextFun: instance DrawingCtxM (CF1 r1)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance DrawingCtxM (CF2 r1 r2)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance DrawingCtxM CF
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Functor (CF1 r1)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Functor (CF2 r1 r2)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Functor CF
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Monad (CF1 r1)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Monad (CF2 r1 r2)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Monad CF
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Monoid a => Monoid (CF a)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Monoid a => Monoid (CF1 r1 a)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance Monoid a => Monoid (CF2 r1 r2 a)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance OPlus a => OPlus (CF a)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance OPlus a => OPlus (CF1 r1 a)
+ Wumpus.Basic.Kernel.Base.ContextFun: instance OPlus a => OPlus (CF2 r1 r2 a)
+ Wumpus.Basic.Kernel.Base.ContextFun: lift0R1 :: CF a -> CF1 r1 a
+ Wumpus.Basic.Kernel.Base.ContextFun: lift0R2 :: CF a -> CF2 r1 r2 a
+ Wumpus.Basic.Kernel.Base.ContextFun: lift1R2 :: CF1 r1 a -> CF2 r1 r2 a
+ Wumpus.Basic.Kernel.Base.ContextFun: locCtx :: LocCF u DrawingContext
+ Wumpus.Basic.Kernel.Base.ContextFun: locPoint :: LocCF u (Point2 u)
+ Wumpus.Basic.Kernel.Base.ContextFun: locThetaAng :: LocThetaCF u Radian
+ Wumpus.Basic.Kernel.Base.ContextFun: locThetaCtx :: LocThetaCF u DrawingContext
+ Wumpus.Basic.Kernel.Base.ContextFun: locThetaPoint :: LocThetaCF u (Point2 u)
+ Wumpus.Basic.Kernel.Base.ContextFun: promoteR1 :: (r1 -> CF a) -> CF1 r1 a
+ Wumpus.Basic.Kernel.Base.ContextFun: promoteR2 :: (r1 -> r2 -> CF a) -> CF2 r1 r2 a
+ Wumpus.Basic.Kernel.Base.ContextFun: queryCtx :: (DrawingContext -> a) -> CF a
+ Wumpus.Basic.Kernel.Base.ContextFun: rot :: LocThetaCF u a -> Radian -> LocCF u a
+ Wumpus.Basic.Kernel.Base.ContextFun: runCF :: DrawingContext -> CF a -> a
+ Wumpus.Basic.Kernel.Base.ContextFun: runCF1 :: DrawingContext -> r1 -> CF1 r1 a -> a
+ Wumpus.Basic.Kernel.Base.ContextFun: runCF2 :: DrawingContext -> r1 -> r2 -> CF2 r1 r2 a -> a
+ Wumpus.Basic.Kernel.Base.ContextFun: type ConnectorCF u a = CF2 (Point2 u) (Point2 u) a
+ Wumpus.Basic.Kernel.Base.ContextFun: type DConnectorCF a = ConnectorCF Double a
+ Wumpus.Basic.Kernel.Base.ContextFun: type DLocCF a = LocCF Double a
+ Wumpus.Basic.Kernel.Base.ContextFun: type DLocThetaCF a = LocThetaCF Double a
+ Wumpus.Basic.Kernel.Base.ContextFun: type LocCF u a = CF1 (Point2 u) a
+ Wumpus.Basic.Kernel.Base.ContextFun: type LocThetaCF u a = CF2 (Point2 u) Radian a
+ Wumpus.Basic.Kernel.Base.DrawingContext: DrawingContext :: GlyphMetrics -> MetricsOps -> StrokeAttr -> FontAttr -> RGBi -> RGBi -> Double -> DrawingContext
+ Wumpus.Basic.Kernel.Base.DrawingContext: askDC :: DrawingCtxM m => m DrawingContext
+ Wumpus.Basic.Kernel.Base.DrawingContext: asksDC :: DrawingCtxM m => (DrawingContext -> a) -> m a
+ Wumpus.Basic.Kernel.Base.DrawingContext: class (Applicative m, Monad m) => DrawingCtxM m :: (* -> *)
+ Wumpus.Basic.Kernel.Base.DrawingContext: data DrawingContext
+ Wumpus.Basic.Kernel.Base.DrawingContext: default_drawing_context :: DrawingContext
+ Wumpus.Basic.Kernel.Base.DrawingContext: fallback_metrics :: DrawingContext -> MetricsOps
+ Wumpus.Basic.Kernel.Base.DrawingContext: fill_colour :: DrawingContext -> RGBi
+ Wumpus.Basic.Kernel.Base.DrawingContext: font_props :: DrawingContext -> FontAttr
+ Wumpus.Basic.Kernel.Base.DrawingContext: glyph_tables :: DrawingContext -> GlyphMetrics
+ Wumpus.Basic.Kernel.Base.DrawingContext: line_spacing_factor :: DrawingContext -> Double
+ Wumpus.Basic.Kernel.Base.DrawingContext: localize :: DrawingCtxM m => (DrawingContext -> DrawingContext) -> m a -> m a
+ Wumpus.Basic.Kernel.Base.DrawingContext: metricsContext :: FontSize -> GlyphMetrics -> DrawingContext
+ Wumpus.Basic.Kernel.Base.DrawingContext: standardContext :: FontSize -> DrawingContext
+ Wumpus.Basic.Kernel.Base.DrawingContext: stroke_colour :: DrawingContext -> RGBi
+ Wumpus.Basic.Kernel.Base.DrawingContext: stroke_props :: DrawingContext -> StrokeAttr
+ Wumpus.Basic.Kernel.Base.DrawingContext: type DrawingContextF = DrawingContext -> DrawingContext
+ Wumpus.Basic.Kernel.Base.DrawingContext: withFontMetrics :: (MetricsOps -> PtSize -> u) -> DrawingContext -> u
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: FontMetricsOps :: FontName -> MetricsOps -> FontMetricsOps
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: MetricsOps :: (forall u. FromPtSize u => PtSize -> BoundingBox u) -> (forall u. FromPtSize u => PtSize -> CharWidthTable u) -> (forall u. FromPtSize u => PtSize -> u) -> MetricsOps
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: data FontMetricsOps
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: data GlyphMetrics
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: data MetricsOps
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: emptyGlyphMetrics :: GlyphMetrics
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: get_bounding_box :: MetricsOps -> forall u. FromPtSize u => PtSize -> BoundingBox u
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: get_cap_height :: MetricsOps -> forall u. FromPtSize u => PtSize -> u
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: get_cw_table :: MetricsOps -> forall u. FromPtSize u => PtSize -> CharWidthTable u
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: insertFont :: FontMetricsOps -> GlyphMetrics -> GlyphMetrics
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: instance Monoid GlyphMetrics
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: lookupFont :: FontName -> GlyphMetrics -> Maybe MetricsOps
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: monospace_metrics :: MetricsOps
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: type CharWidthTable u = CodePoint -> Vec2 u
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: type CodePoint = Int
+ Wumpus.Basic.Kernel.Base.GlyphMetrics: type FontName = String
+ Wumpus.Basic.Kernel.Base.QueryDC: baselineSpacing :: (DrawingCtxM m, Fractional u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: borderedAttr :: DrawingCtxM m => m (RGBi, StrokeAttr, RGBi)
+ Wumpus.Basic.Kernel.Base.QueryDC: cwLookupTable :: (FromPtSize u, DrawingCtxM m) => m (CharWidthTable u)
+ Wumpus.Basic.Kernel.Base.QueryDC: fillAttr :: DrawingCtxM m => m RGBi
+ Wumpus.Basic.Kernel.Base.QueryDC: getFontAttr :: DrawingCtxM m => m FontAttr
+ Wumpus.Basic.Kernel.Base.QueryDC: getFontFace :: DrawingCtxM m => m FontFace
+ Wumpus.Basic.Kernel.Base.QueryDC: getFontSize :: DrawingCtxM m => m Int
+ Wumpus.Basic.Kernel.Base.QueryDC: getLineWidth :: DrawingCtxM m => m Double
+ Wumpus.Basic.Kernel.Base.QueryDC: glyphBoundingBox :: (FromPtSize u, DrawingCtxM m) => m (BoundingBox u)
+ Wumpus.Basic.Kernel.Base.QueryDC: glyphCapHeight :: (FromPtSize u, DrawingCtxM m) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: glyphHeight :: (FromPtSize u, DrawingCtxM m) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: glyphHeightRange :: (FromPtSize u, DrawingCtxM m) => m (u, u)
+ Wumpus.Basic.Kernel.Base.QueryDC: markHalfHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: markHeight :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoAscenderHeight :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoCapHeight :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoCharWidth :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoDefaultPadding :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoDescenderDepth :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoFontPointSize :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoLowerxHeight :: (DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoMultiLineHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => Int -> m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoTextDimensions :: (DrawingCtxM m, Num u, Ord u, FromPtSize u) => String -> m (u, u)
+ Wumpus.Basic.Kernel.Base.QueryDC: monoTextLength :: (DrawingCtxM m, FromPtSize u) => String -> m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoTextWidth :: (DrawingCtxM m, FromPtSize u) => Int -> m u
+ Wumpus.Basic.Kernel.Base.QueryDC: monoVecToCenter :: (DrawingCtxM m, Fractional u, Ord u, FromPtSize u) => String -> m (Vec2 u)
+ Wumpus.Basic.Kernel.Base.QueryDC: strokeAttr :: DrawingCtxM m => m (RGBi, StrokeAttr)
+ Wumpus.Basic.Kernel.Base.QueryDC: textAttr :: DrawingCtxM m => m (RGBi, FontAttr)
+ Wumpus.Basic.Kernel.Base.QueryDC: withBorderedAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> RGBi -> a) -> m a
+ Wumpus.Basic.Kernel.Base.QueryDC: withFillAttr :: DrawingCtxM m => (RGBi -> a) -> m a
+ Wumpus.Basic.Kernel.Base.QueryDC: withStrokeAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> a) -> m a
+ Wumpus.Basic.Kernel.Base.QueryDC: withTextAttr :: DrawingCtxM m => (RGBi -> FontAttr -> a) -> m a
+ Wumpus.Basic.Kernel.Base.ScalingContext: ScalingContext :: (ux -> u) -> (uy -> u) -> ScalingContext ux uy u
+ Wumpus.Basic.Kernel.Base.ScalingContext: class Monad m => ScalingM m where { type family XDim m :: *; type family YDim m :: *; }
+ Wumpus.Basic.Kernel.Base.ScalingContext: coordinateScalingContext :: Num u => u -> u -> ScalingContext Int Int u
+ Wumpus.Basic.Kernel.Base.ScalingContext: data Scaling ux uy u a
+ Wumpus.Basic.Kernel.Base.ScalingContext: data ScalingContext ux uy u
+ Wumpus.Basic.Kernel.Base.ScalingContext: data ScalingT ux uy u m a
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance (u ~ MonUnit m, Monad m, TraceM m) => TraceM (ScalingT ux uy u m)
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance Applicative (Scaling ux uy u)
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance DrawingCtxM m => DrawingCtxM (ScalingT ux uy u m)
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance Functor (Scaling ux uy u)
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance Monad (Scaling ux uy u)
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance Monad m => Applicative (ScalingT ux uy u m)
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance Monad m => Functor (ScalingT ux uy u m)
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance Monad m => Monad (ScalingT ux uy u m)
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance Monad m => ScalingM (ScalingT ux uy u m)
+ Wumpus.Basic.Kernel.Base.ScalingContext: instance ScalingM (Scaling ux uy u)
+ Wumpus.Basic.Kernel.Base.ScalingContext: regularScalingContext :: Num u => u -> ScalingContext u u u
+ Wumpus.Basic.Kernel.Base.ScalingContext: runScaling :: ScalingContext ux uy u -> Scaling ux uy u a -> a
+ Wumpus.Basic.Kernel.Base.ScalingContext: runScalingT :: ScalingContext ux uy u -> ScalingT ux uy u m a -> m a
+ Wumpus.Basic.Kernel.Base.ScalingContext: scalePt :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m), uy ~ (YDim m)) => ux -> uy -> m (Point2 u)
+ Wumpus.Basic.Kernel.Base.ScalingContext: scaleVec :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m), uy ~ (YDim m)) => ux -> uy -> m (Vec2 u)
+ Wumpus.Basic.Kernel.Base.ScalingContext: scaleX :: (ScalingM m, u ~ (MonUnit m), ux ~ (XDim m)) => ux -> m u
+ Wumpus.Basic.Kernel.Base.ScalingContext: scaleY :: (ScalingM m, u ~ (MonUnit m), uy ~ (YDim m)) => uy -> m u
+ Wumpus.Basic.Kernel.Base.ScalingContext: scale_in_x :: ScalingContext ux uy u -> ux -> u
+ Wumpus.Basic.Kernel.Base.ScalingContext: scale_in_y :: ScalingContext ux uy u -> uy -> u
+ Wumpus.Basic.Kernel.Base.ScalingContext: unitX :: (ScalingM m, Num ux, ux ~ (XDim m), u ~ (MonUnit m)) => m u
+ Wumpus.Basic.Kernel.Base.ScalingContext: unitY :: (ScalingM m, Num uy, uy ~ (YDim m), u ~ (MonUnit m)) => m u
+ Wumpus.Basic.Kernel.Base.UpdateDC: bothFillColour :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: bothStrokeColour :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: capButt :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: capRound :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: capSquare :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: dashPattern :: DashPattern -> DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: doubledashes :: DashPattern -> DashPattern
+ Wumpus.Basic.Kernel.Base.UpdateDC: doublegaps :: DashPattern -> DashPattern
+ Wumpus.Basic.Kernel.Base.UpdateDC: doublesize :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: dphase :: Int -> DashPattern -> DashPattern
+ Wumpus.Basic.Kernel.Base.UpdateDC: fillColour :: RGBi -> DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: fontAttr :: FontFace -> Int -> DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: fontFace :: FontFace -> DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: fontSize :: Int -> DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: halfsize :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: joinBevel :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: joinMiter :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: joinRound :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: lineWidth :: Double -> DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: phase :: Int -> DashPattern -> DashPattern
+ Wumpus.Basic.Kernel.Base.UpdateDC: strokeColour :: RGBi -> DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: swapColours :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: thick :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: thin :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: ultrathick :: DrawingContextF
+ Wumpus.Basic.Kernel.Base.UpdateDC: unit_dash_pattern :: DashPattern
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: class TraceM m :: (* -> *)
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: collectH :: PrimGraphic u -> HPrim u
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: data HPrim u
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: data PrimGraphic u
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: getPrimGraphic :: PrimGraphic u -> Primitive u
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: hprimToList :: HPrim u -> [Primitive u]
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: instance (Real u, Floating u) => Rotate (PrimGraphic u)
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: instance (Real u, Floating u) => RotateAbout (PrimGraphic u)
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: instance Eq u => Eq (PrimGraphic u)
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: instance Monoid (HPrim u)
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: instance Num u => Scale (PrimGraphic u)
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: instance Num u => Translate (PrimGraphic u)
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: instance OPlus (PrimGraphic u)
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: instance Show u => Show (PrimGraphic u)
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: metamorphPrim :: (Primitive u -> Primitive u) -> PrimGraphic u -> PrimGraphic u
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: primGraphic :: Primitive u -> PrimGraphic u
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: singleH :: Primitive u -> HPrim u
+ Wumpus.Basic.Kernel.Base.WrappedPrimitive: trace :: (TraceM m, (MonUnit m) ~ u) => HPrim u -> m ()
+ Wumpus.Basic.Kernel.Geometry.Intersection: LS :: (Point2 u) -> (Point2 u) -> LineSegment u
+ Wumpus.Basic.Kernel.Geometry.Intersection: data LineEqn u
+ Wumpus.Basic.Kernel.Geometry.Intersection: data LineSegment u
+ Wumpus.Basic.Kernel.Geometry.Intersection: data PointSlope u
+ Wumpus.Basic.Kernel.Geometry.Intersection: findIntersect :: (Floating u, Real u, Ord u) => Point2 u -> Radian -> [LineSegment u] -> Maybe (Point2 u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: instance Eq u => Eq (IntersectionResult u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: instance Eq u => Eq (LineEqn u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: instance Eq u => Eq (LineSegment u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: instance Eq u => Eq (PointSlope u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: instance Ord u => Ord (LineSegment u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: instance Show u => Show (IntersectionResult u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: instance Show u => Show (LineEqn u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: instance Show u => Show (LineSegment u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: instance Show u => Show (PointSlope u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: intersection :: (Fractional u, Ord u) => LineSegment u -> LineEqn u -> Maybe (Point2 u)
+ Wumpus.Basic.Kernel.Geometry.Intersection: langle :: (Floating u, Real u) => Point2 u -> Point2 u -> Radian
+ Wumpus.Basic.Kernel.Geometry.Intersection: lineEqn :: Num u => Point2 u -> Point2 u -> LineEqn u
+ Wumpus.Basic.Kernel.Geometry.Intersection: pointSlope :: Fractional u => Point2 u -> Radian -> PointSlope u
+ Wumpus.Basic.Kernel.Geometry.Intersection: polygonLines :: [Point2 u] -> [LineSegment u]
+ Wumpus.Basic.Kernel.Geometry.Intersection: rectangleLines :: Num u => Point2 u -> u -> u -> [LineSegment u]
+ Wumpus.Basic.Kernel.Geometry.Intersection: toLineEqn :: Num u => PointSlope u -> LineEqn u
+ Wumpus.Basic.Kernel.Geometry.Paths: diamondPath :: Num u => u -> u -> Point2 u -> PrimPath u
+ Wumpus.Basic.Kernel.Geometry.Paths: equilateralTrianglePath :: Floating u => u -> Point2 u -> PrimPath u
+ Wumpus.Basic.Kernel.Geometry.Paths: equilateralTrianglePoints :: Floating u => u -> Point2 u -> (Point2 u, Point2 u, Point2 u)
+ Wumpus.Basic.Kernel.Geometry.Paths: isoscelesTrianglePath :: Floating u => u -> u -> Point2 u -> PrimPath u
+ Wumpus.Basic.Kernel.Geometry.Paths: isoscelesTrianglePoints :: Floating u => u -> u -> Point2 u -> (Point2 u, Point2 u, Point2 u)
+ Wumpus.Basic.Kernel.Geometry.Paths: polygonPoints :: Floating u => Int -> u -> Point2 u -> [Point2 u]
+ Wumpus.Basic.Kernel.Geometry.Paths: rectanglePath :: Num u => u -> u -> Point2 u -> PrimPath u
+ Wumpus.Basic.Kernel.Objects.AdvanceGraphic: advconcat :: Num u => [AdvGraphic u] -> AdvGraphic u
+ Wumpus.Basic.Kernel.Objects.AdvanceGraphic: advplus :: AdvGraphic u -> AdvGraphic u -> AdvGraphic u
+ Wumpus.Basic.Kernel.Objects.AdvanceGraphic: extractLocGraphic :: AdvGraphic u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.AdvanceGraphic: makeAdvGraphic :: DrawingInfo (PointDisplace u) -> LocGraphic u -> AdvGraphic u
+ Wumpus.Basic.Kernel.Objects.AdvanceGraphic: runAdvGraphic :: DrawingContext -> Point2 u -> AdvGraphic u -> (Point2 u, PrimGraphic u)
+ Wumpus.Basic.Kernel.Objects.AdvanceGraphic: type AdvGraphic u = LocImage u (Point2 u)
+ Wumpus.Basic.Kernel.Objects.AdvanceGraphic: type DAdvGraphic = AdvGraphic Double
+ Wumpus.Basic.Kernel.Objects.BaseObjects: hyperlink :: XLink -> Image u a -> Image u a
+ Wumpus.Basic.Kernel.Objects.BaseObjects: instance (DUnit a ~ u, Num u, Scale a) => Scale (Image u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: instance (DUnit a ~ u, Num u, Scale a) => Scale (LocImage u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: instance (DUnit a ~ u, Num u, Translate a) => Translate (Image u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: instance (DUnit a ~ u, Num u, Translate a) => Translate (LocImage u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: instance (DUnit a ~ u, Real u, Floating u, Rotate a) => Rotate (Image u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: instance (DUnit a ~ u, Real u, Floating u, Rotate a) => Rotate (LocImage u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: instance (DUnit a ~ u, Real u, Floating u, RotateAbout a) => RotateAbout (Image u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: instance (DUnit a ~ u, Real u, Floating u, RotateAbout a) => RotateAbout (LocImage u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type DImage a = Image Double a
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type DLocImage a = LocImage Double a
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type DLocThetaImage a = LocThetaImage Double a
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type DrawingInfo a = CF a
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type GraphicAns u = ImageAns u (UNil u)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type Image u a = CF (ImageAns u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type ImageAns u a = (a, PrimGraphic u)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type LocDrawingInfo u a = LocCF u a
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type LocImage u a = LocCF u (ImageAns u a)
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type LocThetaDrawingInfo u a = LocThetaCF u a
+ Wumpus.Basic.Kernel.Objects.BaseObjects: type LocThetaImage u a = LocThetaCF u (ImageAns u a)
+ Wumpus.Basic.Kernel.Objects.Bounded: centerOrthoBBox :: (Real u, Floating u) => Radian -> BoundingBox u -> BoundingBox u
+ Wumpus.Basic.Kernel.Objects.Bounded: emptyBoundedLocGraphic :: Num u => BoundedLocGraphic u
+ Wumpus.Basic.Kernel.Objects.Bounded: illustrateBoundedGraphic :: Fractional u => BoundedGraphic u -> BoundedGraphic u
+ Wumpus.Basic.Kernel.Objects.Bounded: illustrateBoundedLocGraphic :: Fractional u => BoundedLocGraphic u -> BoundedLocGraphic u
+ Wumpus.Basic.Kernel.Objects.Bounded: illustrateBoundedLocThetaGraphic :: Fractional u => BoundedLocThetaGraphic u -> BoundedLocThetaGraphic u
+ Wumpus.Basic.Kernel.Objects.Bounded: type BoundedGraphic u = Image u (BoundingBox u)
+ Wumpus.Basic.Kernel.Objects.Bounded: type BoundedLocGraphic u = LocImage u (BoundingBox u)
+ Wumpus.Basic.Kernel.Objects.Bounded: type BoundedLocThetaGraphic u = LocThetaImage u (BoundingBox u)
+ Wumpus.Basic.Kernel.Objects.Bounded: type DBoundedGraphic = BoundedGraphic Double
+ Wumpus.Basic.Kernel.Objects.Bounded: type DBoundedLocGraphic = BoundedLocGraphic Double
+ Wumpus.Basic.Kernel.Objects.Bounded: type DBoundedLocThetaGraphic = BoundedLocThetaGraphic Double
+ Wumpus.Basic.Kernel.Objects.Connector: type ConnectorGraphic u = ConnectorCF u (GraphicAns u)
+ Wumpus.Basic.Kernel.Objects.Connector: type ConnectorImage u a = ConnectorCF u (ImageAns u a)
+ Wumpus.Basic.Kernel.Objects.Connector: type DConnectorGraphic = ConnectorGraphic Double
+ Wumpus.Basic.Kernel.Objects.Connector: type DConnectorImage a = ConnectorImage Double a
+ Wumpus.Basic.Kernel.Objects.Drawing: alignH :: (Fractional u, Ord u) => HAlign -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: alignHSep :: (Fractional u, Ord u) => HAlign -> u -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: alignV :: (Fractional u, Ord u) => VAlign -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: alignVSep :: (Fractional u, Ord u) => VAlign -> u -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: atPoint :: (Num u, Ord u) => Drawing u -> Point2 u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: centeredAt :: (Fractional u, Ord u) => Drawing u -> Point2 u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: centric :: (Fractional u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: clipDrawing :: (Num u, Ord u) => (PrimPath u) -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: data Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: drawTracing :: (Real u, Floating u, FromPtSize u) => TraceDrawing u a -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: hcat :: (Real u, Floating u, FromPtSize u) => [Drawing u] -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: hcatA :: (Real u, Floating u, FromPtSize u) => HAlign -> [Drawing u] -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: hsep :: (Real u, Floating u, FromPtSize u) => u -> [Drawing u] -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: hsepA :: (Real u, Floating u, FromPtSize u) => HAlign -> u -> [Drawing u] -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: hspace :: (Num u, Ord u) => u -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: instance (Num u, Ord u) => Scale (Drawing u)
+ Wumpus.Basic.Kernel.Objects.Drawing: instance (Num u, Ord u) => Translate (Drawing u)
+ Wumpus.Basic.Kernel.Objects.Drawing: instance (Real u, Floating u) => Rotate (Drawing u)
+ Wumpus.Basic.Kernel.Objects.Drawing: instance (Real u, Floating u) => RotateAbout (Drawing u)
+ Wumpus.Basic.Kernel.Objects.Drawing: modifyDrawing :: (Picture u -> Picture u) -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: nextToH :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: nextToV :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: over :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: runDrawing :: DrawingContext -> Drawing u -> Maybe (Picture u)
+ Wumpus.Basic.Kernel.Objects.Drawing: runDrawingU :: DrawingContext -> Drawing u -> Picture u
+ Wumpus.Basic.Kernel.Objects.Drawing: type DDrawing = Drawing Double
+ Wumpus.Basic.Kernel.Objects.Drawing: under :: (Num u, Ord u) => Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: vcat :: (Real u, Floating u, FromPtSize u) => [Drawing u] -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: vcatA :: (Real u, Floating u, FromPtSize u) => VAlign -> [Drawing u] -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: vsep :: (Real u, Floating u, FromPtSize u) => u -> [Drawing u] -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: vsepA :: (Real u, Floating u, FromPtSize u) => VAlign -> u -> [Drawing u] -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: vspace :: (Num u, Ord u) => u -> Drawing u -> Drawing u -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Drawing: zconcat :: (Real u, Floating u, FromPtSize u) => [Drawing u] -> Drawing u
+ Wumpus.Basic.Kernel.Objects.Graphic: borderedCircle :: Floating u => Int -> u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: borderedDisk :: Num u => u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: borderedEllipse :: Num u => u -> u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: borderedPath :: Num u => PrimPath u -> Graphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: borderedRectangle :: Fractional u => u -> u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: closedStroke :: Num u => PrimPath u -> Graphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: curveBetween :: Fractional u => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Graphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: emptyLocGraphic :: Num u => LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: emptyLocPath :: Num u => LocCF u (PrimPath u)
+ Wumpus.Basic.Kernel.Objects.Graphic: escapedline :: Num u => EscapedText -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: filledCircle :: Floating u => Int -> u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: filledDisk :: Num u => u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: filledEllipse :: Num u => u -> u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: filledPath :: Num u => PrimPath u -> Graphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: filledRectangle :: Fractional u => u -> u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: hkernline :: Num u => [KerningChar u] -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: intoImage :: CF a -> Graphic u -> Image u a
+ Wumpus.Basic.Kernel.Objects.Graphic: intoLocImage :: LocCF u a -> LocGraphic u -> LocImage u a
+ Wumpus.Basic.Kernel.Objects.Graphic: intoLocThetaImage :: LocThetaCF u a -> LocThetaGraphic u -> LocThetaImage u a
+ Wumpus.Basic.Kernel.Objects.Graphic: locPath :: Num u => [Vec2 u] -> LocCF u (PrimPath u)
+ Wumpus.Basic.Kernel.Objects.Graphic: moveStartPoint :: PointDisplace u -> LocCF u a -> LocCF u a
+ Wumpus.Basic.Kernel.Objects.Graphic: moveStartPointTheta :: PointDisplace u -> LocThetaCF u a -> LocThetaCF u a
+ Wumpus.Basic.Kernel.Objects.Graphic: openStroke :: Num u => PrimPath u -> Graphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: rborderedEllipse :: Num u => u -> u -> LocThetaGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: rescapedline :: Num u => EscapedText -> LocThetaGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: rfilledEllipse :: Num u => u -> u -> LocThetaGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: rstrokedEllipse :: Num u => u -> u -> LocThetaGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: rtextline :: Num u => String -> LocThetaGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: straightLine :: Fractional u => Vec2 u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: straightLineBetween :: Fractional u => Point2 u -> Point2 u -> Graphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: strokedCircle :: Floating u => Int -> u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: strokedDisk :: Num u => u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: strokedEllipse :: Num u => u -> u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: strokedRectangle :: Fractional u => u -> u -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: textline :: Num u => String -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.Graphic: type DGraphic = Graphic Double
+ Wumpus.Basic.Kernel.Objects.Graphic: type DLocGraphic = LocGraphic Double
+ Wumpus.Basic.Kernel.Objects.Graphic: type DLocThetaGraphic = LocThetaGraphic Double
+ Wumpus.Basic.Kernel.Objects.Graphic: type Graphic u = Image u (UNil u)
+ Wumpus.Basic.Kernel.Objects.Graphic: type LocGraphic u = LocImage u (UNil u)
+ Wumpus.Basic.Kernel.Objects.Graphic: type LocThetaGraphic u = LocThetaImage u (UNil u)
+ Wumpus.Basic.Kernel.Objects.Graphic: vkernline :: Num u => [KerningChar u] -> LocGraphic u
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: data TraceDrawing u a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: data TraceDrawingT u m a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: draw :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => Graphic u -> m ()
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: drawi :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => Image u a -> m a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: drawi_ :: (TraceM m, DrawingCtxM m, (MonUnit m) ~ u) => Image u a -> m ()
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: evalTraceDrawing :: DrawingContext -> TraceDrawing u a -> a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: evalTraceDrawingT :: Monad m => DrawingContext -> TraceDrawingT u m a -> m a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: execTraceDrawing :: DrawingContext -> TraceDrawing u a -> HPrim u
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: execTraceDrawingT :: Monad m => DrawingContext -> TraceDrawingT u m a -> m (HPrim u)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance Applicative (TraceDrawing u)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance DrawingCtxM (TraceDrawing u)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance Functor (TraceDrawing u)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance Monad (TraceDrawing u)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance Monad m => Applicative (TraceDrawingT u m)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance Monad m => DrawingCtxM (TraceDrawingT u m)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance Monad m => Functor (TraceDrawingT u m)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance Monad m => Monad (TraceDrawingT u m)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance Monad m => TraceM (TraceDrawingT u m)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: instance TraceM (TraceDrawing u)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: liftToPictureMb :: (Real u, Floating u, FromPtSize u) => HPrim u -> Maybe (Picture u)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: liftToPictureU :: (Real u, Floating u, FromPtSize u) => HPrim u -> Picture u
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: mbPictureU :: (Real u, Floating u, FromPtSize u) => Maybe (Picture u) -> Picture u
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: node :: (TraceM m, DrawingCtxM m, PointSupplyM m, (MonUnit m) ~ u) => LocGraphic u -> m ()
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: nodei :: (TraceM m, DrawingCtxM m, PointSupplyM m, (MonUnit m) ~ u) => LocImage u a -> m a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: query :: DrawingCtxM m => CF a -> m a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: runTraceDrawing :: DrawingContext -> TraceDrawing u a -> (a, HPrim u)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: runTraceDrawingT :: Monad m => DrawingContext -> TraceDrawingT u m a -> m (a, HPrim u)
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: type DTraceDrawing a = TraceDrawing Double a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: type DTraceDrawingT m a = TraceDrawingT Double m a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: xdraw :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => XLink -> Graphic u -> m ()
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: xdrawi :: (TraceM m, DrawingCtxM m, (MonUnit m) ~ u) => XLink -> Image u a -> m a
+ Wumpus.Basic.Kernel.Objects.TraceDrawing: xdrawi_ :: (TraceM m, DrawingCtxM m, (MonUnit m) ~ u) => XLink -> Image u a -> m ()
+ Wumpus.Basic.System.FontLoader.Afm: loadAfmMetrics :: FilePath -> [FontName] -> IO (GlyphMetrics, [String])
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: afmFileParser :: CharParser AfmGlyphMetrics -> CharParser AfmFile
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: charBBox :: CharParser AfmBoundingBox
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: cint :: CharParser Int
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: double :: CharParser Double
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: getCapHeight :: GlobalInfo -> Maybe AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: getEncodingScheme :: GlobalInfo -> Maybe String
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: getFontBBox :: GlobalInfo -> Maybe AfmBoundingBox
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: hexInt :: CharParser Int
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: int :: CharParser Int
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: integer :: CharParser Integer
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: keyName :: CharParser AfmKey
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: keyStringPair :: CharParser (AfmKey, String)
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: lexeme :: CharParser a -> CharParser a
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: metric :: String -> a -> CharParser a -> CharParser a
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: name :: CharParser String
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: name1 :: CharParser String
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: newlineOrEOF :: CharParser ()
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: number :: CharParser AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: octInt :: CharParser Int
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: runQuery :: String -> CharParser a -> GlobalInfo -> Maybe a
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: semi :: CharParser Char
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: startCharMetrics :: CharParser Int
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: symbol :: String -> CharParser String
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: textQuery :: String -> GlobalInfo -> Maybe String
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: uptoNewline :: CharParser String
+ Wumpus.Basic.System.FontLoader.Base.AfmParserBase: versionNumber :: CharParser String
+ Wumpus.Basic.System.FontLoader.Base.AfmV2Parser: afmV2Parser :: CharParser AfmFile
+ Wumpus.Basic.System.FontLoader.Base.AfmV4Dot1Parser: afmV4Dot1Parser :: CharParser AfmFile
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: AfmFile :: Maybe String -> Maybe AfmBoundingBox -> Maybe AfmUnit -> [AfmGlyphMetrics] -> AfmFile
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: AfmGlyphMetrics :: !PSCharCode -> !Vec2 AfmUnit -> !String -> AfmGlyphMetrics
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: FontProps :: BoundingBox cu -> Vec2 cu -> IntMap (Vec2 cu) -> cu -> FontProps cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: MonospaceDefaults :: BoundingBox cu -> cu -> Vec2 cu -> MonospaceDefaults cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: afmUnitScale :: AfmUnit -> PtSize
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: afmValue :: FromPtSize u => AfmUnit -> PtSize -> u
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: afm_cap_height :: AfmFile -> Maybe AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: afm_char_code :: AfmGlyphMetrics -> !PSCharCode
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: afm_char_name :: AfmGlyphMetrics -> !String
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: afm_encoding :: AfmFile -> Maybe String
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: afm_glyph_metrics :: AfmFile -> [AfmGlyphMetrics]
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: afm_letter_bbox :: AfmFile -> Maybe AfmBoundingBox
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: afm_width_vector :: AfmGlyphMetrics -> !Vec2 AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: buildMetricsOps :: (cu -> PtSize) -> FontProps cu -> MetricsOps
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: data AfmFile
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: data AfmGlyphMetrics
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: data AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: data FontProps cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: data MonospaceDefaults cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: default_cap_height :: MonospaceDefaults cu -> cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: default_char_width :: MonospaceDefaults cu -> Vec2 cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: default_letter_bbox :: MonospaceDefaults cu -> BoundingBox cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: fp_adv_vecs :: FontProps cu -> IntMap (Vec2 cu)
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: fp_bounding_box :: FontProps cu -> BoundingBox cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: fp_cap_height :: FontProps cu -> cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: fp_default_adv_vec :: FontProps cu -> Vec2 cu
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Eq AfmGlyphMetrics
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Eq AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Eq cu => Eq (MonospaceDefaults cu)
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Floating AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Fractional AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Num AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Ord AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Real AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance RealFloat AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance RealFrac AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Show AfmFile
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Show AfmGlyphMetrics
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Show AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: instance Show cu => Show (MonospaceDefaults cu)
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: type AfmBoundingBox = BoundingBox AfmUnit
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: type AfmKey = String
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: type GlobalInfo = Map AfmKey String
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: type PSCharCode = Int
+ Wumpus.Basic.System.FontLoader.Base.Datatypes: type PSEncodingScheme = String
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: buildAfmFontProps :: MonospaceDefaults AfmUnit -> AfmFile -> FontLoadIO (FontProps AfmUnit)
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: checkFontPath :: FilePath -> FilePath -> FontLoadIO FilePath
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: data FontLoadIO a
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: evalFontLoadIO :: FontLoadIO a -> IO (Either FontLoadErr a)
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: instance Functor FontLoadIO
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: instance Monad FontLoadIO
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: instance Monoid FontLoadLog
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: loadError :: FontLoadErr -> FontLoadIO a
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: logLoadMsg :: String -> FontLoadIO ()
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: promoteEither :: Either FontLoadErr a -> FontLoadIO a
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: promoteIO :: IO a -> FontLoadIO a
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: runFontLoadIO :: FontLoadIO a -> IO (Either FontLoadErr a, [String])
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: runParserFLIO :: FilePath -> Parser Char a -> FontLoadIO a
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: sequenceAll :: [FontLoadIO a] -> FontLoadIO [a]
+ Wumpus.Basic.System.FontLoader.Base.FontLoadMonad: type FontLoadErr = String
+ Wumpus.Basic.System.FontLoader.Base.GSFontMap: GSFontMap :: String -> Map String (String, FilePath) -> GSFontMap
+ Wumpus.Basic.System.FontLoader.Base.GSFontMap: data GSFontMap
+ Wumpus.Basic.System.FontLoader.Base.GSFontMap: ghostscript_fontmap :: GSFontMap -> Map String (String, FilePath)
+ Wumpus.Basic.System.FontLoader.Base.GSFontMap: ghostscript_fontmap_8_54 :: GSFontMap
+ Wumpus.Basic.System.FontLoader.Base.GSFontMap: ghostscript_version :: GSFontMap -> String
+ Wumpus.Basic.System.FontLoader.Base.GSFontMap: gsFontAlias :: GSFontMap -> String -> Maybe String
+ Wumpus.Basic.System.FontLoader.Base.GSFontMap: gsMetricsFile :: GSFontMap -> String -> Maybe FilePath
+ Wumpus.Basic.System.FontLoader.Base.GSFontMap: gsVersionNumber :: GSFontMap -> String
+ Wumpus.Basic.System.FontLoader.GhostScript: loadGSMetrics :: FilePath -> [FontName] -> IO (GlyphMetrics, [String])
+ Wumpus.Drawing.Arrows.Connectors: connector :: ConnectorPath u -> Connector u
+ Wumpus.Drawing.Arrows.Connectors: data Connector u
+ Wumpus.Drawing.Arrows.Connectors: dblArrow :: ConnectorPath u -> Arrowhead u -> Connector u
+ Wumpus.Drawing.Arrows.Connectors: leftArrow :: ConnectorPath u -> Arrowhead u -> Connector u
+ Wumpus.Drawing.Arrows.Connectors: leftrightArrow :: ConnectorPath u -> Arrowhead u -> Arrowhead u -> Connector u
+ Wumpus.Drawing.Arrows.Connectors: rightArrow :: ConnectorPath u -> Arrowhead u -> Connector u
+ Wumpus.Drawing.Arrows.Connectors: strokeConnector :: (Real u, Floating u) => Connector u -> ConnectorImage u (Path u)
+ Wumpus.Drawing.Arrows.Tips: Arrowhead :: LocThetaImage u u -> Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: barb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: barb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: barb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: bracket :: (Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: curveTip :: (Real u, Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: diamondTip :: (Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: diskTip :: (Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: getArrowhead :: Arrowhead u -> LocThetaImage u u
+ Wumpus.Drawing.Arrows.Tips: newtype Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: odiamondTip :: (Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: odiskTip :: (Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: orevtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: orevtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: orevtri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: osquareTip :: (Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: otri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: otri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: otri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: perp :: (Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: revbarb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: revbarb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: revbarb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: revcurveTip :: (Real u, Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: revtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: revtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: revtri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: squareTip :: (Floating u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: tri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: tri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Arrows.Tips: tri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
+ Wumpus.Drawing.Chains.Base: Done :: AnaAlg st a
+ Wumpus.Drawing.Chains.Base: IterStep :: a -> !st -> IterAlg st a
+ Wumpus.Drawing.Chains.Base: Step :: a -> !st -> AnaAlg st a
+ Wumpus.Drawing.Chains.Base: bivariate :: st -> (st -> AnaAlg st (ux, uy)) -> BivariateAlg ux uy
+ Wumpus.Drawing.Chains.Base: bounded :: Int -> SequenceAlg (ux, uy) -> BivariateAlg ux uy
+ Wumpus.Drawing.Chains.Base: chain :: BivariateAlg ux uy -> Chain ux uy u
+ Wumpus.Drawing.Chains.Base: chainFrom :: Num u => BivariateAlg ux uy -> LocChain ux uy u
+ Wumpus.Drawing.Chains.Base: data AnaAlg st a
+ Wumpus.Drawing.Chains.Base: data BivariateAlg ux uy
+ Wumpus.Drawing.Chains.Base: data Chain ux uy u
+ Wumpus.Drawing.Chains.Base: data IterAlg st a
+ Wumpus.Drawing.Chains.Base: data SequenceAlg a
+ Wumpus.Drawing.Chains.Base: iteration :: (a -> a) -> a -> SequenceAlg a
+ Wumpus.Drawing.Chains.Base: pairOnXs :: (ux -> uy) -> SequenceAlg ux -> SequenceAlg (ux, uy)
+ Wumpus.Drawing.Chains.Base: pairOnYs :: (r -> l) -> SequenceAlg r -> SequenceAlg (l, r)
+ Wumpus.Drawing.Chains.Base: type LocChain ux uy u = Point2 u -> Chain ux uy u
+ Wumpus.Drawing.Chains.Base: unchain :: ScalingContext ux uy u -> Chain ux uy u -> [Point2 u]
+ Wumpus.Drawing.Chains.Derived: horizontal :: Int -> Chain Int Int u
+ Wumpus.Drawing.Chains.Derived: horizontals :: (Num ua, Num u) => [ua] -> LocChain ua ua u
+ Wumpus.Drawing.Chains.Derived: rescale :: Fractional a => a -> a -> a -> a -> a -> a
+ Wumpus.Drawing.Chains.Derived: tableDown :: Int -> Int -> Chain Int Int u
+ Wumpus.Drawing.Chains.Derived: tableRight :: Num u => Int -> Int -> Chain Int Int u
+ Wumpus.Drawing.Chains.Derived: univariateX :: (Fractional uy, Num ux, Num u) => [ux] -> LocChain ux uy u
+ Wumpus.Drawing.Chains.Derived: univariateY :: (Fractional ux, Num uy, Num u) => [uy] -> LocChain ux uy u
+ Wumpus.Drawing.Chains.Derived: vertical :: Int -> Chain Int Int u
+ Wumpus.Drawing.Chains.Derived: verticals :: (Num ua, Num u) => [ua] -> LocChain ua ua u
+ Wumpus.Drawing.Colour.SVGColours: alice_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: antique_white :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: aqua :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: aquamarine :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: azure :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: beige :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: bisque :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: black :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: blanched_almond :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: blue_violet :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: brown :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: burlywood :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: cadet_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: chartreuse :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: chocolate :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: coral :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: cornflower_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: cornsilk :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: crimson :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: cyan :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_cyan :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_goldenrod :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_gray :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_grey :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_khaki :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_magenta :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_olive_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_orange :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_orchid :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_red :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_salmon :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_sea_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_slate_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_slate_gray :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_slate_grey :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_turquoise :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dark_violet :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: deep_pink :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: deep_sky_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dim_gray :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dim_grey :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: dodger_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: firebrick :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: floral_white :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: forest_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: fuchsia :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: gainsboro :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: ghost_white :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: gold :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: goldenrod :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: gray :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: green_yellow :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: grey :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: honeydew :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: hot_pink :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: indian_red :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: indigo :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: ivory :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: khaki :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: lavender :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: lavender_blush :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: lawn_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: lemon_chiffon :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_coral :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_cyan :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_goldenrod_yellow :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_gray :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_grey :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_pink :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_salmon :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_sea_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_sky_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_slate_gray :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_slate_grey :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_steel_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: light_yellow :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: lime :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: lime_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: linen :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: magenta :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: maroon :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: medium_aquamarine :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: medium_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: medium_orchid :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: medium_purple :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: medium_sea_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: medium_slate_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: medium_spring_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: medium_turquoise :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: medium_violet_red :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: midnight_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: mintcream :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: mistyrose :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: moccasin :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: navajo_white :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: navy :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: old_lace :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: olive :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: olive_drab :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: orange :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: orange_red :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: orchid :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: pale_goldenrod :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: pale_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: pale_turquoise :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: pale_violet_red :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: papaya_whip :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: peach_puff :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: peru :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: pink :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: plum :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: powder_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: purple :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: red :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: rosy_brown :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: royal_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: saddle_brown :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: salmon :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: sandy_brown :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: sea_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: seashell :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: sienna :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: silver :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: sky_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: slate_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: slate_gray :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: slate_grey :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: snow :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: spring_green :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: steel_blue :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: tan :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: teal :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: thistle :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: tomato :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: turquoise :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: violet :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: wheat :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: white :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: whitesmoke :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: yellow :: RGBi
+ Wumpus.Drawing.Colour.SVGColours: yellow_green :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: antique_white1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: antique_white2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: antique_white3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: antique_white4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: aquamarine1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: aquamarine2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: aquamarine3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: aquamarine4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: azure1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: azure2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: azure3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: azure4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: bisque1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: bisque2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: bisque3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: bisque4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: brown1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: brown2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: brown3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: brown4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: burlywood1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: burlywood2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: burlywood3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: burlywood4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cadet_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cadet_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cadet_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cadet_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: chartreuse1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: chartreuse2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: chartreuse3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: chartreuse4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: chocolate1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: chocolate2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: chocolate3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: chocolate4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: coral1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: coral2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: coral3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: coral4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cornsilk1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cornsilk2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cornsilk3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cornsilk4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cyan1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cyan2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cyan3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: cyan4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_goldenrod1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_goldenrod2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_goldenrod3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_goldenrod4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_olive_green1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_olive_green2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_olive_green3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_olive_green4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_orange1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_orange2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_orange3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_orange4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_orchid1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_orchid2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_orchid3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_orchid4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_sea_green1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_sea_green2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_sea_green3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_sea_green4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_slate_gray1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_slate_gray2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_slate_gray3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dark_slate_gray4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: deep_pink1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: deep_pink2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: deep_pink3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: deep_pink4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: deep_sky_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: deep_sky_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: deep_sky_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: deep_sky_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dodger_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dodger_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dodger_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: dodger_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: firebrick1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: firebrick2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: firebrick3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: firebrick4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: gold1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: gold2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: gold3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: gold4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: goldenrod1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: goldenrod2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: goldenrod3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: goldenrod4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: green1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: green2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: green3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: green4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: honeydew1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: honeydew2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: honeydew3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: honeydew4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: hot_pink1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: hot_pink2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: hot_pink3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: hot_pink4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: indian_red1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: indian_red2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: indian_red3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: indian_red4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: ivory1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: ivory2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: ivory3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: ivory4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: khaki1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: khaki2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: khaki3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: khaki4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: lavender_blush1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: lavender_blush2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: lavender_blush3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: lavender_blush4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: lemon_chiffon1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: lemon_chiffon2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: lemon_chiffon3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: lemon_chiffon4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_cyan1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_cyan2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_cyan3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_cyan4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_goldenrod1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_goldenrod2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_goldenrod3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_goldenrod4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_pink1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_pink2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_pink3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_pink4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_salmon1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_salmon2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_salmon3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_salmon4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_sky_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_sky_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_sky_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_sky_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_steel_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_steel_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_steel_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_steel_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_yellow1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_yellow2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_yellow3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: light_yellow4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: magenta1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: magenta2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: magenta3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: magenta4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: maroon1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: maroon2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: maroon3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: maroon4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: medium_orchid1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: medium_orchid2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: medium_orchid3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: medium_orchid4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: medium_purple1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: medium_purple2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: medium_purple3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: medium_purple4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: misty_rose1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: misty_rose2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: misty_rose3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: misty_rose4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: navajo_white1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: navajo_white2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: navajo_white3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: navajo_white4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: olive_drab1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: olive_drab2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: olive_drab3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: olive_drab4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orange1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orange2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orange3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orange4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orange_red1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orange_red2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orange_red3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orange_red4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orchid1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orchid2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orchid3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: orchid4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_green1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_green2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_green3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_green4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_turquoise1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_turquoise2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_turquoise3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_turquoise4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_violet_red1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_violet_red2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_violet_red3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pale_violet_red4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: peach_puff1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: peach_puff2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: peach_puff3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: peach_puff4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pink1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pink2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pink3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: pink4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: plum1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: plum2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: plum3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: plum4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: purple1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: purple2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: purple3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: purple4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: red1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: red2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: red3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: red4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: rosy_brown1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: rosy_brown2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: rosy_brown3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: rosy_brown4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: royal_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: royal_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: royal_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: royal_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: salmon1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: salmon2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: salmon3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: salmon4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sea_green1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sea_green2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sea_green3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sea_green4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: seashell1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: seashell2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: seashell3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: seashell4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sienna1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sienna2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sienna3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sienna4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sky_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sky_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sky_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: sky_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: slate_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: slate_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: slate_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: slate_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: slate_gray1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: slate_gray2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: slate_gray3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: slate_gray4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: snow1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: snow2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: snow3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: snow4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: spring_green1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: spring_green2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: spring_green3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: spring_green4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: steel_blue1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: steel_blue2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: steel_blue3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: steel_blue4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: tan1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: tan2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: tan3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: tan4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: thistle1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: thistle2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: thistle3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: thistle4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: tomato1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: tomato2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: tomato3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: tomato4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: turquoise1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: turquoise2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: turquoise3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: turquoise4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: violet_red1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: violet_red2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: violet_red3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: violet_red4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: wheat1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: wheat2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: wheat3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: wheat4 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: yellow1 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: yellow2 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: yellow3 :: RGBi
+ Wumpus.Drawing.Colour.X11Colours: yellow4 :: RGBi
+ Wumpus.Drawing.Dots.AnchorDots: data DotAnchor u
+ Wumpus.Drawing.Dots.AnchorDots: dotAsterisk :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotChar :: (Floating u, Real u, FromPtSize u) => Char -> DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotCircle :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotCross :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotDiamond :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotDisk :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotFDiamond :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotFOCross :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotHLine :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotOCross :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotOPlus :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotPentagon :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotPlus :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotSquare :: (Floating u, Real u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotStar :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotText :: (Floating u, Real u, FromPtSize u) => String -> DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotTriangle :: (Real u, Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotVLine :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: dotX :: (Floating u, FromPtSize u) => DotLocImage u
+ Wumpus.Drawing.Dots.AnchorDots: instance CardinalAnchor (DotAnchor u)
+ Wumpus.Drawing.Dots.AnchorDots: instance CardinalAnchor2 (DotAnchor u)
+ Wumpus.Drawing.Dots.AnchorDots: instance CenterAnchor (DotAnchor u)
+ Wumpus.Drawing.Dots.AnchorDots: instance Eq Cardinal
+ Wumpus.Drawing.Dots.AnchorDots: instance RadialAnchor (DotAnchor u)
+ Wumpus.Drawing.Dots.AnchorDots: instance Show Cardinal
+ Wumpus.Drawing.Dots.AnchorDots: type DDotLocImage = DotLocImage Double
+ Wumpus.Drawing.Dots.AnchorDots: type DotLocImage u = LocImage u (DotAnchor u)
+ Wumpus.Drawing.Dots.Marks: markAsterisk :: (Floating u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markBDiamond :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markChar :: (Real u, Floating u, FromPtSize u) => Char -> LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markCircle :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markCross :: (Floating u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markDiamond :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markDisk :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markFDiamond :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markFOCross :: (Floating u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markHLine :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markOCross :: (Floating u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markOPlus :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markPentagon :: (Floating u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markPlus :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markSquare :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markStar :: (Floating u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markText :: (Real u, Floating u, FromPtSize u) => String -> LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markTriangle :: (Floating u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markVLine :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Dots.Marks: markX :: (Fractional u, FromPtSize u) => LocGraphic u
+ Wumpus.Drawing.Paths.Base: (:<<) :: PathSegment u -> Path u -> PathViewL u
+ Wumpus.Drawing.Paths.Base: (:>>) :: Path u -> PathSegment u -> PathViewR u
+ Wumpus.Drawing.Paths.Base: Curve1 :: (Point2 u) -> (Point2 u) -> (Point2 u) -> (Point2 u) -> PathSegment u
+ Wumpus.Drawing.Paths.Base: Line1 :: (Point2 u) -> (Point2 u) -> PathSegment u
+ Wumpus.Drawing.Paths.Base: PathOneL :: (PathSegment u) -> PathViewL u
+ Wumpus.Drawing.Paths.Base: PathOneR :: (PathSegment u) -> PathViewR u
+ Wumpus.Drawing.Paths.Base: append :: Floating u => Path u -> Path u -> Path u
+ Wumpus.Drawing.Paths.Base: atend :: (Real u, Floating u) => Path u -> (Point2 u, Radian)
+ Wumpus.Drawing.Paths.Base: atend_ :: Path u -> Point2 u
+ Wumpus.Drawing.Paths.Base: atstart :: (Real u, Floating u) => Path u -> (Point2 u, Radian)
+ Wumpus.Drawing.Paths.Base: atstart_ :: Path u -> Point2 u
+ Wumpus.Drawing.Paths.Base: curve :: (Floating u, Ord u) => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Path u
+ Wumpus.Drawing.Paths.Base: curveByAngles :: (Floating u, Ord u) => Point2 u -> Radian -> Radian -> Point2 u -> Path u
+ Wumpus.Drawing.Paths.Base: data Path u
+ Wumpus.Drawing.Paths.Base: data PathSegment u
+ Wumpus.Drawing.Paths.Base: data PathViewL u
+ Wumpus.Drawing.Paths.Base: data PathViewR u
+ Wumpus.Drawing.Paths.Base: directionL :: (Real u, Floating u) => Path u -> Radian
+ Wumpus.Drawing.Paths.Base: directionR :: (Real u, Floating u) => Path u -> Radian
+ Wumpus.Drawing.Paths.Base: instance Eq u => Eq (Path u)
+ Wumpus.Drawing.Paths.Base: instance Eq u => Eq (PathSeg u)
+ Wumpus.Drawing.Paths.Base: instance Eq u => Eq (PathSegment u)
+ Wumpus.Drawing.Paths.Base: instance Eq u => Eq (PathViewL u)
+ Wumpus.Drawing.Paths.Base: instance Eq u => Eq (PathViewR u)
+ Wumpus.Drawing.Paths.Base: instance Ord u => Ord (Path u)
+ Wumpus.Drawing.Paths.Base: instance Ord u => Ord (PathSeg u)
+ Wumpus.Drawing.Paths.Base: instance Ord u => Ord (PathSegment u)
+ Wumpus.Drawing.Paths.Base: instance Ord u => Ord (PathViewL u)
+ Wumpus.Drawing.Paths.Base: instance Ord u => Ord (PathViewR u)
+ Wumpus.Drawing.Paths.Base: instance Show u => Show (Path u)
+ Wumpus.Drawing.Paths.Base: instance Show u => Show (PathSeg u)
+ Wumpus.Drawing.Paths.Base: instance Show u => Show (PathSegment u)
+ Wumpus.Drawing.Paths.Base: instance Show u => Show (PathViewL u)
+ Wumpus.Drawing.Paths.Base: instance Show u => Show (PathViewR u)
+ Wumpus.Drawing.Paths.Base: length :: Num u => Path u -> u
+ Wumpus.Drawing.Paths.Base: line :: Floating u => Point2 u -> Point2 u -> Path u
+ Wumpus.Drawing.Paths.Base: midway :: (Real u, Floating u) => Path u -> (Point2 u, Radian)
+ Wumpus.Drawing.Paths.Base: midway_ :: (Real u, Floating u) => Path u -> Point2 u
+ Wumpus.Drawing.Paths.Base: pathViewL :: Num u => Path u -> PathViewL u
+ Wumpus.Drawing.Paths.Base: pathViewR :: Num u => Path u -> PathViewR u
+ Wumpus.Drawing.Paths.Base: pconcat :: Floating u => Path u -> [Path u] -> Path u
+ Wumpus.Drawing.Paths.Base: pivot :: Floating u => Point2 u -> Path u
+ Wumpus.Drawing.Paths.Base: shortenBoth :: (Real u, Floating u) => u -> Path u -> Path u
+ Wumpus.Drawing.Paths.Base: shortenL :: (Real u, Floating u) => u -> Path u -> Path u
+ Wumpus.Drawing.Paths.Base: shortenR :: (Real u, Floating u) => u -> Path u -> Path u
+ Wumpus.Drawing.Paths.Base: tipL :: Path u -> Point2 u
+ Wumpus.Drawing.Paths.Base: tipR :: Path u -> Point2 u
+ Wumpus.Drawing.Paths.Base: toPrimPath :: Num u => Path u -> PrimPath u
+ Wumpus.Drawing.Paths.Base: traceCurvePoints :: (Floating u, Ord u) => [Point2 u] -> Path u
+ Wumpus.Drawing.Paths.Base: traceLinePoints :: Floating u => [Point2 u] -> Path u
+ Wumpus.Drawing.Paths.Base: type DPath = Path Double
+ Wumpus.Drawing.Paths.Base: type DPathSegment = PathSegment Double
+ Wumpus.Drawing.Paths.Base: type DPathViewL = PathViewL Double
+ Wumpus.Drawing.Paths.Base: type DPathViewR = PathViewR Double
+ Wumpus.Drawing.Paths.Connectors: connIsosceles :: (Real u, Floating u) => u -> ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connIsosceles2 :: (Real u, Floating u) => u -> ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connIsoscelesCurve :: (Real u, Floating u) => u -> ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connLightningBolt :: (Real u, Floating u) => u -> ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connLine :: Floating u => ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connRightHV :: Floating u => ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connRightHVH :: Floating u => u -> ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connRightVH :: Floating u => ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connRightVHV :: Floating u => u -> ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connSquareCurve :: (Real u, Floating u) => ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connTrapezoidCurve :: (Real u, Floating u) => u -> u -> ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connUSquareCurve :: (Real u, Floating u) => ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connUZSquareCurve :: (Real u, Floating u) => ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: connZSquareCurve :: (Real u, Floating u) => ConnectorPath u
+ Wumpus.Drawing.Paths.Connectors: type ConnectorPath u = Point2 u -> Point2 u -> Path u
+ Wumpus.Drawing.Paths.Connectors: type DConnectorPath = ConnectorPath Double
+ Wumpus.Drawing.Paths.Construction: bezierto :: (Floating u, Ord u) => Point2 u -> Point2 u -> Point2 u -> PathM u ()
+ Wumpus.Drawing.Paths.Construction: curveto :: (Floating u, Ord u) => Radian -> Radian -> Point2 u -> PathM u ()
+ Wumpus.Drawing.Paths.Construction: data PathM u a
+ Wumpus.Drawing.Paths.Construction: execPath :: Floating u => Point2 u -> PathM u a -> Path u
+ Wumpus.Drawing.Paths.Construction: hline :: Floating u => u -> PathM u ()
+ Wumpus.Drawing.Paths.Construction: horizontalVertical :: Floating u => Point2 u -> PathM u ()
+ Wumpus.Drawing.Paths.Construction: instance Applicative (PathM u)
+ Wumpus.Drawing.Paths.Construction: instance Functor (PathM u)
+ Wumpus.Drawing.Paths.Construction: instance Monad (PathM u)
+ Wumpus.Drawing.Paths.Construction: lineto :: Floating u => Point2 u -> PathM u ()
+ Wumpus.Drawing.Paths.Construction: rlineto :: Floating u => Vec2 u -> PathM u ()
+ Wumpus.Drawing.Paths.Construction: runPath :: Floating u => Point2 u -> PathM u a -> (a, Path u)
+ Wumpus.Drawing.Paths.Construction: tip :: PathM u (Point2 u)
+ Wumpus.Drawing.Paths.Construction: verticalHorizontal :: Floating u => Point2 u -> PathM u ()
+ Wumpus.Drawing.Paths.Construction: vline :: Floating u => u -> PathM u ()
+ Wumpus.Drawing.Paths.ControlPoints: dblpointIsosceles :: (Real u, Floating u) => u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)
+ Wumpus.Drawing.Paths.ControlPoints: midpointIsosceles :: (Real u, Floating u) => u -> Point2 u -> Point2 u -> Point2 u
+ Wumpus.Drawing.Paths.ControlPoints: rectangleFromBasePoints :: (Real u, Floating u) => u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)
+ Wumpus.Drawing.Paths.ControlPoints: squareFromBasePoints :: (Real u, Floating u) => Point2 u -> Point2 u -> (Point2 u, Point2 u)
+ Wumpus.Drawing.Paths.ControlPoints: squareFromCornerPoints :: (Real u, Floating u) => Point2 u -> Point2 u -> (Point2 u, Point2 u)
+ Wumpus.Drawing.Paths.ControlPoints: trapezoidFromBasePoints :: (Real u, Floating u) => u -> u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)
+ Wumpus.Drawing.Paths.ControlPoints: usquareFromBasePoints :: (Real u, Floating u) => Point2 u -> Point2 u -> (Point2 u, Point2 u)
+ Wumpus.Drawing.Paths.RoundCorners: cornerCurve :: (Real u, Floating u) => Point2 u -> Point2 u -> Point2 u -> Path u
+ Wumpus.Drawing.Paths.RoundCorners: illustratePath :: Fractional u => Path u -> Graphic u
+ Wumpus.Drawing.Paths.RoundCorners: roundEvery :: (Real u, Floating u) => u -> [Point2 u] -> Path u
+ Wumpus.Drawing.Shapes.Base: askCTM :: ShapeGeom u (ShapeCTM u)
+ Wumpus.Drawing.Shapes.Base: borderedShape :: Num u => Shape u t -> Image u (t u)
+ Wumpus.Drawing.Shapes.Base: data Shape u t
+ Wumpus.Drawing.Shapes.Base: data ShapeCTM u
+ Wumpus.Drawing.Shapes.Base: data ShapeGeom u a
+ Wumpus.Drawing.Shapes.Base: filledShape :: Num u => Shape u t -> Image u (t u)
+ Wumpus.Drawing.Shapes.Base: instance (Real u, Floating u) => Rotate (Shape u sh)
+ Wumpus.Drawing.Shapes.Base: instance (Real u, Floating u) => RotateAbout (Shape u sh)
+ Wumpus.Drawing.Shapes.Base: instance (Real u, Floating u) => RotateAbout (ShapeCTM u)
+ Wumpus.Drawing.Shapes.Base: instance Applicative (ShapeGeom u)
+ Wumpus.Drawing.Shapes.Base: instance Eq u => Eq (ShapeCTM u)
+ Wumpus.Drawing.Shapes.Base: instance Functor (ShapeGeom u)
+ Wumpus.Drawing.Shapes.Base: instance Monad (ShapeGeom u)
+ Wumpus.Drawing.Shapes.Base: instance Num u => Scale (Shape u sh)
+ Wumpus.Drawing.Shapes.Base: instance Num u => Scale (ShapeCTM u)
+ Wumpus.Drawing.Shapes.Base: instance Num u => Translate (Shape u sh)
+ Wumpus.Drawing.Shapes.Base: instance Num u => Translate (ShapeCTM u)
+ Wumpus.Drawing.Shapes.Base: instance Ord u => Ord (ShapeCTM u)
+ Wumpus.Drawing.Shapes.Base: instance Rotate (ShapeCTM u)
+ Wumpus.Drawing.Shapes.Base: instance Show u => Show (ShapeCTM u)
+ Wumpus.Drawing.Shapes.Base: makeShape :: Num u => (ShapeCTM u -> Path u) -> (ShapeCTM u -> t u) -> LocShape u t
+ Wumpus.Drawing.Shapes.Base: makeShapeCTM :: Num u => Point2 u -> ShapeCTM u
+ Wumpus.Drawing.Shapes.Base: projectPoint :: (Real u, Floating u) => Point2 u -> ShapeGeom u (Point2 u)
+ Wumpus.Drawing.Shapes.Base: runShapeGeom :: ShapeCTM u -> ShapeGeom u a -> a
+ Wumpus.Drawing.Shapes.Base: shapeAngle :: ShapeGeom u Radian
+ Wumpus.Drawing.Shapes.Base: shapeCenter :: ShapeGeom u (Point2 u)
+ Wumpus.Drawing.Shapes.Base: strokedShape :: Num u => Shape u t -> Image u (t u)
+ Wumpus.Drawing.Shapes.Base: type LocShape u t = Point2 u -> Shape u t
+ Wumpus.Drawing.Shapes.Base: type ShapeConstructor u t = ShapeCTM u -> t u
+ Wumpus.Drawing.Shapes.Coordinate: coordinate :: Num u => LocCoordinate u
+ Wumpus.Drawing.Shapes.Coordinate: coordinateDot :: (Real u, Floating u, FromPtSize u) => Coordinate u -> Image u (CoordinateAnchor u)
+ Wumpus.Drawing.Shapes.Coordinate: coordinateX :: (Real u, Floating u, FromPtSize u) => Coordinate u -> Image u (CoordinateAnchor u)
+ Wumpus.Drawing.Shapes.Coordinate: data Coordinate u
+ Wumpus.Drawing.Shapes.Coordinate: data CoordinateAnchor u
+ Wumpus.Drawing.Shapes.Coordinate: instance (Real u, Floating u) => CenterAnchor (CoordinateAnchor u)
+ Wumpus.Drawing.Shapes.Coordinate: instance (Real u, Floating u) => Rotate (Coordinate u)
+ Wumpus.Drawing.Shapes.Coordinate: instance (Real u, Floating u) => RotateAbout (Coordinate u)
+ Wumpus.Drawing.Shapes.Coordinate: instance Eq u => Eq (Coordinate u)
+ Wumpus.Drawing.Shapes.Coordinate: instance Eq u => Eq (CoordinateAnchor u)
+ Wumpus.Drawing.Shapes.Coordinate: instance Num u => Scale (Coordinate u)
+ Wumpus.Drawing.Shapes.Coordinate: instance Num u => Translate (Coordinate u)
+ Wumpus.Drawing.Shapes.Coordinate: instance Ord u => Ord (Coordinate u)
+ Wumpus.Drawing.Shapes.Coordinate: instance Ord u => Ord (CoordinateAnchor u)
+ Wumpus.Drawing.Shapes.Coordinate: instance Show u => Show (Coordinate u)
+ Wumpus.Drawing.Shapes.Coordinate: instance Show u => Show (CoordinateAnchor u)
+ Wumpus.Drawing.Shapes.Coordinate: type DCoordinate = Coordinate Double
+ Wumpus.Drawing.Shapes.Coordinate: type DCoordinateAnchor = CoordinateAnchor Double
+ Wumpus.Drawing.Shapes.Derived: circle :: (Real u, Floating u) => u -> LocShape u Circle
+ Wumpus.Drawing.Shapes.Derived: data Circle u
+ Wumpus.Drawing.Shapes.Derived: data Diamond u
+ Wumpus.Drawing.Shapes.Derived: data Ellipse u
+ Wumpus.Drawing.Shapes.Derived: data Rectangle u
+ Wumpus.Drawing.Shapes.Derived: diamond :: (Real u, Floating u) => u -> u -> LocShape u Diamond
+ Wumpus.Drawing.Shapes.Derived: ellipse :: (Real u, Floating u) => u -> u -> LocShape u Ellipse
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (Circle u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (Diamond u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (Ellipse u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (Rectangle u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor2 (Circle u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor2 (Ellipse u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor2 (Rectangle u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (Circle u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (Diamond u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (Ellipse u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (Rectangle u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (Circle u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (Diamond u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (Ellipse u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (Rectangle u)
+ Wumpus.Drawing.Shapes.Derived: instance (Real u, Floating u, Fractional u) => CardinalAnchor2 (Diamond u)
+ Wumpus.Drawing.Shapes.Derived: instance Eq u => Eq (Circle u)
+ Wumpus.Drawing.Shapes.Derived: instance Eq u => Eq (Rectangle u)
+ Wumpus.Drawing.Shapes.Derived: instance Ord u => Ord (Rectangle u)
+ Wumpus.Drawing.Shapes.Derived: instance Show u => Show (Circle u)
+ Wumpus.Drawing.Shapes.Derived: instance Show u => Show (Rectangle u)
+ Wumpus.Drawing.Shapes.Derived: mkRectangle :: u -> u -> ShapeConstructor u Rectangle
+ Wumpus.Drawing.Shapes.Derived: rdiamond :: (Real u, Floating u) => u -> u -> u -> LocShape u Diamond
+ Wumpus.Drawing.Shapes.Derived: rectangle :: (Real u, Floating u) => u -> u -> LocShape u Rectangle
+ Wumpus.Drawing.Shapes.Derived: rrectangle :: (Real u, Floating u) => u -> u -> u -> LocShape u Rectangle
+ Wumpus.Drawing.Shapes.Derived: type DCircle = Circle Double
+ Wumpus.Drawing.Shapes.Derived: type DDiamond = Diamond Double
+ Wumpus.Drawing.Shapes.Derived: type DEllipse = Ellipse Double
+ Wumpus.Drawing.Shapes.Derived: type DRectangle = Rectangle Double
+ Wumpus.Drawing.Text.LRText: baseCenterEscChar :: (Real u, Floating u, FromPtSize u) => EscapedChar -> BoundedLocGraphic u
+ Wumpus.Drawing.Text.LRText: baseCenterLine :: (Real u, Floating u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Drawing.Text.LRText: baseLeftLine :: (Real u, Floating u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Drawing.Text.LRText: baseRightLine :: (Real u, Floating u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Drawing.Text.LRText: ctrCenterLine :: (Real u, Floating u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Drawing.Text.LRText: multiAlignCenter :: (Floating u, Real u, Ord u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Drawing.Text.LRText: multiAlignLeft :: (Floating u, Real u, Ord u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Drawing.Text.LRText: multiAlignRight :: (Floating u, Real u, Ord u, FromPtSize u) => String -> BoundedLocGraphic u
+ Wumpus.Drawing.Text.LRText: rbaseCenterLine :: (Real u, Floating u, FromPtSize u) => String -> BoundedLocThetaGraphic u
+ Wumpus.Drawing.Text.LRText: rbaseLeftLine :: (Real u, Floating u, FromPtSize u) => String -> BoundedLocThetaGraphic u
+ Wumpus.Drawing.Text.LRText: rbaseRightLine :: (Real u, Floating u, FromPtSize u) => String -> BoundedLocThetaGraphic u
+ Wumpus.Drawing.Text.LRText: rmultiAlignCenter :: (Floating u, Real u, Ord u, FromPtSize u) => String -> BoundedLocThetaGraphic u
+ Wumpus.Drawing.Text.LRText: rmultiAlignLeft :: (Floating u, Real u, Ord u, FromPtSize u) => String -> BoundedLocThetaGraphic u
+ Wumpus.Drawing.Text.LRText: rmultiAlignRight :: (Floating u, Real u, Ord u, FromPtSize u) => String -> BoundedLocThetaGraphic u
+ Wumpus.Drawing.Text.SafeFonts: courier :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: courier_bold :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: courier_bold_oblique :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: courier_oblique :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: helvetica :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: helvetica_bold :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: helvetica_bold_oblique :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: helvetica_oblique :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: symbol :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: times_bold :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: times_bold_italic :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: times_italic :: FontFace
+ Wumpus.Drawing.Text.SafeFonts: times_roman :: FontFace
+ Wumpus.Drawing.Turtle.TurtleClass: class Monad m => TurtleM m
+ Wumpus.Drawing.Turtle.TurtleClass: getLoc :: TurtleM m => m (Int, Int)
+ Wumpus.Drawing.Turtle.TurtleClass: getOrigin :: TurtleM m => m (Int, Int)
+ Wumpus.Drawing.Turtle.TurtleClass: moveDown :: TurtleM m => m ()
+ Wumpus.Drawing.Turtle.TurtleClass: moveLeft :: TurtleM m => m ()
+ Wumpus.Drawing.Turtle.TurtleClass: moveRight :: TurtleM m => m ()
+ Wumpus.Drawing.Turtle.TurtleClass: moveUp :: TurtleM m => m ()
+ Wumpus.Drawing.Turtle.TurtleClass: nextLine :: TurtleM m => m ()
+ Wumpus.Drawing.Turtle.TurtleClass: resetLoc :: TurtleM m => m ()
+ Wumpus.Drawing.Turtle.TurtleClass: setLoc :: TurtleM m => (Int, Int) -> m ()
+ Wumpus.Drawing.Turtle.TurtleClass: setOrigin :: TurtleM m => (Int, Int) -> m ()
+ Wumpus.Drawing.Turtle.TurtleClass: setsLoc :: TurtleM m => (Coord -> (a, Coord)) -> m a
+ Wumpus.Drawing.Turtle.TurtleClass: setsLoc_ :: TurtleM m => (Coord -> Coord) -> m ()
+ Wumpus.Drawing.Turtle.TurtleClass: type Coord = (Int, Int)
+ Wumpus.Drawing.Turtle.TurtleMonad: data TurtleT u m a
+ Wumpus.Drawing.Turtle.TurtleMonad: instance (u ~ MonUnit m, Monad m, Num u) => PointSupplyM (TurtleT u m)
+ Wumpus.Drawing.Turtle.TurtleMonad: instance (u ~ MonUnit m, Monad m, TraceM m) => TraceM (TurtleT u m)
+ Wumpus.Drawing.Turtle.TurtleMonad: instance DrawingCtxM m => DrawingCtxM (TurtleT u m)
+ Wumpus.Drawing.Turtle.TurtleMonad: instance Monad m => Applicative (TurtleT u m)
+ Wumpus.Drawing.Turtle.TurtleMonad: instance Monad m => Functor (TurtleT u m)
+ Wumpus.Drawing.Turtle.TurtleMonad: instance Monad m => Monad (TurtleT u m)
+ Wumpus.Drawing.Turtle.TurtleMonad: instance Monad m => TurtleM (TurtleT u m)
+ Wumpus.Drawing.Turtle.TurtleMonad: runTurtleT :: (Monad m, Num u) => (Int, Int) -> ScalingContext Int Int u -> TurtleT u m a -> m a

Files

demo/ArrowCircuit.hs view
@@ -8,14 +8,14 @@  module ArrowCircuit 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.Basic.Kernel+import Wumpus.Basic.System.FontLoader.Afm+import Wumpus.Basic.System.FontLoader.GhostScript+import Wumpus.Drawing.Arrows+import Wumpus.Drawing.Paths +import Wumpus.Drawing.Shapes+import Wumpus.Drawing.Text.LRText+import Wumpus.Drawing.Text.SafeFonts  import Wumpus.Core                      -- package: wumpus-core @@ -40,7 +40,8 @@ makeGSPicture :: FilePath -> IO () makeGSPicture font_dir = do      putStrLn "Using GhostScript metrics..."-    base_metrics <- loadGSMetrics font_dir ["Times-Roman", "Times-Italic"]+    (base_metrics, msgs) <- loadGSMetrics font_dir ["Times-Roman", "Times-Italic"]+    mapM_ putStrLn msgs     let pic1 = runDrawingU (makeCtx base_metrics) circuit_drawing     writeEPS "./out/arrow_circuit01.eps" pic1     writeSVG "./out/arrow_circuit01.svg" pic1 @@ -48,14 +49,15 @@ makeAfmPicture :: FilePath -> IO () makeAfmPicture font_dir = do      putStrLn "Using AFM 4.1 metrics..."-    base_metrics <- loadAfmMetrics font_dir ["Times-Roman", "Times-Italic"]+    (base_metrics, msgs) <- loadAfmMetrics font_dir ["Times-Roman", "Times-Italic"]+    mapM_ putStrLn msgs     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+makeCtx :: GlyphMetrics -> DrawingContext+makeCtx = fontFace times_roman . metricsContext 11   @@ -93,7 +95,7 @@             , Real u, Floating u, FromPtSize u )           => ConnectorPath u -> Point2 u -> Point2 u -> m () connWith con p0 p1 = localize doublesize $ -    drawi_ $ situ2 (strokeConnector (rightArrow con tri45)) p0 p1+    drawi_ $ apply2R2 (strokeConnector (rightArrow con tri45)) p0 p1   atext :: ( CenterAnchor t, DUnit t ~ u@@ -101,11 +103,11 @@          , TraceM m, DrawingCtxM m, u ~ MonUnit m )       => t -> String -> m () atext ancr ss = let pt = center ancr in-   drawi_ $ singleLineCC ss `at` pt+   drawi_ $ ctrCenterLine ss `at` pt   ptext :: ( Real u, Floating u, FromPtSize u          , TraceM m, DrawingCtxM m, u ~ MonUnit m )       => Point2 u -> String -> m ()-ptext pt ss = localize (fontsize 14 . fontface times_italic) $ -    drawi_ $ singleLineCC ss `at` pt+ptext pt ss = localize (fontAttr times_italic 14) $ +    drawi_ $ ctrCenterLine ss `at` pt
demo/Arrowheads.hs view
@@ -3,11 +3,11 @@ module Arrowheads where  -import Wumpus.Basic.Arrows-import Wumpus.Basic.Chains-import Wumpus.Basic.Colour.SVGColours-import Wumpus.Basic.Graphic-import Wumpus.Basic.Paths hiding ( length )+import Wumpus.Basic.Kernel+import Wumpus.Drawing.Arrows+import Wumpus.Drawing.Chains+import Wumpus.Drawing.Colour.SVGColours+import Wumpus.Drawing.Paths hiding ( length )  import Wumpus.Core                              -- package: wumpus-core @@ -75,7 +75,7 @@                  => (Arrowhead u, Arrowhead u) -> Point2 u                   -> TraceDrawing u () makeArrowDrawing (arrl,arrr) p0 = -    drawi_ $ situ2 (strokeConnector (leftrightArrow connLine arrl arrr)) p0 p1+    drawi_ $ apply2R2 (strokeConnector (leftrightArrow connLine arrl arrr)) p0 p1   where     p1 = p0 .+^ hvec 100   
demo/ClipPic.hs view
@@ -12,12 +12,11 @@  module ClipPic where -import Wumpus.Basic.Chains-import Wumpus.Basic.Colour.SVGColours-import Wumpus.Basic.DrawingComposition-import Wumpus.Basic.Graphic-import Wumpus.Basic.Paths-import Wumpus.Basic.SafeFonts+import Wumpus.Basic.Kernel+import Wumpus.Drawing.Chains+import Wumpus.Drawing.Colour.SVGColours+import Wumpus.Drawing.Paths+import Wumpus.Drawing.Text.SafeFonts  import Wumpus.Core                              -- package: wumpus-core @@ -76,7 +75,7 @@ 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)+    draw $ localize (fontFace symbol) $ textline "&heart;" `at` (pt .+^ hvec 7)   path01 :: Floating u => Path u
demo/ColourChartUtils.hs view
@@ -22,8 +22,8 @@    ) where -import qualified Wumpus.Basic.Colour.SVGColours    as SVG-import qualified Wumpus.Basic.Colour.X11Colours    as X11+import qualified Wumpus.Drawing.Colour.SVGColours    as SVG+import qualified Wumpus.Drawing.Colour.X11Colours    as X11  import Wumpus.Core.Colour ( RGBi ) 
demo/ColourCharts.hs view
@@ -4,8 +4,8 @@  import ColourChartUtils -import Wumpus.Basic.Chains-import Wumpus.Basic.Graphic+import Wumpus.Basic.Kernel+import Wumpus.Drawing.Chains  import Wumpus.Core                              -- package: wumpus-core 
demo/Connectors.hs view
@@ -3,11 +3,11 @@ module Connectors where  -import Wumpus.Basic.Arrows-import Wumpus.Basic.Chains-import Wumpus.Basic.Colour.SVGColours-import Wumpus.Basic.Graphic-import Wumpus.Basic.Paths hiding ( length )+import Wumpus.Basic.Kernel+import Wumpus.Drawing.Arrows+import Wumpus.Drawing.Chains+import Wumpus.Drawing.Colour.SVGColours+import Wumpus.Drawing.Paths hiding ( length )  import Wumpus.Core                              -- package: wumpus-core @@ -67,7 +67,7 @@ makeConnDrawing :: (Real u, Floating u, FromPtSize u)                   => ConnectorPath u -> Point2 u -> TraceDrawing u () makeConnDrawing conn p0 = -    drawi_ $ situ2 (strokeConnector (dblArrow conn curveTip)) p0 p1+    drawi_ $ connect (strokeConnector (dblArrow conn curveTip)) p0 p1   where     p1 = p0 .+^ vec 100 40   
demo/DotPic.hs view
@@ -3,13 +3,13 @@ module DotPic where  -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 Wumpus.Basic.Kernel+import Wumpus.Basic.System.FontLoader.Afm+import Wumpus.Basic.System.FontLoader.GhostScript+import Wumpus.Drawing.Chains+import Wumpus.Drawing.Colour.SVGColours+import Wumpus.Drawing.Dots.AnchorDots+import Wumpus.Drawing.Text.SafeFonts  import FontLoaderUtils @@ -36,24 +36,26 @@ makeGSPicture :: FilePath -> IO () makeGSPicture font_dir = do      putStrLn "Using GhostScript metrics..."-    base_metrics <- loadGSMetrics font_dir ["Helvetica"]+    (base_metrics, msgs) <- loadGSMetrics font_dir ["Helvetica"]+    mapM_ putStrLn msgs     let pic1 = runDrawingU (makeCtx base_metrics) dot_drawing -    writeEPS "./out/dots01.eps" pic1-    writeSVG "./out/dots01.svg" pic1+    writeEPS "./out/dots01_gs.eps" pic1+    writeSVG "./out/dots01_gs.svg" pic1     makeAfmPicture :: FilePath -> IO () makeAfmPicture font_dir = do      putStrLn "Using AFM 4.1 metrics..."-    base_metrics <- loadAfmMetrics font_dir ["Helvetica"]+    (base_metrics, msgs) <- loadAfmMetrics font_dir ["Helvetica"]+    mapM_ putStrLn msgs     let pic1 = runDrawingU (makeCtx base_metrics) dot_drawing -    writeEPS "./out/dots02.eps" pic1-    writeSVG "./out/dots02.svg" pic1+    writeEPS "./out/dots01_afm.eps" pic1+    writeSVG "./out/dots01_afm.svg" pic1   -makeCtx :: BaseGlyphMetrics -> DrawingContext-makeCtx = fillColour peru . fontface helvetica . metricsContext 24+makeCtx :: GlyphMetrics -> DrawingContext+makeCtx = fillColour peru . fontFace helvetica . metricsContext 24   dot_drawing :: Drawing Double@@ -75,6 +77,7 @@     , dotFOCross     , dotFDiamond     , dotText "%" +    , dotTriangle     ]  
demo/DrawingCompo.hs view
@@ -2,9 +2,8 @@  module DrawingCompo where -import Wumpus.Basic.Colour.SVGColours-import Wumpus.Basic.DrawingComposition-import Wumpus.Basic.Graphic+import Wumpus.Basic.Kernel+import Wumpus.Drawing.Colour.SVGColours  import Wumpus.Core                              -- package: wumpus-core 
demo/FeatureModel.hs view
@@ -5,14 +5,14 @@  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.Basic.Kernel+import Wumpus.Basic.System.FontLoader.Afm+import Wumpus.Basic.System.FontLoader.GhostScript+import Wumpus.Drawing.Arrows+import Wumpus.Drawing.Paths +import Wumpus.Drawing.Shapes+import Wumpus.Drawing.Text.LRText+import Wumpus.Drawing.Text.SafeFonts  import Wumpus.Core                      -- package: wumpus-core @@ -35,7 +35,8 @@ makeGSPicture :: FilePath -> IO () makeGSPicture font_dir = do      putStrLn "Using GhostScript metrics..."-    base_metrics <- loadGSMetrics font_dir ["Courier-Bold"]+    (base_metrics, msgs) <- loadGSMetrics font_dir ["Courier-Bold"]+    mapM_ putStrLn msgs     let pic1 = runDrawingU (makeCtx base_metrics) feature_model      writeEPS "./out/feature_model01.eps" pic1     writeSVG "./out/feature_model01.svg" pic1 @@ -43,13 +44,14 @@ makeAfmPicture :: FilePath -> IO () makeAfmPicture font_dir = do      putStrLn "Using AFM 4.1 metrics..."-    base_metrics <- loadAfmMetrics font_dir ["Courier-Bold"]+    (base_metrics, msgs) <- loadAfmMetrics font_dir ["Courier-Bold"]+    mapM_ putStrLn msgs     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+makeCtx :: GlyphMetrics -> DrawingContext+makeCtx = fontFace courier_bold . metricsContext 18   -- Note - I haven't worked out how to do @alternative@, @or@ and@@ -90,7 +92,7 @@         => 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+    drawi_ $ ctrCenterLine ss `at` center a     return a  box :: (Real u, Floating u, FromPtSize u) @@ -105,10 +107,10 @@ connWith :: ( Real u, Floating u, FromPtSize u )           => Arrowhead u -> Box u -> Box u -> TraceDrawing u (Path u) connWith arrh b0 b1 = do-   lw <- lineWidth+   lw <- getLineWidth    let p0 = south b0    let p1 = northwards (realToFrac lw) b1-   drawi $ situ2 (strokeConnector (rightArrow connLine arrh)) p0 p1+   drawi $ apply2R2 (strokeConnector (rightArrow connLine arrh)) p0 p1  infixr 4 `cmandatory`, `coptional`, `cmandatory_`, `coptional_` 
demo/FontPic.hs view
@@ -2,11 +2,11 @@  module FontPic where -import Wumpus.Basic.Chains-import Wumpus.Basic.Graphic-import Wumpus.Basic.Colour.SVGColours ( steel_blue )-import Wumpus.Basic.Colour.X11Colours ( indian_red1 )-import Wumpus.Basic.SafeFonts+import Wumpus.Basic.Kernel+import Wumpus.Drawing.Chains+import Wumpus.Drawing.Colour.SVGColours ( steel_blue )+import Wumpus.Drawing.Colour.X11Colours ( indian_red1 )+import Wumpus.Drawing.Text.SafeFonts  import Wumpus.Core                              -- package: wumpus-core @@ -44,7 +44,7 @@ makeLabel :: RGBi -> FontFace -> Int -> DLocGraphic makeLabel rgb ff sz = localize upd (textline $ fontMsg ff sz)   where-    upd = fillColour rgb . fontsize sz . fontface ff+    upd = fillColour rgb . fontAttr ff sz   -- indian_red1 -- steel_blue
demo/LeftRightText.hs view
@@ -16,13 +16,13 @@ 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 Wumpus.Basic.Kernel+import Wumpus.Basic.System.FontLoader.Afm+import Wumpus.Basic.System.FontLoader.GhostScript+import Wumpus.Drawing.Colour.SVGColours+import Wumpus.Drawing.Dots.Marks+import Wumpus.Drawing.Text.LRText+import Wumpus.Drawing.Text.SafeFonts  import FontLoaderUtils @@ -47,56 +47,110 @@ makeGSPicture :: FilePath -> IO () makeGSPicture font_dir = do     putStrLn "Using GhostScript metrics..."-    gs_metrics <- loadGSMetrics font_dir ["Helvetica"]+    (gs_metrics, msgs) <- loadGSMetrics font_dir ["Helvetica"]+    mapM_ putStrLn msgs     let pic1 = runDrawingU (makeCtx gs_metrics) text_drawing -    writeEPS "./out/new_text01.eps" pic1-    writeSVG "./out/new_text01.svg" pic1+    writeEPS "./out/lr_text01.eps" pic1+    writeSVG "./out/lr_text01.svg" pic1  makeAfmPicture :: FilePath -> IO () makeAfmPicture font_dir = do     putStrLn "Using AFM 4.1 metrics..."-    afm_metrics <- loadAfmMetrics font_dir ["Helvetica"]+    (afm_metrics, msgs) <- loadAfmMetrics font_dir ["Helvetica"]+    mapM_ putStrLn msgs     let pic2 = runDrawingU (makeCtx afm_metrics) text_drawing -    writeEPS "./out/new_text02.eps" pic2-    writeSVG "./out/new_text02.svg" pic2+    writeEPS "./out/lr_text02.eps" pic2+    writeSVG "./out/lr_text02.svg" pic2    -makeCtx :: BaseGlyphMetrics -> DrawingContext-makeCtx = fontface helvetica . metricsContext 18+makeCtx :: GlyphMetrics -> 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 -       +    drawi_ $ (fn left_text)       `at` P2   0 400+    drawi_ $ (fn center_text)     `at` P2 200 400+    drawi_ $ (fn right_text)      `at` P2 400 400+    drawi_ $ (fn blank_text)      `at` P2   0 300+    drawi_ $ (fn bl_oneline)      `at` P2 200 300+    drawi_ $ (fn cc_oneline)      `at` P2 400 300+    drawi_ $ (fn newblr)          `at` P2   0 200+    drawi_ $ (fn newblc)          `at` P2 200 200+    drawi_ $ (fn newbll)          `at` P2 400 200+    drawi_ $ (fn rnewblr)         `at` P2   0 100+    drawi_ $ (fn rnewblc)         `at` P2 200 100+    drawi_ $ (fn rnewbll)         `at` P2 400 100+    drawi_ $ (fn rleft_text)      `at` P2   0 (-75)+    drawi_ $ (fn rcenter_text)    `at` P2 200 (-75)+    drawi_ $ (fn rright_text)     `at` P2 400 (-75)+      + +    draw $ redPlus            `at` P2   0 400+    draw $ redPlus            `at` P2 200 400+    draw $ redPlus            `at` P2 400 400+    draw $ redPlus            `at` P2   0 300  +    draw $ redPlus            `at` P2 200 300 +    draw $ redPlus            `at` P2 400 300 +    draw $ redPlus            `at` P2   0 200  +    draw $ redPlus            `at` P2 200 200 +    draw $ redPlus            `at` P2 400 200  +    draw $ redPlus            `at` P2   0 100  +    draw $ redPlus            `at` P2 200 100 +    draw $ redPlus            `at` P2 400 100 +    draw $ redPlus            `at` P2   0 (-75)+    draw $ redPlus            `at` P2 200 (-75)+    draw $ redPlus            `at` P2 400 (-75)+         where     fn = illustrateBoundedLocGraphic-+    redPlus :: (Fractional u, FromPtSize u) => LocGraphic u redPlus = localize (strokeColour red) markPlus ++newblc :: BoundedLocGraphic Double+newblc = +    localize (strokeColour dark_slate_gray) $ +        baseCenterLine "new baseline center"++newbll :: BoundedLocGraphic Double+newbll = +    localize (strokeColour dark_slate_gray) $ +        baseLeftLine "new baseline left"++newblr :: BoundedLocGraphic Double+newblr = +    localize (strokeColour dark_slate_gray) $ +        baseRightLine "new baseline right"+++rnewblc :: BoundedLocGraphic Double+rnewblc = +    localize (strokeColour dark_slate_gray) $ +        rbaseCenterLine "baseline center" `rot` (0.25*pi)++rnewbll :: BoundedLocGraphic Double+rnewbll = +    localize (strokeColour dark_slate_gray) $ +        rbaseLeftLine "baseline left" `rot` (0.25*pi)++rnewblr :: BoundedLocGraphic Double+rnewblr = +    localize (strokeColour dark_slate_gray) $ +        rbaseRightLine "baseline right" `rot` (0.25 * pi)++ bl_oneline :: BoundedLocGraphic Double bl_oneline = -    localize (strokeColour dark_slate_gray) $ singleLineBL "Baseline-left..."+    localize (strokeColour dark_slate_gray) $ baseLeftLine "Baseline-left..."   cc_oneline :: BoundedLocGraphic Double cc_oneline = -    localize (strokeColour dark_slate_gray) $ singleLineCC "Center-center..."+    localize (strokeColour dark_slate_gray) $ ctrCenterLine "Center-center..."  blank_text :: BoundedLocGraphic Double blank_text = @@ -115,6 +169,23 @@ center_text :: BoundedLocGraphic Double center_text =      localize (strokeColour dark_slate_gray) $ multiAlignCenter dummy_text+++rleft_text :: BoundedLocGraphic Double+rleft_text = +    localize (strokeColour dark_slate_gray) $ +        rmultiAlignLeft dummy_text `rot`   (0.25*pi)+++rright_text :: BoundedLocGraphic Double+rright_text = +    localize (strokeColour dark_slate_gray) $ +        rmultiAlignRight dummy_text `rot`  (0.25*pi)++rcenter_text :: BoundedLocGraphic Double+rcenter_text = +    localize (strokeColour dark_slate_gray) $ +        rmultiAlignCenter dummy_text `rot` (0.25*pi)   dummy_text :: String 
demo/PetriNet.hs view
@@ -7,14 +7,19 @@  module PetriNet where -import Wumpus.Basic.Arrows-import Wumpus.Basic.Colour.SVGColours-import Wumpus.Basic.Graphic                     -- package: wumpus-basic-import Wumpus.Basic.Paths-import Wumpus.Basic.Shapes.Base-import Wumpus.Basic.Shapes.Derived-import Wumpus.Basic.SafeFonts+import Wumpus.Basic.Kernel+import Wumpus.Basic.System.FontLoader.Afm+import Wumpus.Basic.System.FontLoader.GhostScript+import Wumpus.Drawing.Arrows+import Wumpus.Drawing.Colour.SVGColours+import Wumpus.Drawing.Paths+import Wumpus.Drawing.Shapes.Base+import Wumpus.Drawing.Shapes.Derived+import Wumpus.Drawing.Text.SafeFonts+import Wumpus.Drawing.Text.LRText +import FontLoaderUtils+ import Wumpus.Core                              -- package: wumpus-core  @@ -22,15 +27,40 @@   + main :: IO () main = do +    (mb_gs, mb_afm) <- processCmdLine default_font_loader_help     createDirectoryIfMissing True "./out/"-    let pic1 = runDrawingU (standardContext 14) petri_net-    writeEPS "./out/petri_net.eps" pic1-    writeSVG "./out/petri_net.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..." +makeGSPicture :: FilePath -> IO ()+makeGSPicture font_dir = do +    putStrLn "Using GhostScript metrics..."+    (base_metrics, msgs) <- loadGSMetrics font_dir ["Helvetica", "Helvetica-Bold"]+    mapM_ putStrLn msgs+    let pic1 = runDrawingU (makeCtx base_metrics) petri_net+    writeEPS "./out/petri_net01.eps" pic1+    writeSVG "./out/petri_net01.svg" pic1  +makeAfmPicture :: FilePath -> IO ()+makeAfmPicture font_dir = do +    putStrLn "Using AFM 4.1 metrics..."+    (base_metrics, msgs) <- loadAfmMetrics font_dir ["Helvetica", "Helvetica-Bold"]+    mapM_ putStrLn msgs+    let pic1 = runDrawingU (makeCtx base_metrics) petri_net+    writeEPS "./out/petri_net02.eps" pic1+    writeSVG "./out/petri_net02.svg" pic1 +++makeCtx :: GlyphMetrics -> DrawingContext+makeCtx = fontFace helvetica . metricsContext 14++ petri_net :: DDrawing petri_net = drawTracing $ do     pw     <- place 0 140@@ -95,32 +125,34 @@          , Real u, Floating u, FromPtSize u )        => Point2 u -> Point2 u -> m () connector' p0 p1 = -    drawi_ $ situ2 (strokeConnector (rightArrow connLine tri45)) p0 p1+    drawi_ $ apply2R2 (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_ $ situ2 (strokeConnector (rightArrow (connRightVHV v) tri45)) p0 p1+    drawi_ $ apply2R2 (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_ $ situ2 (strokeConnector (rightArrow (connIsosceles u) tri45)) p0 p1+    drawi_ $ apply2R2 (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 :: (Real u, Floating u, FromPtSize u) => String -> LocGraphic u+lblBold ss = localize (fontFace helvetica_bold) $ post $ ctrCenterLine ss+  where+    post = fmap (replaceL uNil)
demo/Symbols.hs view
@@ -2,9 +2,9 @@  module Symbols where -import Wumpus.Basic.Chains-import Wumpus.Basic.Graphic-import Wumpus.Basic.SafeFonts+import Wumpus.Basic.Kernel+import Wumpus.Drawing.Chains+import Wumpus.Drawing.Text.SafeFonts   import Wumpus.Core                              -- package: wumpus-core@@ -25,7 +25,7 @@   std_ctx :: DrawingContext-std_ctx = fontface times_roman $ standardContext 12+std_ctx = fontFace times_roman $ standardContext 12   -- Because the font changes, we draw the all the symbols in one@@ -35,7 +35,7 @@ -- symbols :: DDrawing symbols = drawTracing $ do-    localize (fontface symbol) $ zipWithM_ sdraw all_letters ps+    localize (fontFace symbol) $ zipWithM_ sdraw all_letters ps     zipWithM_ ldraw all_letters ps   where     sdraw (s,_)     pt = draw $ textline s `at` pt
− src/Wumpus/Basic/Arrows.hs
@@ -1,28 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Arrows--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Shim module for arrow connectors and arrowheads.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Arrows-  ( --    module Wumpus.Basic.Arrows.Tips-  , module Wumpus.Basic.Arrows.Connectors--  ) where--import Wumpus.Basic.Arrows.Tips-import Wumpus.Basic.Arrows.Connectors--
− src/Wumpus/Basic/Arrows/Connectors.hs
@@ -1,148 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Arrows.Connectors--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Draw arrows.--------------------------------------------------------------------------------------module Wumpus.Basic.Arrows.Connectors-  ( --    Connector-  , connector-  , leftArrow-  , rightArrow-  , dblArrow-  , leftrightArrow-  , strokeConnector---  ) where--import Wumpus.Basic.Arrows.Tips-import Wumpus.Basic.Graphic-import Wumpus.Basic.Paths--import Wumpus.Core                      -- package: wumpus-core--import Control.Applicative---- An arrowhead always know how to draw itself (filled triangle, --- stroked barb, etc.)------ A Path might will typically be drawn with openStroke,--- eventually there might be scope for drawing --- e.g. parallel lines  ====------- A ConnectorPath gets wrapped with how it is drawn into--- another type.---data Connector u = Connector -      { connector_path  :: ConnectorPath u-      , opt_left_arrow  :: Maybe (Arrowhead u)-      , opt_right_arrow :: Maybe (Arrowhead u)-      }----- | connector with no arrow heads.----connector :: ConnectorPath u -> Connector u-connector cp = -    Connector { connector_path  = cp-              , opt_left_arrow  = Nothing-              , opt_right_arrow = Nothing-              }--leftArrow :: ConnectorPath u -> Arrowhead u -> Connector u-leftArrow cp la =-    Connector { connector_path  = cp-              , opt_left_arrow  = Just la-              , opt_right_arrow = Nothing-              }---rightArrow :: ConnectorPath u -> Arrowhead u -> Connector u-rightArrow cp ra = -    Connector { connector_path  = cp-              , opt_left_arrow  = Nothing-              , opt_right_arrow = Just ra-              }---- | Same tip both ends.----dblArrow :: ConnectorPath u -> Arrowhead u -> Connector u-dblArrow cp arw = leftrightArrow cp arw arw--leftrightArrow :: ConnectorPath u -> Arrowhead u -> Arrowhead u -> Connector u-leftrightArrow cp la ra =-    Connector { connector_path  = cp-              , opt_left_arrow  = Just la-              , opt_right_arrow = Just ra-              }----strokeConnector :: (Real u, Floating u) -                => Connector u -> ConnectorImage u (Path u)-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-    drawP       = openStroke . toPrimPath   ----- for Paths.Base ?----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 --- it has to wrap the tips back up as Graphics with @pure@ so they --- can be concatenated to the drawn path as GraphicTrafos.------ The Arrowhead type could be changed, so rather than returning --- an Image (retract_distance, PrimGraphic) it returns --- (retract_distance, GraphicTrafo) but that would burden all --- arrowheads with some extra complexity.--- --- In short - the code here works but it isn\'t exemplary, and it --- doesn\'t show whether or not GraphicTrafo is a valuable type or--- if it is implemented correctly (as GraphicTrafo could having--- different implementations according to how it regards the --- DrawingCtx).-----tipEval :: Num u -        => 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 :: 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
@@ -1,485 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Arrows.Tips--- 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 in future revisions.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Arrows.Tips-  ( ---    Arrowhead(..)-- -  , tri90-  , tri60-  , tri45-  , otri90-  , otri60-  , otri45--  , revtri90-  , revtri60-  , revtri45-  , orevtri90-  , orevtri60-  , orevtri45--  , barb90-  , barb60-  , barb45-  , revbarb90-  , revbarb60-  , revbarb45--  , perp--  , bracket--  , diskTip-  , odiskTip-  , squareTip-  , osquareTip-  , diamondTip-  , odiamondTip--  , curveTip-  , revcurveTip--  ) where--import Wumpus.Basic.Graphic-import Wumpus.Basic.Paths--import Wumpus.Core                      -- package: wumpus-core--import Data.AffineSpace                 -- package: vector-space--import Control.Applicative----- | Encode an arrowhead as an image where the /answer/ is the--- retract distance.------ The retract distance is context sensitive - usually just on--- the markHeight (or halfMarkHeight) so it has to be calculated--- w.r.t. the DrawingCtx.----newtype Arrowhead u = Arrowhead { getArrowhead :: LocThetaImage u u }------- | Tiplen is length of the tip \*along the line it follows\*. ------ > |\--- > | \--- > | /--- > |/--- > --- > |  |  -- tip len------- | Tip width is the distance between upper and lower --- arrow points.------ >       __--- > |\    --- > | \   tip--- > | /   width--- > |/    __--- >       ------ | This one is for triangular tips defined by their tip angle--- e.g. 90deg, 60deg, 45deg.------ The tip width will be variable (tip length should be the --- markHeight).--- -triVecsByAngle :: Floating u => u -> Radian -> Radian -> (Vec2 u, Vec2 u)-triVecsByAngle tiplen halfang theta = (vec_to_upper, vec_to_lower)-  where-    hypo_len     = tiplen / (fromRadian $ cos halfang)-    rtheta       = pi + theta        -- theta in the opposite direction-    vec_to_upper = avec (circularModulo $ rtheta - halfang) hypo_len-    vec_to_lower = avec (circularModulo $ rtheta + halfang) hypo_len ------ | This one is for triangles when the tip height and tip width--- are known.----triVecsByDist  :: (Real u, Floating u) -               => u -> u -> Radian -> (Vec2 u, Vec2 u)-triVecsByDist tiplen half_tipwidth theta = (vec_to_upper, vec_to_lower)-  where-    hypo_len     = sqrt $ (tiplen*tiplen) + (half_tipwidth*half_tipwidth)-    halfang      = toRadian $ atan (half_tipwidth / tiplen) -    rtheta       = pi + theta        -- theta in the opposite direction-    vec_to_upper = avec (circularModulo $ rtheta - halfang) hypo_len-    vec_to_lower = avec (circularModulo $ rtheta + halfang) hypo_len -----{--markHeightPlusLineWidth :: (Fractional u, FromPtSize u) => DrawingR u-markHeightPlusLineWidth = -    (\h lw -> h + realToFrac lw) <$> markHeight <*> lineWidth--}---markHeightLessLineWidth :: (Fractional u, FromPtSize u) => CF u-markHeightLessLineWidth = -    (\h lw -> h - realToFrac lw) <$> markHeight <*> lineWidth----- noRetract ignores both the angle and the point.------ Its common for the rectraction not to care about the angle or --- the point and only care about the DrawingCtx.----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--- mark height (but that is okay - seemingly this is how TikZ --- does it).----tripointsByAngle :: (Floating u, FromPtSize u)-                 => 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 -                    -> 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)-                => 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)-                   => 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) -> 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 $ -    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/2) filledPath)---tri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-tri60 = Arrowhead $-    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/3) filledPath)---tri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-tri45 = Arrowhead $ -    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/4) filledPath)--otri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-otri90 = Arrowhead $-    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/2) closedStroke)--otri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-otri60 = Arrowhead $   -    intoLocThetaImage (dblstatic markHeight) (triTLG (pi/3) closedStroke)--otri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-otri45 = Arrowhead $ -    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) -> 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 $ -    intoLocThetaImage (dblstatic markHeightLessLineWidth) -                      (revtriTLG (pi/2) filledPath)--revtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-revtri60 = Arrowhead $ -    intoLocThetaImage (dblstatic markHeightLessLineWidth) -                      (revtriTLG (pi/3) filledPath)--revtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-revtri45 = Arrowhead $ -    intoLocThetaImage (dblstatic markHeightLessLineWidth) -                      (revtriTLG (pi/4) filledPath)---orevtri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-orevtri90 = Arrowhead $ -    intoLocThetaImage (dblstatic markHeightLessLineWidth) -                      (revtriTLG (pi/2) closedStroke)--orevtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-orevtri60 = Arrowhead $ -    intoLocThetaImage (dblstatic markHeightLessLineWidth) -                      (revtriTLG (pi/3) closedStroke)--orevtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-orevtri45 = Arrowhead $ -    intoLocThetaImage (dblstatic markHeightLessLineWidth) -                      (revtriTLG (pi/4) closedStroke)----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 $ intoLocThetaImage noRetract (barbTLG (pi/2))--barb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-barb60 = Arrowhead $ intoLocThetaImage noRetract (barbTLG (pi/3))---barb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-barb45 = Arrowhead $ intoLocThetaImage noRetract (barbTLG (pi/4))----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 $ -    intoLocThetaImage (dblstatic markHeight) (revbarbTLG (pi/2))---revbarb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-revbarb60 = Arrowhead $ -    intoLocThetaImage (dblstatic markHeight) (revbarbTLG (pi/3))--revbarb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u-revbarb45 = Arrowhead $ -    intoLocThetaImage (dblstatic markHeight) (revbarbTLG (pi/4))---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 $ intoLocThetaImage noRetract perpTLG----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 $ intoLocThetaImage noRetract bracketTLG---diskTLG :: (Floating u, FromPtSize u) -        => (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 $ intoLocThetaImage (dblstatic markHeight) (diskTLG drawF)-  where-    drawF r pt = localize bothStrokeColour $ filledDisk r `at` pt---odiskTip :: (Floating u, FromPtSize u) => Arrowhead u-odiskTip = Arrowhead $ intoLocThetaImage (dblstatic markHeight) (diskTLG drawF)-  where-    drawF r pt = strokedDisk r `at` pt---squareTLG :: (Floating u, FromPtSize u) -        => (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 $ intoLocThetaImage (dblstatic markHeight) (squareTLG drawF)-  where-    drawF = localize bothStrokeColour . filledPath---osquareTip :: (Floating u, FromPtSize u) => Arrowhead u-osquareTip = Arrowhead $ -    intoLocThetaImage (dblstatic markHeight) (squareTLG closedStroke)---diamondTLG :: (Floating u, FromPtSize u) -           => (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 $ -    intoLocThetaImage (dblstatic $ fmap (2*) markHeightLessLineWidth) -                      (diamondTLG drawF)-  where-    drawF = localize bothStrokeColour . filledPath---odiamondTip :: (Floating u, FromPtSize u) => Arrowhead u-odiamondTip = Arrowhead $ -    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) => 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 $ -    intoLocThetaImage (dblstatic $ fmap realToFrac lineWidth) curveTLG----- Note - points flipped to get the second trapezium to --- draw /underneath/.----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 $ -    intoLocThetaImage (dblstatic markHeight) revcurveTLG-
− src/Wumpus/Basic/Chains.hs
@@ -1,29 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Chains--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC ------ Shim module.------ WARNING - very unstable.--------------------------------------------------------------------------------------module Wumpus.Basic.Chains-  (-    module Wumpus.Basic.Chains.Base-  , module Wumpus.Basic.Chains.Derived-  --  ) where---import Wumpus.Basic.Chains.Base-import Wumpus.Basic.Chains.Derived
− src/Wumpus/Basic/Chains/Base.hs
@@ -1,161 +0,0 @@-{-# LANGUAGE ExistentialQuantification  #-}-{-# LANGUAGE RankNTypes                 #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Chains.Base--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC ------ Generate points in an iterated chain.------ WARNING - very unstable.--------------------------------------------------------------------------------------module Wumpus.Basic.Chains.Base-  (---    Chain-  , LocChain-  , chain-  , chainFrom-  , unchain---  , AnaAlg(..)-  , IterAlg(..)--  , BivariateAlg-  , bivariate-  -  , SequenceAlg-  , iteration--  , bounded-  , pairOnXs-  , pairOnYs--  ) where--import Wumpus.Basic.Graphic--import Wumpus.Core                              -- package: wumpus-core----- Chain uses the Scaling monad, but it is not itself a monad.---newtype Chain ux uy u = Chain { getChain :: Scaling ux uy u [Point2 u] }---type LocChain ux uy u = Point2 u -> Chain ux uy u----chain :: BivariateAlg ux uy -> Chain ux uy u-chain alg = Chain (scaledBivariatePt alg)--chainFrom :: Num u => BivariateAlg ux uy -> LocChain ux uy u-chainFrom alg start = Chain (scaledBivariateVec alg start)---unchain :: ScalingContext ux uy u -> Chain ux uy u -> [Point2 u]-unchain ctx ch = runScaling ctx $ getChain ch- ---- | Chains are built as unfolds - AnaAlg avoids the pair --- constructor in the usual definition of unfoldr and makes the--- state strict.------ It is expected that all Chains built on unfolds will terminate. ----data AnaAlg st a = Done | Step a !st----- | IterAlg is a variant of AnaAlg that builds infinite --- sequences (iterations).--- --- When lifted to a Chain an iteration is bounded by a count so--- it will terminate.----data IterAlg st a = IterStep a !st ---data BivariateAlg ux uy = forall st. BivariateAlg-      { st_zero     :: st-      , gen_step    :: st -> AnaAlg st (ux,uy)-      }--bivariate :: st -> (st -> AnaAlg st (ux,uy)) -> BivariateAlg ux uy-bivariate st0 step_alg = BivariateAlg { st_zero = st0-                                      , gen_step = step_alg }---scaledBivariatePt :: BivariateAlg ux uy -> Scaling ux uy u [Point2 u]-scaledBivariatePt (BivariateAlg { st_zero = st0, gen_step = step}) = -    go (step st0)   -  where-    go Done              = return []-    go (Step (x,y) next) = scalePt x y    >>= \pt   ->-                           go (step next) >>= \rest ->  -                           return  (pt:rest)---- Note - cannot encode this with (.+^) from Data.AffineSpace.--- The u (u ~ MonUnit m) extracted from the Scaling Context is --- not compatible with the u that forms Points (u ~ Diff (Point2 u)).--scaledBivariateVec :: Num u -                   => BivariateAlg ux uy -                   -> Point2 u -                   -> Scaling ux uy u [Point2 u]-scaledBivariateVec (BivariateAlg { st_zero = st0, gen_step = step}) (P2 x0 y0) = -    go (step st0)   -  where-    go Done              = return []-    go (Step (x,y) next) = scaleVec x y   >>= \(V2 dx dy)   ->-                           go (step next) >>= \rest ->  -                           return (P2 (x0+dx) (y0+dy):rest)---data SequenceAlg a = forall st. SequenceAlg-      { initial_st  :: st-      , iter_step   :: st -> IterAlg st a-      }--iteration :: (a -> a) -> a -> SequenceAlg a-iteration fn s0 = SequenceAlg { initial_st = s0, iter_step = step }-  where-    step s = IterStep s (fn s)---bounded :: Int -> SequenceAlg (ux,uy) -> BivariateAlg ux uy-bounded n (SequenceAlg a0 fn) =-    BivariateAlg { st_zero     = (0,a0)-                 , gen_step    = gstep  }-  where-    gstep (i,s) | i < n = let (IterStep ans next) = fn s in Step ans (i+1,next)-    gstep _             = Done-----pairOnXs :: (ux -> uy) -> SequenceAlg ux -> SequenceAlg (ux,uy)-pairOnXs fn (SequenceAlg { initial_st = s0, iter_step = step }) = -    SequenceAlg s0 step2-  where-    step2 s = let (IterStep a s') = step s in IterStep (a, fn a) s'---pairOnYs :: (r -> l) -> SequenceAlg r -> SequenceAlg (l,r) -pairOnYs fn (SequenceAlg { initial_st = s0, iter_step = step }) = -    SequenceAlg  s0 step2-  where-    step2 s = let (IterStep a s') = step s in IterStep (fn a, a) s'-
− src/Wumpus/Basic/Chains/Derived.hs
@@ -1,129 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Chains.Derived--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC ------ Generate points in an iterated chain.------ WARNING - very unstable.--------------------------------------------------------------------------------------module Wumpus.Basic.Chains.Derived-  (-    -    univariateX-  , univariateY--  , tableDown-  , tableRight--  , horizontal-  , vertical--  , horizontals-  , verticals--  , rescale--  ) where--import Wumpus.Basic.Chains.Base-----univariateX :: (Fractional uy, Num ux, Num u) -            => [ux] -> LocChain ux uy u-univariateX zs = chainFrom $ bivariate (0,zs) gstep-  where-    gstep (_,[])     = Done -    gstep (n,x:xs)   = Step (x,n) (n+i,xs)-    len              = length zs-    i                = rescale 0 1 0 (fromIntegral $ len-1) 1---univariateY :: (Fractional ux, Num uy, Num u) -            => [uy] -> LocChain ux uy u-univariateY zs = chainFrom $ bivariate (0,zs) gstep-  where-    gstep (_,[])     = Done -    gstep (n,y:ys)   = Step (n,y) (n+i,ys)-    len              = length zs-    i                = rescale 0 1 0 (fromIntegral $ len-1) 1--------------------------------------------------------------------------------------- Tables---tableDown :: Int -> Int -> Chain Int Int u-tableDown rows cols = -    chain $ bounded (rows*cols) (iteration (downstep rows) (0,rows-1))----downstep :: Int -> (Int,Int) -> (Int,Int)-downstep row_count (x,y) | y == 0 = (x+1,row_count-1)-downstep _         (x,y)          = (x,y-1)----tableRight :: Num u => Int -> Int -> Chain Int Int u-tableRight rows cols = -    chain $ bounded (rows*cols) (iteration (rightstep cols) (0,rows-1))---rightstep :: Int -> (Int,Int) -> (Int,Int)-rightstep col_count (x,y) | x == (col_count-1) = (0,y-1)-rightstep _         (x,y)                      = (x+1,y)---horizontal :: Int -> Chain Int Int u-horizontal count = chain $ bivariate 0 alg-  where-    alg st | st == count = Done-    alg st               = Step (st,0) (st+1)---vertical :: Int -> Chain Int Int u-vertical count = chain $ bivariate 0 alg-  where-    alg st | st == count = Done-    alg st               = Step (0,st) (st+1)----horizontals :: (Num ua, Num u) => [ua] -> LocChain ua ua u-horizontals xs0 = chainFrom $ bivariate xs0 alg-  where-    alg []     = Done-    alg (x:xs) = Step (x,0) xs---verticals :: (Num ua, Num u)  => [ua] -> LocChain ua ua u-verticals ys0 = chainFrom $ bivariate ys0 alg-  where-    alg []     = Done-    alg (y:ys) = Step (0,y) ys-------------------------------------------------------------------------------------- general helpers--rescale :: Fractional a => a -> a -> a -> a -> a -> a-rescale outmin outmax innmin innmax a = -    outmin + innpos * (outrange / innrange)  -  where-    outrange = outmax - outmin-    innrange = innmax - innmin-    innpos   = a - innmin -
− src/Wumpus/Basic/Colour/SVGColours.hs
@@ -1,625 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Colour.SVGColours--- Copyright   :  (c) Stephen Tetley 2009-2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  unstable--- Portability :  GHC------ The SVG \'named colours\', as rgb [0,1] values --------------------------------------------------------------------------------------module Wumpus.Basic.Colour.SVGColours -  (-    -  -- * Named colours-    alice_blue-  , antique_white-  , aqua-  , aquamarine-  , azure-  , beige-  , bisque-  , black-  , blanched_almond-  , blue-  , blue_violet-  , brown-  , burlywood-  , cadet_blue-  , chartreuse-  , chocolate-  , coral-  , cornflower_blue-  , cornsilk-  , crimson-  , cyan-  , dark_blue-  , dark_cyan-  , dark_goldenrod-  , dark_gray-  , dark_green-  , dark_grey-  , dark_khaki-  , dark_magenta-  , dark_olive_green-  , dark_orange-  , dark_orchid-  , dark_red-  , dark_salmon-  , dark_sea_green-  , dark_slate_blue-  , dark_slate_gray-  , dark_slate_grey-  , dark_turquoise-  , dark_violet-  , deep_pink-  , deep_sky_blue-  , dim_gray-  , dim_grey-  , dodger_blue-  , firebrick-  , floral_white-  , forest_green-  , fuchsia-  , gainsboro-  , ghost_white-  , gold-  , goldenrod-  , gray-  , grey-  , green-  , green_yellow-  , honeydew-  , hot_pink-  , indian_red-  , indigo-  , ivory-  , khaki-  , lavender-  , lavender_blush-  , lawn_green-  , lemon_chiffon-  , light_blue-  , light_coral-  , light_cyan-  , light_goldenrod_yellow-  , light_gray-  , light_green-  , light_grey-  , light_pink-  , light_salmon-  , light_sea_green-  , light_sky_blue-  , light_slate_gray-  , light_slate_grey-  , light_steel_blue-  , light_yellow-  , lime-  , lime_green-  , linen-  , magenta-  , maroon-  , medium_aquamarine-  , medium_blue-  , medium_orchid-  , medium_purple-  , medium_sea_green-  , medium_slate_blue-  , medium_spring_green-  , medium_turquoise-  , medium_violet_red-  , midnight_blue-  , mintcream-  , mistyrose-  , moccasin-  , navajo_white-  , navy-  , old_lace-  , olive-  , olive_drab-  , orange-  , orange_red-  , orchid-  , pale_goldenrod-  , pale_green-  , pale_turquoise-  , pale_violet_red-  , papaya_whip-  , peach_puff-  , peru-  , pink-  , plum-  , powder_blue-  , purple-  , red-  , rosy_brown-  , royal_blue-  , saddle_brown-  , salmon-  , sandy_brown-  , sea_green-  , seashell-  , sienna-  , silver-  , sky_blue-  , slate_blue-  , slate_gray-  , slate_grey-  , snow-  , spring_green-  , steel_blue-  , tan-  , teal-  , thistle-  , tomato-  , turquoise-  , violet-  , wheat-  , white-  , whitesmoke-  , yellow-  , yellow_green-  -  ) where---import Wumpus.Core.Colour ( RGBi(..) )---import Prelude ( )-  ------------------------------------------------------------------------------------  -alice_blue              :: RGBi-alice_blue              = RGBi 0xf0 0xf8 0xff--antique_white           :: RGBi -antique_white           = RGBi 0xfa 0xeb 0xd7--aqua                    :: RGBi-aqua                    = RGBi 0x00 0xff 0xff--aquamarine              :: RGBi-aquamarine              = RGBi 0x7f 0xff 0xd4--azure                   :: RGBi-azure                   = RGBi 0xf0 0xff 0xff--beige                   :: RGBi-beige                   = RGBi 0xf5 0xf5 0xdc--bisque                  :: RGBi-bisque                  = RGBi 0xff 0xe4 0xc4--black                   :: RGBi-black                   = RGBi 0x00 0x00 0x00--blanched_almond         :: RGBi-blanched_almond         = RGBi 0xff 0xeb 0xcd--blue                    :: RGBi-blue                    = RGBi 0x00 0x00 0xff--blue_violet             :: RGBi-blue_violet             = RGBi 0x8a 0x2b 0xe2--brown                   :: RGBi-brown                   = RGBi 0xa5 0x2a 0x2a--burlywood               :: RGBi-burlywood               = RGBi 0xde 0xb8 0x87--cadet_blue              :: RGBi-cadet_blue              = RGBi 0x5f 0x9e 0xa0--chartreuse              :: RGBi-chartreuse              = RGBi 0x7f 0xff 0x00--chocolate               :: RGBi-chocolate               = RGBi 0xd2 0x69 0x1e--coral                   :: RGBi-coral                   = RGBi 0xff 0x7f 0x50--cornflower_blue         :: RGBi-cornflower_blue         = RGBi 0x64 0x95 0xed--cornsilk                :: RGBi-cornsilk                = RGBi 0xff 0xf8 0xdc--crimson                 :: RGBi-crimson                 = RGBi 0xdc 0x14 0x3c--cyan                    :: RGBi-cyan                    = RGBi 0x00 0xff 0xff--dark_blue               :: RGBi-dark_blue               = RGBi 0x00 0x00 0x8b--dark_cyan               :: RGBi-dark_cyan               = RGBi 0x00 0x8b 0x8b--dark_goldenrod          :: RGBi-dark_goldenrod          = RGBi 0xb8 0x86 0x0b--dark_gray               :: RGBi-dark_gray               = RGBi 0xa9 0xa9 0xa9--dark_green              :: RGBi-dark_green              = RGBi 0x00 0x64 0x00--dark_grey               :: RGBi-dark_grey               = RGBi 0xa9 0xa9 0xa9--dark_khaki              :: RGBi-dark_khaki              = RGBi 0xbd 0xb7 0x6b--dark_magenta            :: RGBi-dark_magenta            = RGBi 0x8b 0x00 0x8b--dark_olive_green        :: RGBi-dark_olive_green        = RGBi 0x55 0x6b 0x2f--dark_orange             :: RGBi-dark_orange             = RGBi 0xff 0x8c 0x00--dark_orchid             :: RGBi-dark_orchid             = RGBi 0x99 0x32 0xcc--dark_red                :: RGBi-dark_red                = RGBi 0x8b 0x00 0x00--dark_salmon             :: RGBi-dark_salmon             = RGBi 0xe9 0x96 0x7a--dark_sea_green          :: RGBi-dark_sea_green          = RGBi 0x8f 0xbc 0x8f--dark_slate_blue         :: RGBi-dark_slate_blue         = RGBi 0x48 0x3d 0x8b--dark_slate_gray         :: RGBi-dark_slate_gray         = RGBi 0x2f 0x4f 0x4f--dark_slate_grey         :: RGBi-dark_slate_grey         = RGBi 0x2f 0x4f 0x4f--dark_turquoise          :: RGBi-dark_turquoise          = RGBi 0x00 0xce 0xd1--dark_violet             :: RGBi-dark_violet             = RGBi 0x94 0x00 0xd3--deep_pink               :: RGBi-deep_pink               = RGBi 0xff 0x14 0x93--deep_sky_blue           :: RGBi-deep_sky_blue           = RGBi 0x00 0xbf 0xff--dim_gray                :: RGBi-dim_gray                = RGBi 0x69 0x69 0x69--dim_grey                :: RGBi-dim_grey                = RGBi 0x69 0x69 0x69--dodger_blue             :: RGBi-dodger_blue             = RGBi 0x1e 0x90 0xff--firebrick               :: RGBi-firebrick               = RGBi 0xb2 0x22 0x22--floral_white            :: RGBi-floral_white            = RGBi 0xff 0xfa 0xf0--forest_green            :: RGBi-forest_green            = RGBi 0x22 0x8b 0x22--fuchsia                 :: RGBi-fuchsia                 = RGBi 0xff 0x00 0xff--gainsboro               :: RGBi-gainsboro               = RGBi 0xdc 0xdc 0xdc--ghost_white             :: RGBi-ghost_white             = RGBi 0xf8 0xf8 0xff--gold                    :: RGBi-gold                    = RGBi 0xff 0xd7 0x00--goldenrod               :: RGBi-goldenrod               = RGBi 0xda 0xa5 0x20--gray                    :: RGBi-gray                    = RGBi 0x80 0x80 0x80--green                   :: RGBi-green                   = RGBi 0x00 0x80 0x00--green_yellow            :: RGBi-green_yellow            = RGBi 0xad 0xff 0x2f--grey                    :: RGBi-grey                    = RGBi 0x80 0x80 0x80--honeydew                :: RGBi-honeydew                = RGBi 0xf0 0xff 0xf0--hot_pink                :: RGBi-hot_pink                = RGBi 0xff 0x69 0xb4--indian_red              :: RGBi-indian_red              = RGBi 0xcd 0x5c 0x5c--indigo                  :: RGBi-indigo                  = RGBi 0x4b 0x00 0x82--ivory                   :: RGBi-ivory                   = RGBi 0xff 0xff 0xf0--khaki                   :: RGBi-khaki                   = RGBi 0xf0 0xe6 0x8c--lavender                :: RGBi-lavender                = RGBi 0xe6 0xe6 0xfa--lavender_blush          :: RGBi-lavender_blush          = RGBi 0xff 0xf0 0xf5--lawn_green              :: RGBi-lawn_green              = RGBi 0x7c 0xfc 0x00--lemon_chiffon           :: RGBi-lemon_chiffon           = RGBi 0xff 0xfa 0xcd--light_blue              :: RGBi-light_blue              = RGBi 0xad 0xd8 0xe6--light_coral             :: RGBi-light_coral             = RGBi 0xf0 0x80 0x80--light_cyan              :: RGBi-light_cyan              = RGBi 0xe0 0xff 0xff--light_goldenrod_yellow  :: RGBi-light_goldenrod_yellow  = RGBi 0xfa 0xfa 0xd2--light_gray              :: RGBi-light_gray              = RGBi 0xd3 0xd3 0xd3--light_green             :: RGBi-light_green             = RGBi 0x90 0xee 0x90--light_grey              :: RGBi-light_grey              = RGBi 0xd3 0xd3 0xd3--light_pink              :: RGBi-light_pink              = RGBi 0xff 0xb6 0xc1--light_salmon            :: RGBi-light_salmon            = RGBi 0xff 0xa0 0x7a--light_sea_green         :: RGBi-light_sea_green         = RGBi 0x20 0xb2 0xaa--light_sky_blue          :: RGBi-light_sky_blue          = RGBi 0x87 0xce 0xfa--light_slate_gray        :: RGBi-light_slate_gray        = RGBi 0x77 0x88 0x99--light_slate_grey        :: RGBi-light_slate_grey        = RGBi 0x77 0x88 0x99--light_steel_blue        :: RGBi-light_steel_blue        = RGBi 0xb0 0xc4 0xde--light_yellow            :: RGBi-light_yellow            = RGBi 0xff 0xff 0xe0--lime                    :: RGBi-lime                    = RGBi 0x00 0xff 0x00--lime_green              :: RGBi-lime_green              = RGBi 0x32 0xcd 0x32--linen                   :: RGBi-linen                   = RGBi 0xfa 0xf0 0xe6--magenta                 :: RGBi-magenta                 = RGBi 0xff 0x00 0xff--maroon                  :: RGBi-maroon                  = RGBi 0x80 0x00 0x00--medium_aquamarine       :: RGBi-medium_aquamarine       = RGBi 0x66 0xcd 0xaa--medium_blue             :: RGBi-medium_blue             = RGBi 0x00 0x00 0xcd--medium_orchid           :: RGBi-medium_orchid           = RGBi 0xba 0x55 0xd3--medium_purple           :: RGBi-medium_purple           = RGBi 0x93 0x70 0xdb--medium_sea_green        :: RGBi-medium_sea_green        = RGBi 0x3c 0xb3 0x71--medium_slate_blue       :: RGBi-medium_slate_blue       = RGBi 0x7b 0x68 0xee--medium_spring_green     :: RGBi-medium_spring_green     = RGBi 0x00 0xfa 0x9a--medium_turquoise        :: RGBi-medium_turquoise        = RGBi 0x48 0xd1 0xcc--medium_violet_red       :: RGBi-medium_violet_red       = RGBi 0xc7 0x15 0x85--midnight_blue           :: RGBi-midnight_blue           = RGBi 0x19 0x19 0x70--mintcream               :: RGBi-mintcream               = RGBi 0xf5 0xff 0xfa--mistyrose               :: RGBi-mistyrose               = RGBi 0xff 0xe4 0xe1--moccasin                :: RGBi-moccasin                = RGBi 0xff 0xe4 0xb5--navajo_white            :: RGBi-navajo_white            = RGBi 0xff 0xde 0xad--navy                    :: RGBi-navy                    = RGBi 0x00 0x00 0x80--old_lace                :: RGBi-old_lace                = RGBi 0xfd 0xf5 0xe6--olive                   :: RGBi-olive                   = RGBi 0x80 0x80 0x00--olive_drab              :: RGBi-olive_drab              = RGBi 0x6b 0x8e 0x23--orange                  :: RGBi-orange                  = RGBi 0xff 0xa5 0x00--orange_red              :: RGBi-orange_red              = RGBi 0xff 0x45 0x00--orchid                  :: RGBi-orchid                  = RGBi 0xda 0x70 0xd6--pale_goldenrod          :: RGBi-pale_goldenrod          = RGBi 0xee 0xe8 0xaa--pale_green              :: RGBi-pale_green              = RGBi 0x98 0xfb 0x98--pale_turquoise          :: RGBi-pale_turquoise          = RGBi 0xaf 0xee 0xee--pale_violet_red         :: RGBi-pale_violet_red         = RGBi 0xdb 0x70 0x93--papaya_whip             :: RGBi-papaya_whip             = RGBi 0xff 0xef 0xd5--peach_puff              :: RGBi-peach_puff              = RGBi 0xff 0xda 0xb9--peru                    :: RGBi-peru                    = RGBi 0xcd 0x85 0x3f--pink                    :: RGBi-pink                    = RGBi 0xff 0xc0 0xcb--plum                    :: RGBi-plum                    = RGBi 0xdd 0xa0 0xdd--powder_blue             :: RGBi-powder_blue             = RGBi 0xb0 0xe0 0xe6--purple                  :: RGBi-purple                  = RGBi 0x80 0x00 0x80--red                     :: RGBi-red                     = RGBi 0xff 0x00 0x00--rosy_brown              :: RGBi-rosy_brown              = RGBi 0xbc 0x8f 0x8f--royal_blue              :: RGBi-royal_blue              = RGBi 0x41 0x69 0xe1--saddle_brown            :: RGBi-saddle_brown            = RGBi 0x8b 0x45 0x13--salmon                  :: RGBi-salmon                  = RGBi 0xfa 0x80 0x72--sandy_brown             :: RGBi-sandy_brown             = RGBi 0xf4 0xa4 0x60--sea_green               :: RGBi-sea_green               = RGBi 0x2e 0x8b 0x57--seashell                :: RGBi-seashell                = RGBi 0xff 0xf5 0xee--sienna                  :: RGBi-sienna                  = RGBi 0xa0 0x52 0x2d--silver                  :: RGBi-silver                  = RGBi 0xc0 0xc0 0xc0--sky_blue                :: RGBi-sky_blue                = RGBi 0x87 0xce 0xeb--slate_blue              :: RGBi-slate_blue              = RGBi 0x6a 0x5a 0xcd--slate_gray              :: RGBi-slate_gray              = RGBi 0x70 0x80 0x90--slate_grey              :: RGBi-slate_grey              = RGBi 0x70 0x80 0x90--snow                    :: RGBi-snow                    = RGBi 0xff 0xfa 0xfa--spring_green            :: RGBi-spring_green            = RGBi 0x00 0xff 0x7f--steel_blue              :: RGBi-steel_blue              = RGBi 0x46 0x82 0xb4--tan                     :: RGBi-tan                     = RGBi 0xd2 0xb4 0x8c--teal                    :: RGBi-teal                    = RGBi 0x00 0x80 0x80--thistle                 :: RGBi-thistle                 = RGBi 0xd8 0xbf 0xd8--tomato                  :: RGBi-tomato                  = RGBi 0xff 0x63 0x47--turquoise               :: RGBi-turquoise               = RGBi 0x40 0xe0 0xd0--violet                  :: RGBi-violet                  = RGBi 0xee 0x82 0xee--wheat                   :: RGBi-wheat                   = RGBi 0xf5 0xde 0xb3--white                   :: RGBi-white                   = RGBi 0xff 0xff 0xff--whitesmoke              :: RGBi-whitesmoke              = RGBi 0xf5 0xf5 0xf5--yellow                  :: RGBi-yellow                  = RGBi 0xff 0xff 0x00--yellow_green            :: RGBi-yellow_green            = RGBi 0x9a 0xcd 0x32-----
− src/Wumpus/Basic/Colour/X11Colours.hs
@@ -1,1282 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Colour.X11Colours--- Copyright   :  (c) Stephen Tetley 2009-2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  unstable--- Portability :  GHC------ The X11 \'named colours\', as rgb [0,1] values --------------------------------------------------------------------------------------module Wumpus.Basic.Colour.X11Colours-  ( -  -  -- * Named X11 colours-    antique_white1-  , antique_white2-  , antique_white3-  , antique_white4-  , aquamarine1-  , aquamarine2-  , aquamarine3-  , aquamarine4-  , azure1-  , azure2-  , azure3-  , azure4-  , bisque1-  , bisque2-  , bisque3-  , bisque4-  , blue1-  , blue2-  , blue3-  , blue4-  , brown1-  , brown2-  , brown3-  , brown4-  , burlywood1-  , burlywood2-  , burlywood3-  , burlywood4-  , cadet_blue1-  , cadet_blue2-  , cadet_blue3-  , cadet_blue4-  , chartreuse1-  , chartreuse2-  , chartreuse3-  , chartreuse4-  , chocolate1-  , chocolate2-  , chocolate3-  , chocolate4-  , coral1-  , coral2-  , coral3-  , coral4-  , cornsilk1-  , cornsilk2-  , cornsilk3-  , cornsilk4-  , cyan1-  , cyan2-  , cyan3-  , cyan4-  , dark_goldenrod1-  , dark_goldenrod2-  , dark_goldenrod3-  , dark_goldenrod4-  , dark_olive_green1-  , dark_olive_green2-  , dark_olive_green3-  , dark_olive_green4-  , dark_orange1-  , dark_orange2-  , dark_orange3-  , dark_orange4-  , dark_orchid1-  , dark_orchid2-  , dark_orchid3-  , dark_orchid4-  , dark_sea_green1-  , dark_sea_green2-  , dark_sea_green3-  , dark_sea_green4-  , dark_slate_gray1-  , dark_slate_gray2-  , dark_slate_gray3-  , dark_slate_gray4-  , deep_pink1-  , deep_pink2-  , deep_pink3-  , deep_pink4-  , deep_sky_blue1-  , deep_sky_blue2-  , deep_sky_blue3-  , deep_sky_blue4-  , dodger_blue1-  , dodger_blue2-  , dodger_blue3-  , dodger_blue4-  , firebrick1-  , firebrick2-  , firebrick3-  , firebrick4-  , gold1-  , gold2-  , gold3-  , gold4-  , goldenrod1-  , goldenrod2-  , goldenrod3-  , goldenrod4-  , green1-  , green2-  , green3-  , green4-  , honeydew1-  , honeydew2-  , honeydew3-  , honeydew4-  , hot_pink1-  , hot_pink2-  , hot_pink3-  , hot_pink4-  , indian_red1-  , indian_red2-  , indian_red3-  , indian_red4-  , ivory1-  , ivory2-  , ivory3-  , ivory4-  , khaki1-  , khaki2-  , khaki3-  , khaki4-  , lavender_blush1-  , lavender_blush2-  , lavender_blush3-  , lavender_blush4-  , lemon_chiffon1-  , lemon_chiffon2-  , lemon_chiffon3-  , lemon_chiffon4-  , light_blue1-  , light_blue2-  , light_blue3-  , light_blue4-  , light_cyan1-  , light_cyan2-  , light_cyan3-  , light_cyan4-  , light_goldenrod1-  , light_goldenrod2-  , light_goldenrod3-  , light_goldenrod4-  , light_pink1-  , light_pink2-  , light_pink3-  , light_pink4-  , light_salmon1-  , light_salmon2-  , light_salmon3-  , light_salmon4-  , light_sky_blue1-  , light_sky_blue2-  , light_sky_blue3-  , light_sky_blue4-  , light_steel_blue1-  , light_steel_blue2-  , light_steel_blue3-  , light_steel_blue4-  , light_yellow1-  , light_yellow2-  , light_yellow3-  , light_yellow4-  , magenta1-  , magenta2-  , magenta3-  , magenta4-  , maroon1-  , maroon2-  , maroon3-  , maroon4-  , medium_orchid1-  , medium_orchid2-  , medium_orchid3-  , medium_orchid4-  , medium_purple1-  , medium_purple2-  , medium_purple3-  , medium_purple4-  , misty_rose1-  , misty_rose2-  , misty_rose3-  , misty_rose4-  , navajo_white1-  , navajo_white2-  , navajo_white3-  , navajo_white4-  , olive_drab1-  , olive_drab2-  , olive_drab3-  , olive_drab4-  , orange1-  , orange2-  , orange3-  , orange4-  , orange_red1-  , orange_red2-  , orange_red3-  , orange_red4-  , orchid1-  , orchid2-  , orchid3-  , orchid4-  , pale_green1-  , pale_green2-  , pale_green3-  , pale_green4-  , pale_turquoise1-  , pale_turquoise2-  , pale_turquoise3-  , pale_turquoise4-  , pale_violet_red1-  , pale_violet_red2-  , pale_violet_red3-  , pale_violet_red4-  , peach_puff1-  , peach_puff2-  , peach_puff3-  , peach_puff4-  , pink1-  , pink2-  , pink3-  , pink4-  , plum1-  , plum2-  , plum3-  , plum4-  , purple1-  , purple2-  , purple3-  , purple4-  , red1-  , red2-  , red3-  , red4-  , rosy_brown1-  , rosy_brown2-  , rosy_brown3-  , rosy_brown4-  , royal_blue1-  , royal_blue2-  , royal_blue3-  , royal_blue4-  , salmon1-  , salmon2-  , salmon3-  , salmon4-  , sea_green1-  , sea_green2-  , sea_green3-  , sea_green4-  , seashell1-  , seashell2-  , seashell3-  , seashell4-  , sienna1-  , sienna2-  , sienna3-  , sienna4-  , sky_blue1-  , sky_blue2-  , sky_blue3-  , sky_blue4-  , slate_blue1-  , slate_blue2-  , slate_blue3-  , slate_blue4-  , slate_gray1-  , slate_gray2-  , slate_gray3-  , slate_gray4-  , snow1-  , snow2-  , snow3-  , snow4-  , spring_green1-  , spring_green2-  , spring_green3-  , spring_green4-  , steel_blue1-  , steel_blue2-  , steel_blue3-  , steel_blue4-  , tan1-  , tan2-  , tan3-  , tan4-  , thistle1-  , thistle2-  , thistle3-  , thistle4-  , tomato1-  , tomato2-  , tomato3-  , tomato4-  , turquoise1-  , turquoise2-  , turquoise3-  , turquoise4-  , violet_red1-  , violet_red2-  , violet_red3-  , violet_red4-  , wheat1-  , wheat2-  , wheat3-  , wheat4-  , yellow1-  , yellow2-  , yellow3-  , yellow4--  ) where--import Wumpus.Core.Colour ( RGBi(..) )-------------------------------------------------------------------------------------antique_white1          :: RGBi-antique_white1          = RGBi 0xff 0xef 0xdb--antique_white2          :: RGBi-antique_white2          = RGBi 0xee 0xdf 0xcc--antique_white3          :: RGBi-antique_white3          = RGBi 0xcd 0xc0 0xb0--antique_white4          :: RGBi-antique_white4          = RGBi 0x8b 0x83 0x78--aquamarine1             :: RGBi-aquamarine1             = RGBi 0x7f 0xff 0xd4--aquamarine2             :: RGBi-aquamarine2             = RGBi 0x76 0xee 0xc6--aquamarine3             :: RGBi-aquamarine3             = RGBi 0x66 0xcd 0xaa--aquamarine4             :: RGBi-aquamarine4             = RGBi 0x45 0x8b 0x74--azure1                  :: RGBi-azure1                  = RGBi 0xf0 0xff 0xff--azure2                  :: RGBi-azure2                  = RGBi 0xe0 0xee 0xee--azure3                  :: RGBi-azure3                  = RGBi 0xc1 0xcd 0xcd--azure4                  :: RGBi-azure4                  = RGBi 0x83 0x8b 0x8b--bisque1                 :: RGBi-bisque1                 = RGBi 0xff 0xe4 0xc4--bisque2                 :: RGBi-bisque2                 = RGBi 0xee 0xd5 0xb7--bisque3                 :: RGBi-bisque3                 = RGBi 0xcd 0xb7 0x9e--bisque4                 :: RGBi-bisque4                 = RGBi 0x8b 0x7d 0x6b--blue1                   :: RGBi-blue1                   = RGBi 0x00 0x00 0xff--blue2                   :: RGBi-blue2                   = RGBi 0x00 0x00 0xee--blue3                   :: RGBi-blue3                   = RGBi 0x00 0x00 0xcd--blue4                   :: RGBi-blue4                   = RGBi 0x00 0x00 0x8b--brown1                  :: RGBi-brown1                  = RGBi 0xff 0x40 0x40--brown2                  :: RGBi-brown2                  = RGBi 0xee 0x3b 0x3b--brown3                  :: RGBi-brown3                  = RGBi 0xcd 0x33 0x33--brown4                  :: RGBi-brown4                  = RGBi 0x8b 0x23 0x23--burlywood1              :: RGBi-burlywood1              = RGBi 0xff 0xd3 0x9b--burlywood2              :: RGBi-burlywood2              = RGBi 0xee 0xc5 0x91--burlywood3              :: RGBi-burlywood3              = RGBi 0xcd 0xaa 0x7d--burlywood4              :: RGBi-burlywood4              = RGBi 0x8b 0x73 0x55--cadet_blue1             :: RGBi-cadet_blue1             = RGBi 0x98 0xf5 0xff--cadet_blue2             :: RGBi-cadet_blue2             = RGBi 0x8e 0xe5 0xee--cadet_blue3             :: RGBi-cadet_blue3             = RGBi 0x7a 0xc5 0xcd--cadet_blue4             :: RGBi-cadet_blue4             = RGBi 0x53 0x86 0x8b--chartreuse1             :: RGBi-chartreuse1             = RGBi 0x7f 0xff 0x00--chartreuse2             :: RGBi-chartreuse2             = RGBi 0x76 0xee 0x00--chartreuse3             :: RGBi-chartreuse3             = RGBi 0x66 0xcd 0x00--chartreuse4             :: RGBi-chartreuse4             = RGBi 0x45 0x8b 0x00--chocolate1              :: RGBi-chocolate1              = RGBi 0xff 0x7f 0x24--chocolate2              :: RGBi-chocolate2              = RGBi 0xee 0x76 0x21--chocolate3              :: RGBi-chocolate3              = RGBi 0xcd 0x66 0x1d--chocolate4              :: RGBi-chocolate4              = RGBi 0x8b 0x45 0x13--coral1                  :: RGBi-coral1                  = RGBi 0xff 0x72 0x56--coral2                  :: RGBi-coral2                  = RGBi 0xee 0x6a 0x50--coral3                  :: RGBi-coral3                  = RGBi 0xcd 0x5b 0x45--coral4                  :: RGBi-coral4                  = RGBi 0x8b 0x3e 0x2f--cornsilk1               :: RGBi-cornsilk1               = RGBi 0xff 0xf8 0xdc--cornsilk2               :: RGBi-cornsilk2               = RGBi 0xee 0xe8 0xcd--cornsilk3               :: RGBi-cornsilk3               = RGBi 0xcd 0xc8 0xb1--cornsilk4               :: RGBi-cornsilk4               = RGBi 0x8b 0x88 0x78--cyan1                   :: RGBi-cyan1                   = RGBi 0x00 0xff 0xff--cyan2                   :: RGBi-cyan2                   = RGBi 0x00 0xee 0xee--cyan3                   :: RGBi-cyan3                   = RGBi 0x00 0xcd 0xcd--cyan4                   :: RGBi-cyan4                   = RGBi 0x00 0x8b 0x8b--dark_goldenrod1         :: RGBi-dark_goldenrod1         = RGBi 0xff 0xb9 0x0f--dark_goldenrod2         :: RGBi-dark_goldenrod2         = RGBi 0xee 0xad 0x0e--dark_goldenrod3         :: RGBi-dark_goldenrod3         = RGBi 0xcd 0x95 0x0c--dark_goldenrod4         :: RGBi-dark_goldenrod4         = RGBi 0x8b 0x65 0x08--dark_olive_green1       :: RGBi-dark_olive_green1       = RGBi 0xca 0xff 0x70--dark_olive_green2       :: RGBi-dark_olive_green2       = RGBi 0xbc 0xee 0x68--dark_olive_green3       :: RGBi-dark_olive_green3       = RGBi 0xa2 0xcd 0x5a--dark_olive_green4       :: RGBi-dark_olive_green4       = RGBi 0x6e 0x8b 0x3d--dark_orange1            :: RGBi-dark_orange1            = RGBi 0xff 0x7f 0x00--dark_orange2            :: RGBi-dark_orange2            = RGBi 0xee 0x76 0x00--dark_orange3            :: RGBi-dark_orange3            = RGBi 0xcd 0x66 0x00--dark_orange4            :: RGBi-dark_orange4            = RGBi 0x8b 0x45 0x00--dark_orchid1            :: RGBi-dark_orchid1            = RGBi 0xbf 0x3e 0xff--dark_orchid2            :: RGBi-dark_orchid2            = RGBi 0xb2 0x3a 0xee--dark_orchid3            :: RGBi-dark_orchid3            = RGBi 0x9a 0x32 0xcd--dark_orchid4            :: RGBi-dark_orchid4            = RGBi 0x68 0x22 0x8b--dark_sea_green1         :: RGBi-dark_sea_green1         = RGBi 0xc1 0xff 0xc1--dark_sea_green2         :: RGBi-dark_sea_green2         = RGBi 0xb4 0xee 0xb4--dark_sea_green3         :: RGBi-dark_sea_green3         = RGBi 0x9b 0xcd 0x9b--dark_sea_green4         :: RGBi-dark_sea_green4         = RGBi 0x69 0x8b 0x69--dark_slate_gray1        :: RGBi-dark_slate_gray1        = RGBi 0x97 0xff 0xff--dark_slate_gray2        :: RGBi-dark_slate_gray2        = RGBi 0x8d 0xee 0xee--dark_slate_gray3        :: RGBi-dark_slate_gray3        = RGBi 0x79 0xcd 0xcd--dark_slate_gray4        :: RGBi-dark_slate_gray4        = RGBi 0x52 0x8b 0x8b--deep_pink1              :: RGBi-deep_pink1              = RGBi 0xff 0x14 0x93--deep_pink2              :: RGBi-deep_pink2              = RGBi 0xee 0x12 0x89--deep_pink3              :: RGBi-deep_pink3              = RGBi 0xcd 0x10 0x76--deep_pink4              :: RGBi-deep_pink4              = RGBi 0x8b 0x0a 0x50--deep_sky_blue1          :: RGBi-deep_sky_blue1          = RGBi 0x00 0xbf 0xff--deep_sky_blue2          :: RGBi-deep_sky_blue2          = RGBi 0x00 0xb2 0xee--deep_sky_blue3          :: RGBi-deep_sky_blue3          = RGBi 0x00 0x9a 0xcd--deep_sky_blue4          :: RGBi-deep_sky_blue4          = RGBi 0x00 0x68 0x8b--dodger_blue1            :: RGBi-dodger_blue1            = RGBi 0x1e 0x90 0xff--dodger_blue2            :: RGBi-dodger_blue2            = RGBi 0x1c 0x86 0xee--dodger_blue3            :: RGBi-dodger_blue3            = RGBi 0x18 0x74 0xcd--dodger_blue4            :: RGBi-dodger_blue4            = RGBi 0x10 0x4e 0x8b--firebrick1              :: RGBi-firebrick1              = RGBi 0xff 0x30 0x30--firebrick2              :: RGBi-firebrick2              = RGBi 0xee 0x2c 0x2c--firebrick3              :: RGBi-firebrick3              = RGBi 0xcd 0x26 0x26--firebrick4              :: RGBi-firebrick4              = RGBi 0x8b 0x1a 0x1a--gold1                   :: RGBi-gold1                   = RGBi 0xff 0xd7 0x00--gold2                   :: RGBi-gold2                   = RGBi 0xee 0xc9 0x00--gold3                   :: RGBi-gold3                   = RGBi 0xcd 0xad 0x00--gold4                   :: RGBi-gold4                   = RGBi 0x8b 0x75 0x00--goldenrod1              :: RGBi-goldenrod1              = RGBi 0xff 0xc1 0x25--goldenrod2              :: RGBi-goldenrod2              = RGBi 0xee 0xb4 0x22--goldenrod3              :: RGBi-goldenrod3              = RGBi 0xcd 0x9b 0x1d--goldenrod4              :: RGBi-goldenrod4              = RGBi 0x8b 0x69 0x14--green1                  :: RGBi-green1                  = RGBi 0x00 0xff 0x00--green2                  :: RGBi-green2                  = RGBi 0x00 0xee 0x00--green3                  :: RGBi-green3                  = RGBi 0x00 0xcd 0x00--green4                  :: RGBi-green4                  = RGBi 0x00 0x8b 0x00--honeydew1               :: RGBi-honeydew1               = RGBi 0xf0 0xff 0xf0--honeydew2               :: RGBi-honeydew2               = RGBi 0xe0 0xee 0xe0--honeydew3               :: RGBi-honeydew3               = RGBi 0xc1 0xcd 0xc1--honeydew4               :: RGBi-honeydew4               = RGBi 0x83 0x8b 0x83--hot_pink1               :: RGBi-hot_pink1               = RGBi 0xff 0x6e 0xb4--hot_pink2               :: RGBi-hot_pink2               = RGBi 0xee 0x6a 0xa7--hot_pink3               :: RGBi-hot_pink3               = RGBi 0xcd 0x60 0x90--hot_pink4               :: RGBi-hot_pink4               = RGBi 0x8b 0x3a 0x62--indian_red1             :: RGBi-indian_red1             = RGBi 0xff 0x6a 0x6a--indian_red2             :: RGBi-indian_red2             = RGBi 0xee 0x63 0x63--indian_red3             :: RGBi-indian_red3             = RGBi 0xcd 0x55 0x55--indian_red4             :: RGBi-indian_red4             = RGBi 0x8b 0x3a 0x3a--ivory1                  :: RGBi-ivory1                  = RGBi 0xff 0xff 0xf0--ivory2                  :: RGBi-ivory2                  = RGBi 0xee 0xee 0xe0--ivory3                  :: RGBi-ivory3                  = RGBi 0xcd 0xcd 0xc1--ivory4                  :: RGBi-ivory4                  = RGBi 0x8b 0x8b 0x83--khaki1                  :: RGBi-khaki1                  = RGBi 0xff 0xf6 0x8f--khaki2                  :: RGBi-khaki2                  = RGBi 0xee 0xe6 0x85--khaki3                  :: RGBi-khaki3                  = RGBi 0xcd 0xc6 0x73--khaki4                  :: RGBi-khaki4                  = RGBi 0x8b 0x86 0x4e--lavender_blush1         :: RGBi-lavender_blush1         = RGBi 0xff 0xf0 0xf5--lavender_blush2         :: RGBi-lavender_blush2         = RGBi 0xee 0xe0 0xe5--lavender_blush3         :: RGBi-lavender_blush3         = RGBi 0xcd 0xc1 0xc5--lavender_blush4         :: RGBi-lavender_blush4         = RGBi 0x8b 0x83 0x86--lemon_chiffon1          :: RGBi-lemon_chiffon1          = RGBi 0xff 0xfa 0xcd--lemon_chiffon2          :: RGBi-lemon_chiffon2          = RGBi 0xee 0xe9 0xbf--lemon_chiffon3          :: RGBi-lemon_chiffon3          = RGBi 0xcd 0xc9 0xa5--lemon_chiffon4          :: RGBi-lemon_chiffon4          = RGBi 0x8b 0x89 0x70--light_blue1             :: RGBi-light_blue1             = RGBi 0xbf 0xef 0xff--light_blue2             :: RGBi-light_blue2             = RGBi 0xb2 0xdf 0xee--light_blue3             :: RGBi-light_blue3             = RGBi 0x9a 0xc0 0xcd--light_blue4             :: RGBi-light_blue4             = RGBi 0x68 0x83 0x8b--light_cyan1             :: RGBi-light_cyan1             = RGBi 0xe0 0xff 0xff--light_cyan2             :: RGBi-light_cyan2             = RGBi 0xd1 0xee 0xee--light_cyan3             :: RGBi-light_cyan3             = RGBi 0xb4 0xcd 0xcd--light_cyan4             :: RGBi-light_cyan4             = RGBi 0x7a 0x8b 0x8b--light_goldenrod1        :: RGBi-light_goldenrod1        = RGBi 0xff 0xec 0x8b--light_goldenrod2        :: RGBi-light_goldenrod2        = RGBi 0xee 0xdc 0x82--light_goldenrod3        :: RGBi-light_goldenrod3        = RGBi 0xcd 0xbe 0x70--light_goldenrod4        :: RGBi-light_goldenrod4        = RGBi 0x8b 0x81 0x4c--light_pink1             :: RGBi-light_pink1             = RGBi 0xff 0xae 0xb9--light_pink2             :: RGBi-light_pink2             = RGBi 0xee 0xa2 0xad--light_pink3             :: RGBi-light_pink3             = RGBi 0xcd 0x8c 0x95--light_pink4             :: RGBi-light_pink4             = RGBi 0x8b 0x5f 0x65--light_salmon1           :: RGBi-light_salmon1           = RGBi 0xff 0xa0 0x7a--light_salmon2           :: RGBi-light_salmon2           = RGBi 0xee 0x95 0x72--light_salmon3           :: RGBi-light_salmon3           = RGBi 0xcd 0x81 0x62--light_salmon4           :: RGBi-light_salmon4           = RGBi 0x8b 0x57 0x42--light_sky_blue1         :: RGBi-light_sky_blue1         = RGBi 0xb0 0xe2 0xff--light_sky_blue2         :: RGBi-light_sky_blue2         = RGBi 0xa4 0xd3 0xee--light_sky_blue3         :: RGBi-light_sky_blue3         = RGBi 0x8d 0xb6 0xcd--light_sky_blue4         :: RGBi-light_sky_blue4         = RGBi 0x60 0x7b 0x8b--light_steel_blue1       :: RGBi-light_steel_blue1       = RGBi 0xca 0xe1 0xff--light_steel_blue2       :: RGBi-light_steel_blue2       = RGBi 0xbc 0xd2 0xee--light_steel_blue3       :: RGBi-light_steel_blue3       = RGBi 0xa2 0xb5 0xcd--light_steel_blue4       :: RGBi-light_steel_blue4       = RGBi 0x6e 0x7b 0x8b--light_yellow1           :: RGBi-light_yellow1           = RGBi 0xff 0xff 0xe0--light_yellow2           :: RGBi-light_yellow2           = RGBi 0xee 0xee 0xd1--light_yellow3           :: RGBi-light_yellow3           = RGBi 0xcd 0xcd 0xb4--light_yellow4           :: RGBi-light_yellow4           = RGBi 0x8b 0x8b 0x7a--magenta1                :: RGBi-magenta1                = RGBi 0xff 0x00 0xff--magenta2                :: RGBi-magenta2                = RGBi 0xee 0x00 0xee--magenta3                :: RGBi-magenta3                = RGBi 0xcd 0x00 0xcd--magenta4                :: RGBi-magenta4                = RGBi 0x8b 0x00 0x8b--maroon1                 :: RGBi-maroon1                 = RGBi 0xff 0x34 0xb3--maroon2                 :: RGBi-maroon2                 = RGBi 0xee 0x30 0xa7--maroon3                 :: RGBi-maroon3                 = RGBi 0xcd 0x29 0x90--maroon4                 :: RGBi-maroon4                 = RGBi 0x8b 0x1c 0x62--medium_orchid1          :: RGBi-medium_orchid1          = RGBi 0xe0 0x66 0xff--medium_orchid2          :: RGBi-medium_orchid2          = RGBi 0xd1 0x5f 0xee--medium_orchid3          :: RGBi-medium_orchid3          = RGBi 0xb4 0x52 0xcd--medium_orchid4          :: RGBi-medium_orchid4          = RGBi 0x7a 0x37 0x8b--medium_purple1          :: RGBi-medium_purple1          = RGBi 0xab 0x82 0xff--medium_purple2          :: RGBi-medium_purple2          = RGBi 0x9f 0x79 0xee--medium_purple3          :: RGBi-medium_purple3          = RGBi 0x89 0x68 0xcd--medium_purple4          :: RGBi-medium_purple4          = RGBi 0x5d 0x47 0x8b--misty_rose1             :: RGBi-misty_rose1             = RGBi 0xff 0xe4 0xe1--misty_rose2             :: RGBi-misty_rose2             = RGBi 0xee 0xd5 0xd2--misty_rose3             :: RGBi-misty_rose3             = RGBi 0xcd 0xb7 0xb5--misty_rose4             :: RGBi-misty_rose4             = RGBi 0x8b 0x7d 0x7b--navajo_white1           :: RGBi-navajo_white1           = RGBi 0xff 0xde 0xad--navajo_white2           :: RGBi-navajo_white2           = RGBi 0xee 0xcf 0xa1--navajo_white3           :: RGBi-navajo_white3           = RGBi 0xcd 0xb3 0x8b--navajo_white4           :: RGBi-navajo_white4           = RGBi 0x8b 0x79 0x5e--olive_drab1             :: RGBi-olive_drab1             = RGBi 0xc0 0xff 0x3e--olive_drab2             :: RGBi-olive_drab2             = RGBi 0xb3 0xee 0x3a--olive_drab3             :: RGBi-olive_drab3             = RGBi 0x9a 0xcd 0x32--olive_drab4             :: RGBi-olive_drab4             = RGBi 0x69 0x8b 0x22--orange1                 :: RGBi-orange1                 = RGBi 0xff 0xa5 0x00--orange2                 :: RGBi-orange2                 = RGBi 0xee 0x9a 0x00--orange3                 :: RGBi-orange3                 = RGBi 0xcd 0x85 0x00--orange4                 :: RGBi-orange4                 = RGBi 0x8b 0x5a 0x00--orange_red1             :: RGBi-orange_red1             = RGBi 0xff 0x45 0x00--orange_red2             :: RGBi-orange_red2             = RGBi 0xee 0x40 0x00--orange_red3             :: RGBi-orange_red3             = RGBi 0xcd 0x37 0x00--orange_red4             :: RGBi-orange_red4             = RGBi 0x8b 0x25 0x00--orchid1                 :: RGBi-orchid1                 = RGBi 0xff 0x83 0xfa--orchid2                 :: RGBi-orchid2                 = RGBi 0xee 0x7a 0xe9--orchid3                 :: RGBi-orchid3                 = RGBi 0xcd 0x69 0xc9--orchid4                 :: RGBi-orchid4                 = RGBi 0x8b 0x47 0x89--pale_green1             :: RGBi-pale_green1             = RGBi 0x9a 0xff 0x9a--pale_green2             :: RGBi-pale_green2             = RGBi 0x90 0xee 0x90--pale_green3             :: RGBi-pale_green3             = RGBi 0x7c 0xcd 0x7c--pale_green4             :: RGBi-pale_green4             = RGBi 0x54 0x8b 0x54--pale_turquoise1         :: RGBi-pale_turquoise1         = RGBi 0xbb 0xff 0xff--pale_turquoise2         :: RGBi-pale_turquoise2         = RGBi 0xae 0xee 0xee--pale_turquoise3         :: RGBi-pale_turquoise3         = RGBi 0x96 0xcd 0xcd--pale_turquoise4         :: RGBi-pale_turquoise4         = RGBi 0x66 0x8b 0x8b--pale_violet_red1        :: RGBi-pale_violet_red1        = RGBi 0xff 0x82 0xab--pale_violet_red2        :: RGBi-pale_violet_red2        = RGBi 0xee 0x79 0x9f--pale_violet_red3        :: RGBi-pale_violet_red3        = RGBi 0xcd 0x68 0x89--pale_violet_red4        :: RGBi-pale_violet_red4        = RGBi 0x8b 0x47 0x5d--peach_puff1             :: RGBi-peach_puff1             = RGBi 0xff 0xda 0xb9--peach_puff2             :: RGBi-peach_puff2             = RGBi 0xee 0xcb 0xad--peach_puff3             :: RGBi-peach_puff3             = RGBi 0xcd 0xaf 0x95--peach_puff4             :: RGBi-peach_puff4             = RGBi 0x8b 0x77 0x65--pink1                   :: RGBi-pink1                   = RGBi 0xff 0xb5 0xc5--pink2                   :: RGBi-pink2                   = RGBi 0xee 0xa9 0xb8--pink3                   :: RGBi-pink3                   = RGBi 0xcd 0x91 0x9e--pink4                   :: RGBi-pink4                   = RGBi 0x8b 0x63 0x6c--plum1                   :: RGBi-plum1                   = RGBi 0xff 0xbb 0xff--plum2                   :: RGBi-plum2                   = RGBi 0xee 0xae 0xee--plum3                   :: RGBi-plum3                   = RGBi 0xcd 0x96 0xcd--plum4                   :: RGBi-plum4                   = RGBi 0x8b 0x66 0x8b--purple1                 :: RGBi-purple1                 = RGBi 0x9b 0x30 0xff--purple2                 :: RGBi-purple2                 = RGBi 0x91 0x2c 0xee--purple3                 :: RGBi-purple3                 = RGBi 0x7d 0x26 0xcd--purple4                 :: RGBi-purple4                 = RGBi 0x55 0x1a 0x8b--red1                    :: RGBi-red1                    = RGBi 0xff 0x00 0x00--red2                    :: RGBi-red2                    = RGBi 0xee 0x00 0x00--red3                    :: RGBi-red3                    = RGBi 0xcd 0x00 0x00--red4                    :: RGBi-red4                    = RGBi 0x8b 0x00 0x00--rosy_brown1             :: RGBi-rosy_brown1             = RGBi 0xff 0xc1 0xc1--rosy_brown2             :: RGBi-rosy_brown2             = RGBi 0xee 0xb4 0xb4--rosy_brown3             :: RGBi-rosy_brown3             = RGBi 0xcd 0x9b 0x9b--rosy_brown4             :: RGBi-rosy_brown4             = RGBi 0x8b 0x69 0x69--royal_blue1             :: RGBi-royal_blue1             = RGBi 0x48 0x76 0xff--royal_blue2             :: RGBi-royal_blue2             = RGBi 0x43 0x6e 0xee--royal_blue3             :: RGBi-royal_blue3             = RGBi 0x3a 0x5f 0xcd--royal_blue4             :: RGBi-royal_blue4             = RGBi 0x27 0x40 0x8b---salmon1                 :: RGBi-salmon1                 = RGBi 0xff 0x8c 0x69--salmon2                 :: RGBi-salmon2                 = RGBi 0xee 0x82 0x62--salmon3                 :: RGBi-salmon3                 = RGBi 0xcd 0x70 0x54--salmon4                 :: RGBi-salmon4                 = RGBi 0x8b 0x4c 0x39--sea_green1              :: RGBi-sea_green1              = RGBi 0x54 0xff 0x9f--sea_green2              :: RGBi-sea_green2              = RGBi 0x4e 0xee 0x94--sea_green3              :: RGBi-sea_green3              = RGBi 0x43 0xcd 0x80--sea_green4              :: RGBi-sea_green4              = RGBi 0x2e 0x8b 0x57--seashell1               :: RGBi-seashell1               = RGBi 0xff 0xf5 0xee--seashell2               :: RGBi-seashell2               = RGBi 0xee 0xe5 0xde--seashell3               :: RGBi-seashell3               = RGBi 0xcd 0xc5 0xbf--seashell4               :: RGBi-seashell4               = RGBi 0x8b 0x86 0x82--sienna1                 :: RGBi-sienna1                 = RGBi 0xff 0x82 0x47--sienna2                 :: RGBi-sienna2                 = RGBi 0xee 0x79 0x42--sienna3                 :: RGBi-sienna3                 = RGBi 0xcd 0x68 0x39--sienna4                 :: RGBi-sienna4                 = RGBi 0x8b 0x47 0x26--sky_blue1               :: RGBi-sky_blue1               = RGBi 0x87 0xce 0xff--sky_blue2               :: RGBi-sky_blue2               = RGBi 0x7e 0xc0 0xee--sky_blue3               :: RGBi-sky_blue3               = RGBi 0x6c 0xa6 0xcd--sky_blue4               :: RGBi-sky_blue4               = RGBi 0x4a 0x70 0x8b--slate_blue1             :: RGBi-slate_blue1             = RGBi 0x83 0x6f 0xff--slate_blue2             :: RGBi-slate_blue2             = RGBi 0x7a 0x67 0xee--slate_blue3             :: RGBi-slate_blue3             = RGBi 0x69 0x59 0xcd--slate_blue4             :: RGBi-slate_blue4             = RGBi 0x47 0x3c 0x8b--slate_gray1             :: RGBi-slate_gray1             = RGBi 0xc6 0xe2 0xff--slate_gray2             :: RGBi-slate_gray2             = RGBi 0xb9 0xd3 0xee--slate_gray3             :: RGBi-slate_gray3             = RGBi 0x9f 0xb6 0xcd--slate_gray4             :: RGBi-slate_gray4             = RGBi 0x6c 0x7b 0x8b--snow1                   :: RGBi-snow1                   = RGBi 0xff 0xfa 0xfa--snow2                   :: RGBi-snow2                   = RGBi 0xee 0xe9 0xe9--snow3                   :: RGBi-snow3                   = RGBi 0xcd 0xc9 0xc9--snow4                   :: RGBi-snow4                   = RGBi 0x8b 0x89 0x89--spring_green1           :: RGBi-spring_green1           = RGBi 0x00 0xff 0x7f--spring_green2           :: RGBi-spring_green2           = RGBi 0x00 0xee 0x76--spring_green3           :: RGBi-spring_green3           = RGBi 0x00 0xcd 0x66--spring_green4           :: RGBi-spring_green4           = RGBi 0x00 0x8b 0x45--steel_blue1             :: RGBi-steel_blue1             = RGBi 0x63 0xb8 0xff--steel_blue2             :: RGBi-steel_blue2             = RGBi 0x5c 0xac 0xee--steel_blue3             :: RGBi-steel_blue3             = RGBi 0x4f 0x94 0xcd--steel_blue4             :: RGBi-steel_blue4             = RGBi 0x36 0x64 0x8b--tan1                    :: RGBi-tan1                    = RGBi 0xff 0xa5 0x4f--tan2                    :: RGBi-tan2                    = RGBi 0xee 0x9a 0x49--tan3                    :: RGBi-tan3                    = RGBi 0xcd 0x85 0x3f--tan4                    :: RGBi-tan4                    = RGBi 0x8b 0x5a 0x2b--thistle1                :: RGBi-thistle1                = RGBi 0xff 0xe1 0xff--thistle2                :: RGBi-thistle2                = RGBi 0xee 0xd2 0xee--thistle3                :: RGBi-thistle3                = RGBi 0xcd 0xb5 0xcd--thistle4                :: RGBi-thistle4                = RGBi 0x8b 0x7b 0x8b--tomato1                 :: RGBi-tomato1                 = RGBi 0xff 0x63 0x47--tomato2                 :: RGBi-tomato2                 = RGBi 0xee 0x5c 0x42--tomato3                 :: RGBi-tomato3                 = RGBi 0xcd 0x4f 0x39--tomato4                 :: RGBi-tomato4                 = RGBi 0x8b 0x36 0x26--turquoise1              :: RGBi-turquoise1              = RGBi 0x00 0xf5 0xff--turquoise2              :: RGBi-turquoise2              = RGBi 0x00 0xe5 0xee--turquoise3              :: RGBi-turquoise3              = RGBi 0x00 0xc5 0xcd--turquoise4              :: RGBi-turquoise4              = RGBi 0x00 0x86 0x8b--violet_red1             :: RGBi-violet_red1             = RGBi 0xff 0x3e 0x96--violet_red2             :: RGBi-violet_red2             = RGBi 0xee 0x3a 0x8c--violet_red3             :: RGBi-violet_red3             = RGBi 0xcd 0x32 0x78--violet_red4             :: RGBi-violet_red4             = RGBi 0x8b 0x22 0x52--wheat1                  :: RGBi-wheat1                  = RGBi 0xff 0xe7 0xba--wheat2                  :: RGBi-wheat2                  = RGBi 0xee 0xd8 0xae--wheat3                  :: RGBi-wheat3                  = RGBi 0xcd 0xba 0x96--wheat4                  :: RGBi-wheat4                  = RGBi 0x8b 0x7e 0x66--yellow1                 :: RGBi-yellow1                 = RGBi 0xff 0xff 0x00--yellow2                 :: RGBi-yellow2                 = RGBi 0xee 0xee 0x00--yellow3                 :: RGBi-yellow3                 = RGBi 0xcd 0xcd 0x00--yellow4                 :: RGBi-yellow4                 = RGBi 0x8b 0x8b 0x00------
− src/Wumpus/Basic/Dots/AnchorDots.hs
@@ -1,244 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE ExistentialQuantification  #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Dots.AnchorDots--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Dots with anchors.------ In many cases a surrounding circle is used to locate anchor--- points - this could be improved to use the actual dot border --- at some point.--------------------------------------------------------------------------------------module Wumpus.Basic.Dots.AnchorDots-  ( --  -- * Existential anchor type-    DotAnchor- -  , DotLocImage-  , DDotLocImage--  -- * Dots with anchor points-  , dotChar-  , dotText-  , dotHLine-  , dotVLine-  , dotX-  , dotPlus-  , dotCross-  , dotDiamond-  , dotFDiamond--  , dotDisk-  , dotSquare-  , dotCircle-  , dotPentagon-  , dotStar--  , dotAsterisk-  , dotOPlus-  , dotOCross-  , dotFOCross--  ) where--import Wumpus.Basic.Dots.Marks-import Wumpus.Basic.Graphic-import Wumpus.Basic.Text.LRText-import Wumpus.Basic.Utils.Intersection--import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace                         -- package: vector-space------ An existential thing that supports anchors.--- This means any dot can retun the same (opaque) structure------ But it does mean that which anchor class are supported is --- fixed - the datatype needs a field for each one.--- Supporting north, southeast etc. will also be tedious...----data DotAnchor u = forall s.  -                    DotAnchor { center_anchor   :: Point2 u-                              , radial_anchor   :: Radian   -> Point2 u-                              , cardinal_anchor :: Cardinal -> Point2 u }--data Cardinal = NN | NE | EE | SE | SS | SW | WW | NW-  deriving (Eq,Show) --type instance DUnit (DotAnchor u) = u--instance CenterAnchor (DotAnchor u) where-  center (DotAnchor ca _ _) = ca--instance RadialAnchor (DotAnchor u) where-   radialAnchor theta (DotAnchor _ ra _) = ra theta--instance CardinalAnchor (DotAnchor u) where-   north (DotAnchor _ _ c1) = c1 NN-   south (DotAnchor _ _ c1) = c1 SS-   east  (DotAnchor _ _ c1) = c1 EE-   west  (DotAnchor _ _ c1) = c1 WW----instance CardinalAnchor2 (DotAnchor u) where-   northeast (DotAnchor _ _ c1) = c1 NE-   southeast (DotAnchor _ _ c1) = c1 SE-   southwest (DotAnchor _ _ c1) = c1 SW-   northwest (DotAnchor _ _ c1) = c1 NW---radialCardinal :: Floating u => u -> Point2 u ->  Cardinal -> Point2 u-radialCardinal rad ctr NN = ctr .+^ (avec (pi/2)     rad) -radialCardinal rad ctr NE = ctr .+^ (avec (pi/4)     rad) -radialCardinal rad ctr EE = ctr .+^ (avec  0         rad) -radialCardinal rad ctr SE = ctr .+^ (avec (7/4 * pi) rad) -radialCardinal rad ctr SS = ctr .+^ (avec (6/4 * pi) rad) -radialCardinal rad ctr SW = ctr .+^ (avec (5/4 * pi) rad) -radialCardinal rad ctr WW = ctr .+^ (avec  pi        rad) -radialCardinal rad ctr NW = ctr .+^ (avec (3/4 * pi) rad) ----- Rectangle cardinal points are at \"middles and corners\".-----rectCardinal :: Floating u => u ->  u -> Point2 u -> Cardinal -> Point2 u-rectCardinal _  hh ctr NN = ctr .+^ (vvec hh) -rectCardinal hw hh ctr NE = ctr .+^ (vec  hw     hh) -rectCardinal hw _  ctr EE = ctr .+^ (hvec hw) -rectCardinal hw hh ctr SE = ctr .+^ (vec  hw    (-hh)) -rectCardinal _  hh ctr SS = ctr .+^ (vvec (-hh)) -rectCardinal hw hh ctr SW = ctr .+^ (vec  (-hw) (-hh) )-rectCardinal hw _  ctr WW = ctr .+^ (hvec (-hw)) -rectCardinal hw hh ctr NW = ctr .+^ (vec  (-hw)  hh) ---rectangleAnchor :: (Real u, Floating u) => u -> u -> Point2 u -> DotAnchor u-rectangleAnchor hw hh ctr = -    DotAnchor { center_anchor   = ctr-              , radial_anchor   = fn  -              , cardinal_anchor = rectCardinal hw hh ctr }-  where-    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 -> 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-circleAnchor rad ctr = DotAnchor ctr -                                 (\theta -> ctr .+^ (avec theta rad))-                                 (radialCardinal rad ctr)--circleLDO :: (Floating u, FromPtSize u) => LocDrawingInfo u (DotAnchor u)-circleLDO = bind1 (static1 markHeight) $ \diam -> -    promote1 $ \pt -> wrap $ circleAnchor (diam * 0.5) pt--------------------------------------------------------------------------------------type DotLocImage u = LocImage u (DotAnchor u) --type DDotLocImage = DotLocImage Double --dotChar :: (Floating u, Real u, FromPtSize u) -        => Char -> DotLocImage u-dotChar ch = dotText [ch]----- | Note - dots now use font metrics...----dotText :: (Floating u, Real u, FromPtSize u) -        => String -> DotLocImage u -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---dotVLine :: (Floating u, FromPtSize u) => DotLocImage u-dotVLine = intoLocImage circleLDO markVLine---dotX :: (Floating u, FromPtSize u) => DotLocImage u-dotX = intoLocImage circleLDO markX--dotPlus :: (Floating u, FromPtSize u) => DotLocImage u-dotPlus = intoLocImage circleLDO markPlus--dotCross :: (Floating u, FromPtSize u) => DotLocImage u-dotCross = intoLocImage circleLDO markCross--dotDiamond :: (Floating u, FromPtSize u) => DotLocImage u-dotDiamond = intoLocImage circleLDO markDiamond--dotFDiamond :: (Floating u, FromPtSize u) => DotLocImage u-dotFDiamond = intoLocImage circleLDO markFDiamond----dotDisk :: (Floating u, FromPtSize u) => DotLocImage u-dotDisk = intoLocImage circleLDO markDisk---dotSquare :: (Floating u, Real u, FromPtSize u) => DotLocImage u-dotSquare = bind1 (static1 markHeight) $ \ h ->-    intoLocImage (rectangleLDO h h) markSquare-----dotCircle :: (Floating u, FromPtSize u) => DotLocImage u-dotCircle = intoLocImage circleLDO markCircle---dotPentagon :: (Floating u, FromPtSize u) => DotLocImage u-dotPentagon = intoLocImage circleLDO markPentagon--dotStar :: (Floating u, FromPtSize u) => DotLocImage u-dotStar = intoLocImage circleLDO markStar---dotAsterisk :: (Floating u, FromPtSize u) => DotLocImage u-dotAsterisk = intoLocImage circleLDO markAsterisk--dotOPlus :: (Floating u, FromPtSize u) => DotLocImage u-dotOPlus = intoLocImage circleLDO markOPlus--dotOCross :: (Floating u, FromPtSize u) => DotLocImage u-dotOCross = intoLocImage circleLDO markOCross--dotFOCross :: (Floating u, FromPtSize u) => DotLocImage u-dotFOCross = intoLocImage circleLDO markFOCross
− src/Wumpus/Basic/Dots/Marks.hs
@@ -1,229 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Dots.Marks--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Marks - dots without anchor handles.------ \*\* WARNING \*\* - names are expected to change - filled and--- background-filled marks need a naming convention.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Dots.Marks-  ( ---  -- * Marks-    markChar-  , markText--  , markHLine-  , markVLine-  , markX-  , markPlus-  , markCross-  , markDiamond-  , markFDiamond-  , markBDiamond -  , markDisk-  , markSquare-  , markCircle  -  , markPentagon-  , markStar-  , markAsterisk-  , markOPlus-  , markOCross-  , markFOCross---  ) where---import Wumpus.Basic.Graphic-import Wumpus.Basic.Text.LRText--import Wumpus.Core                      -- package: wumpus-core--import Data.AffineSpace                 -- package: vector-space-import Data.VectorSpace--import Control.Applicative-import Data.List---- Marks should be the height of a lower-case letter...---- NOTES------ TikZ has both stroked and bordered (filled and outline-stroked)--- marks e.g. square and square*-------- | 'polygonPoints' : @ num_points * radius * center -> [point] @ ----polygonPoints :: Floating u => Int -> u -> Point2 u -> [Point2 u]-polygonPoints n radius ctr = unfoldr phi (0,(pi*0.5))-  where-    theta = (pi*2) / fromIntegral n-    -    phi (i,ang) | i < n     = Just (ctr .+^ avec ang radius, (i+1,ang+theta))-                | otherwise = Nothing-----shiftOrigin :: Num u => u -> u -> LocGraphic u -> LocGraphic u-shiftOrigin dx dy = prepro1 (displace dx dy)--markChar :: (Fractional u, Ord u, FromPtSize u) => Char -> LocGraphic u-markChar ch = markText [ch]-----markText :: (Fractional u, Ord u, FromPtSize u) => String -> LocGraphic u-markText ss = postpro1 (\(_,b) -> b) $ singleLineCC ss-------- | Supplied point is the center.----axialLine :: Fractional u => Vec2 u -> LocGraphic u-axialLine v = localPoint (\ctr -> ctr .-^ (0.5 *^ v)) (straightLine v)---markHLine :: (Fractional u, FromPtSize u) => LocGraphic u -markHLine = bind1 (static1 markHeight) $ \h -> axialLine (hvec h)---markVLine :: (Fractional u, FromPtSize u) => LocGraphic u -markVLine = bind1 (static1 markHeight) $ \h -> axialLine (vvec h) ---markX :: (Fractional u, FromPtSize u) => LocGraphic u-markX = bind1 (static1 markHeight) $ \h -> -    let w = 0.75 * h in axialLine (vec w h) `oplus` axialLine (vec (-w) h)----markPlus :: (Fractional u, FromPtSize u) =>  LocGraphic u-markPlus = markVLine `oplus` markHLine---markCross :: (Floating u, FromPtSize u) =>  LocGraphic u-markCross = bind1 (static1 markHeight) $ \h ->  -    (axialLine $ avec ang h) `oplus` (axialLine $ avec (-ang) h)-  where-    ang = pi*0.25  ---- needs horizontal pinch...--pathDiamond :: (Fractional u, FromPtSize u) -            => 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 `bind1` (static1 . closedStroke)--markFDiamond :: (Fractional u, FromPtSize u) => LocGraphic u-markFDiamond = pathDiamond `bind1` (static1 . filledPath)----- Note - the (const . fn) composition doesn\'t /tell/ much about--- what is going on - though obviously it can be decoded - make --- the function obvious to the second argument. --- --- A named combinator might be better.-----markBDiamond :: (Fractional u, FromPtSize u) => LocGraphic u-markBDiamond = pathDiamond `bind1` (static1 . borderedPath)----- | Note disk is filled.----markDisk :: (Fractional u, FromPtSize u) => LocGraphic u-markDisk = bind1 (static1 markHalfHeight) filledDisk ----markSquare :: (Fractional u, FromPtSize u) => LocGraphic u-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 = bind1 (static1 markHalfHeight) strokedDisk ---markBCircle :: (Fractional u, FromPtSize u) => LocGraphic u-markBCircle = bind1 (static1 markHalfHeight) borderedDisk ----markPentagon :: (Floating u, FromPtSize u) => LocGraphic u-markPentagon = bind1 (static1 markHeight) $ \h ->-    promote1 $ \pt -> closedStroke $ vertexPath $ polygonPoints 5 (0.5*h) pt-- ---markStar :: (Floating u, FromPtSize u) => LocGraphic u -markStar = bind1 (static1 markHeight) $ \h -> -    promote1 $ \pt -> let ps = polygonPoints 5 (0.5*h) pt in step $ map (fn pt) ps-  where-    fn st p1    = openStroke $ primPath st [lineTo p1] -    step (x:xs) = oconcat x xs-    step _      = error "markStar - unreachable"----- Note - relies on the functional instance of OPlus--markAsterisk :: (Floating u, FromPtSize u) => LocGraphic u-markAsterisk = bind1 (static1 markHeight) $ \h -> -    lineF1 h `oplus` lineF2 h `oplus` lineF3 h-  where-    ang       = (pi*2) / 6-    lineF1 z  = axialLine (vvec z)-    lineF2 z  = axialLine (avec ((pi*0.5) + ang)    z)-    lineF3 z  = axialLine (avec ((pi*0.5) + ang + ang) z)----markOPlus :: (Fractional u, FromPtSize u) => LocGraphic u-markOPlus = markCircle `oplus` markPlus---markOCross :: (Floating u, FromPtSize u) => LocGraphic u-markOCross = markCircle `oplus` markCross---markFOCross :: (Floating u, FromPtSize u) => LocGraphic u-markFOCross = markCross `oplus` markBCircle ----- bkCircle :: (Fractional u, FromPtSize u) => LocGraphic u--- bkCircle = disk (fillAttr attr) (0.5*markHeight attr) -
− src/Wumpus/Basic/DrawingComposition.hs
@@ -1,458 +0,0 @@-{-# 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
@@ -1,62 +0,0 @@-{-# 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
@@ -1,215 +0,0 @@-{-# 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
@@ -1,67 +0,0 @@-{-# 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
@@ -1,67 +0,0 @@-{-# 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
@@ -1,222 +0,0 @@-{-# 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
@@ -1,87 +0,0 @@-{-# 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
@@ -1,63 +0,0 @@-{-# 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
@@ -1,43 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Graphic--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  highly unstable--- Portability :  GHC ------ Import shim for @Wumpus.Basic.Graphic@ modules.-----------------------------------------------------------------------------------------module Wumpus.Basic.Graphic-  (-    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.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.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
@@ -1,158 +0,0 @@-{-# 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
@@ -1,232 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE TypeSynonymInstances       #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Graphic.Base--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  highly unstable--- Portability :  GHC ------ 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. --- --------------------------------------------------------------------------------------module Wumpus.Basic.Graphic.Base-  (--  -- A semigroup class.-    OPlus(..)-  , oconcat-  , anterior    -  , superior--  -- * Alignment.-  , HAlign(..)-  , VAlign(..)  --  -- * Drawing monads.-  , MonUnit-  , TraceM(..)-  , DrawingCtxM(..)-  , asksDC- -  , PointSupplyM(..)---  -- * Base types-  , HPrim-  , hprimToList-  , singleH--  , PrimGraphic-  , getPrimGraphic-  , primGraphic-  , collectH--  ) where--import Wumpus.Basic.Graphic.DrawingContext-import Wumpus.Basic.Utils.HList--import Wumpus.Core                      -- package: wumpus-core---import Control.Applicative-import Data.Monoid----infixr 6 `oplus`---- | A Semigroup class.--- -class OPlus t where-  oplus :: t -> t -> t--oconcat :: OPlus t => t -> [t] -> t-oconcat t = step t-  where-    step ac []     = ac-    step ac (x:xs) = step (ac `oplus` x) xs--anterior :: OPlus t => t -> (t -> t)-anterior a = (a `oplus`)--superior :: OPlus t => t -> (t -> t)-superior a = (`oplus` a)-----instance Ord u => OPlus (BoundingBox u) where-  oplus = boundaryUnion--instance OPlus (Primitive u) where-  a `oplus` b = primGroup [a,b]--instance (OPlus a, OPlus b) => OPlus (a,b) where-  (a,b) `oplus` (a',b') = (a `oplus` a', b `oplus` b')---instance OPlus a => OPlus (r -> a) where-  f `oplus` g = \x -> f x `oplus` g x---- The functional instance (r -> a) also covers (r1 -> r2 -> a),--- (r1 -> r2 -> r3 -> a) etc.--------------------------------------------------------------------------------------- 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 --- (seemingly) an equivalent type family is needed for monads.--type family MonUnit m :: * ----- | Collect elementary graphics as part of a larger drawing.------ TraceM works much like a writer monad.----class Monad m => TraceM (m :: * -> *) where-  trace  :: HPrim (MonUnit m) -> m ()--class (Applicative m, Monad m) => DrawingCtxM (m :: * -> *) where-  askDC    :: m DrawingContext-  localize :: (DrawingContext -> DrawingContext) -> m a -> m a----- | Project a value out of a context.----asksDC :: DrawingCtxM m => (DrawingContext -> a) -> m a-asksDC f = askDC >>= (return . f)------ | A monad that supplies points, e.g. a turtle monad. ----class Monad m => PointSupplyM (m :: * -> *) where-  position :: u ~ MonUnit m => m (Point2 u)- ------------------------------------------------------------------------------------- Lists of primitives...---- | Graphics objects, even simple ones (line, arrow, dot) might --- need more than one primitive (path or text label) for their--- construction. Hence, the primary representation that all the --- others are built upon must support /concatenation/ of --- primitives. ------ Wumpus-Core has a type Picture - made from one or more --- Primitives - but Pictures include support for affine frames. --- For drawing many simple graphics (dots, connector lines...) --- that do not need individual affine transformations this is a --- penalty. A list of Primitives is therefore more suitable --- representation, and a Hughes list which supports--- efficient concatenation is wise.----newtype HPrim u = HPrim { getHPrim :: H (Primitive u) }---- Note - only a Monoid instance for HPrim - they cannot be --- shown, fmapped etc.--instance Monoid (HPrim u) where-  mempty          = HPrim emptyH-  ha `mappend` hb = HPrim $ getHPrim ha `appendH` getHPrim hb---hprimToList :: HPrim u -> [Primitive u]-hprimToList = toListH . getHPrim---singleH :: Primitive u -> HPrim u-singleH = HPrim . wrapH ---- As of version 0.36.0, Wumpus-Core supports grouping primitives--- together (a common operation in vector drawing editors). ------ For Wumpus-Basic this means e.g. a line with arrowheads can --- still be a primitive.------ Still, we wrap Primitive as a newtype...-----newtype PrimGraphic u = PrimGraphic { getPrimGraphic :: Primitive u }-  deriving (Eq,Show)--type instance DUnit (PrimGraphic u) = u--instance OPlus (PrimGraphic u) where-  oplus a b = PrimGraphic $ getPrimGraphic a `oplus` getPrimGraphic b----- Affine transformations--instance (Real u, Floating u) => Rotate (PrimGraphic u) where-  rotate ang = PrimGraphic . rotate ang . getPrimGraphic---instance (Real u, Floating u) => RotateAbout (PrimGraphic u) where-  rotateAbout ang pt = PrimGraphic . rotateAbout ang pt . getPrimGraphic---instance Num u => Scale (PrimGraphic u) where-  scale sx sy = PrimGraphic . scale sx sy . getPrimGraphic---instance Num u => Translate (PrimGraphic u) where-  translate dx dy = PrimGraphic . translate dx dy . getPrimGraphic---primGraphic :: Primitive u -> PrimGraphic u -primGraphic = PrimGraphic--collectH :: PrimGraphic u -> HPrim u-collectH = singleH . getPrimGraphic-
− src/Wumpus/Basic/Graphic/ContextFunction.hs
@@ -1,718 +0,0 @@-{-# 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
@@ -1,124 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Graphic.Drawing--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC ------ 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-  , DDrawing-  , runDrawing-  , runDrawingU-  , drawTracing--  , clipDrawing-  , modifyDrawing-  , drawingConcat--  ) where--import Wumpus.Basic.Graphic.ContextFunction-import Wumpus.Basic.Graphic.DrawingContext-import Wumpus.Basic.Graphic.TraceDrawing--import Wumpus.Core                              -- package: wumpus-core--newtype Drawing u = Drawing { getDrawing :: CF (Maybe (Picture u)) }--type DDrawing = Drawing Double---type instance DUnit (Drawing u) = u-----runDrawing :: DrawingContext -> Drawing u -> Maybe (Picture u)-runDrawing ctx drw = runCF ctx (getDrawing drw)  ---runDrawingU :: DrawingContext -> Drawing u -> Picture u-runDrawingU ctx df = maybe fk id $ runDrawing ctx df-  where-    fk = error "runDrawingU - empty Drawing."   ----drawTracing :: (Real u, Floating u, FromPtSize u) -            => TraceDrawing u a -> Drawing u-drawTracing mf = Drawing $ -    drawingCtx >>= \ctx -> return (liftToPictureMb (execTraceDrawing ctx mf) )----- Note - cannot get an answer from a TraceDrawing with this --- Drawing type. There is nowhere to put the answer in the type.------ If the type was extended:------ > newtype Drawing u a = Drawing { getDrawing :: CF (a, Maybe (Picture u))) }------ 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)? --------------------------------------------------------------------------------------clipDrawing :: (Num u, Ord u) => (PrimPath u) -> Drawing u -> Drawing u-clipDrawing cpath = modifyDrawing (clip cpath)---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)--instance (Real u, Floating u) => RotateAbout (Drawing u) where-  rotateAbout r pt = modifyDrawing (rotateAbout r pt)--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)------drawingConcat :: (Picture u -> Picture u -> Picture u) -              -> Drawing u -> Drawing u -> Drawing u-drawingConcat op a b = Drawing $ mbpostcomb op (getDrawing a) (getDrawing b)----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
@@ -1,324 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Graphic.DrawingContext--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Drawing attributes------ \*\* WARNING \*\* - this module needs systematic naming --- schemes both for update functions (primaryColour, ...) and --- for synthesized selectors (e.g. lowerxHeight). The current --- names will change.------ -----------------------------------------------------------------------------------module Wumpus.Basic.Graphic.DrawingContext-  ( --  -- * Drawing context-    DrawingContext(..)-  , DrawingContextF--  , standardContext-  , metricsContext--  , default_drawing_context--  -- * Modifiers -  -- ** Line widths-  , thick-  , ultrathick-  , thin--  -- ** Line caps-  , capButt-  , capRound-  , capSquare--  -- ** Line joins-  , joinMiter-  , joinRound-  , joinBevel--  -- ** Dash Pattern-  , dashPattern-  , unit_dash_pattern-  , phase-  , dphase-  , doublegaps-  , doubledashes--  -- * Font properties-  , fontsize-  , fontface--  -- * Font / mark drawing size-  , doublesize-  , halfsize--  -- * Colour-  , swapColours-  , bothStrokeColour-  , bothFillColour-  , strokeColour-  , fillColour --  -- * Glyph metrics-  , withFontMetrics--  -  ) where---import Wumpus.Basic.Graphic.GlyphMetrics--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-      { 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-      }---- TODO - hand craft a Show instance --type DrawingContextF = DrawingContext -> DrawingContext---standardContext :: FontSize -> DrawingContext-standardContext sz = -    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)---updateStrokeProps :: (StrokeAttr -> StrokeAttr) -> DrawingContextF-updateStrokeProps fn = (\s i -> s { stroke_props = fn i }) <*> stroke_props--updateFontProps :: (FontAttr -> FontAttr) -> DrawingContextF-updateFontProps fn = (\s i -> s { font_props = fn i }) <*> font_props-------------------------------------------------------------------------------------- line widths---- Note - some care might be needed if we ever define other unit --- types...---- std_line_width      :: Double--- std_line_width      = 1.0--thick_line          :: Double-thick_line          = 2.0--ultra_thick_line    :: Double-ultra_thick_line    = 4.0--thin_line           :: Double-thin_line           = 0.5--setLineWidth       :: Double -> DrawingContextF-setLineWidth d      = updateStrokeProps (\s -> s { line_width = d })---- | Set the line width to a /thick/.------ Note this context update is /oblivious/ - operationally the --- line width is set to exactly @2.0@.----thick               :: DrawingContextF-thick               = setLineWidth thick_line--ultrathick          :: DrawingContextF-ultrathick          = setLineWidth ultra_thick_line--thin                :: DrawingContextF-thin                = setLineWidth thin_line---setLineCap          :: LineCap -> DrawingContextF-setLineCap d        = updateStrokeProps (\s -> s { line_cap = d })---capButt             :: DrawingContextF-capButt             = setLineCap CapButt--capRound            :: DrawingContextF-capRound            = setLineCap CapRound--capSquare           :: DrawingContextF-capSquare           = setLineCap CapSquare---setLineJoin         :: LineJoin -> DrawingContextF-setLineJoin d       = updateStrokeProps (\s -> s { line_join = d })---joinMiter           :: DrawingContextF-joinMiter           = setLineJoin JoinMiter--joinRound           :: DrawingContextF-joinRound           = setLineJoin JoinRound--joinBevel           :: DrawingContextF-joinBevel           = setLineJoin JoinBevel-------------------------------------------------------------------------------------dashPattern         :: DashPattern -> DrawingContextF-dashPattern d       = updateStrokeProps (\s -> s { dash_pattern = d })        --unit_dash_pattern   :: DashPattern-unit_dash_pattern   = Dash 0 [(1,1)]---- oblivious-phase               :: Int -> DashPattern -> DashPattern-phase _ Solid       = Solid-phase i (Dash _ xs) = Dash i xs---- non-oblivious-dphase               :: Int -> DashPattern -> DashPattern-dphase _ Solid       = Solid-dphase d (Dash i xs) = Dash (i+d) xs--doublegaps              :: DashPattern -> DashPattern-doublegaps Solid        = Solid-doublegaps (Dash i xs)  = Dash i (map fn xs)-  where-    fn (a,b) = (a,2*b)--doubledashes              :: DashPattern -> DashPattern-doubledashes Solid        = Solid-doubledashes (Dash i xs)  = Dash i (map fn xs)-  where-    fn (a,b) = (a*2,b)--------------------------------------------------------------------------------------fontface            :: FontFace -> DrawingContextF-fontface ff         = updateFontProps (\(FontAttr sz _) -> FontAttr sz ff)--fontsize            :: Int -> DrawingContextF-fontsize sz         = updateFontProps (\(FontAttr _ ff) -> FontAttr sz ff)-------------------------------------------------------------------------------------- | Set the font size to double the current size, note the font--- size also controls the size of dots, arrowsheads etc.--- -doublesize          :: DrawingContextF-doublesize          = (\s sz -> fontsize (sz*2) s) <*> (font_size . font_props)----- | Set the font size to half the current size, note the font--- size also controls the size of dots, arrowsheads etc.--- --- As fontsize is an integer this is not exact - half size of--- 15pt type is 7pt.--- -halfsize            :: DrawingContextF-halfsize            = (\s sz -> fontsize (sz `div` 2) s) -                        <*> (font_size . font_props)-------------------------------------------------------------------------------------swapColours :: DrawingContextF-swapColours = -    (\s a b -> s { stroke_colour = b, fill_colour = a })-        <*> stroke_colour <*> fill_colour--bothStrokeColour :: DrawingContextF-bothStrokeColour = (\s a -> s { fill_colour = a }) <*> stroke_colour--bothFillColour :: DrawingContextF-bothFillColour = (\s a -> s { stroke_colour = a }) <*> fill_colour----strokeColour :: RGBi -> DrawingContextF-strokeColour rgb = \s -> s { stroke_colour = rgb } ---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
@@ -1,110 +0,0 @@-{-# 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
@@ -1,399 +0,0 @@-{-# 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
@@ -1,441 +0,0 @@-{-# 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/Query.hs
@@ -1,264 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Graphic.Query--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Querying the Drawing Context.--------------------------------------------------------------------------------------module Wumpus.Basic.Graphic.Query-  ( --    -    textAttr-  , withTextAttr--  , strokeAttr-  , withStrokeAttr--  , fillAttr-  , withFillAttr--  , borderedAttr-  , withBorderedAttr--  , lineWidth-  , fontSize-  , fontFace-  , fontAttr-  , markHeight-  , markHalfHeight-  , baselineSpacing--  -- * Glyph metrics-  , glyphBoundingBox-  , glyphHeightRange-  , glyphHeight-  , glyphCapHeight--  , avLookupTable--  -- * Default monospace metrics--  , monoFontPointSize-  , monoCharWidth-  , monoTextWidth-  , monoTextLength-  , monoCapHeight-  , monoLowerxHeight-  , monoDescenderDepth-  , monoAscenderHeight-  , monoTextDimensions-  , monoMultiLineHeight-  , monoDefaultPadding-  , monoVecToCenter  -  ) where--import Wumpus.Basic.Graphic.Base-import Wumpus.Basic.Graphic.DrawingContext-import Wumpus.Basic.Graphic.GlyphMetrics--import Wumpus.Core                              -- package: wumpus-core-import qualified Wumpus.Core.FontSize   as FS- -import Control.Applicative---textAttr :: DrawingCtxM m => m (RGBi,FontAttr)-textAttr = (,) <$> asksDC stroke_colour <*> asksDC font_props---- | Because @textAttr@ is so commonly used here is a functional--- version that avoids tupling.----withTextAttr :: DrawingCtxM m => (RGBi -> FontAttr -> a) -> m a-withTextAttr fn = fn <$> asksDC stroke_colour <*> asksDC font_props---strokeAttr :: DrawingCtxM m => m (RGBi, StrokeAttr)-strokeAttr = (,) <$> asksDC stroke_colour <*> asksDC stroke_props--withStrokeAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> a) -> m a-withStrokeAttr fn = fn <$> asksDC stroke_colour <*> asksDC stroke_props---fillAttr :: DrawingCtxM m => m RGBi-fillAttr = asksDC fill_colour--withFillAttr :: DrawingCtxM m => (RGBi -> a) -> m a-withFillAttr fn = fn <$> asksDC fill_colour--borderedAttr :: DrawingCtxM m => m (RGBi, StrokeAttr, RGBi)-borderedAttr = (,,) <$> asksDC fill_colour <*> asksDC stroke_props -                                           <*> asksDC stroke_colour--withBorderedAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> RGBi -> a) -> m a-withBorderedAttr fn = -    fn <$> asksDC fill_colour <*> asksDC stroke_props -                              <*> asksDC stroke_colour-----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------- | Vertical distance between baselines of consecutive text --- lines.----baselineSpacing :: (DrawingCtxM m, Fractional u) => m u-baselineSpacing = -    (\sz factor -> realToFrac $ factor * fromIntegral sz)-      <$> asksDC (font_size . font_props) <*> asksDC line_spacing_factor---- | The /mark/ height is the height of a lowercase letter in the --- current font.------ Arrowheads, dots etc. should generally be drawn at the mark --- height.--- -markHeight :: (DrawingCtxM m, FromPtSize u) => m u-markHeight = (fromPtSize . FS.xcharHeight . font_size) <$> asksDC font_props---markHalfHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u-markHalfHeight = (0.5*) <$> markHeight----- Note - there are probably enough functions that use just --- 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----- 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 $ FS.textWidth sz n---monoTextLength :: (DrawingCtxM m, FromPtSize u) => String -> m u-monoTextLength ss = monoTextWidth $ charCount ss---monoCapHeight :: (DrawingCtxM m, FromPtSize u) => m u-monoCapHeight = withFontSize (fromPtSize . FS.capHeight)--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 . FS.xcharHeight)--monoDescenderDepth :: (DrawingCtxM m, FromPtSize u) => m u-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.------ Note - the width will generally be a over-estimate for --- non-monospaced fonts.--- -monoTextDimensions :: (DrawingCtxM m, Num u, Ord u, FromPtSize u)-                   => String -> m (u,u)-monoTextDimensions ss = -    (\sz -> post $ textBounds sz zeroPt ss) -      <$> asksDC (font_size . font_props)-  where-    post bb = (boundaryWidth bb, boundaryHeight bb)----- | 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-monoMultiLineHeight n | n < 0   = pure 0-monoMultiLineHeight n           = -    (\h lsf -> h + (fromIntegral $ n-1) * (h * realToFrac lsf))-      <$> 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/.----monoDefaultPadding :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u-monoDefaultPadding = (0.5*) <$> monoCharWidth---- | Vector from baseline left to center----monoVecToCenter :: (DrawingCtxM m, Fractional u, Ord u, FromPtSize u) -                => String -> m (Vec2 u)-monoVecToCenter ss = (\(w,h) dy -> vec (0.5*w) (0.5*h - dy)) -                       <$> monoTextDimensions ss <*> monoDescenderDepth
− src/Wumpus/Basic/Graphic/ScalingContext.hs
@@ -1,191 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Graphic.ScalingContext--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC------ Scaling in X and Y--------------------------------------------------------------------------------------module Wumpus.Basic.Graphic.ScalingContext-  (--    ScalingM(..)-  , ScalingContext(..)--  , Scaling-  , runScaling-  , ScalingT-  , runScalingT--  , regularScalingContext-  , coordinateScalingContext--  , unitX-  , unitY---  ) where--import Wumpus.Basic.Graphic.Base--import Wumpus.Core				-- package: wumpus-core--import Control.Applicative------ | Scaling...----class Monad m => ScalingM m where-  type XDim m :: *-  type YDim m :: *-  scaleX :: (u ~ MonUnit m, ux ~ XDim m) => ux -> m u-  scaleY :: (u ~ MonUnit m, uy ~ YDim m) => uy -> m u-  scalePt  :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m) -           => ux -> uy -> m (Point2 u)-  scaleVec :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m) -           => ux -> uy -> m (Vec2 u)----data ScalingContext ux uy u = ScalingContext-      { scale_in_x  :: ux -> u-      , scale_in_y  :: uy -> u-      }------ Chains (for example) want a plain monad rather than a transformer.----newtype Scaling ux uy u a = Scaling {-          getScaling :: ScalingContext ux uy u -> a }---type instance MonUnit (Scaling ux uy u) = u----instance Functor (Scaling ux uy u) where-  fmap f ma = Scaling $ \ctx -> let a = getScaling ma ctx in f a--instance Applicative (Scaling ux uy u) where-  pure a    = Scaling $ \_   -> a-  mf <*> ma = Scaling $ \ctx -> let f = getScaling mf ctx-                                    a = getScaling ma ctx-             			in (f a)--instance Monad (Scaling ux uy u) where-  return a = Scaling $ \_   -> a-  m >>= k  = Scaling $ \ctx -> let a = getScaling m ctx-    	     	               in (getScaling . k) a ctx----instance ScalingM (Scaling ux uy u) where-  type XDim (Scaling ux uy u) = ux -  type YDim (Scaling ux uy u) = uy-  scaleX ux       = Scaling $ \ctx -> (scale_in_x ctx) ux-  scaleY uy       = Scaling $ \ctx -> (scale_in_y ctx) uy-  scalePt ux uy   = Scaling $ \ctx -> P2 (scale_in_x ctx ux) (scale_in_y ctx uy)-  scaleVec ux uy  = Scaling $ \ctx -> V2 (scale_in_x ctx ux) (scale_in_y ctx uy)--runScaling :: ScalingContext ux uy u -> Scaling ux uy u a -> a-runScaling ctx sf = (getScaling sf) ctx    ---------------------------------------------------------------------------------------- Transformer---- Turtle (for example) wants a transformer so it can use TraceM--- and DrawingCtxM----newtype ScalingT ux uy u m a = ScalingT { -          getScalingT :: ScalingContext ux uy u -> m a }--type instance MonUnit (ScalingT ux uy u m) = u---instance Monad m => Functor (ScalingT ux uy u m) where-  fmap f ma = ScalingT $ \ctx -> getScalingT ma ctx >>= \a -> return (f a)--instance Monad m => Applicative (ScalingT ux uy u m) where-  pure a    = ScalingT $ \_   -> return a-  mf <*> ma = ScalingT $ \ctx -> getScalingT mf ctx >>= \f -> -                                 getScalingT ma ctx >>= \a ->-             			 return (f a)--instance Monad m => Monad (ScalingT ux uy u m) where-  return a = ScalingT $ \_   -> return a-  m >>= k  = ScalingT $ \ctx -> getScalingT m ctx >>= \a -> -    	     	      	     	(getScalingT . k) a ctx---instance Monad m => ScalingM (ScalingT ux uy u m) where-  type XDim (ScalingT ux uy u m) = ux -  type YDim (ScalingT ux uy u m) = uy-  scaleX ux       = ScalingT $ \ctx -> return $ (scale_in_x ctx) ux-  scaleY uy       = ScalingT $ \ctx -> return $ (scale_in_y ctx) uy-  scalePt ux uy   = ScalingT $ \ctx -> -                      return $ P2 (scale_in_x ctx ux) (scale_in_y ctx uy)-  scaleVec ux uy  = ScalingT $ \ctx -> -                      return $ V2 (scale_in_x ctx ux) (scale_in_y ctx uy)------ Cross instances - needed to run SalingT /locally/ in Drawing.--instance DrawingCtxM m => DrawingCtxM (ScalingT ux uy u m) where-  askDC           = ScalingT $ \_    -> askDC >>= \dctx -> return dctx-  localize upd mf = ScalingT $ \sctx -> localize upd (getScalingT mf sctx)---instance (Monad m, TraceM m, u ~ MonUnit m) => TraceM (ScalingT ux uy u m) where-  trace a  = ScalingT $ \_ -> trace a -----runScalingT :: ScalingContext ux uy u -> ScalingT ux uy u m a -> m a-runScalingT ctx sf = (getScalingT sf) ctx    ------------------------------------------------------------------------------------- constructors for scaling context--regularScalingContext :: Num u => u -> ScalingContext u u u-regularScalingContext u = ScalingContext-      { scale_in_x  = (\x -> u*x)-      , scale_in_y  = (\y -> u*y)-      }--coordinateScalingContext :: Num u => u -> u -> ScalingContext Int Int u-coordinateScalingContext sx sy = ScalingContext-      { scale_in_x  = (\x -> sx * fromIntegral x)-      , scale_in_y  = (\y -> sy * fromIntegral y)-      }--------------------------------------------------------------------------------------- operations-----unitX :: (ScalingM m, Num ux, ux ~ XDim m, u ~ MonUnit m) => m u-unitX = scaleX 1- -unitY :: (ScalingM m, Num uy, uy ~ YDim m, u ~ MonUnit m) => m u-unitY = scaleY 1-- 
− src/Wumpus/Basic/Graphic/TraceDrawing.hs
@@ -1,329 +0,0 @@-{-# 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/Kernel.hs view
@@ -0,0 +1,57 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- Import shim for @Wumpus.Basic.Kernel@ modules.+--+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel+  (+    module Wumpus.Basic.Kernel.Base.Anchors+  , module Wumpus.Basic.Kernel.Base.BaseDefs+  , module Wumpus.Basic.Kernel.Base.ContextFun+  , module Wumpus.Basic.Kernel.Base.DrawingContext+  , module Wumpus.Basic.Kernel.Base.GlyphMetrics+  , module Wumpus.Basic.Kernel.Base.QueryDC+  , module Wumpus.Basic.Kernel.Base.ScalingContext+  , module Wumpus.Basic.Kernel.Base.UpdateDC+  , module Wumpus.Basic.Kernel.Base.WrappedPrimitive+  , module Wumpus.Basic.Kernel.Geometry.Intersection+  , module Wumpus.Basic.Kernel.Geometry.Paths+  , module Wumpus.Basic.Kernel.Objects.AdvanceGraphic+  , module Wumpus.Basic.Kernel.Objects.BaseObjects+  , module Wumpus.Basic.Kernel.Objects.Bounded+  , module Wumpus.Basic.Kernel.Objects.Connector+  , module Wumpus.Basic.Kernel.Objects.Drawing+  , module Wumpus.Basic.Kernel.Objects.Graphic+  , module Wumpus.Basic.Kernel.Objects.TraceDrawing+  ) where++import Wumpus.Basic.Kernel.Base.Anchors+import Wumpus.Basic.Kernel.Base.BaseDefs+import Wumpus.Basic.Kernel.Base.ContextFun+import Wumpus.Basic.Kernel.Base.DrawingContext+import Wumpus.Basic.Kernel.Base.GlyphMetrics+import Wumpus.Basic.Kernel.Base.QueryDC+import Wumpus.Basic.Kernel.Base.ScalingContext+import Wumpus.Basic.Kernel.Base.UpdateDC+import Wumpus.Basic.Kernel.Base.WrappedPrimitive+import Wumpus.Basic.Kernel.Geometry.Intersection+import Wumpus.Basic.Kernel.Geometry.Paths+import Wumpus.Basic.Kernel.Objects.AdvanceGraphic+import Wumpus.Basic.Kernel.Objects.BaseObjects+import Wumpus.Basic.Kernel.Objects.Bounded+import Wumpus.Basic.Kernel.Objects.Connector+import Wumpus.Basic.Kernel.Objects.Drawing+import Wumpus.Basic.Kernel.Objects.Graphic+import Wumpus.Basic.Kernel.Objects.TraceDrawing
+ src/Wumpus/Basic/Kernel/Base/Anchors.hs view
@@ -0,0 +1,238 @@+{-# LANGUAGE TypeFamilies               #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Base.Anchors+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Anchor points on shapes, bounding boxes, etc.+--+-- Anchors are addressable positions, an examplary use is taking+-- anchors on node shapes to get the start and end points for +-- connectors in a network (graph) diagram.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Base.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+++-- | Center of an object.+--+class CenterAnchor t where+  center :: DUnit t ~ u => t -> Point2 u++-- | Cardinal (compass) positions on an object. +-- +-- 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.+--+-- Wumpus generally follows the TikZ convention.+--+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+++-- | Secondary group of cardinal (compass) positions on an object. +-- +-- It seems possible that for some objects defining the primary+-- compass points (north, south,...) will be straight-forward +-- whereas defining the secondary compass points may be +-- problemmatic, hence the compass points are split into two +-- classes.+--+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 addressed by an angle.+--+-- The angle is counter-clockwise from the right-horizontal, i.e.+-- 0 is /east/.+--+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' : @ dist * object -> Point @+-- +-- Project the anchor along a line from the center that goes +-- through the north anchor. +--+-- If the distance is zero the answer with be the north anchor.+--+-- If the distance is negative the answer within the object before +-- the north anchor.+--+-- If the distance is positive the anchor outside the object.+--+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' : @ dist * object -> Point @+-- +-- Variant of the function 'northwards', but projecting the line +-- southwards from the center of the object.+--+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' : @ dist * object -> Point @+-- +-- Variant of the function 'northwards', but projecting the line +-- eastwards from the center of the object.+--+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' : @ dist * object -> Point @+-- +-- Variant of the function 'northwards', but projecting the line +-- westwards from the center of the object.+--+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' : @ dist * object -> Point @+-- +-- Variant of the function 'northwards', but projecting the line +-- northeastwards from the center of the object.+--+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' : @ dist * object -> Point @+-- +-- Variant of the function 'northwards', but projecting the line +-- southeastwards from the center of the object.+--+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' : @ dist * object -> Point @+-- +-- Variant of the function 'northwards', but projecting the line +-- southwestwards from the center of the object.+--+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' : @ dist * object -> Point @+-- +-- Variant of the function 'northwards', but projecting the line +-- northwestwards from the center of the object.+--+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' : @ object_a * object_b -> (Point_a, Point_b) @+--+-- Find the radial connectors points for objects @a@ and @b@ along+-- the line joining their centers.+--+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/Kernel/Base/BaseDefs.hs view
@@ -0,0 +1,281 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeSynonymInstances       #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernal.Base.BaseDefs+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- The elementary base types and classes.+-- +--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Base.BaseDefs+  (++  -- * A semigroup class+    OPlus(..)+  , oconcat++  -- * A bifunctor class+  , Bimap(..)+  , replaceL+  , replaceR++  -- * Alignment+  , HAlign(..)+  , VAlign(..)  ++  -- * Advance vector+  , AdvanceVec+  , advanceH+  , advanceV++  -- * Moving points+  , PointDisplace+  , displace+  , displaceVec+  , displaceH+  , displaceV++  , ThetaPointDisplace+  , displaceParallel+  , displacePerpendicular++++  -- * Monadic drawing+  , MonUnit++  , PointSupplyM(..)++  ) where++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space++infixr 6 `oplus`++-- | A Semigroup class.+-- +-- The perhaps unusual name is the TeX name for the circled plus +-- glyph. It would be nice if there was a semigroup class in the+-- Haskell Base libraries...  +-- +class OPlus t where+  oplus :: t -> t -> t++oconcat :: OPlus t => t -> [t] -> t+oconcat t = step t+  where+    step ac []     = ac+    step ac (x:xs) = step (ac `oplus` x) xs++++instance OPlus () where+  _ `oplus` _ = ()++instance OPlus (UNil u) where+  _ `oplus` _ = uNil++instance Ord u => OPlus (BoundingBox u) where+  oplus = boundaryUnion++instance OPlus (Primitive u) where+  a `oplus` b = primGroup [a,b]++instance (OPlus a, OPlus b) => OPlus (a,b) where+  (a,b) `oplus` (a',b') = (a `oplus` a', b `oplus` b')+++instance OPlus a => OPlus (r -> a) where+  f `oplus` g = \x -> f x `oplus` g x++-- The functional instance (r -> a) also covers (r1 -> r2 -> a),+-- (r1 -> r2 -> r3 -> a) etc.++--------------------------------------------------------------------------------++-- | A Bifunctor class.+-- +-- Again, it would be nice if there was a Bifunctor class in the+-- Haskell Base libraries...  +-- +class Bimap f where+  bimap     :: (a -> p) -> (b -> q) -> f a b -> f p q+  bimapL    :: (a -> p) -> f a b -> f p b+  bimapR    :: (b -> q) -> f a b -> f a q++++instance Bimap (,) where+  bimap f g (a,b) = (f a, g b)+  bimapL f (a,b)  = (f a, b)+  bimapR g (a,b)  = (a, g b)++instance Bimap Either where+  bimap f _ (Left a)  = Left (f a)+  bimap _ g (Right b) = Right (g b)++  bimapL f (Left a)  = Left (f a)+  bimapL _ (Right b) = Right b++  bimapR _ (Left a)  = Left a+  bimapR g (Right b) = Right (g b)++replaceL :: Bimap f => p -> f a b -> f p b+replaceL = bimapL . const++replaceR :: Bimap f => q -> f a b -> f a q+replaceR = bimapR . const+++--------------------------------------------------------------------------------++-- 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)+++--------------------------------------------------------------------------------++-- | Advance vectors provide an idiom for drawing consecutive+-- graphics. PostScript uses them to draw left-to-right text - +-- each character has an advance vector for the width and +-- as characters are drawn they successively displace the start+-- point for the next character with their advance vector.+--+-- Type alias for Vec2.+--+type AdvanceVec u = Vec2 u+++-- | 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 when drawing text.+--+advanceH :: AdvanceVec u -> u+advanceH (V2 w _)  = w++-- | Extract the verticall component of an advance vector.+--+advanceV :: AdvanceVec u -> u+advanceV (V2 _ h)  = h++--------------------------------------------------------------------------------+-- Displacing points++-- | 'PointDisplace' is a type representing functions +-- @from Point to Point@.+--+-- It is especially useful for building composite graphics where +-- one part of the graphic is drawn from a different start point +-- to the other part.+--+type PointDisplace u = Point2 u -> Point2 u++-- | 'displace' : @ x -> y -> PointDisplace @+--+-- Build a combinator to move @Points@ by the supplied @x@ and +-- @y@ distances.+--+displace :: Num u => u -> u -> PointDisplace u+displace dx dy (P2 x y) = P2 (x+dx) (y+dy)+++-- | 'displaceV' : @ (V2 x y) -> PointDisplace @+-- +-- Version of 'displace' where the displacement is supplied as+-- a vector rather than two parameters.+-- +displaceVec :: Num u => Vec2 u -> PointDisplace u+displaceVec (V2 dx dy) (P2 x y) = P2 (x+dx) (y+dy)+++-- | 'displaceH' : @ x -> PointDisplace @+-- +-- Build a combinator to move @Points@ by horizontally the +-- supplied @x@ distance.+--+displaceH :: Num u => u -> PointDisplace u+displaceH dx (P2 x y) = P2 (x+dx) y++-- | 'displaceV' : @ y -> PointDisplace @+-- +-- Build a combinator to move @Points@ vertically by the supplied +-- @y@ distance.+--+displaceV :: Num u => u -> PointDisplace u+displaceV dy (P2 x y) = P2 x (y+dy)+++-- | 'ThetaPointDisplace' is a type representing functions +-- @from Radian * Point to Point@.+--+-- It is useful for building arrowheads which are constructed +-- with an implicit angle representing the direction of the line +-- at the arrow tip.+--+type ThetaPointDisplace u = Radian -> PointDisplace u++++-- | 'displaceParallel' : @ dist -> ThetaPointDisplace @+-- +-- Build a combinator to move @Points@ in parallel to the +-- direction of the implicit angle by the supplied distance +-- @dist@. +--+displaceParallel :: Floating u => u -> ThetaPointDisplace u+displaceParallel d = \theta pt -> pt .+^ avec (circularModulo theta) d+++-- | 'displaceParallel' : @ dist -> ThetaPointDisplace @+-- +-- Build a combinator to move @Points@ perpendicular to the +-- direction of the implicit angle by the supplied distance +-- @dist@. +--+displacePerpendicular :: Floating u => u -> ThetaPointDisplace u+displacePerpendicular d = +    \theta pt -> pt .+^ avec (circularModulo $ theta + (0.5*pi)) d+++--------------------------------------------------------------------------------+-- Monadic drawing++-- | DUnit is always for fully saturated type constructors, so +-- (seemingly) an equivalent type family is needed for monads.++type family MonUnit m :: * +++-- | A monad that supplies points, e.g. a turtle monad. +--+-- \*\* WARNING \*\* - the idea behind this class is somewhat+-- half-baked. It may be revised or even dropped in subsequent+-- versions of Wumpus-Basic.+--+class Monad m => PointSupplyM (m :: * -> *) where+  position :: MonUnit m ~ u => m (Point2 u)
+ src/Wumpus/Basic/Kernel/Base/ContextFun.hs view
@@ -0,0 +1,541 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Base.ContextFun+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- Function types operating over the DrawingContext as a /static/ +-- argument. +--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Base.ContextFun+  (++  -- * /Context functional/ types+    CF     +  , CF1+  , CF2++  , LocCF+  , LocThetaCF+  , ConnectorCF+  , DLocCF+  , DLocThetaCF+  , DConnectorCF++++  -- * Run functions+  , runCF+  , runCF1 +  , runCF2++  -- * Lift functions+  , lift0R1+  , lift0R2+  , lift1R2+ +  , promoteR1+  , promoteR2+++  , apply1R1+  , apply2R2+  , apply1R2++  -- * Extractors+  , drawingCtx+  , queryCtx+  , locCtx+  , locPoint+  , locThetaCtx+  , locThetaPoint+  , locThetaAng+  , connCtx+  , connStart+  , connEnd++  -- * Combinators+  , at+  , rot+  , connect+  , chain1+++  ) where++import Wumpus.Basic.Kernel.Base.BaseDefs+import Wumpus.Basic.Kernel.Base.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  { unCF :: DrawingContext -> a }+++-- | Variation of 'CF' with one parametric /static argument/.+--+-- The static argument is commonly a point representing the start +-- point / origin of a drawing.+-- +-- > CF1 :: DrawingContext -> r1 -> a +--+newtype CF1 r1 a        = CF1 { unCF1 :: DrawingContext -> r1 -> a }+++-- | Variation of 'CF' with two parametric /static arguments/.+--+-- The first argument is commonly a point representing the start +-- point / origin of a drawing. The second argument might +-- typically be the angle of displacement (for drawing arrowheads) +-- or an end point (for drawing connectors between two points).+-- +-- > CF2 :: DrawingContext -> r1 -> r2 -> a +--+newtype CF2 r1 r2 a     = CF2 { unCF2 :: DrawingContext -> r1 -> r2 -> a }++ ++-- | Type specialized verison of 'CF1' where the /static argument/+-- is the /start point/.+-- +-- > LocCF :: DrawingContext -> Point2 u -> a +--+type LocCF          u a = CF1 (Point2 u) a+++-- | Type specialized verison of 'CF2' where the /static arguments/+-- are the /start point/ and the /angle of displacement/.+-- +-- > LocThetaCF :: DrawingContext -> Point2 u -> Radian -> a +--+type LocThetaCF     u a = CF2 (Point2 u) Radian a+++-- | Type specialized verison of 'CF2' where the /static arguments/+-- are the /start point/ and the /end point/.+-- +-- > ConnectorCF :: DrawingContext -> Point2 u -> Point2 u -> a +--+type ConnectorCF    u a = CF2 (Point2 u) (Point2 u) a+++-- | Alias of 'LocCF' where the unit type is specialized to +-- @Double@.+--+type DLocCF a           = LocCF       Double a+++-- | Alias of 'LocThetaCF' where the unit type is specialized to +-- @Double@.+--+type DLocThetaCF a      = LocThetaCF  Double a++-- | Alias of 'ConnectorCF' where the unit type is specialized to +-- @Double@.+--+type DConnectorCF a     = ConnectorCF Double a++++--------------------------------------------------------------------------------+-- CF instances++-- OPlus++instance OPlus a => OPlus (CF a)  where+  fa `oplus` fb = CF $ \ctx -> unCF fa ctx `oplus` unCF fb ctx++instance OPlus a => OPlus (CF1 r1 a)  where+  fa `oplus` fb = CF1 $ \ctx r1 -> unCF1 fa ctx r1 `oplus` unCF1 fb ctx r1++instance OPlus a => OPlus (CF2 r1 r2 a)  where+  fa `oplus` fb = CF2 $ \ctx r1 r2 -> +                          unCF2 fa ctx r1 r2 `oplus` unCF2 fb ctx r1 r2+++-- Monoid+ +-- Nothing is stopping monoid instances, though in practice there+-- might be few useful types (more in Semgigroup / OPlus)...++instance Monoid a => Monoid (CF a) where +  mempty          = CF $ \_   -> mempty+  fa `mappend` fb = CF $ \ctx -> unCF fa ctx `mappend` unCF fb ctx++instance Monoid a => Monoid (CF1 r1 a) where +  mempty          = CF1 $ \_   _  -> mempty+  fa `mappend` fb = CF1 $ \ctx r1 -> unCF1 fa ctx r1 `mappend` unCF1 fb ctx r1++instance Monoid a => Monoid (CF2 r1 r2 a) where +  mempty          = CF2 $ \_   _  _  -> mempty+  fa `mappend` fb = CF2 $ \ctx r1 r2 -> +                            unCF2 fa ctx r1 r2 `mappend` unCF2 fb ctx r1 r2++++-- Functor++instance Functor CF where+  fmap f ma = CF $ \ctx -> f $ unCF ma ctx +++instance Functor (CF1 r1) where+  fmap f ma = CF1 $ \ctx r1 -> f $ unCF1 ma ctx r1 ++instance Functor (CF2 r1 r2) where+  fmap f ma = CF2 $ \ctx r1 r2 -> f $ unCF2 ma ctx r1 r2++++-- Applicative++instance Applicative CF where+  pure a    = CF $ \_   -> a+  mf <*> ma = CF $ \ctx -> let f = unCF mf ctx+                               a = unCF ma ctx+                           in f a+++instance Applicative (CF1 r1) where+  pure a    = CF1 $ \_   _  -> a+  mf <*> ma = CF1 $ \ctx r1 -> let f = unCF1 mf ctx r1 +                                   a = unCF1 ma ctx r1+                               in f a+++instance Applicative (CF2 r1 r2) where+  pure a    = CF2 $ \_   _  _  -> a+  mf <*> ma = CF2 $ \ctx r1 r2 -> let f = unCF2 mf ctx r1 r2+                                      a = unCF2 ma ctx r1 r2+                                  in f a+++++-- Monad ++instance Monad CF where+  return a  = CF $ \_   -> a+  ma >>= k  = CF $ \ctx -> let a = unCF ma ctx in (unCF . k) a ctx ++instance Monad (CF1 r1) where+  return a  = CF1 $ \_   _  -> a+  ma >>= k  = CF1 $ \ctx r1 -> let a = unCF1 ma ctx  r1 in (unCF1 . k) a ctx r1 ++instance Monad (CF2 r1 r2) where+  return a  = CF2 $ \_   _  _  -> a+  ma >>= k  = CF2 $ \ctx r1 r2 -> +                      let a = unCF2 ma ctx r1 r2 in (unCF2 . k) a ctx r1 r2++++-- DrawingCtxM ++instance DrawingCtxM CF where+  askDC           = CF $ \ctx -> ctx+  localize upd df = CF $ \ctx -> unCF df (upd ctx)+  ++instance DrawingCtxM (CF1 r1) where+  askDC           = CF1 $ \ctx _  -> ctx+  localize upd df = CF1 $ \ctx r1 -> unCF1 df (upd ctx) r1+++instance DrawingCtxM (CF2 r1 r2) where+  askDC           = CF2 $ \ctx _  _  -> ctx+  localize upd df = CF2 $ \ctx r1 r2 -> unCF2 df (upd ctx) r1 r2+++-- Note - there is nothing determining a DUnit for the CF types, +-- so it seems appropriate not to define affine instances.+--+-- However affine instances can be made for the Image type in +-- Objects.BaseObjects.+--+++--------------------------------------------------------------------------------+-- Run functions++-- | Run a /CF/ (context function) with the supplied +-- /DrawingContext/.+--+runCF :: DrawingContext -> CF a -> a+runCF ctx df = unCF df ctx+++-- | Run a /CF1/ (context function) with the supplied +-- /DrawingContext/ and static argument.+--+runCF1 :: DrawingContext -> r1 -> CF1 r1 a -> a+runCF1 ctx r1 df = unCF1 df ctx r1+++-- | Run a /CF1/ (context function) with the supplied +-- /DrawingContext/ and two static arguments.+--+runCF2 :: DrawingContext -> r1 -> r2 -> CF2 r1 r2 a -> a+runCF2 ctx r1 r2 df = unCF2 df ctx r1 r2++++--------------------------------------------------------------------------------+-- lift functions+++-- | Lift a zero-arity context function 'CF' to an arity one +-- context function 'CF1'.+-- +lift0R1             :: CF a -> CF1 r1 a+lift0R1 mf          = CF1 $ \ctx _ -> unCF mf ctx++-- | Lift a zero-arity context function 'CF' to an arity two +-- context function 'CF2'.+-- +lift0R2             :: CF a -> CF2 r1 r2 a+lift0R2 mf          = CF2 $ \ctx _ _ -> unCF mf ctx++-- | Lift an arity one context function 'CF1' to an arity two+-- context function 'CF2'.+-- +lift1R2             :: CF1 r1 a -> CF2 r1 r2 a+lift1R2 mf          = CF2 $ \ctx r1 _ -> unCF1 mf ctx r1++++-- | Promote a function @from one argument to a Context function@ +-- to an arity one @Context function@.+--+-- The type signature is as explanatory as a description:+--+-- > promoteR1 :: (r1 -> CF a) -> CF1 r1 a+-- +promoteR1           :: (r1 -> CF a) -> CF1 r1 a+promoteR1 mf        = CF1 $ \ctx r1 -> unCF (mf r1) ctx++-- | Promote a function @from two arguments to a Context function@ +-- to an arity two @Context function@.+--+-- The type signature is as explanatory as a description:+--+-- > promoteR2 :: (r1 -> r2 -> CF a) -> CF2 r1 r2 a+-- +promoteR2           :: (r1 -> r2 -> CF a) -> CF2 r1 r2 a+promoteR2 mf        = CF2 $ \ctx r1 r2 -> unCF (mf r1 r2) ctx++++-- | Apply an arity-one Context function to a single argument, +-- downcasting it by one level, making an arity-zero Context +-- function. +-- +-- The type signature is as explanatory as a description:+--+-- > apply1R1 :: CF1 r1 a -> r1 -> CF a+--+apply1R1            :: CF1 r1 a -> r1 -> CF a+apply1R1 mf r1      = CF $ \ctx -> unCF1 mf ctx r1+++-- | Apply an arity-two Context function to two arguments, +-- downcasting it by two levels, making an arity-zero Context +-- function. +-- +-- The type signature is as explanatory as a description:+--+-- > apply2R2 :: CF2 r1 r2 a -> r1 -> r2 -> CF a+-- +apply2R2            :: CF2 r1 r2 a -> r1 -> r2 -> CF a+apply2R2 mf r1 r2   = CF $ \ctx -> unCF2 mf ctx r1 r2++-- | Apply an arity-two Context function to one argument, +-- downcasting it by one level, making an arity-one Context +-- function. +-- +-- The type signature is as explanatory as a description:+--+-- > apply1R2 :: CF2 r1 r2 a -> r2 -> CF1 r1 a+--+apply1R2            :: CF2 r1 r2 a -> r2 -> CF1 r1 a+apply1R2 mf r2      = CF1 $ \ctx r1 -> unCF2 mf ctx r1 r2+++--------------------------------------------------------------------------------+-- 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          = CF1 $ \ctx _  -> ctx++-- | Extract the /start/ point from a LocCF.+--+-- > (ctx -> pt -> pt)+--+locPoint        :: LocCF u (Point2 u)+locPoint        = CF1 $ \_ pt -> pt+++-- | Extract the drawing context from a LocThetaCF.+--+-- > (ctx -> pt -> ang -> ctx)+--+locThetaCtx     :: LocThetaCF u DrawingContext+locThetaCtx     = CF2 $ \ctx _ _ -> ctx+++-- | Extract the /start/ point from a LocThetaCF.+--+-- > (ctx -> pt -> ang -> pt)+--+locThetaPoint   :: LocThetaCF u (Point2 u)+locThetaPoint   = CF2 $ \_ pt _ -> pt++-- | Extract the angle from a LocThetaCF.+--+-- > (ctx -> pt -> ang -> ang)+--+locThetaAng     :: LocThetaCF u Radian+locThetaAng     = CF2 $ \_ _ ang -> ang++-- | Extract the drawing context from a ConnectorCF.+--+-- > (ctx -> pt1 -> pt2 -> ctx)+--+connCtx         :: ConnectorCF u DrawingContext+connCtx         = CF2 $ \ctx _ _ -> ctx++-- | Extract the start point from a ConnectorCF.+--+-- > (ctx -> pt1 -> pt2 -> pt1)+--+connStart       :: ConnectorCF u (Point2 u) +connStart       = CF2 $ \_ pt _ -> pt++-- | Extract the end point from a ConnectorCF.+--+-- > (ctx -> pt1 -> pt2 -> pt2)+--+connEnd         :: ConnectorCF u (Point2 u) +connEnd         = CF2 $ \_ _ pt -> pt++++++--------------------------------------------------------------------------------+-- Combinators++++infixr 1 `at`+++-- | Downcast a 'LocCF' function by applying it to the supplied +-- point, making an arity-zero Context function. +-- +-- Remember a 'LocCF' function is a 'CF1' context function where+-- the /static argument/ is specialized to a start point.+--+at :: LocCF u a -> Point2 u -> CF a+at = apply1R1+++infixr 1 `rot`+++-- | Downcast a 'LocThetaCF' function by applying it to the +-- supplied angle, making an arity-one Context function (a +-- 'LocCF'). +-- ++rot :: LocThetaCF u a -> Radian -> LocCF u a+rot = apply1R2+++-- | Downcast a 'ConnectorCF' function by applying it to the +-- start and end point, making an arity-zero Context function +-- (a 'CF'). +-- +connect :: ConnectorCF u a -> Point2 u -> Point2 u -> CF a+connect = apply2R2++++infixr 6 `chain1`++-- | /Chaining/ combinator - the /answer/ of the +-- first Context function is feed to the second Context function. +--+-- This contrasts with the usual idiom in @Wumpus-Basic@ where +-- composite graphics are built by applying both functions to the +-- same initial /static argument/.+--+-- Desciption:+--+-- 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@.+--+-- @ (ctx -> s1 -> (w,s1)) -> (ctx -> s1 -> (w,s1)) -> (ctx -> s1 -> (w,s1)) @+--+-- This models chaining start points together, which is the model+-- PostScript uses for text output when successively calling the +-- @show@ operator.+-- +chain1 :: OPlus w +            => CF1 s1 (s1,w) -> CF1 s1 (s1,w) -> CF1 s1 (s1,w)+chain1 f g = CF1 $ \ctx s -> let (s1,a1) = unCF1 f ctx s+                                 (s2,a2) = unCF1 g ctx s1+                             in (s2, a1 `oplus` a2)++
+ src/Wumpus/Basic/Kernel/Base/DrawingContext.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE KindSignatures             #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Base.DrawingContext+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Drawing attributes+--+-- \*\* WARNING \*\* - this module needs systematic naming +-- schemes both for update functions (primaryColour, ...) and +-- for synthesized selectors (e.g. lowerxHeight). The current +-- names will change.+--+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Base.DrawingContext+  ( ++  -- * Drawing context+    DrawingContext(..)+  , DrawingContextF++  , standardContext+  , metricsContext++  , default_drawing_context++  -- * DrawingCtxM (reader) monad+  , DrawingCtxM(..)+  , asksDC+++  -- * Glyph metrics+  , withFontMetrics++  +  ) where+++import Wumpus.Basic.Kernel.Base.GlyphMetrics++import Wumpus.Core                              -- package: wumpus-core+import Wumpus.Core.Text.StandardEncoding++import Control.Applicative+import Data.Maybe+++data DrawingContext = DrawingContext+      { glyph_tables          :: GlyphMetrics+      , fallback_metrics      :: MetricsOps+      , stroke_props          :: StrokeAttr+      , font_props            :: FontAttr+      , stroke_colour         :: RGBi      -- also text colour...+      , fill_colour           :: RGBi      +      , line_spacing_factor   :: Double+      }++-- TODO - hand craft a Show instance ++type DrawingContextF = DrawingContext -> DrawingContext+++standardContext :: FontSize -> DrawingContext+standardContext sz = +    DrawingContext { glyph_tables         = emptyGlyphMetrics+                   , 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  +                   }++-- out-of-date - should be adding loaded fonts, not replacing the +-- GlyphMetrics Map wholesale.+--+metricsContext :: FontSize -> GlyphMetrics -> 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)++++--------------------------------------------------------------------------------+++class (Applicative m, Monad m) => DrawingCtxM (m :: * -> *) where+  askDC    :: m DrawingContext+  localize :: (DrawingContext -> DrawingContext) -> m a -> m a+++-- | Project a value out of a context.+--+asksDC :: DrawingCtxM m => (DrawingContext -> a) -> m a+asksDC f = askDC >>= (return . f)++++--------------------------------------------------------------------------------+-- Glyph metrics++-- These are directly on the DrawingContext /for efficiency/.++++withFontMetrics :: (MetricsOps -> 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) $ +                    lookupFont ps_name (glyph_tables ctx) ++
+ src/Wumpus/Basic/Kernel/Base/GlyphMetrics.hs view
@@ -0,0 +1,117 @@+{-# LANGUAGE RankNTypes                 #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Base.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.Kernel.Base.GlyphMetrics+  ( ++    FontName+  , CodePoint+  , CharWidthTable+  , MetricsOps(..)+  , FontMetricsOps(..)++  , GlyphMetrics+  , emptyGlyphMetrics+  , lookupFont+  , insertFont++  , monospace_metrics++  +  ) where++import Wumpus.Core                              -- package: wumpus-core++import qualified Data.Map      as Map+import Data.Monoid++++type FontName = String++-- | A Unicode code-point.+--+type CodePoint = Int++-- | A lookup from code point to /width vector/.+--+-- Note - in PostScript terminology a width vector is not obliged+-- to be left-to-right (writing direction 0). It could be +-- top-to-bottom (writing direction 1).+--+type CharWidthTable u = CodePoint -> Vec2 u++++-- | Operations on the metrics set of a font.+--+-- The is the internal representation used by Wumpus-Basic after+-- parsing the font file.+--+data MetricsOps = MetricsOps+      { get_bounding_box  :: forall u. FromPtSize u => PtSize -> BoundingBox u +      , get_cw_table      :: forall u. FromPtSize u => PtSize -> CharWidthTable u+      , get_cap_height    :: forall u. FromPtSize u => PtSize -> u+      }++-- | 'MetricsOps' tfor a particular named font.+-- +data FontMetricsOps = FontMetricsOps FontName MetricsOps+++-- | A map between a font name and MetricsOps.+--+newtype GlyphMetrics = GlyphMetrics { +          getGlyphMetrics :: Map.Map FontName MetricsOps }++instance Monoid GlyphMetrics where+  mempty        = emptyGlyphMetrics+  a `mappend` b = GlyphMetrics $ getGlyphMetrics a `mappend` getGlyphMetrics b+++emptyGlyphMetrics :: GlyphMetrics+emptyGlyphMetrics = GlyphMetrics $ Map.empty++lookupFont :: FontName -> GlyphMetrics -> Maybe MetricsOps+lookupFont name = Map.lookup name . getGlyphMetrics++insertFont :: FontMetricsOps -> GlyphMetrics -> GlyphMetrics+insertFont (FontMetricsOps name ops) = +    GlyphMetrics . Map.insert name ops . getGlyphMetrics++-- | This ignores the Char code lookup and just returns the +-- default advance vector.+--+monospace_metrics :: MetricsOps+monospace_metrics = MetricsOps+    { get_bounding_box  = \sz -> BBox (lowerLeft sz) (upperRight sz)+    , get_cw_table      = \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) ++
+ src/Wumpus/Basic/Kernel/Base/QueryDC.hs view
@@ -0,0 +1,263 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Base.QueryDC+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Querying the Drawing Context.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Base.QueryDC+  ( ++    +    textAttr+  , withTextAttr++  , strokeAttr+  , withStrokeAttr++  , fillAttr+  , withFillAttr++  , borderedAttr+  , withBorderedAttr++  , getLineWidth+  , getFontAttr+  , getFontSize+  , getFontFace+  , markHeight+  , markHalfHeight+  , baselineSpacing++  -- * Glyph metrics+  , glyphBoundingBox+  , glyphHeightRange+  , glyphHeight+  , glyphCapHeight++  , cwLookupTable++  -- * Default monospace metrics++  , monoFontPointSize+  , monoCharWidth+  , monoTextWidth+  , monoTextLength+  , monoCapHeight+  , monoLowerxHeight+  , monoDescenderDepth+  , monoAscenderHeight+  , monoTextDimensions+  , monoMultiLineHeight+  , monoDefaultPadding+  , monoVecToCenter  +  ) where++import Wumpus.Basic.Kernel.Base.DrawingContext+import Wumpus.Basic.Kernel.Base.GlyphMetrics++import Wumpus.Core                              -- package: wumpus-core+import qualified Wumpus.Core.FontSize   as FS+ +import Control.Applicative+++textAttr :: DrawingCtxM m => m (RGBi,FontAttr)+textAttr = (,) <$> asksDC stroke_colour <*> asksDC font_props++-- | Because @textAttr@ is so commonly used here is a functional+-- version that avoids tupling.+--+withTextAttr :: DrawingCtxM m => (RGBi -> FontAttr -> a) -> m a+withTextAttr fn = fn <$> asksDC stroke_colour <*> asksDC font_props+++strokeAttr :: DrawingCtxM m => m (RGBi, StrokeAttr)+strokeAttr = (,) <$> asksDC stroke_colour <*> asksDC stroke_props++withStrokeAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> a) -> m a+withStrokeAttr fn = fn <$> asksDC stroke_colour <*> asksDC stroke_props+++fillAttr :: DrawingCtxM m => m RGBi+fillAttr = asksDC fill_colour++withFillAttr :: DrawingCtxM m => (RGBi -> a) -> m a+withFillAttr fn = fn <$> asksDC fill_colour++borderedAttr :: DrawingCtxM m => m (RGBi, StrokeAttr, RGBi)+borderedAttr = (,,) <$> asksDC fill_colour <*> asksDC stroke_props +                                           <*> asksDC stroke_colour++withBorderedAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> RGBi -> a) -> m a+withBorderedAttr fn = +    fn <$> asksDC fill_colour <*> asksDC stroke_props +                              <*> asksDC stroke_colour+++++getLineWidth :: DrawingCtxM m => m Double+getLineWidth = line_width <$> asksDC stroke_props++getFontAttr :: DrawingCtxM m => m FontAttr+getFontAttr = asksDC font_props++getFontSize :: DrawingCtxM m => m Int+getFontSize = font_size <$> asksDC font_props++getFontFace :: DrawingCtxM m => m FontFace+getFontFace = font_face <$> asksDC font_props+++++-- | Vertical distance between baselines of consecutive text +-- lines.+--+baselineSpacing :: (DrawingCtxM m, Fractional u) => m u+baselineSpacing = +    (\sz factor -> realToFrac $ factor * fromIntegral sz)+      <$> asksDC (font_size . font_props) <*> asksDC line_spacing_factor++-- | The /mark/ height is the height of a lowercase letter in the +-- current font.+--+-- Arrowheads, dots etc. should generally be drawn at the mark +-- height.+-- +markHeight :: (DrawingCtxM m, FromPtSize u) => m u+markHeight = (fromPtSize . FS.xcharHeight . font_size) <$> asksDC font_props+++markHalfHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u+markHalfHeight = (0.5*) <$> markHeight+++-- Note - there are probably enough functions that use just +-- markHeight to merit a withMarkHeight function.+++--------------------------------------------------------------------------------++glyphQuery :: DrawingCtxM m => (MetricsOps -> 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++cwLookupTable :: (FromPtSize u, DrawingCtxM m) => m (CharWidthTable u)+cwLookupTable = glyphQuery get_cw_table+++--------------------------------------------------------------------------------++withFontSize :: DrawingCtxM m => (FontSize -> u) -> m u+withFontSize fn = (fn . font_size) <$> asksDC font_props+++-- 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 $ FS.textWidth sz n+++monoTextLength :: (DrawingCtxM m, FromPtSize u) => String -> m u+monoTextLength ss = monoTextWidth $ charCount ss+++monoCapHeight :: (DrawingCtxM m, FromPtSize u) => m u+monoCapHeight = withFontSize (fromPtSize . FS.capHeight)++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 . FS.xcharHeight)++monoDescenderDepth :: (DrawingCtxM m, FromPtSize u) => m u+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.+--+-- Note - the width will generally be a over-estimate for +-- non-monospaced fonts.+-- +monoTextDimensions :: (DrawingCtxM m, Num u, Ord u, FromPtSize u)+                   => String -> m (u,u)+monoTextDimensions ss = +    (\sz -> post $ textBounds sz zeroPt ss) +      <$> asksDC (font_size . font_props)+  where+    post bb = (boundaryWidth bb, boundaryHeight bb)+++-- | 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+monoMultiLineHeight n | n < 0   = pure 0+monoMultiLineHeight n           = +    (\h lsf -> h + (fromIntegral $ n-1) * (h * realToFrac lsf))+      <$> 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/.+--+monoDefaultPadding :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u+monoDefaultPadding = (0.5*) <$> monoCharWidth++-- | Vector from baseline left to center+--+monoVecToCenter :: (DrawingCtxM m, Fractional u, Ord u, FromPtSize u) +                => String -> m (Vec2 u)+monoVecToCenter ss = (\(w,h) dy -> vec (0.5*w) (0.5*h - dy)) +                       <$> monoTextDimensions ss <*> monoDescenderDepth
+ src/Wumpus/Basic/Kernel/Base/ScalingContext.hs view
@@ -0,0 +1,195 @@+{-# LANGUAGE TypeFamilies               #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Base.ScalingContext+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC+--+-- Scaling in X and Y+--+-- \*\* WARNING \*\* - half baked.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Base.ScalingContext+  (++    ScalingM(..)+  , ScalingContext(..)++  , Scaling+  , runScaling+  , ScalingT+  , runScalingT++  , regularScalingContext+  , coordinateScalingContext++  , unitX+  , unitY+++  ) where++import Wumpus.Basic.Kernel.Base.BaseDefs+import Wumpus.Basic.Kernel.Base.DrawingContext+import Wumpus.Basic.Kernel.Base.WrappedPrimitive++import Wumpus.Core				-- package: wumpus-core++import Control.Applicative++++-- | Scaling...+--+class Monad m => ScalingM m where+  type XDim m :: *+  type YDim m :: *+  scaleX :: (u ~ MonUnit m, ux ~ XDim m) => ux -> m u+  scaleY :: (u ~ MonUnit m, uy ~ YDim m) => uy -> m u+  scalePt  :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m) +           => ux -> uy -> m (Point2 u)+  scaleVec :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m) +           => ux -> uy -> m (Vec2 u)++++data ScalingContext ux uy u = ScalingContext+      { scale_in_x  :: ux -> u+      , scale_in_y  :: uy -> u+      }++++-- Chains (for example) want a plain monad rather than a transformer.+--+newtype Scaling ux uy u a = Scaling {+          getScaling :: ScalingContext ux uy u -> a }+++type instance MonUnit (Scaling ux uy u) = u++++instance Functor (Scaling ux uy u) where+  fmap f ma = Scaling $ \ctx -> let a = getScaling ma ctx in f a++instance Applicative (Scaling ux uy u) where+  pure a    = Scaling $ \_   -> a+  mf <*> ma = Scaling $ \ctx -> let f = getScaling mf ctx+                                    a = getScaling ma ctx+             			in (f a)++instance Monad (Scaling ux uy u) where+  return a = Scaling $ \_   -> a+  m >>= k  = Scaling $ \ctx -> let a = getScaling m ctx+    	     	               in (getScaling . k) a ctx++++instance ScalingM (Scaling ux uy u) where+  type XDim (Scaling ux uy u) = ux +  type YDim (Scaling ux uy u) = uy+  scaleX ux       = Scaling $ \ctx -> (scale_in_x ctx) ux+  scaleY uy       = Scaling $ \ctx -> (scale_in_y ctx) uy+  scalePt ux uy   = Scaling $ \ctx -> P2 (scale_in_x ctx ux) (scale_in_y ctx uy)+  scaleVec ux uy  = Scaling $ \ctx -> V2 (scale_in_x ctx ux) (scale_in_y ctx uy)++runScaling :: ScalingContext ux uy u -> Scaling ux uy u a -> a+runScaling ctx sf = (getScaling sf) ctx    +++++--------------------------------------------------------------------------------+-- Transformer++-- Turtle (for example) wants a transformer so it can use TraceM+-- and DrawingCtxM+--+newtype ScalingT ux uy u m a = ScalingT { +          getScalingT :: ScalingContext ux uy u -> m a }++type instance MonUnit (ScalingT ux uy u m) = u+++instance Monad m => Functor (ScalingT ux uy u m) where+  fmap f ma = ScalingT $ \ctx -> getScalingT ma ctx >>= \a -> return (f a)++instance Monad m => Applicative (ScalingT ux uy u m) where+  pure a    = ScalingT $ \_   -> return a+  mf <*> ma = ScalingT $ \ctx -> getScalingT mf ctx >>= \f -> +                                 getScalingT ma ctx >>= \a ->+             			 return (f a)++instance Monad m => Monad (ScalingT ux uy u m) where+  return a = ScalingT $ \_   -> return a+  m >>= k  = ScalingT $ \ctx -> getScalingT m ctx >>= \a -> +    	     	      	     	(getScalingT . k) a ctx+++instance Monad m => ScalingM (ScalingT ux uy u m) where+  type XDim (ScalingT ux uy u m) = ux +  type YDim (ScalingT ux uy u m) = uy+  scaleX ux       = ScalingT $ \ctx -> return $ (scale_in_x ctx) ux+  scaleY uy       = ScalingT $ \ctx -> return $ (scale_in_y ctx) uy+  scalePt ux uy   = ScalingT $ \ctx -> +                      return $ P2 (scale_in_x ctx ux) (scale_in_y ctx uy)+  scaleVec ux uy  = ScalingT $ \ctx -> +                      return $ V2 (scale_in_x ctx ux) (scale_in_y ctx uy)++++-- Cross instances - needed to run SalingT /locally/ in Drawing.++instance DrawingCtxM m => DrawingCtxM (ScalingT ux uy u m) where+  askDC           = ScalingT $ \_    -> askDC >>= \dctx -> return dctx+  localize upd mf = ScalingT $ \sctx -> localize upd (getScalingT mf sctx)+++instance (Monad m, TraceM m, u ~ MonUnit m) => TraceM (ScalingT ux uy u m) where+  trace a  = ScalingT $ \_ -> trace a +++++runScalingT :: ScalingContext ux uy u -> ScalingT ux uy u m a -> m a+runScalingT ctx sf = (getScalingT sf) ctx    ++--------------------------------------------------------------------------------+-- constructors for scaling context++regularScalingContext :: Num u => u -> ScalingContext u u u+regularScalingContext u = ScalingContext+      { scale_in_x  = (\x -> u*x)+      , scale_in_y  = (\y -> u*y)+      }++coordinateScalingContext :: Num u => u -> u -> ScalingContext Int Int u+coordinateScalingContext sx sy = ScalingContext+      { scale_in_x  = (\x -> sx * fromIntegral x)+      , scale_in_y  = (\y -> sy * fromIntegral y)+      }++++--------------------------------------------------------------------------------+-- operations+++++unitX :: (ScalingM m, Num ux, ux ~ XDim m, u ~ MonUnit m) => m u+unitX = scaleX 1+ +unitY :: (ScalingM m, Num uy, uy ~ YDim m, u ~ MonUnit m) => m u+unitY = scaleY 1++ 
+ src/Wumpus/Basic/Kernel/Base/UpdateDC.hs view
@@ -0,0 +1,244 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Base.UpdateDC+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Customize drawing attributes+--+-- \*\* WARNING \*\* - this module needs systematic naming +-- schemes both for update functions (primaryColour, ...) and +-- for synthesized selectors (e.g. lowerxHeight). The current +-- names will change.+--+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Base.UpdateDC+  ( ++  -- * Modifiers +  -- ** Line widths+    lineWidth+  , thick+  , ultrathick+  , thin++  -- ** Line caps+  , capButt+  , capRound+  , capSquare++  -- ** Line joins+  , joinMiter+  , joinRound+  , joinBevel++  -- ** Dash Pattern+  , dashPattern+  , unit_dash_pattern+  , phase+  , dphase+  , doublegaps+  , doubledashes++  -- * Font properties+  , fontAttr+  , fontSize+  , fontFace++  -- * Font / mark drawing size+  , doublesize+  , halfsize++  -- * Colour+  , swapColours+  , bothStrokeColour+  , bothFillColour+  , strokeColour+  , fillColour +++  +  ) where+++import Wumpus.Basic.Kernel.Base.DrawingContext++import Wumpus.Core                              -- package: wumpus-core++import Control.Applicative+++--------------------------------------------------------------------------------++updateStrokeProps :: (StrokeAttr -> StrokeAttr) -> DrawingContextF+updateStrokeProps fn = (\s i -> s { stroke_props = fn i }) <*> stroke_props++updateFontProps :: (FontAttr -> FontAttr) -> DrawingContextF+updateFontProps fn = (\s i -> s { font_props = fn i }) <*> font_props+++--------------------------------------------------------------------------------+-- line widths++-- Note - some care might be needed if we ever define other unit +-- types...++lineWidth       :: Double -> DrawingContextF+lineWidth d      = updateStrokeProps (\s -> s { line_width = d })+++-- std_line_width      :: Double+-- std_line_width      = 1.0++thick_line          :: Double+thick_line          = 2.0++ultra_thick_line    :: Double+ultra_thick_line    = 4.0++thin_line           :: Double+thin_line           = 0.5+++-- | Set the line width to a /thick/.+--+-- Note this context update is /oblivious/ - operationally the +-- line width is set to exactly @2.0@.+--+thick               :: DrawingContextF+thick               = lineWidth thick_line++ultrathick          :: DrawingContextF+ultrathick          = lineWidth ultra_thick_line++thin                :: DrawingContextF+thin                = lineWidth thin_line+++--------------------------------------------------------------------------------++setLineCap          :: LineCap -> DrawingContextF+setLineCap d        = updateStrokeProps (\s -> s { line_cap = d })+++capButt             :: DrawingContextF+capButt             = setLineCap CapButt++capRound            :: DrawingContextF+capRound            = setLineCap CapRound++capSquare           :: DrawingContextF+capSquare           = setLineCap CapSquare+++setLineJoin         :: LineJoin -> DrawingContextF+setLineJoin d       = updateStrokeProps (\s -> s { line_join = d })+++joinMiter           :: DrawingContextF+joinMiter           = setLineJoin JoinMiter++joinRound           :: DrawingContextF+joinRound           = setLineJoin JoinRound++joinBevel           :: DrawingContextF+joinBevel           = setLineJoin JoinBevel+++--------------------------------------------------------------------------------++dashPattern         :: DashPattern -> DrawingContextF+dashPattern d       = updateStrokeProps (\s -> s { dash_pattern = d })        ++unit_dash_pattern   :: DashPattern+unit_dash_pattern   = Dash 0 [(1,1)]++-- oblivious+phase               :: Int -> DashPattern -> DashPattern+phase _ Solid       = Solid+phase i (Dash _ xs) = Dash i xs++-- non-oblivious+dphase               :: Int -> DashPattern -> DashPattern+dphase _ Solid       = Solid+dphase d (Dash i xs) = Dash (i+d) xs++doublegaps              :: DashPattern -> DashPattern+doublegaps Solid        = Solid+doublegaps (Dash i xs)  = Dash i (map fn xs)+  where+    fn (a,b) = (a,2*b)++doubledashes              :: DashPattern -> DashPattern+doubledashes Solid        = Solid+doubledashes (Dash i xs)  = Dash i (map fn xs)+  where+    fn (a,b) = (a*2,b)+++--------------------------------------------------------------------------------++fontAttr            :: FontFace -> Int -> DrawingContextF+fontAttr ff sz      = (\s -> s { font_props = FontAttr sz ff })++fontFace            :: FontFace -> DrawingContextF+fontFace ff         = updateFontProps (\(FontAttr sz _) -> FontAttr sz ff)++fontSize            :: Int -> DrawingContextF+fontSize sz         = updateFontProps (\(FontAttr _ ff) -> FontAttr sz ff)+++--------------------------------------------------------------------------------++-- | Set the font size to double the current size, note the font+-- size also controls the size of dots, arrowsheads etc.+-- +doublesize          :: DrawingContextF+doublesize          = (\s sz -> fontSize (sz*2) s) +                        <*> (font_size . font_props)+++-- | Set the font size to half the current size, note the font+-- size also controls the size of dots, arrowsheads etc.+-- +-- As fontsize is an integer this is not exact - half size of+-- 15pt type is 7pt.+-- +halfsize            :: DrawingContextF+halfsize            = (\s sz -> fontSize (sz `div` 2) s) +                        <*> (font_size . font_props)+++--------------------------------------------------------------------------------++swapColours :: DrawingContextF+swapColours = +    (\s a b -> s { stroke_colour = b, fill_colour = a })+        <*> stroke_colour <*> fill_colour++bothStrokeColour :: DrawingContextF+bothStrokeColour = (\s a -> s { fill_colour = a }) <*> stroke_colour++bothFillColour :: DrawingContextF+bothFillColour = (\s a -> s { stroke_colour = a }) <*> fill_colour++++strokeColour :: RGBi -> DrawingContextF+strokeColour rgb = \s -> s { stroke_colour = rgb } +++fillColour :: RGBi -> DrawingContextF+fillColour rgb = \s -> s { fill_colour = rgb } ++++
+ src/Wumpus/Basic/Kernel/Base/WrappedPrimitive.hs view
@@ -0,0 +1,149 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeSynonymInstances       #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Base.WrappedPrimitive+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- Two /warpped/ versions of the Primitive type from Wumpus-Core.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Base.WrappedPrimitive+  (++  -- * Primitives+    HPrim+  , hprimToList+  , singleH++  -- * Collect primitives (writer monad) +  , TraceM(..)++  , PrimGraphic++  , getPrimGraphic+  , primGraphic+  , metamorphPrim+  , collectH++  ) where++import Wumpus.Basic.Kernel.Base.BaseDefs+import Wumpus.Basic.Utils.HList++import Wumpus.Core                      -- package: wumpus-core+++import Data.Monoid++++-- As of version 0.36.0, Wumpus-Core supports grouping primitives+-- together (a common operation in vector drawing editors). +--+-- For Wumpus-Basic this means e.g. a line with arrowheads can +-- still be a primitive.+--+-- Still, we wrap Primitive as a newtype...+--++newtype PrimGraphic u = PrimGraphic { getPrimGraphic :: Primitive u }+  deriving (Eq,Show)+++type instance DUnit (PrimGraphic u) = u++++--------------------------------------------------------------------------------+-- Lists of primitives...++-- | Graphics objects, even simple ones (line, arrow, dot) might +-- need more than one primitive (path or text label) for their+-- construction. Hence, the primary representation that all the +-- others are built upon must support /concatenation/ of +-- primitives. +--+-- Wumpus-Core has a type Picture - made from one or more +-- Primitives - but Pictures include support for affine frames. +-- For drawing many simple graphics (dots, connector lines...) +-- that do not need individual affine transformations this is a +-- penalty. A list of Primitives is therefore more suitable +-- representation, and a Hughes list which supports+-- efficient concatenation is wise.+--+newtype HPrim u = HPrim { getHPrim :: H (Primitive u) }++-- Note - only a Monoid instance for HPrim - they cannot be +-- shown, fmapped etc.++instance Monoid (HPrim u) where+  mempty          = HPrim emptyH+  ha `mappend` hb = HPrim $ getHPrim ha `appendH` getHPrim hb+++hprimToList :: HPrim u -> [Primitive u]+hprimToList = toListH . getHPrim+++singleH :: Primitive u -> HPrim u+singleH = HPrim . wrapH +++--------------------------------------------------------------------------------++-- | Collect elementary graphics as part of a larger drawing.+--+-- TraceM works much like a writer monad.+--+class TraceM (m :: * -> *) where+  trace  :: MonUnit m ~ u => HPrim u -> m ()++++++--------------------------------------------------------------------------------+-- instances++instance OPlus (PrimGraphic u) where+  oplus a b = PrimGraphic $ getPrimGraphic a `oplus` getPrimGraphic b+++-- Affine transformations++instance (Real u, Floating u) => Rotate (PrimGraphic u) where+  rotate ang = PrimGraphic . rotate ang . getPrimGraphic+++instance (Real u, Floating u) => RotateAbout (PrimGraphic u) where+  rotateAbout ang pt = PrimGraphic . rotateAbout ang pt . getPrimGraphic+++instance Num u => Scale (PrimGraphic u) where+  scale sx sy = PrimGraphic . scale sx sy . getPrimGraphic+++instance Num u => Translate (PrimGraphic u) where+  translate dx dy = PrimGraphic . translate dx dy . getPrimGraphic++--------------------------------------------------------------------------------++primGraphic :: Primitive u -> PrimGraphic u +primGraphic = PrimGraphic++metamorphPrim :: (Primitive u -> Primitive u) -> PrimGraphic u -> PrimGraphic u+metamorphPrim f = primGraphic . f . getPrimGraphic++collectH :: PrimGraphic u -> HPrim u+collectH = singleH . getPrimGraphic+
+ src/Wumpus/Basic/Kernel/Geometry/Intersection.hs view
@@ -0,0 +1,172 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Geometry.Intersection+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Intersection of line to line and line to plane+-- +-- \*\* - WARNING \*\* - half baked. +--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Geometry.Intersection+  ( +    LineSegment(..)+  , PointSlope+  , pointSlope+  , LineEqn+  , lineEqn+  , toLineEqn+  , findIntersect+  , intersection++  , rectangleLines+  , polygonLines+  , langle+  ) +  where++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space+import Data.VectorSpace+++-- WARNING - This module is not very good (neither particularly +-- robust, nor efficient).+-- +-- I really need to find an algorithm that does this properly.+--++data LineSegment u = LS (Point2 u) (Point2 u)+  deriving (Eq,Ord,Show)+++data PointSlope u = PointSlope +      { _point_slope_point :: Point2 u+      , _point_slope_slope :: u+      }+  deriving (Eq,Show)++pointSlope :: Fractional u => Point2 u -> Radian -> PointSlope u +pointSlope pt theta = PointSlope pt (fromRadian $ tan theta)+++-- | Line in equational form, i.e. @Ax + By + C = 0@.+data LineEqn u = LineEqn +      { _line_eqn_A :: !u+      , _line_eqn_B :: !u+      , _line_eqn_C :: !u +      }+  deriving (Eq,Show)++lineEqn :: Num u => Point2 u -> Point2 u -> LineEqn u+lineEqn (P2 x1 y1) (P2 x2 y2) = LineEqn a b c +  where+    a = y1 - y2+    b = x2 - x1+    c = (x1*y2) - (x2*y1)+++toLineEqn :: Num u => PointSlope u -> LineEqn u+toLineEqn (PointSlope (P2 x0 y0) m) = LineEqn m (-1) ((-m) * x0 + y0)+++++data IntersectionResult u = Intersects u u | Contained | NoIntersect+  deriving (Eq,Show)+++-- Note the uses a /plane/ so is susceptible to picking the +-- wrong quadrant...+--+findIntersect :: (Floating u, Real u, Ord u)+               => Point2 u -> Radian -> [LineSegment u] -> Maybe (Point2 u)+findIntersect ctr ang0 = step +  where+    theta       = circularModulo ang0+    eqn         = toLineEqn $ pointSlope ctr theta+    step []     = Nothing+    step (x:xs) = case intersection x eqn of +                     Just pt | quadrantCheck theta ctr pt -> Just pt+                     _       -> step xs+++quadrantCheck :: (Real u, Floating u) +              => Radian -> Point2 u -> Point2 u -> Bool+quadrantCheck theta ctr pt = theta == langle ctr pt++intersection :: (Fractional u, Ord u) +             => LineSegment u -> LineEqn u -> Maybe (Point2 u)+intersection ls@(LS p q) eqn = case intersect1 ls eqn of+    Intersects fp fq -> let t = fp / (fp-fq) in Just $ affineComb p q t +    Contained        -> Just p+    NoIntersect      -> Nothing++++intersect1 :: (Num u, Ord u) +           => LineSegment u -> LineEqn u -> IntersectionResult u+intersect1 (LS p q) eqn = +     if inters fp fq then Intersects fp fq+                     else if contained fp fq then Contained else NoIntersect+  where+    inters a b    = (a < 0 && b >= 0) || (a > 0 && b <= 0)+    contained a b = a == 0 && b == 0+    fp            = lineF p eqn+    fq            = lineF q eqn+ +lineF :: Num u => Point2 u -> LineEqn u -> u+lineF (P2 x y) (LineEqn a b c) = a*x + b*y + c++affineComb :: Num u => Point2 u -> Point2 u -> u -> Point2 u+affineComb p q t = p .+^ t *^ (q .-. p)+++++rectangleLines :: Num u => Point2 u -> u -> u -> [LineSegment u]+rectangleLines ctr hw hh = [LS br tr, LS tr tl, LS tl bl, LS bl br]+  where+    br = ctr .+^ (vec hw    (-hh))+    tr = ctr .+^ (vec hw    hh)+    tl = ctr .+^ (vec (-hw) hh)+    bl = ctr .+^ (vec (-hw) (-hh))+++polygonLines :: [Point2 u] -> [LineSegment u]+polygonLines []     = error "polygonLines - emptyList"+polygonLines (x:xs) = step x xs +  where+    step a []        = [LS a x]+    step a (b:bs)    = LS a b : step b bs++++-- | Calculate the counter-clockwise angle between two points +-- and the x-axis.+--+langle :: (Floating u, Real u) => Point2 u -> Point2 u -> Radian+langle (P2 x1 y1) (P2 x2 y2) = step (x2 - x1) (y2 - y1)+  where+    -- north-east quadrant +    step x y | pve x && pve y = toRadian $ atan (y/x)          +    +    -- north-west quadrant+    step x y | pve y          = pi     - (toRadian $ atan (y / abs x))++    -- south-east quadrant+    step x y | pve x          = (2*pi) - (toRadian $ atan (abs y / x)) ++    -- otherwise... south-west quadrant+    step x y                  = pi     + (toRadian $ atan (y/x))++    pve a                     = signum a >= 0
+ src/Wumpus/Basic/Kernel/Geometry/Paths.hs view
@@ -0,0 +1,114 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Geometry.Paths+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Paths for /elementary/ shapes - rectangles...+-- +-- \*\* - WARNING \*\* - half baked. +--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Geometry.Paths+  ( +    rectanglePath+  , diamondPath+  , polygonPoints+  , isoscelesTrianglePath+  , isoscelesTrianglePoints+  , equilateralTrianglePath+  , equilateralTrianglePoints+  ) +  where++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space+++import Data.List ( unfoldr )++-- TODO add regular polygon building from old Wumpus-Extra...++-- | Supplied point is /bottom-left/.+--+rectanglePath :: Num u => u -> u -> Point2 u -> PrimPath u+rectanglePath w h bl = primPath bl [ lineTo br, lineTo tr, lineTo tl ]+  where+    br = bl .+^ hvec w+    tr = br .+^ vvec h+    tl = bl .+^ vvec h ++++-- | 'diamondPath' : @ half_width * half_height * center_point -> PrimPath @+--+diamondPath :: Num u => u -> u -> Point2 u -> PrimPath u+diamondPath hw hh ctr = primPath s [ lineTo e, lineTo n, lineTo w]+  where+    s     = ctr .+^ vvec (-hh)+    e     = ctr .+^ hvec hw+    n     = ctr .+^ vvec hh+    w     = ctr .+^ hvec (-hw)+    ++-- | 'polygonPoints' : @ num_points * radius * center -> [point] @ +--+polygonPoints :: Floating u => Int -> u -> Point2 u -> [Point2 u]+polygonPoints n radius ctr = unfoldr phi (0,(pi*0.5))+  where+    theta = (pi*2) / fromIntegral n+    +    phi (i,ang) | i < n     = Just (ctr .+^ avec ang radius, (i+1,ang+theta))+                | otherwise = Nothing++-- | @isocelesTriangle bw h pt@+--+-- Supplied point is the centriod of the triangle. This has a +-- nicer visual balance than using half-height.+--+isoscelesTrianglePoints :: Floating u +                        => u -> u -> Point2 u -> (Point2 u, Point2 u, Point2 u)+isoscelesTrianglePoints bw h ctr = (bl, br, top) +  where+    hw         = 0.5*bw +    theta      = atan $ h / hw+    centroid_h = hw * tan (0.5*theta)+    top        = ctr .+^ vvec (h - centroid_h)+    br         = ctr .+^ V2   hw  (-centroid_h)+    bl         = ctr .+^ V2 (-hw) (-centroid_h)++++-- | @isocelesTriangle bw h pt@+--+-- Supplied point is the centriod of the triangle. This has a +-- nicer visual balance than using half-height.+--+isoscelesTrianglePath :: Floating u => u -> u -> Point2 u -> PrimPath u+isoscelesTrianglePath bw h ctr = primPath bl [ lineTo br, lineTo top ] +  where+    hw         = 0.5*bw +    theta      = atan $ h / hw+    centroid_h = hw * tan (0.5*theta)+    top        = ctr .+^ vvec (h - centroid_h)+    br         = ctr .+^ V2   hw  (-centroid_h)+    bl         = ctr .+^ V2 (-hw) (-centroid_h)++equilateralTrianglePoints :: Floating u +                          => u -> Point2 u -> (Point2 u, Point2 u, Point2 u)+equilateralTrianglePoints sl = isoscelesTrianglePoints sl h+  where+    h = sl * sin (pi/3)++equilateralTrianglePath :: Floating u => u -> Point2 u -> PrimPath u+equilateralTrianglePath sl ctr = primPath bl [ lineTo br, lineTo top ] +  where+    (bl,br,top) = equilateralTrianglePoints sl ctr
+ src/Wumpus/Basic/Kernel/Objects/AdvanceGraphic.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeSynonymInstances       #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Objects.AdvanceGraphic+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- Extended Graphic object - an AdvanceGraphic is a Graphic +-- twinned with and AdvanceV vector.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Objects.AdvanceGraphic+  (++  -- * Advance-vector graphic+    AdvGraphic+  , DAdvGraphic+++  , makeAdvGraphic+  , extractLocGraphic+  , runAdvGraphic++  -- * Composition+  , advplus+  , advconcat++  ) where++import Wumpus.Basic.Kernel.Base.BaseDefs+import Wumpus.Basic.Kernel.Base.ContextFun+import Wumpus.Basic.Kernel.Base.DrawingContext+import Wumpus.Basic.Kernel.Base.WrappedPrimitive+import Wumpus.Basic.Kernel.Objects.BaseObjects+import Wumpus.Basic.Kernel.Objects.Graphic++import Wumpus.Core                              -- package: wumpus-core+++import Control.Applicative++-- | /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++++--------------------------------------------------------------------------------++++-- | Construction is different to intoZZ functions hence the +-- different name.+--+makeAdvGraphic :: DrawingInfo (PointDisplace u)+               -> LocGraphic u +               -> AdvGraphic u+makeAdvGraphic dispf gf = +    promoteR1 $ \pt -> dispf >>= \fn -> fmap (replaceL $ fn pt) (gf `at` pt)  ++++++-- This should probably go - the name is not exact enough...++extractLocGraphic :: AdvGraphic u -> LocGraphic u+extractLocGraphic = fmap (replaceL uNil)++runAdvGraphic :: DrawingContext  -> Point2 u -> AdvGraphic u +              -> (Point2 u, PrimGraphic u)+runAdvGraphic ctx pt df = runCF1 ctx pt df++++--------------------------------------------------------------------------------+-- composition++-- Note there are opportunities for extra composition operators+-- like the /picture language/...++infixr 6 `advplus`+++-- | \*\* WARNING \*\* - pending removal.+--+advplus :: AdvGraphic u -> AdvGraphic u -> AdvGraphic u+advplus = chain1+++advconcat :: Num u => [AdvGraphic u] -> AdvGraphic u+advconcat []     = makeAdvGraphic (pure id) emptyLocGraphic+advconcat [x]    = x+advconcat (x:xs) = x `chain1` advconcat xs 
+ src/Wumpus/Basic/Kernel/Objects/BaseObjects.hs view
@@ -0,0 +1,191 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeSynonymInstances       #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Objects.BaseObjects+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- Aliases for ContextFun types.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Objects.BaseObjects+  (++  -- * Drawing info+    DrawingInfo+  , LocDrawingInfo+  , LocThetaDrawingInfo+++  +  -- * Drawing objects+  , ImageAns+  , GraphicAns++  , Image+  , LocImage+  , LocThetaImage++  , DImage+  , DLocImage+  , DLocThetaImage++  , hyperlink++  ) where++import Wumpus.Basic.Kernel.Base.ContextFun+import Wumpus.Basic.Kernel.Base.WrappedPrimitive++import Wumpus.Core                              -- package: wumpus-core++--------------------------------------------------------------------------------+-- 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+++++--------------------------------------------------------------------------------+-- Image+++-- | An Image always returns a pair of some polymorphic answer @a@+-- and a PrimGraphic.+--+-- Note a PrimGraphic cannot be empty.+-- +type ImageAns u a       = (a, PrimGraphic u)+++type GraphicAns u       = ImageAns u (UNil u)+++-- | Draw a PrimGraphic repsective to the 'DrawingContext' and +-- return some answer @a@.+-- +type Image u a      = CF (ImageAns u a)+++-- | Draw a PrimGraphic respective to the 'DrawingContext' and +-- the supplied point, return some answer @a@.+-- +type LocImage u a   = LocCF u (ImageAns u a)+++-- | Draw a PrimGraphic respective to the 'DrawingContext' and+-- the supplied point and angle.+-- +type LocThetaImage u a   = LocThetaCF u (ImageAns u a)++++type DImage a            = Image Double a+type DLocImage a         = LocImage Double a+type DLocThetaImage a    = LocThetaImage Double a+++type instance DUnit (Image u a) = u -- GuardEq (DUnit a) (DUnit (PrimGraphic u))++type instance DUnit (LocImage u a) = u --  GuardEq (DUnit a) (DUnit (PrimGraphic u))++type instance DUnit (LocThetaImage u a) = u++++--------------------------------------------------------------------------------+-- Affine instances++-- Note - it seems better to have these instances for Image (even +-- though Image is a type synonym) rather than more general +-- instances on a CF.+--+-- There is nothing determining a DUnit for the CF types.+--+-- The downside is these instances are effectively orphan +-- instances.+--++instance (Real u, Floating u, Rotate a, DUnit a ~ u) => +    Rotate (Image u a) where+  rotate ang = fmap (rotate ang)+++instance (Real u, Floating u, RotateAbout a, DUnit a ~ u) => +    RotateAbout (Image u a) where+  rotateAbout ang pt = fmap (rotateAbout ang pt)+++instance (Num u, Scale a, DUnit a ~ u) => Scale (Image u a) where+  scale sx sy = fmap (scale sx sy)+++instance (Num u, Translate a, DUnit a ~ u) => Translate (Image u a) where+  translate dx dy = fmap (translate dx dy)+++-- \*\* WARNING \*\* - I am not sure having affine instances for +-- LocImage makes sense...+--+-- Particularly, what is a rotateAbout on a function from Point to +-- Graphic? Is it just a post-transformation, or should the start +-- point be transformed as well.+--++instance (Real u, Floating u, Rotate a, DUnit a ~ u) => +    Rotate (LocImage u a) where+  rotate ang = fmap (rotate ang)++instance (Real u, Floating u, RotateAbout a, DUnit a ~ u) => +    RotateAbout (LocImage u a) where+  rotateAbout ang pt = fmap (rotateAbout ang pt)+++instance (Num u, Scale a, DUnit a ~ u) => Scale (LocImage u a) where+  scale sx sy = fmap (scale sx sy)+++instance (Num u, Translate a, DUnit a ~ u) => Translate (LocImage u a) where+  translate dx dy = fmap (translate dx dy)++--------------------------------------------------------------------------------+++hyperlink :: XLink -> Image u a -> Image u a+hyperlink hypl = +    fmap (\(a,prim) -> (a, metamorphPrim (xlink hypl) prim))++++++
+ src/Wumpus/Basic/Kernel/Objects/Bounded.hs view
@@ -0,0 +1,140 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Objects.Bounded+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- Bounded versions of Graphic and LocGraphic.+--+-- Bounded meaning they are actually Images that return the +-- bounding box of the Graphic.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Objects.Bounded+  (+++  -- * Bounded graphic / loc graphic+    BoundedGraphic+  , DBoundedGraphic+  , BoundedLocGraphic+  , DBoundedLocGraphic+  , BoundedLocThetaGraphic+  , DBoundedLocThetaGraphic++  , emptyBoundedLocGraphic++  , centerOrthoBBox+  , illustrateBoundedGraphic+  , illustrateBoundedLocGraphic+  , illustrateBoundedLocThetaGraphic++  ) where++import Wumpus.Basic.Kernel.Base.BaseDefs+import Wumpus.Basic.Kernel.Base.ContextFun+import Wumpus.Basic.Kernel.Base.DrawingContext+import Wumpus.Basic.Kernel.Base.UpdateDC+import Wumpus.Basic.Kernel.Objects.BaseObjects+import Wumpus.Basic.Kernel.Objects.Graphic++import Wumpus.Core                              -- package: wumpus-core+import Wumpus.Core.Colour ( blue )++import Control.Applicative++--------------------------------------------------------------------------------++-- | Graphic with a bounding box.+-- +type BoundedGraphic u      = Image u (BoundingBox u)++type DBoundedGraphic       = BoundedGraphic Double+++++-- | LocGraphic with a bounding box.+--+type BoundedLocGraphic u      = LocImage u (BoundingBox u)++type DBoundedLocGraphic       = BoundedLocGraphic Double+++-- | LocThetaGraphic with a bounding box.+--+-- Note the size of bounding box for the \"same\" shape will vary +-- according to the rotation. A bounding box is always +-- orthonormal (?) to the x- and y-axes.+--+type BoundedLocThetaGraphic u   = LocThetaImage u (BoundingBox u)++type DBoundedLocThetaGraphic    = BoundedLocThetaGraphic Double+++++-- | 'openStroke' : @ theta * bbox -> BBox @+-- +-- Rotate a bounding box by @theta@ about its center. Take the +-- new bounding box.+--+-- Remember that bounding boxes are always orthonormal rectangles,+-- so the dimensions as well as the positions may change under +-- rotation. +--+centerOrthoBBox :: (Real u, Floating u) +                => Radian -> BoundingBox u -> BoundingBox u+centerOrthoBBox theta bb = +    traceBoundary $ map (rotateAbout theta ctr) ps+  where+    ps  = boundaryCornerList bb+    ctr = boundaryCenter bb+++emptyBoundedLocGraphic :: Num u => BoundedLocGraphic u+emptyBoundedLocGraphic = intoLocImage fn  emptyLocGraphic+  where+    fn = promoteR1 $ \pt -> pure (BBox pt pt)++--------------------------------------------------------------------------------+-- ++-- This is a common pattern so needs a name...++illustrateBoundedGraphic :: Fractional u => BoundedGraphic u -> BoundedGraphic u+illustrateBoundedGraphic mf = +    mf >>= \(bb,g1) -> bbrectangle bb >>= \(_,g0) -> return (bb, g0 `oplus` g1)+++illustrateBoundedLocGraphic :: Fractional u +                            => BoundedLocGraphic u -> BoundedLocGraphic u+illustrateBoundedLocGraphic mf = +    promoteR1 $ \pt -> illustrateBoundedGraphic $ apply1R1 mf pt+++illustrateBoundedLocThetaGraphic :: Fractional u +    => BoundedLocThetaGraphic u -> BoundedLocThetaGraphic u+illustrateBoundedLocThetaGraphic mf = +    promoteR2 $ \pt theta-> illustrateBoundedGraphic $ apply2R2 mf pt theta++++bbrectangle :: Fractional u => BoundingBox u -> Graphic u+bbrectangle (BBox p1@(P2 llx lly) p2@(P2 urx ury))+    | llx == urx && lly == ury = emptyLocGraphic `at` p1+    | otherwise                = +        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/Kernel/Objects/Connector.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeSynonymInstances       #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Objects.Connector+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- Graphic and Image types representing connectors - connectors+-- have two implicit points - start and end.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Objects.Connector+  (++  -- * Connector Graphic+    ConnectorGraphic+  , DConnectorGraphic+++  -- * Connector Image+  , ConnectorImage+  , DConnectorImage++++  ) where++import Wumpus.Basic.Kernel.Base.ContextFun+import Wumpus.Basic.Kernel.Objects.BaseObjects++-- import Wumpus.Core                              -- package: wumpus-core+++--------------------------------------------------------------------------------+-- Connector Graphic+++-- | ConnectorGraphic is a connector drawn between two points +-- contructing a Graphic.+--+type ConnectorGraphic u         = ConnectorCF u (GraphicAns u)+++type DConnectorGraphic          = ConnectorGraphic Double+++++--------------------------------------------------------------------------------+-- Connector Image+++-- | 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 (ImageAns u a)+++type DConnectorImage a  = ConnectorImage Double a++++
+ src/Wumpus/Basic/Kernel/Objects/Drawing.hs view
@@ -0,0 +1,563 @@+{-# LANGUAGE TypeFamilies               #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Objects.Drawing+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC +--+-- 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.Kernel.Objects.Drawing+  (++    Drawing+  , DDrawing+  , runDrawing+  , runDrawingU+  , drawTracing++  , clipDrawing+  , modifyDrawing++  -- * 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.Kernel.Base.Anchors+import Wumpus.Basic.Kernel.Base.BaseDefs+import Wumpus.Basic.Kernel.Base.ContextFun+import Wumpus.Basic.Kernel.Base.DrawingContext+import Wumpus.Basic.Kernel.Objects.TraceDrawing++import Wumpus.Core                              -- package: wumpus-core++import Data.AdditiveGroup                       -- package: vector-space+import Data.AffineSpace++import Control.Applicative+import Data.List ( foldl' )++++newtype Drawing u = Drawing { getDrawing :: CF (Maybe (Picture u)) }++type DDrawing = Drawing Double+++type instance DUnit (Drawing u) = u+++++runDrawing :: DrawingContext -> Drawing u -> Maybe (Picture u)+runDrawing ctx drw = runCF ctx (getDrawing drw)  +++runDrawingU :: DrawingContext -> Drawing u -> Picture u+runDrawingU ctx df = maybe fk id $ runDrawing ctx df+  where+    fk = error "runDrawingU - empty Drawing."   ++++drawTracing :: (Real u, Floating u, FromPtSize u) +            => TraceDrawing u a -> Drawing u+drawTracing mf = Drawing $ +    drawingCtx >>= \ctx -> return (liftToPictureMb (execTraceDrawing ctx mf) )+++-- Note - cannot get an answer from a TraceDrawing with this +-- Drawing type. There is nowhere to put the answer in the type.+--+-- If the type was extended:+--+-- > newtype Drawing u a = Drawing { getDrawing :: CF (a, Maybe (Picture u))) }+--+-- 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)? +--+--------------------------------------------------------------------------------++clipDrawing :: (Num u, Ord u) => (PrimPath u) -> Drawing u -> Drawing u+clipDrawing cpath = modifyDrawing (clip cpath)+++modifyDrawing :: (Picture u -> Picture u) -> Drawing u -> Drawing u+modifyDrawing pf = Drawing . fmap (fmap pf) . getDrawing++instance (Real u, Floating u) => Rotate (Drawing u) where +  rotate ang = modifyDrawing (rotate ang)++instance (Real u, Floating u) => RotateAbout (Drawing u) where+  rotateAbout r pt = modifyDrawing (rotateAbout r pt)++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)++++--------------------------------------------------------------------------------+++--------------------------------------------------------------------------------+-- Extract anchors++boundaryExtr :: (BoundingBox u -> a) -> Picture u -> a+boundaryExtr f = f . boundary++-- Operations on bounds++-- | The center of a picture.+--+boundaryCtr :: Fractional u => Picture u -> Point2 u+boundaryCtr = 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+++drawingConcat :: (Picture u -> Picture u -> Picture u) +              -> Drawing u -> Drawing u -> Drawing u+drawingConcat op a b = Drawing $ mbpostcomb op (getDrawing a) (getDrawing b)++++mbpostcomb :: (a -> a -> a) -> CF (Maybe a) -> CF (Maybe a) -> CF (Maybe a)+mbpostcomb op = liftA2 fn +  where+    fn (Just a) (Just b) = Just $ a `op` b+    fn a        Nothing  = a+    fn Nothing  b        = b+++-- 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 boundaryCtr boundaryCtr 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/Kernel/Objects/Graphic.hs view
@@ -0,0 +1,470 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE TypeSynonymInstances       #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Objects.Graphic+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  highly unstable+-- Portability :  GHC +--+-- Graphic type - this is largely equivalent to Primitive in+-- Wumpus-Core, but drawing attributes are implicitly supplied +-- by the DrawingContext.+--+-- API in @Wumpus.Core@, but here they exploit the implicit +-- @DrawingContext@.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Kernel.Objects.Graphic+  (++    Graphic+  , DGraphic+++  -- * LocGraphic  +  , LocGraphic+  , DLocGraphic+++  , LocThetaGraphic+  , DLocThetaGraphic++  -- * Functions+  , intoImage+  , intoLocImage+  , intoLocThetaImage++  , moveStartPoint+  , moveStartPointTheta++  , locPath+  , emptyLocPath+  , emptyLocGraphic+++  , openStroke+  , closedStroke+  , filledPath+  , borderedPath++  , textline+  , rtextline+  , escapedline+  , rescapedline++  , hkernline+  , vkernline++  , strokedEllipse+  , rstrokedEllipse+  , filledEllipse+  , rfilledEllipse++  , borderedEllipse+  , rborderedEllipse++  , straightLine+  , straightLineBetween+  , curveBetween++  , strokedRectangle+  , filledRectangle+  , borderedRectangle++  , strokedCircle+  , filledCircle+  , borderedCircle+  +  , strokedDisk+  , filledDisk+  , borderedDisk++  ) where++import Wumpus.Basic.Kernel.Base.ContextFun+import Wumpus.Basic.Kernel.Base.BaseDefs+import Wumpus.Basic.Kernel.Base.QueryDC+import Wumpus.Basic.Kernel.Base.WrappedPrimitive+import Wumpus.Basic.Kernel.Geometry.Paths+import Wumpus.Basic.Kernel.Objects.BaseObjects++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space++import Control.Applicative++--------------------------------------------------------------------------------+-- Graphic++-- | Simple drawing - produce a primitive, access the DrawingContext+-- as required, e.g for fill colour, stroke colur, line width, etc.+--+type Graphic u          = Image u (UNil u)++-- | Alias of 'Graphic' where the unit type is specialized to +-- Double. +--+type DGraphic           = Graphic Double+++-- | /Originated/ drawing - produce a primitive respective to the +-- supplied start-point, access the DrawingContext as required.+--+type LocGraphic u       = LocImage u (UNil u)++-- | Alias of 'LocGraphic' where the unit type is specialized to +-- Double. +--+type DLocGraphic        = LocGraphic Double+++++-- | /Originated/ drawing - produce a primitive respective to the +-- supplied start-point, access the DrawingContext as required.+--+type LocThetaGraphic u       = LocThetaImage u (UNil u)+++-- | Alias of 'LocThetaGraphic' where the unit type is specialized +-- to Double. +--+type DLocThetaGraphic        = LocThetaGraphic Double+++--------------------------------------------------------------------------------+-- Functions+++-- | Build an Image...+--+intoImage :: CF a -> Graphic u -> Image u a+intoImage = liftA2 (\a (_,b) -> (a,b))+++-- | Build a LocImage...+--+intoLocImage :: LocCF u a -> LocGraphic u -> LocImage u a+intoLocImage = liftA2 (\a (_,b) -> (a,b))++-- | Build a LocThetaImage...+--+intoLocThetaImage :: LocThetaCF u a -> LocThetaGraphic u -> LocThetaImage u a+intoLocThetaImage = liftA2 (\a (_,b) -> (a,b))+++-- | Move the start-point of a LocImage with the supplied +-- displacement function.+--+moveStartPoint :: PointDisplace u -> LocCF u a -> LocCF u a+moveStartPoint f ma = promoteR1 $ \pt -> apply1R1 ma (f pt)+++-- | Move the start-point of a LocImage with the supplied +-- displacement function.+--+moveStartPointTheta :: PointDisplace u -> LocThetaCF u a -> LocThetaCF u a+moveStartPointTheta f ma = promoteR2 $ \pt theta -> apply2R2 ma (f pt) theta++--------------------------------------------------------------------------------++++graphicBody :: Primitive u -> (UNil u, PrimGraphic u)+graphicBody p = (uNil, primGraphic p)+++-- | This is the analogue to 'vectorPath' in @Wumpus-core@.+--+locPath :: Num u => [Vec2 u] -> LocCF u (PrimPath u)+locPath vs = promoteR1 $ \pt  -> pure $ vectorPath pt vs+++-- | This is the analogue to 'emptyPath' in @Wumpus-core@.+--+emptyLocPath :: Num u => LocCF u (PrimPath u)+emptyLocPath = locPath []++-- | Build an empty LocGraphic - this is a path with a start+-- point but no path segments. +-- +-- The 'emptyLocGraphic' It is treated as a /null primitive/ by +-- @Wumpus-Core@ and is not drawn, although it does generate a +-- minimum bounding box at the implicit start point.+-- +emptyLocGraphic :: Num u => LocGraphic u+emptyLocGraphic = emptyLocPath >>= (lift0R1 . openStroke)+++-- | 'openStroke' : @ path -> Graphic @+--+-- This is the analogue to 'ostroke' in @Wumpus-core@, but the +-- drawing properties (colour, line width, etc.) are taken from +-- the implicit 'DrawingContext'.+--+openStroke :: Num u => PrimPath u -> Graphic u+openStroke pp = +    withStrokeAttr $ \rgb attr -> graphicBody $ ostroke rgb attr pp+++-- | 'closedStroke' : @ path -> Graphic @+--+-- This is the analogue to 'cstroke' in @Wumpus-core@, but the +-- drawing properties (colour, line width, etc.) are taken from +-- the implicit 'DrawingContext'.+--+closedStroke :: Num u => PrimPath u -> Graphic u+closedStroke pp = +    withStrokeAttr $ \rgb attr -> graphicBody $ cstroke rgb attr pp+++-- | 'filledPath' : @ path -> Graphic @+-- +-- This is the analogue to 'fill' in @Wumpus-core@, but the +-- fill colour is taken from the implicit 'DrawingContext'.+--+--+filledPath :: Num u => PrimPath u -> Graphic u+filledPath pp = withFillAttr $ \rgb -> graphicBody $ fill rgb pp+                 ++-- | 'borderedPath' : @ path -> Graphic @+--+-- This is the analogue to 'fillStroke' in @Wumpus-core@, but the +-- drawing properties (fill colour, border colour, line width, +-- etc.) are taken from the implicit 'DrawingContext'.+--+--+borderedPath :: Num u => PrimPath u -> Graphic u+borderedPath pp =+    withBorderedAttr $ \frgb attr srgb -> +      graphicBody $ fillStroke frgb attr srgb pp+++++-- | This is the analogue to 'textlabel' in @Wumpus-core@.+--+textline :: Num u => String -> LocGraphic u+textline ss = +    promoteR1 $ \pt -> +      withTextAttr $ \rgb attr -> graphicBody (textlabel rgb attr ss pt)+++++-- | This is the analogue to 'rtextlabel' in @Wumpus-core@.+--+rtextline :: Num u => String -> LocThetaGraphic u+rtextline ss = +    promoteR2 $ \pt theta -> +      withTextAttr $ \rgb attr -> graphicBody (rtextlabel rgb attr ss theta pt)++++-- | This is the analogue to 'escapedlabel' in @Wumpus-core@.+--+escapedline :: Num u => EscapedText -> LocGraphic u+escapedline ss = +    promoteR1 $ \pt -> +      withTextAttr $ \rgb attr -> graphicBody (escapedlabel rgb attr ss pt)++++-- | This is the analogue to 'rescapedlabel' in @Wumpus-core@.+--+rescapedline :: Num u => EscapedText -> LocThetaGraphic u+rescapedline ss = +    promoteR2 $ \pt theta -> +      withTextAttr $ \rgb attr -> graphicBody (rescapedlabel rgb attr ss theta pt)+++++-- | This is the analogue to 'hkernlabel' in @Wumpus-core@.+--+hkernline :: Num u => [KerningChar u] -> LocGraphic u+hkernline xs = +    promoteR1 $ \pt -> +      withTextAttr $ \rgb attr -> graphicBody (hkernlabel rgb attr xs pt)+++-- | This is the analogue to 'vkernlabel' in @Wumpus-core@.+--+vkernline :: Num u => [KerningChar u] -> LocGraphic u+vkernline xs = +    promoteR1 $ \pt -> +      withTextAttr $ \rgb attr -> graphicBody (vkernlabel rgb attr xs pt)+++++--------------------------------------------------------------------------------++++++-- | This is the analogue to 'strokeEllipse' in @Wumpus-core@.+--+strokedEllipse :: Num u => u -> u -> LocGraphic u+strokedEllipse hw hh =+    promoteR1 $ \pt -> +      withStrokeAttr $ \rgb attr -> graphicBody (strokeEllipse rgb attr hw hh pt)++++-- | This is the analogue to 'rstrokeEllispe' in @Wumpus-core@.+--+rstrokedEllipse :: Num u => u -> u -> LocThetaGraphic u+rstrokedEllipse hw hh = +    promoteR2 $ \ pt theta -> +      withStrokeAttr $ \rgb attr -> +        graphicBody (rstrokeEllipse rgb attr hw hh theta pt)+++-- | This is the analogue to 'fillEllispe' in @Wumpus-core@.+--+filledEllipse :: Num u => u -> u -> LocGraphic u+filledEllipse hw hh = +    promoteR1 $ \pt ->  +      withFillAttr $ \rgb -> graphicBody (fillEllipse rgb hw hh pt)+++-- | This is the analogue to 'rfillEllispe' in @Wumpus-core@.+--+rfilledEllipse :: Num u => u -> u -> LocThetaGraphic u+rfilledEllipse hw hh = +    promoteR2 $ \pt theta ->+      withFillAttr $ \rgb -> graphicBody (rfillEllipse rgb hw hh theta pt)++++-- | This is the analogue to 'fillStrokeEllispe' in @Wumpus-core@.+--+borderedEllipse :: Num u => u -> u -> LocGraphic u+borderedEllipse hw hh =+    promoteR1 $ \pt -> +      withBorderedAttr $ \frgb attr srgb -> +        graphicBody (fillStrokeEllipse frgb attr srgb hw hh pt)++-- | This is the analogue to 'rfillStrokeEllispe' in @Wumpus-core@.+--+rborderedEllipse :: Num u => u -> u -> LocThetaGraphic u+rborderedEllipse hw hh = +    promoteR2 $ \pt theta -> +      withBorderedAttr $ \frgb attr srgb -> +        graphicBody (rfillStrokeEllipse frgb attr srgb hw hh theta pt)++++-- Note - clipping needs a picture as well as a path, so there is+-- no analogous @clippedPath@ function.++--------------------------------------------------------------------------------+++-- | Draw a straight line formed from displacing the implicit +-- start point with the supplied vector.+-- +straightLine :: Fractional u => Vec2 u -> LocGraphic u+straightLine v = mf >>= (lift0R1 . openStroke)+  where+    mf = promoteR1 $ \pt -> pure $ primPath pt [lineTo $ pt .+^ v]++          +-- | Draw a straight line - start and end point are supplied +-- explicitly.+-- +straightLineBetween :: Fractional u => Point2 u -> Point2 u -> Graphic u+straightLineBetween p1 p2 = openStroke $ primPath p1 [lineTo p2]++++-- | Draw a Bezier curve - all points are supplied explicitly.+-- +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]+++-- This is a permuted version of the cardinal-prime combinator...+-- +-- > (r2 -> a) -> (a -> r1 -> ans) -> (r1 -> r2 -> ans)+--++drawWith :: (Point2 u -> PrimPath u) -> (PrimPath u -> Graphic u) -> LocGraphic u +drawWith g mf = promoteR1 $ \pt -> mf (g pt)+++-- | Supplied point is /bottom left/.+--+strokedRectangle :: Fractional u => u -> u -> LocGraphic u+strokedRectangle w h = rectanglePath w h `drawWith` closedStroke+++-- | Supplied point is /bottom left/.+--+filledRectangle :: Fractional u => u -> u -> LocGraphic u+filledRectangle w h = rectanglePath w h `drawWith` filledPath++-- | Supplied point is /bottom left/.+--+borderedRectangle :: Fractional u => u -> u -> LocGraphic u+borderedRectangle w h = rectanglePath w h `drawWith` borderedPath+++-- | Supplied point is center. Circle is drawn with Bezier +-- curves. +--+strokedCircle :: Floating u => Int -> u -> LocGraphic u+strokedCircle n r = (curvedPath . bezierCircle n r) `drawWith` closedStroke ++++-- | Supplied point is center. Circle is drawn with Bezier +-- curves. +--+filledCircle :: Floating u => Int -> u -> LocGraphic u+filledCircle n r =  (curvedPath . bezierCircle n r) `drawWith` filledPath++++-- | Supplied point is center. Circle is drawn with Bezier +-- curves. +--+borderedCircle :: Floating u => Int -> u -> LocGraphic u+borderedCircle n r = (curvedPath . bezierCircle n r) `drawWith` borderedPath +++-- | '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 adequately scaled, use +-- 'strokedCircle' instead.+--+strokedDisk :: Num u => u -> LocGraphic u+strokedDisk radius = strokedEllipse radius radius++-- | Filled disk...+--+filledDisk :: Num u => u -> LocGraphic u+filledDisk radius = filledEllipse radius radius++-- | bordered disk...+--+borderedDisk :: Num u => u -> LocGraphic u+borderedDisk radius = borderedEllipse radius radius
+ src/Wumpus/Basic/Kernel/Objects/TraceDrawing.hs view
@@ -0,0 +1,338 @@+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Kernel.Objects.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.Kernel.Objects.TraceDrawing+  (++    TraceDrawing+  , DTraceDrawing+  , TraceDrawingT+  , DTraceDrawingT++  , runTraceDrawing+  , execTraceDrawing+  , evalTraceDrawing+  , runTraceDrawingT+  , execTraceDrawingT+  , evalTraceDrawingT++  , liftToPictureU+  , liftToPictureMb+  , mbPictureU+ ++  , query+  , draw+  , xdraw+  , drawi+  , drawi_+  , xdrawi+  , xdrawi_++  , node+  , nodei++  ) where+++import Wumpus.Basic.Kernel.Base.BaseDefs+import Wumpus.Basic.Kernel.Base.ContextFun+import Wumpus.Basic.Kernel.Base.DrawingContext+import Wumpus.Basic.Kernel.Base.WrappedPrimitive+import Wumpus.Basic.Kernel.Objects.BaseObjects+import Wumpus.Basic.Kernel.Objects.Graphic++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 DTraceDrawing a    = TraceDrawing Double a+type DTraceDrawingT m a = TraceDrawingT Double m a++++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 $ snd $ runCF ctx gf)++-- | Hyperlink version of 'draw'.+--+xdraw :: (TraceM m, DrawingCtxM m, u ~ MonUnit m) +      => XLink -> Graphic u -> m ()+xdraw xl gf = draw (hyperlink 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) = runCF ctx img in trace (collectH o) >> return a++-- | Forgetful 'drawi'.+--+drawi_ ::  (TraceM m, DrawingCtxM m, MonUnit m ~ u) => Image u a -> m ()+drawi_ img = drawi img >> return ()+++-- | Hyperlink version of 'drawi'.+--+xdrawi ::  (TraceM m, DrawingCtxM m, MonUnit m ~ u) +       => XLink -> Image u a -> m a+xdrawi xl img = drawi (hyperlink xl img)+++-- | Forgetful 'xdrawi'.+--+xdrawi_ ::  (TraceM m, DrawingCtxM m, MonUnit m ~ u)+        => XLink -> Image u a -> m ()+xdrawi_ xl img = xdrawi xl img >> return ()+++++node :: (TraceM m, DrawingCtxM m, PointSupplyM m, MonUnit m ~ u) +     => LocGraphic u -> m ()+node gf = askDC    >>= \ctx -> +          position >>= \pt  -> +          let (_,prim) = runCF1 ctx pt gf in trace (collectH prim)+++nodei :: (TraceM m, DrawingCtxM m, PointSupplyM m, MonUnit m ~ u) +     => LocImage u a -> m a+nodei imgL = askDC    >>= \ctx -> +             position >>= \pt  -> +             let (a,o) = runCF ctx (apply1R1 imgL pt)+             in trace (collectH o) >> return a+
− src/Wumpus/Basic/Monads/TurtleClass.hs
@@ -1,91 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Monads.TurtleClass--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC ------ Turtle monad and monad transformer.------ The Turtle monad embodies the LOGO style of imperative --- drawing - sending commands to update the a cursor.------ While Wumpus generally aims for a more compositional,--- \"coordinate-free\" style of drawing, some types of diagram --- are more easily expressed in the LOGO style.------ Note - as turtle drawing with Wumpus is a /local effect/, --- there is only one instance of TurtleM. Potentially TurtleM --- will be removed and the functions implemented directly. --------------------------------------------------------------------------------------module Wumpus.Basic.Monads.TurtleClass-  (--    Coord--  , TurtleM(..)--  , setsLoc-  , setsLoc_--  -- * movement-  , resetLoc-  , moveLeft-  , moveRight-  , moveUp-  , moveDown-  , nextLine- --  ) where----type Coord = (Int,Int)---class Monad m => TurtleM m where-  getLoc     :: m (Int,Int)-  setLoc     :: (Int,Int) -> m ()-  getOrigin  :: m (Int,Int)-  setOrigin  :: (Int,Int) -> m ()----setsLoc :: TurtleM m => (Coord -> (a,Coord)) -> m a-setsLoc f = getLoc      >>= \coord -> -            let (a,coord') = f coord in setLoc coord' >> return a--setsLoc_ :: TurtleM m => (Coord -> Coord) -> m ()-setsLoc_ f = getLoc     >>= \coord ->  setLoc (f coord)---resetLoc    :: TurtleM m => m ()-resetLoc    = getOrigin >>= setLoc---moveRight   :: TurtleM m => m ()-moveRight   = setsLoc_ $ \(x,y)-> (x+1, y)---moveLeft    :: TurtleM m => m ()-moveLeft    = setsLoc_ $ \(x,y) -> (x-1,y)--moveUp      :: TurtleM m => m ()-moveUp      = setsLoc_ $ \(x,y) -> (x,y+1)--moveDown    :: TurtleM m => m ()-moveDown    = setsLoc_ $ \(x,y) -> (x ,y-1)---nextLine    :: TurtleM m => m ()-nextLine    = getOrigin >>= \(ox,_) ->-              setsLoc_ $ \(_,y) -> (ox,y-1)-
− src/Wumpus/Basic/Monads/TurtleMonad.hs
@@ -1,140 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE MultiParamTypeClasses      #-}-{-# LANGUAGE UndecidableInstances       #-}-{-# LANGUAGE TypeSynonymInstances       #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Monads.TurtleMonad--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC ------ Turtle monad transformer.------ The Turtle monad embodies the LOGO style of imperative --- drawing - sending commands to update the a cursor.------ While Wumpus generally aims for a more compositional,--- \"coordinate-free\" style of drawing, some types of --- diagram are more easily expressed in the LOGO style.------ Turtle is only a transformer - it is intended to be run within--- a 'Drawing'.--------------------------------------------------------------------------------------module Wumpus.Basic.Monads.TurtleMonad-  (-    -- * Re-exports-    module Wumpus.Basic.Monads.TurtleClass--  -- * Turtle transformer-  , TurtleT-  , runTurtleT--   -  ) where--import Wumpus.Basic.Graphic-import Wumpus.Basic.Monads.TurtleClass----import Control.Applicative-import Control.Monad----- Note - if Turtle is now just a /local effect/ monad is the --- Turtle class still needed? Afterall, there is (probably)--- only ever going to be one instance.------- Turtle is a Reader / State monad--- --- The env is the horizontal and vertical move distances.--- --- The state is the current coordinate and the origin.-----data TurtleState = TurtleState -      { _turtle_origin   :: (Int,Int)-      , _current_coord   :: (Int,Int)-      }--type TurtleScalingT u m a = ScalingT Int Int u m a--newtype TurtleT u m a = TurtleT { -          getTurtleT :: TurtleState -> TurtleScalingT u m (a, TurtleState) }--type instance MonUnit (TurtleT u m) = u-    ----- Functor----instance Monad m => Functor (TurtleT u m) where-  fmap f m = TurtleT $ \s -> getTurtleT m s >>= \(a,s') ->-                             return (f a, s')----- Applicative --instance Monad m => Applicative (TurtleT u m) where-  pure a    = TurtleT $ \s -> return (a,s)-  mf <*> ma = TurtleT $ \s -> getTurtleT mf s  >>= \(f,s')  ->-                              getTurtleT ma s' >>= \(a,s'') ->-                              return (f a,s'') ----- Monad --instance Monad m => Monad (TurtleT u m) where-  return a = TurtleT $ \s -> return (a,s)-  m >>= k  = TurtleT $ \s -> getTurtleT m s        >>= \(a,s')  ->-                             (getTurtleT . k) a s' >>= \(b,s'') ->-                             return (b,s'')-----instance Monad m => TurtleM (TurtleT u m) where-  getLoc      = TurtleT $ \s@(TurtleState _ c) -> return (c,s)-  setLoc c    = TurtleT $ \(TurtleState o _)   -> return ((),TurtleState o c)-  getOrigin   = TurtleT $ \s@(TurtleState o _) -> return (o,s)-  setOrigin o = TurtleT $ \(TurtleState _ c)   -> return ((),TurtleState o c)---runTurtleT :: (Monad m, Num u) -           => (Int,Int) -> ScalingContext Int Int u -> TurtleT u m a -> m a-runTurtleT ogin cfg mf = -    runScalingT cfg (getTurtleT mf st0) >>= \(a,_) -> return a-  where -    st0 = TurtleState ogin ogin ----------------------------------------------------------------------------------------- Cross instances--instance DrawingCtxM m => DrawingCtxM (TurtleT u m) where-  askDC           = TurtleT $ \s -> askDC >>= \ ctx -> return (ctx,s)-  localize upd mf = TurtleT $ \s -> localize upd (getTurtleT mf s)----- This needs undecidable instances...--instance (Monad m, TraceM m, u ~ MonUnit m) => TraceM (TurtleT u m) where-  trace a  = TurtleT $ \s -> trace a >> return ((),s)---instance (Monad m, u ~ MonUnit m, Num u) => PointSupplyM (TurtleT u m) where-  position = TurtleT $ \s@(TurtleState _ (x,y)) -> scalePt x y >>= \pt -> return (pt,s)-
− src/Wumpus/Basic/Paths.hs
@@ -1,31 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Paths--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Shim import module for Paths.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Paths -  ( --    module Wumpus.Basic.Paths.Base-  , module Wumpus.Basic.Paths.Connectors-  , module Wumpus.Basic.Paths.Construction-  , module Wumpus.Basic.Paths.ControlPoints--  ) where--import Wumpus.Basic.Paths.Base-import Wumpus.Basic.Paths.Connectors-import Wumpus.Basic.Paths.Construction-import Wumpus.Basic.Paths.ControlPoints-
− src/Wumpus/Basic/Paths/Base.hs
@@ -1,529 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Paths.Base--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Extended path type - more amenable for complex drawings than--- the type in Wumpus-Core.------ \*\* WARNING \*\* this module is an experiment, and may --- change significantly or even be dropped from future revisions.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Paths.Base-  ( --    Path-  , DPath-  , length-  , append-  , pconcat-  , line-  , curve-  , pivot-  , traceLinePoints-  , traceCurvePoints-  , curveByAngles--  , toPrimPath --  , tipL-  , tipR--  , shortenBoth-  , shortenL-  , shortenR-  , directionL-  , directionR--  , midway-  , midway_-  , atstart-  , atstart_-  , atend-  , atend_--  , PathViewL(..)-  , DPathViewL-  , PathViewR(..)-  , DPathViewR-  , PathSegment(..)-  , DPathSegment-  , pathViewL-  , pathViewR--  ) where---import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace-import Data.VectorSpace--import Data.List ( foldl' ) -import Data.Sequence ( Seq, (><), ViewL(..), viewl-                     , ViewR(..), viewr, (<|) , (|>) )-import qualified Data.Sequence as S--import Prelude hiding ( length )--data Path u = Path { _path_length   :: u -                   , _path_start    :: Point2 u-                   , _path_elements :: Seq (PathSeg u)-                   , _path_end      :: Point2 u-                   }-  deriving (Eq,Ord,Show)--type DPath = Path Double---- Annotating each segment with length is \*\* good \*\*.--- Makes it much more efficient to find the midway point.------ But what do we do about the start point:------ a) put it in the segment - too much info in the type, allows --- consistency problems vis-a-vis gaps in the path.------ b) leave it out - too little info in the type, allows --- consistency problems with length.------ Option (a) is probably most convenient espcially as the --- constructors won\'t be exported.---- Annotation is length...--- -data PathSeg u = LineSeg  { _line_length  :: u -                          , _line_start   :: Point2 u-                          , _line_end     :: Point2 u-                          }-               | CurveSeg { _curve_length :: u -                          , _curve_start  :: Point2 u-                          , _ctrl_pt_one  :: Point2 u-                          , _ctrl_pt_two  :: Point2 u-                          , _curve_end    :: Point2 u-                          }-  deriving (Eq,Ord,Show)---type instance DUnit (Path u)    = u-type instance DUnit (PathSeg u) = u---infixr 1 `append`--length :: Num u => Path u -> u-length (Path u _ _ _) = u--append :: Floating u => Path u -> Path u -> Path u-append (Path len1 start1 se1 end1) (Path len2 start2 se2 end2) -    | end1 == start2 = Path (len1+len2) start1 (se1 >< se2) end2 -    | otherwise      = let join      = lineSegment end1 start2-                           total_len = len1 + len2 + segmentLength join-                       in Path total_len start1 (se1 >< (join <| se2)) end2 --pconcat :: Floating u => Path u -> [Path u] -> Path u-pconcat p0 ps = foldl' append p0 ps--segmentLength :: PathSeg u -> u-segmentLength (LineSeg u _ _)       = u-segmentLength (CurveSeg u _ _ _ _)  = u---segmentStart :: PathSeg u -> Point2 u-segmentStart (LineSeg  _ p0 _)      = p0-segmentStart (CurveSeg _ p0 _ _ _)  = p0--segmentEnd :: PathSeg u -> Point2 u-segmentEnd (LineSeg  _ _ p1)        = p1-segmentEnd (CurveSeg _ _ _ _ p3)    = p3-----lineSegment :: Floating u => Point2 u -> Point2 u -> PathSeg u -lineSegment p0 p1 = let v = vlength $ pvec p0 p1 in LineSeg v p0 p1--line :: Floating u => Point2 u -> Point2 u -> Path u -line p0 p1 = let v = vlength $ pvec p0 p1 -             in Path v p0 (S.singleton $ LineSeg v p0 p1) p1-   --curve :: (Floating u, Ord u)-      => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Path u -curve p0 p1 p2 p3 = let v = curveLength p0 p1 p2 p3-                    in Path v p0 (S.singleton $ CurveSeg v p0 p1 p2 p3) p3---- | A draw a /straight line/ of length 0 at the supplied point. ------ This is /might/ be useful in concatenating curved paths--- as it introduces and extra control point.--- -pivot :: Floating u => Point2 u -> Path u -pivot p0 = Path 0 p0 (S.singleton $ LineSeg 0 p0 p0) p0----- | 'traceLinePoints' throws a runtime error if the supplied list--- is empty. ----traceLinePoints :: Floating u => [Point2 u] -> Path u-traceLinePoints []       = error "traceLinePoints - empty point list."-traceLinePoints [a]      = line a a-traceLinePoints (a:b:xs) = step (line a b) b xs-  where-    step acc _ []     = acc-    step acc e (y:ys) = step (acc `append` line e y) y ys----- | 'traceCurvePoints' consumes 4 points from the list on the --- intial step (start, control1, control2, end) then steps --- through the list taking 3 points at a time thereafter--- (control1,control2, end). Leftover points are discarded.    --- --- 'traceCurvePoints' throws a runtime error if the supplied list--- is has less than 4 elements (start, control1, control2, end). ----traceCurvePoints :: (Floating u, Ord u) => [Point2 u] -> Path u-traceCurvePoints (a:b:c:d:xs) = step (curve a b c d) d xs-  where-    step acc p0 (x:y:z:zs) = step (acc `append` curve p0 x y z) z zs-    step acc _  _          = acc--traceCurvePoints _            = error "tracePointsCurve - less than 4 elems."---curveByAngles :: (Floating u, Ord u) -              => Point2 u -> Radian -> Radian -> Point2 u -> Path u-curveByAngles start cin cout end = curve start (start .+^ v1) (end .+^ v2) end-  where-    sz     = 0.375 * (vlength $ pvec start end)-    v1     = avec cin  sz-    v2     = avec cout sz------ | Turn a Path into an ordinary PrimPath.------ Assumes path is properly formed - i.e. end point of one --- segment is the same point as the start point of the next--- segment.----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 -                                    primPath start $ a : step2 (viewl se)--    step2 EmptyL                  = []-    step2 (e :< se)               = seg2 e : step2 (viewl se)-    -    seg1 (LineSeg  _ p0 p1)       = (p0, lineTo p1)-    seg1 (CurveSeg _ p0 p1 p2 p3) = (p0, curveTo p1 p2 p3)- -    seg2 (LineSeg  _ _  p1)       = lineTo p1-    seg2 (CurveSeg _ _  p1 p2 p3) = curveTo p1 p2 p3--------------------------------------------------------------------------------------- Curve length--data StrictCurve u = Curve !(Point2 u) !(Point2 u) !(Point2 u) !(Point2 u)--curveLength :: (Floating u, Ord u)      -            => Point2 u -> Point2 u -> Point2 u -> Point2 u -> u-curveLength p0 p1 p2 p3 = gravesenLength 0.1 $ Curve p0 p1 p2 p3----- | Jens Gravesen\'s bezier arc-length approximation. ------ Note this implementation is parametrized on error tolerance.----gravesenLength :: (Floating u, Ord u) => u -> StrictCurve u -> u-gravesenLength err_tol crv = step crv where-  step c = let l1 = ctrlPolyLength c-               l0 = cordLength c-           in if   l1-l0 > err_tol-              then let (a,b) = subdivide c in step a + step b-              else 0.5*l0 + 0.5*l1---ctrlPolyLength :: Floating u => StrictCurve u -> u-ctrlPolyLength (Curve p0 p1 p2 p3) = len p0 p1 + len p1 p2 + len p2 p3-  where-    len pa pb = vlength $ pvec pa pb--cordLength :: Floating u => StrictCurve u -> u-cordLength (Curve p0 _ _ p3) = vlength $ pvec p0 p3----- | mid-point between two points----pointMidpoint :: Fractional u => Point2 u -> Point2 u -> Point2 u-pointMidpoint p0 p1 = p0 .+^ v1 ^/ 2 where v1 = p1 .-. p0----- | Curve subdivision via de Casteljau\'s algorithm.----subdivide :: Fractional u -          => StrictCurve u -> (StrictCurve u, StrictCurve u)-subdivide (Curve p0 p1 p2 p3) =-    (Curve p0 p01 p012 p0123, Curve p0123 p123 p23 p3)-  where-    p01   = pointMidpoint p0    p1-    p12   = pointMidpoint p1    p2-    p23   = pointMidpoint p2    p3-    p012  = pointMidpoint p01   p12-    p123  = pointMidpoint p12   p23-    p0123 = pointMidpoint p012  p123---- | subdivide with an affine weight along the line...----subdividet :: Real u-           => u -> StrictCurve u -> (StrictCurve u, StrictCurve u)-subdividet t (Curve p0 p1 p2 p3) = -    (Curve p0 p01 p012 p0123, Curve p0123 p123 p23 p3)-  where-    p01   = affineCombination t p0    p1-    p12   = affineCombination t p1    p2-    p23   = affineCombination t p2    p3-    p012  = affineCombination t p01   p12-    p123  = affineCombination t p12   p23-    p0123 = affineCombination t p012  p123--affineCombination :: Real u => u -> Point2 u -> Point2 u -> Point2 u-affineCombination a p1 p2 = p1 .+^ a *^ (p2 .-. p1)------------------------------------------------------------------------------------- tips --tipL :: Path u -> Point2 u-tipL (Path _ sp _ _) = sp---tipR :: Path u -> Point2 u-tipR (Path _ _ _ ep) = ep----- | Shorten both ends...------ u should be less-than half the path length----shortenBoth :: (Real u, Floating u) => u -> Path u -> Path u-shortenBoth u p = shortenL u $ shortenR u p------------------------------------------------------------------------------------- shorten from the left...---- | Note - shortening a line from the left by --- greater-than-or-equal its length is operationally equivalent --- to making a zero-length line at the end point.----shortenL :: (Real u, Floating u) => u -> Path u -> Path u-shortenL n (Path u _ segs ep) -    | n >= u                  = line ep ep-    | otherwise               = step n (viewl segs)-  where-    step _ EmptyL     = line ep ep      -- should be unreachable-    step d (e :< se)  = let z  = segmentLength e in-                        case compare d z of-                          GT -> step (d-z) (viewl se)-                          EQ -> makeLeftPath (u-n) se ep-                          LT -> let e1 = shortenSegL d e-                                in Path (u-n) (segmentStart e1) (e1 <| se) ep---makeLeftPath :: Floating u => u -> Seq (PathSeg u) -> Point2 u -> Path u-makeLeftPath u se ep = -    case viewl se of-      EmptyL   -> line ep ep-      (e :< _) -> Path u (segmentStart e) se ep---shortenSegL :: (Real u, Floating u) => u -> PathSeg u -> PathSeg u-shortenSegL n (LineSeg  u p0 p1)        = -    LineSeg  (u-n) (shortenLineL n p0 p1) p1--shortenSegL n (CurveSeg u p0 p1 p2 p3)  = -    let (Curve p0' p1' p2' p3') = snd $ subdividet (n/u) (Curve p0 p1 p2 p3)-    in CurveSeg (u-n) p0' p1' p2' p3'---shortenLineL :: (Real u, Floating u) -             => u -> Point2 u -> Point2 u -> Point2 u-shortenLineL n p0 p1 = p0 .+^ v-  where-    v0 = p1 .-. p0-    v  = avec (direction v0) n--------------------------------------------------------------------------------------- shorten from the right ...- --- | Note - shortening a line from the right by --- greater-than-or-equal its length is operationally equivalent --- to making a zero-length line at the start point.----shortenR :: (Real u, Floating u) => u -> Path u -> Path u-shortenR n (Path u sp segs _) -    | n >= u                  = line sp sp-    | otherwise               = step n (viewr segs)-  where-    step _ EmptyR     = line sp sp      -- should be unreachable-    step d (se :> e)  = let z = segmentLength e in-                        case compare d z of-                          GT -> step (d-z) (viewr se)-                          EQ -> makeRightPath n sp se-                          LT -> let e1 = shortenSegR d e-                                in Path (u-n) sp (se |> e1) (segmentEnd e1)-                         --makeRightPath :: Floating u => u -> Point2 u -> Seq (PathSeg u) -> Path u-makeRightPath u sp se = -    case viewr se of-      EmptyR   -> line sp sp-      (_ :> e) -> Path u sp se (segmentEnd e)----shortenSegR :: (Real u, Floating u) => u -> PathSeg u -> PathSeg u-shortenSegR n (LineSeg  u p0 p1)        = -    LineSeg  (u-n) p0 (shortenLineR n p0 p1) --shortenSegR n (CurveSeg u p0 p1 p2 p3)  = -    let (Curve p0' p1' p2' p3') = fst $ subdividet ((u-n)/u) (Curve p0 p1 p2 p3)-    in CurveSeg (u-n) p0' p1' p2' p3'---shortenLineR :: (Real u, Floating u) -             => u -> Point2 u -> Point2 u -> Point2 u-shortenLineR n p0 p1 = p1 .+^ v-  where-    v0 = p0 .-. p1-    v  = avec (direction v0) n---------------------------------------------------------------------------------------- line direction---- | Direction of empty path is considered to be 0.----directionL :: (Real u, Floating u) => Path u -> Radian-directionL (Path _ _ se _)  = step $ viewl se-  where-    step (LineSeg  _ p0 p1 :< _)      = lineDirection p1 p0  -- 1-to-0-    step (CurveSeg _ p0 p1 _ _ :< _)  = lineDirection p1 p0-    step _                            = 0       -- should be unreachable----- | Direction of empty path is considered to be 0.----directionR :: (Real u, Floating u) => Path u -> Radian-directionR (Path _ _ se _) = step $ viewr se-  where-    step (_ :> LineSeg  _ p0 p1)      = lineDirection p0 p1-    step (_ :> CurveSeg _ _  _ p2 p3) = lineDirection p2 p3-    step _                            = 0       -- should be unreachable             ------------------------------------------------------------------------------------------ Return direction as well because the calculation is expensive...----midway :: (Real u, Floating u) => Path u -> (Point2 u, Radian)-midway pa@(Path u sp _ _) -    | u == 0    = (sp,0)-    | otherwise = let pa1 = shortenR (u/2) pa in (tipR pa1, directionR pa1)---- Just the midway point.----midway_ :: (Real u, Floating u) => Path u -> Point2 u-midway_ = fst . midway---atstart :: (Real u, Floating u) => Path u -> (Point2 u, Radian)-atstart pa@(Path _ sp _ _) = (sp, directionL pa)--atstart_ :: Path u -> Point2 u-atstart_ (Path _ sp _ _) = sp---atend :: (Real u, Floating u) => Path u -> (Point2 u, Radian)-atend pa@(Path _ _ _ ep) = (ep, directionR pa)- --atend_ :: Path u -> Point2 u-atend_ (Path _ _ _ ep) = ep----- nearstart, nearend, verynear ...-------------------------------------------------------------------------------------data PathViewL u = PathOneL (PathSegment u)-                 | PathSegment u :<< Path u-  deriving (Eq,Ord,Show) --type DPathViewL = PathViewL Double--data PathViewR u = PathOneR (PathSegment u)-                 | Path u :>> PathSegment u-  deriving (Eq,Ord,Show) --type DPathViewR = PathViewR Double---data PathSegment u = Line1  (Point2 u) (Point2 u)-                   | Curve1 (Point2 u) (Point2 u) (Point2 u) (Point2 u)-  deriving (Eq,Ord,Show) --type DPathSegment = PathSegment Double--type instance DUnit (PathViewL u)   = u-type instance DUnit (PathViewR u)   = u-type instance DUnit (PathSegment u) = u--pathViewL :: Num u => Path u -> PathViewL u-pathViewL (Path u _ segs ep) = go (viewl segs)-  where-    go EmptyL                   = error "pathViewL - (not) unreachable."-     -    go (LineSeg v p0 p1 :< se)-        | S.null se             = PathOneL (Line1 p0 p1)-        | otherwise             = Line1 p0 p1 :<< Path (u-v) p1 se ep--    go (CurveSeg v p0 p1 p2 p3 :< se) -        | S.null se             = PathOneL (Curve1 p0 p1 p2 p3)-        | otherwise             = Curve1 p0 p1 p2 p3 :<< Path (u-v) p3 se ep---pathViewR :: Num u => Path u -> PathViewR u-pathViewR (Path u _ segs ep) = go (viewr segs)-  where-    go EmptyR                   = error "pathViewR - (not) unreachable."--    go (se :> LineSeg v p0 p1) -        | S.null se             = PathOneR (Line1 p0 p1)-        | otherwise             = Path (u-v) p1 se ep :>> Line1 p0 p1--    go (se :> CurveSeg v p0 p1 p2 p3) -        | S.null se             = PathOneR (Curve1 p0 p1 p2 p3)-        | otherwise             = Path (u-v) p3 se ep :>> Curve1 p0 p1 p2 p3-
− src/Wumpus/Basic/Paths/Connectors.hs
@@ -1,206 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Paths.Connectors--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Library of connector paths...------ \*\* WARNING \*\* this module is experimental and may change --- significantly in future revisions.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Paths.Connectors -  ( --    ConnectorPath-  , DConnectorPath--  , connLine--  , connRightVH-  , connRightHV-  , connRightVHV-  , connRightHVH--  , connIsosceles-  , connIsosceles2-  , connLightningBolt---  , connIsoscelesCurve-  , connSquareCurve-  , connUSquareCurve--  , connTrapezoidCurve-  , connZSquareCurve-  , connUZSquareCurve--  ) where--import Wumpus.Basic.Paths.Base-import Wumpus.Basic.Paths.ControlPoints--import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace                         -- package: vector-space--import Prelude hiding ( length )----type ConnectorPath u = Point2 u -> Point2 u -> Path u--type DConnectorPath = ConnectorPath Double-------------------------------------------------------------------------------------- | Connect with a straight line.----connLine :: Floating u => ConnectorPath u-connLine = line---- | Right-angled connector - go vertical, then go horizontal.----connRightVH :: Floating u => ConnectorPath u-connRightVH p1@(P2 x1 _) p2@(P2 _ y2) = -    let mid = P2 x1 y2 in traceLinePoints [p1, mid, p2]---- | Right-angled connector - go horizontal, then go vertical.----connRightHV :: Floating u => ConnectorPath u-connRightHV p1@(P2 _ y1) p2@(P2 x2 _) = -    let mid = P2 x2 y1 in traceLinePoints [p1, mid, p2]---- | Right-angled connector - go vertical for the supplied --- distance, go horizontal, go vertical again for the --- remaining distance.--- -connRightVHV :: Floating u => u -> ConnectorPath u-connRightVHV v p1@(P2 x1 _) p2@(P2 x2 _) = traceLinePoints [p1, a1, a2, p2]-  where-    a1 = p1 .+^ vvec v-    a2 = a1 .+^ hvec (x2 - x1)----- | Right-angled connector - go horizontal for the supplied --- distance, go verical, go horizontal again for the --- remaining distance.--- -connRightHVH :: Floating u => u -> ConnectorPath u-connRightHVH h p1@(P2 _ y1) p2@(P2 _ y2) = traceLinePoints [p1,a1,a2,p2]-  where-    a1 = p1 .+^ hvec h-    a2 = a1 .+^ vvec (y2 - y1)----- | /Triangular/ joint.--- --- @u@ is the altitude of the triangle.----connIsosceles :: (Real u, Floating u) => u -> ConnectorPath u -connIsosceles dy p1 p2 = traceLinePoints [p1, mid_pt, p2]-  where-    mid_pt  = midpointIsosceles dy p1 p2------ | Double /triangular/ joint.--- --- @u@ is the altitude of the triangle.----connIsosceles2 :: (Real u, Floating u) => u -> ConnectorPath u -connIsosceles2 u p1 p2 = traceLinePoints [ p1, cp1, cp2, p2 ]-  where-    (cp1,cp2) = dblpointIsosceles u p1 p2----- | /Lightning bolt/ joint - a two joint connector with an /axis/--- perpendicular to the connector direction.--- --- @u@ is the half length of the of the axis.----connLightningBolt :: (Real u, Floating u) => u -> ConnectorPath u -connLightningBolt u p1 p2 = traceLinePoints [ p1, cp1, cp2, p2 ]-  where-    cp1 = midpointIsosceles   u  p1 p2-    cp2 = midpointIsosceles (-u) p1 p2---------------------------------------------------------------------------------------- | Form a curve inside an isosceles triangle. ------ The two Bezier control points take the same point - the--- altitude of the triangle. The curve tends to be quite shallow--- relative to the altitude.------ @u@ is the altitude of the triangle.----connIsoscelesCurve :: (Real u, Floating u) => u -> ConnectorPath u -connIsoscelesCurve u p1 p2 = traceCurvePoints [p1, control_pt, control_pt, p2]-  where-    control_pt  = midpointIsosceles u p1 p2-    ----- | Form a curve inside a square. ------ The two Bezier control points take the /top/ corners. The--- curve tends to be very deep.--- -connSquareCurve :: (Real u, Floating u) => ConnectorPath u -connSquareCurve p1 p2 = traceCurvePoints [p1, cp1, cp2, p2]-  where-    (cp1,cp2) = squareFromBasePoints p1 p2---- | Form a curve inside a square. ------ As per 'connSquareCurve' but the curve is drawn /underneath/--- the line formed between the start and end points.--- --- (Underneath is modulo the direction, of course).--- -connUSquareCurve :: (Real u, Floating u) => ConnectorPath u -connUSquareCurve p1 p2 = traceCurvePoints [p1, cp1, cp2, p2]-  where-    (cp1,cp2) = usquareFromBasePoints p1 p2------ | altitude * ratio_to_base ------ Form a curve inside a trapeziod.--- -connTrapezoidCurve :: (Real u, Floating u) => u -> u -> ConnectorPath u -connTrapezoidCurve u ratio_to_base p1 p2 = traceCurvePoints [p1, cp1, cp2, p2]-  where-    (cp1,cp2)  = trapezoidFromBasePoints u ratio_to_base p1 p2----- | Make a curve within a square, following the corner points as--- a Z.----connZSquareCurve :: (Real u, Floating u) => ConnectorPath u -connZSquareCurve p1 p2 = traceCurvePoints [p1,cp1,cp2,p2]-   where-     (cp1,cp2)  = squareFromCornerPoints p1 p2 -      --- | Make a curve within a square, following the corner points as--- a Z.------ The order of tracing flips the control points, so this is an--- /underneath/ version of 'connZSquareCurve'.--- -connUZSquareCurve :: (Real u, Floating u) => ConnectorPath u -connUZSquareCurve p1 p2 = traceCurvePoints [p1,cp2,cp1,p2]-   where-     (cp1,cp2)  = squareFromCornerPoints p1 p2 
− src/Wumpus/Basic/Paths/Construction.hs
@@ -1,160 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Paths.Construction--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Build paths monadically.------ \*\* WARNING \*\* this module is an experiment, and may --- change significantly or even be dropped from future revisions.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Paths.Construction-  ( --    PathM-  , runPath-  , execPath--  , tip--  , lineto-  , rlineto-  , hline-  , vline--  , bezierto-  , curveto--  , verticalHorizontal-  , horizontalVertical--  ) where--import Wumpus.Basic.Paths.Base-import Wumpus.Basic.Utils.HList--import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace                         -- package: vector-space--import Control.Applicative-import Data.List----- Are connectors and paths quite different things?------ It looks like they are - connectors always know start and end --- points.-------- State monad version is quite good - it ameliorates the problem--- of joining to the end point of an empty path...--data St u = St-      { current_point :: Point2 u -      , path_acc      :: H (Path u)-      }---newtype PathM u a = PathM { getPathM :: St u -> (a,St u) }---instance Functor (PathM u) where-  fmap f mf = PathM $ \s -> let (a,s1) = getPathM mf s in (f a,s1)---instance Applicative (PathM u) where-  pure a    = PathM $ \s -> (a,s)-  mf <*> ma = PathM $ \s -> let (f,s1) = getPathM mf s-                                (a,s2) = getPathM ma s1-                            in (f a,s2)--instance Monad (PathM u) where-  return a  = PathM $ \s -> (a,s)-  m >>= k   = PathM $ \s -> let (a,s1) = getPathM m s in-                            (getPathM . k) a s1------ Running the path is (probably) agnostic to the DrawingCtx.----runPath :: Floating u => Point2 u -> PathM u a -> (a, Path u)-runPath start mf = -    let (a,s') = getPathM mf s in (a, post $ toListH $ path_acc s')-  where-    s = St { current_point = start-           , path_acc      = emptyH-           }-    post []     = line start start-    post (x:xs) = foldl' append x xs  --execPath :: Floating u => Point2 u -> PathM u a -> Path u-execPath start mf = snd $ runPath start mf--snocline :: Floating u => Vec2 u -> PathM u ()-snocline v = PathM $ \(St pt ac) -> let ep = pt .+^ v -                                    in ((), St ep (ac `snocH` line pt ep))---tip :: PathM u (Point2 u)-tip = PathM $ \s -> (current_point s,s)---lineto :: Floating u => Point2 u -> PathM u ()-lineto pt = PathM $ \(St p0 ac) -> ((), St pt (ac `snocH` line p0 pt))--rlineto :: Floating u => Vec2 u -> PathM u ()-rlineto (V2 dx dy) = tip >>= \(P2 x y) -> lineto (P2 (x+dx) (y+dy))---hline :: Floating u => u -> PathM u ()-hline len = snocline (hvec len) --vline :: Floating u => u -> PathM u ()-vline len = snocline (vvec len) ----bezierto :: (Floating u, Ord u) -         => Point2 u -> Point2 u -> Point2 u -> PathM u ()-bezierto c1 c2 ep = PathM $ \(St p0 ac) -> -    ((), St ep (ac `snocH` curve p0 c1 c2 ep))-----------curveto :: (Floating u, Ord u) -        => Radian -> Radian -> Point2 u -> PathM u ()-curveto cin cout end = PathM $ \(St p0 ac) -> -    let seg  = curveByAngles p0 cin cout end -        ac1  = ac `snocH` seg-        end1 = tipR seg-    in ((), St end1 ac1) -----verticalHorizontal :: Floating u => Point2 u -> PathM u ()-verticalHorizontal (P2 x y) = -    tip >>= \(P2 x0 _) -> lineto (P2 x0 y) >> lineto (P2 x y)--horizontalVertical :: Floating u => Point2 u -> PathM u ()-horizontalVertical (P2 x y) = -    tip >>= \(P2 _ y0) -> lineto (P2 x y0) >> lineto (P2 x y)-
− src/Wumpus/Basic/Paths/ControlPoints.hs
@@ -1,189 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Paths.ControlPoints--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Collection of point manufacturing functions.------ \*\* WARNING \*\* this module is experimental and may change --- significantly in future revisions.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Paths.ControlPoints-  ( --    midpointIsosceles-  , dblpointIsosceles--  , rectangleFromBasePoints-  , squareFromBasePoints-  , usquareFromBasePoints--  , trapezoidFromBasePoints--  , squareFromCornerPoints--  ) where--import Wumpus.Basic.Graphic--import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace                         -- package: vector-space------- | 'midpointIsosceles' : --- @ altitude * start_pt * end_pt -> mid_pt @------ Triangular midpoint.--- --- @u@ is the altitude of the triangle - negative values of u --- form the triangle below the line.----midpointIsosceles :: (Real u, Floating u) -                  => u -> Point2 u -> Point2 u -> Point2 u-midpointIsosceles u p1@(P2 x1 y1) p2@(P2 x2 y2) = -    mid_pt .+^ avec perp_ang u-  where-    mid_pt    = P2 (x1 + 0.5*(x2-x1)) (y1 + 0.5*(y2-y1))-    perp_ang  = (pi*0.5) + direction (pvec p1 p2) ------ | 'dblpointIsosceles' : --- @ altitude * start_pt * end_pt * (third_pt, two_thirds_pt) @--- --- Double triangular joint - one joint at a third of the line--- length, the other at two thirds.--- -dblpointIsosceles :: (Real u, Floating u) -                      => u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)  -dblpointIsosceles u p1@(P2 x1 y1) p2@(P2 x2 y2) = -    (mid1 .+^ avec perp_ang u, mid2 .-^ avec perp_ang u)-  where-    mid1      = P2 (x1 + 0.33*(x2-x1)) (y1 + 0.33*(y2-y1))-    mid2      = P2 (x1 + 0.66*(x2-x1)) (y1 + 0.66*(y2-y1))-    perp_ang  = (pi*0.5) + direction (pvec p1 p2) ----------------------------------------------------------------------------------------- | 'rectangleFromBasePoints' : --- @ altitude * start_pt * end_pt * (top_left, top_right) @--- --- Control points forming a rectangle. ------ The two manufactured control points form the top corners, --- so the supplied points map as @start_point == bottom_left@ and --- @end_point == bottom_right@.----rectangleFromBasePoints :: (Real u, Floating u) -                  => u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)-rectangleFromBasePoints u p1 p2 = (cp1, cp2)-  where-    base_vec  = pvec p1 p2-    theta     = direction base_vec-    cp1       = displacePerpendicular u theta p1-    cp2       = displacePerpendicular u theta p2----- | 'squareFromBasePoints' : --- @ start_pt -> end_pt -> (top_left, top_right) @--- --- Control points forming a square - side_len derived from the --- distance between start and end points.------ The two manufactured control points form the top corners, --- so the supplied points map as @start_point == bottom_left@ and --- @end_point == bottom_right@.----squareFromBasePoints :: (Real u, Floating u) -                     => Point2 u -> Point2 u -> (Point2 u, Point2 u)-squareFromBasePoints p1 p2 = rectangleFromBasePoints side_len p1 p2-  where-    side_len  = vlength $ pvec p1 p2----- | 'usquareFromBasePoints' : --- @ start_pt -> end_pt -> (bottom_left, bottom_right) @--- --- Control points forming a square - side_len derived from the --- distance between start and end points.------ As per 'squareFromBasePoints' but the square is drawn --- /underneath/ the line formed between the start and end points.--- (Underneath is modulo the direction, of course).------ The two manufactured control points form the /bottom/ corners, --- so the supplied points map as @start_point == top_left@ and --- @end_point == top_right@.--- -usquareFromBasePoints :: (Real u, Floating u) -                      => Point2 u -> Point2 u -> (Point2 u, Point2 u)-usquareFromBasePoints p1 p2 = rectangleFromBasePoints side_len p1 p2-  where-    side_len  = negate $ vlength $ pvec p1 p2-------- | 'trapezoidFromBasePoints' : --- @ altitude * ratio_to_base * start_pt * end_pt -> (top_left, top_right) @------ Control points form an isosceles trapezoid.------ The two manufactured control points form the top corners, --- so the supplied points map as @start_point == bottom_left@ and --- @end_point == bottom_right@.--- -trapezoidFromBasePoints :: (Real u, Floating u) -                        => u -> u -> Point2 u -> Point2 u -                        -> (Point2 u, Point2 u) -trapezoidFromBasePoints u ratio_to_base p1 p2 = (cp1, cp2)-  where-    base_vec  = pvec p1 p2-    base_len  = vlength base_vec-    theta     = direction base_vec-    half_ulen = 0.5 * ratio_to_base * base_len-    base_mid  = displaceParallel (0.5 * base_len) theta p1-    ubase_mid = displacePerpendicular u theta base_mid-    cp1       = displaceParallel (-half_ulen) theta ubase_mid-    cp2       = displaceParallel   half_ulen  theta ubase_mid------- | 'squareFromCornerPoints' : --- @ altitude * start_pt * end_pt * (top_left, bottom_right) @--- --- Control points forming a square bisected by the line from --- start_pt to end_pt. ------ The two manufactured control points form the top_left and--- bottom_right corners, so the supplied points map as --- @start_point == bottom_left@ and @end_point == top_right@.----squareFromCornerPoints :: (Real u, Floating u) -                       => Point2 u -> Point2 u -> (Point2 u, Point2 u) -squareFromCornerPoints p1 p2 = (cp1, cp2)-  where-    base_vec  = pvec p1 p2-    half_len  = 0.5 * (vlength base_vec)-    theta     = direction base_vec-    base_mid  = displaceParallel half_len theta p1-    cp1       = displacePerpendicular   half_len  theta base_mid-    cp2       = displacePerpendicular (-half_len) theta base_mid-
− src/Wumpus/Basic/Paths/RoundCorners.hs
@@ -1,121 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Paths.RoundCorners--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Drawing round cornered polygons.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Paths.RoundCorners-  ( -    cornerCurve-  , illustratePath-  , roundEvery--  ) where--import Wumpus.Basic.Colour.SVGColours-import Wumpus.Basic.Graphic-import Wumpus.Basic.Paths.Base hiding ( length )-import Wumpus.Basic.Utils.Intersection---import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace                         -- package: vector-space----- | The length of the control-point vector wants to be slighly --- longer than half of /d/ (d - being the distance between the --- /truncated/ points and the corner).----cornerCurve :: (Real u, Floating u) -            => Point2 u -> Point2 u -> Point2 u -> Path u-cornerCurve p1 p2 p3 = curve p1 cp1 cp2 p3-  where-    len1 = 0.6 *  (vlength $ pvec p1 p2)-    len2 = 0.6 *  (vlength $ pvec p3 p2)-    cp1  = p1 .+^ (avec (langle p1 p2) len1)-    cp2  = p3 .+^ (avec (langle p3 p2) len2)----- | 'roundEvery' throws a runtime error if the input list has--- less than 3 eleemnts.----roundEvery :: (Real u, Floating u) -           => u -> [Point2 u] -> Path u -roundEvery u (start:b:c:xs) = step (twoParts u start b c) (b:c:xs)-  where-    step acc (m:n:o:ps)     = step (acc `append` twoParts u m n o) (n:o:ps)-    step acc [n,o]          = acc `append` twoParts u n o start-                                  `append` twoParts u o start b -    step acc _              = acc--roundEvery _ _              = error "roundEvery - input list too short."----- | Two parts - line and corner curve...----twoParts :: (Real u, Floating u) -         => u ->  Point2 u -> Point2 u -> Point2 u -> Path u-twoParts u a b c = line p1 p2 `append` cornerCurve p2 b p3-  where-    p1 = a .+^ (avec (direction $ pvec a b) u)-    p2 = b .+^ (avec (direction $ pvec b a) u)-    p3 = b .+^ (avec (direction $ pvec b c) u)- -------------------------------------------------------------------------------------- ---- This needs moving outside of the Path modules as it has --- dependencies on SVGColour and Graphic (the Path modules should--- be /neutral/ to wards depenedencies on other parts of --- Wumpus-Basic).-----illustratePath :: Fractional u => Path u -> Graphic u-illustratePath = localize (strokeColour black) . step1 . pathViewL-  where-    step1 (PathOneL e)  = drawPath1 e-    step1 (e :<< se)    = drawPathBoth e `oplus` rest (pathViewL se)--    rest (PathOneL e)   = drawPath1 e-    rest (e :<< se)     = drawPath1 e `oplus` rest (pathViewL se)--drawPathBoth :: Fractional u => PathSegment u -> Graphic u-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--drawPath1 (Curve1 p1 p2 p3 p4) =  -    oconcat (bezierCtrl p1 p2) [ bezierCtrl p4 p3, curveBetween p1 p2 p3 p4-                               , 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 `at` p2)---pathPoint :: Num u => Point2 u -> Graphic u-pathPoint pt = localize bothStrokeColour (filledDisk 1 `at` pt)-
− src/Wumpus/Basic/SafeFonts.hs
@@ -1,167 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.SafeFonts--- Copyright   :  (c) Stephen Tetley 2009-2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ 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-  ( -  -- * Times Roman-    times_roman-  , times_italic-  , times_bold-  , times_bold_italic--  -- * Helvetica-  , helvetica-  , helvetica_oblique-  , helvetica_bold-  , helvetica_bold_oblique--  -- * Courier-  , courier-  , courier_oblique-  , courier_bold-  , courier_bold_oblique--  -- * Symbol-  , symbol--  ) where----import Wumpus.Core-import Wumpus.Core.Text.StandardEncoding-import Wumpus.Core.Text.Symbol---- Supported fonts are:------ Times-Roman  Times-Italic       Times-Bold      Times-BoldItalic--- Helvetica    Helvetica-Oblique  Helvetica-Bold  Helvetica-Bold-Oblique--- Courier      Courier-Oblique    Courier-Bold    Courier-Bold-Oblique--- Symbol------------------------------------------------------------------------------------- ---- | Times-Roman--- -times_roman :: FontFace-times_roman = -    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 standard_encoding-                       --- | Times Bold----times_bold :: FontFace-times_bold = -    FontFace "Times-Bold" "Times New Roman" SVG_BOLD standard_encoding---- | Times Bold Italic----times_bold_italic :: FontFace-times_bold_italic = FontFace "Times-BoldItalic" -                             "Times New Roman" -                             SVG_BOLD_ITALIC -                             standard_encoding-------------------------------------------------------------------------------------- Helvetica---- | Helvetica ----helvetica :: FontFace-helvetica = FontFace "Helvetica" "Helvetica" SVG_REGULAR standard_encoding----- | Helvetica Oblique----helvetica_oblique :: FontFace-helvetica_oblique = -    FontFace "Helvetica-Oblique" "Helvetica" SVG_OBLIQUE standard_encoding---- | Helvetica Bold--- -helvetica_bold :: FontFace-helvetica_bold = -    FontFace "Helvetica-Bold" "Helvetica" SVG_BOLD standard_encoding----- | Helvetica Bold Oblique----helvetica_bold_oblique :: FontFace-helvetica_bold_oblique = FontFace "Helvetica-Bold-Oblique" -                                  "Helvetica" -                                  SVG_BOLD_OBLIQUE -                                  standard_encoding---------------------------------------------------------------------------------------- | Courier--- -courier :: FontFace-courier = FontFace "Courier" "Courier New" SVG_REGULAR standard_encoding---- | Courier Oblique--- -courier_oblique :: FontFace-courier_oblique = -    FontFace "Courier-Oblique" "Courier New" SVG_OBLIQUE standard_encoding---- | Courier Bold--- -courier_bold :: FontFace-courier_bold = -    FontFace "Courier-Bold" "Courier New" SVG_BOLD standard_encoding----- | Courier Bold Oblique--- -courier_bold_oblique :: FontFace-courier_bold_oblique = FontFace "Courier-Bold-Oblique" -                                "Courier New" -                                SVG_BOLD_OBLIQUE -                                standard_encoding------------------------------------------------------------------------------------- Symbol---- | Symbol------ 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_encoding-----
− src/Wumpus/Basic/Shapes.hs
@@ -1,27 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Shapes--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Shim module for Shapes.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Shapes-  ( -    module Wumpus.Basic.Shapes.Base-  , module Wumpus.Basic.Shapes.Coordinate-  , module Wumpus.Basic.Shapes.Derived--  ) where--import Wumpus.Basic.Shapes.Base-import Wumpus.Basic.Shapes.Coordinate-import Wumpus.Basic.Shapes.Derived hiding ( mkRectangle )
− src/Wumpus/Basic/Shapes/Base.hs
@@ -1,226 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Shapes.Base--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Common core for shapes--- --- \*\* WARNING \*\* - the types of Shapes are not ideal and are --- pending revision.--------------------------------------------------------------------------------------module Wumpus.Basic.Shapes.Base-  ( ---    Shape-  , LocShape-  , makeShape--  , ShapeConstructor--  , borderedShape-  , filledShape-  , strokedShape--  -- * ShapeCTM -  , ShapeCTM-  , makeShapeCTM--  , ShapeGeom-  , runShapeGeom-  , askCTM-  , projectPoint-  , shapeCenter-  , shapeAngle--  ) where--import Wumpus.Basic.Graphic-import Wumpus.Basic.Paths--import Wumpus.Core                              -- package: wumpus-core---import Control.Applicative----- Currently shapes that aren\'t paths:------ > Coordinate--- > FreeLabel------ Alternative ------ > out_fun :: ShapeCTM u -> (Path u,sh)------ All shapes expect FreeLabel are oblivious to the --- DrawingContext for the /shape/-----newtype ShapeR u a = ShapeR { getShapeR :: ShapeCTM u -> a }--runShapeR :: ShapeCTM u -> ShapeR u a -> a-runShapeR ctm sf = getShapeR sf ctm---data Shape u t =  Shape -      { shape_ctm   :: ShapeCTM u -      , path_fun    :: ShapeR u (Path u)-      , cons_fun    :: ShapeR u (t u)-      }--type instance DUnit (Shape u sh) = u---type LocShape u t = Point2 u -> Shape u t--type ShapeConstructor u t = ShapeCTM u -> t u ---makeShape :: Num u -          => (ShapeCTM u -> Path u) -> (ShapeCTM u -> t u) -> LocShape u t-makeShape pf mkf = \pt -> Shape { shape_ctm = makeShapeCTM pt-                                , path_fun  = ShapeR pf-                                , cons_fun  = ShapeR mkf-                                } ---shapeImage :: Num u => (PrimPath u -> Graphic u) -> Shape u t -> Image u (t u)-shapeImage drawF (Shape { shape_ctm = ctm, path_fun = pf, cons_fun = objf }) = -   intoImage (pure $ runShapeR ctm objf) -             (drawF $ toPrimPath $ runShapeR ctm pf)---borderedShape :: Num u => Shape u t -> Image u (t u)-borderedShape = shapeImage borderedPath--filledShape :: Num u => Shape u t -> Image u (t u)-filledShape = shapeImage filledPath--strokedShape :: Num u => Shape u t -> Image u (t u)-strokedShape = shapeImage closedStroke ----instance (Real u, Floating u) => Rotate (Shape u sh) where-  rotate r = updateCTM (rotate r)--instance (Real u, Floating u) => RotateAbout (Shape u sh) where-  rotateAbout r pt = updateCTM (rotateAbout r pt)--instance Num u => Scale (Shape u sh) where-  scale sx sy = updateCTM (scale sx sy)--instance Num u => Translate (Shape u sh) where-  translate dx dy = updateCTM (translate dx dy)---updateCTM :: (ShapeCTM u -> ShapeCTM u) -> Shape u sh -> Shape u sh-updateCTM fn (Shape ctm pf mkf) = Shape (fn ctm) pf mkf------------------------------------------------------------------------------------- CTM---- Note - all shapes need a location (usually/always the center)--- so this needs to be stored in the CTM.-----data ShapeCTM u = ShapeCTM -      { ctm_center              :: Point2 u-      , ctm_scale_x             :: !u-      , ctm_scale_y             :: !u-      , ctm_rotation            :: Radian-      }-  deriving (Eq,Ord,Show)---type instance DUnit (ShapeCTM u) = u--makeShapeCTM :: Num u => Point2 u -> ShapeCTM u-makeShapeCTM pt = ShapeCTM { ctm_center   = pt-                           , ctm_scale_x  = 1-                           , ctm_scale_y  = 1-                           , ctm_rotation = 0 }------instance Num u => Scale (ShapeCTM u) where-  scale sx sy = (\s x y -> s { ctm_scale_x = x*sx, ctm_scale_y = y*sy })-                  <*> ctm_scale_x <*> ctm_scale_y---instance Rotate (ShapeCTM u) where-  rotate ang = (\s i -> s { ctm_rotation = circularModulo $ i+ang })-                  <*> ctm_rotation--instance (Real u, Floating u) => RotateAbout (ShapeCTM u) where-  rotateAbout ang pt = -    (\s ctr i -> s { ctm_rotation = circularModulo $ i+ang-                   , ctm_center   = rotateAbout ang pt ctr })-      <*> ctm_center <*> ctm_rotation---instance Num u => Translate (ShapeCTM u) where-  translate dx dy = (\s (P2 x y) -> s { ctm_center = P2 (x+dx) (y+dy) })-                      <*> ctm_center-------------------------------------------------------------------------------------newtype ShapeGeom u a = ShapeGeom { getShapeGeom :: ShapeCTM u -> a }---type instance MonUnit (ShapeGeom u) = u---instance Functor (ShapeGeom u) where-  fmap f ma = ShapeGeom $ \ctx -> let a = getShapeGeom ma ctx in f a--instance Applicative (ShapeGeom u) where-  pure a    = ShapeGeom $ \_   -> a-  mf <*> ma = ShapeGeom $ \ctx -> let f = getShapeGeom mf ctx-                                      a = getShapeGeom ma ctx-             			  in (f a)--instance Monad (ShapeGeom u) where-  return a = ShapeGeom $ \_   -> a-  m >>= k  = ShapeGeom $ \ctx -> let a = getShapeGeom m ctx-    	     	                 in (getShapeGeom . k) a ctx----runShapeGeom :: ShapeCTM u -> ShapeGeom u a -> a-runShapeGeom ctm mf = getShapeGeom mf ctm--askCTM :: ShapeGeom u (ShapeCTM u)-askCTM = ShapeGeom $ \ctm -> ctm--shapeCenter :: ShapeGeom u (Point2 u)-shapeCenter = ShapeGeom $ \ctm -> ctm_center ctm--shapeAngle :: ShapeGeom u Radian-shapeAngle = ShapeGeom $ \ctm -> ctm_rotation ctm----projectPoint :: (Real u, Floating u) => Point2 u -> ShapeGeom u (Point2 u)-projectPoint (P2 x y) = ShapeGeom $ -    \(ShapeCTM { ctm_center   = (P2 dx dy)-               , ctm_scale_x  = sx-               , ctm_scale_y  = sy-               , ctm_rotation = theta }) -> -    translate dx dy $ rotate theta $ P2 (sx*x) (sy*y)-
− src/Wumpus/Basic/Shapes/Coordinate.hs
@@ -1,136 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Shapes.Coordinate--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ 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-  (-    CoordinateAnchor-  , DCoordinateAnchor-  , Coordinate-  , DCoordinate-  , coordinate--  , coordinateDot-  , coordinateX--  ) where--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--newtype CoordinateAnchor u = CoordinateAnchor { getCoordAnchor :: ShapeCTM u }-  deriving (Eq,Ord,Show)--type DCoordinateAnchor = CoordinateAnchor Double--type instance DUnit (CoordinateAnchor u) = u--newtype Coordinate u = Coordinate { getCoordinate :: CoordinateAnchor u }-  deriving (Eq,Ord,Show)--type DCoordinate = Coordinate Double--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 = 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 = cMap (translate dx dy)----coordinate :: Num u => LocCoordinate u-coordinate = Coordinate . CoordinateAnchor . makeShapeCTM---coordinateDot :: (Real u, Floating u, FromPtSize u) -              => Coordinate u -> Image u (CoordinateAnchor u)-coordinateDot x = intoImage (return $ getCoordinate x) (drawDot x)------ | 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
@@ -1,372 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE TypeSynonymInstances       #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Shapes.Derived--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Simple shapes - rectangle, circle diamond, ellipse.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Shapes.Derived-  ( -    Rectangle-  , DRectangle-  , rectangle-  , rrectangle--  , mkRectangle   -- hidden in Shim module--  , Circle-  , DCircle-  , circle--  , Diamond-  , DDiamond-  , diamond-  , rdiamond--  , Ellipse-  , DEllipse-  , ellipse---  ) where--import Wumpus.Basic.Graphic-import Wumpus.Basic.Paths-import Wumpus.Basic.Paths.RoundCorners-import Wumpus.Basic.Shapes.Base-import Wumpus.Basic.Utils.Intersection--import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace                         -- package: vector-space -import Data.VectorSpace--import Control.Applicative----- Note - Specific shapes - Rectangle, Circle, etc. - should _NOT_--- have affine instances. ------ Transformations should only operate on the Shape type. Once a--- Shape has been drawn the resultant Rectangle, Circle... cannot --- be further transformed, as this would dis-associate the Anchors--- from the Graphic.---------------------------------------------------------------------------------------- Rectangle--data Rectangle u = Rectangle -      { rect_ctm    :: ShapeCTM u-      , rect_hw     :: !u-      , rect_hh     :: !u -      }-  deriving (Eq,Ord,Show)--type DRectangle = Rectangle Double---type instance DUnit (Rectangle u) = u---runRectangle :: (u -> u -> ShapeGeom u a) -> Rectangle u -> a-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-  center = runRectangle (\ _ _ -> shapeCenter)---instance (Real u, Floating u) => CardinalAnchor (Rectangle u) where-  north = runRectangle $ \_  hh -> projectPoint $ P2 0 hh-  south = runRectangle $ \_  hh -> projectPoint $ P2 0 (-hh)-  east  = runRectangle $ \hw _  -> projectPoint $ P2 hw 0-  west  = runRectangle $ \hw _  -> projectPoint $ P2 (-hw) 0--instance (Real u, Floating u) => CardinalAnchor2 (Rectangle u) where-  northeast = runRectangle $ \hw hh -> projectPoint $ P2 hw hh-  southeast = runRectangle $ \hw hh -> projectPoint $ P2 hw (-hh)-  southwest = runRectangle $ \hw hh -> projectPoint $ P2 (-hw) (-hh)-  northwest = runRectangle $ \hw hh -> projectPoint $ P2 (-hw) hh---instance (Real u, Floating u) => RadialAnchor (Rectangle u) where-  radialAnchor theta = runRectangle $ \hw hh -> -    projectPoint $ rectangleIntersect hw hh theta---- Note - the answer needs projecting with the CTM...----rectangleIntersect :: (Real u, Floating u) -                   => u -> u -> Radian -> Point2 u-rectangleIntersect hw hh theta = -    maybe zeroPt id $ findIntersect zeroPt theta $ rectangleLines zeroPt hw hh ----- | 'rectangle'  : @ width * height -> shape @----rectangle :: (Real u, Floating u) => u -> u -> LocShape u Rectangle-rectangle w h = -    makeShape (traceLinePoints . rectanglePoints (0.5*w) (0.5*h))-              (mkRectangle (0.5*w) (0.5*h))-          ---- | 'rectangle'  : @ round_length * width * height -> shape @----rrectangle :: (Real u, Floating u) => u -> u -> u -> LocShape u Rectangle-rrectangle round_dist w h = -    makeShape (roundEvery round_dist . rectanglePoints (0.5*w) (0.5*h))-              (mkRectangle (0.5*w) (0.5*h))-         ----mkRectangle :: u -> u -> ShapeConstructor u Rectangle-mkRectangle hw hh = \ctm -> -    Rectangle { rect_ctm = ctm, rect_hw = hw, rect_hh = hh }----rectanglePoints :: (Real u, Floating u) => u -> u -> ShapeCTM u -> [Point2 u]-rectanglePoints hw hh ctm = runShapeGeom ctm $ mapM projectPoint [se,ne,nw,sw]-  where-    se = P2   hw  (-hh)-    ne = P2   hw    hh-    nw = P2 (-hw)   hh-    sw = P2 (-hw) (-hh) ----------------------------------------------------------------------------------------- Circle--data Circle u = Circle -      { circ_ctm    :: ShapeCTM u-      , circ_radius :: !u -      }-  deriving (Eq,Show)-  -type DCircle = Circle Double--type instance DUnit (Circle u) = u--runCircle :: (u -> ShapeGeom u a) -> Circle u -> a-runCircle mf (Circle { circ_ctm =ctm, circ_radius = radius }) = -   runShapeGeom ctm $ mf radius ---instance (Real u, Floating u) => CenterAnchor (Circle u) where-  center = runCircle (\_ -> shapeCenter)---instance (Real u, Floating u) => CardinalAnchor (Circle u) where-  north = runCircle $ \r -> projectPoint $ P2 0    r-  south = runCircle $ \r -> projectPoint $ P2 0  (-r)-  east  = runCircle $ \r -> projectPoint $ P2 r    0-  west  = runCircle $ \r -> projectPoint $ P2 (-r) 0---instance (Real u, Floating u) => CardinalAnchor2 (Circle u) where-  northeast = radialAnchor (0.25*pi)-  southeast = radialAnchor (1.75*pi)-  southwest = radialAnchor (1.25*pi)-  northwest = radialAnchor (0.75*pi)---instance (Real u, Floating u) => RadialAnchor (Circle u) where-  radialAnchor theta = runCircle $ \r -> projectPoint $ zeroPt .+^ avec theta r------ | 'circle'  : @ radius -> shape @----circle :: (Real u, Floating u) => u -> LocShape u Circle-circle radius = makeShape (traceCurvePoints . circlePoints radius)-                          (mkCircle radius)-          ---mkCircle :: u -> ShapeConstructor u Circle-mkCircle radius = \ctm -> Circle { circ_ctm = ctm, circ_radius = radius }---circlePoints :: (Real u, Floating u) => u -> ShapeCTM u -> [Point2 u]-circlePoints radius ctm = runShapeGeom ctm $ mapM projectPoint all_points-  where-    all_points  = bezierCircle 2 radius zeroPt --------------------------------------------------------------------------------------- Diamond---data Diamond u = Diamond -      { dia_ctm   :: ShapeCTM u-      , dia_hw    :: !u-      , dia_hh    :: !u-      }--type DDiamond = Diamond Double--type instance DUnit (Diamond u) = u----runDiamond :: (u -> u -> ShapeGeom u a) -> Diamond u -> a-runDiamond mf (Diamond { dia_ctm = ctm, dia_hw = hw, dia_hh = hh }) = -   runShapeGeom ctm $ mf hw hh ---instance (Real u, Floating u) => CenterAnchor (Diamond u) where-  center = runDiamond (\_ _ -> shapeCenter)--instance (Real u, Floating u) => CardinalAnchor (Diamond u) where-  north = runDiamond $ \_  hh -> projectPoint $ P2 0 hh-  south = runDiamond $ \_  hh -> projectPoint $ P2 0 (-hh)-  east  = runDiamond $ \hw _  -> projectPoint $ P2 hw 0-  west  = runDiamond $ \hw _  -> projectPoint $ P2 (-hw) 0--instance (Real u, Floating u, Fractional u) => CardinalAnchor2 (Diamond u) where-  northeast x = midpoint (north x) (east x)-  southeast x = midpoint (south x) (east x)-  southwest x = midpoint (south x) (west x)-  northwest x = midpoint (north x) (west x)----instance (Real u, Floating u) => RadialAnchor (Diamond u) where-   radialAnchor = diamondIntersect---- Utils.Intersection needs improving...---diamondIntersect :: (Real u, Floating u) -                 => Radian -> Diamond u -> Point2 u-diamondIntersect theta = runDiamond $ \hw hh ->  -    (\ctr ctm -> let ps = diamondPoints hw hh ctm -                 in maybe ctr id $ findIntersect ctr theta $ polygonLines ps)-      <$> shapeCenter <*> askCTM ---midpoint :: Fractional u => Point2 u -> Point2 u -> Point2 u-midpoint p1 p2 = let v = 0.5 *^ pvec p1 p2 in p1 .+^ v---- | 'diamond'  : @ half_width * half_height -> shape @------ Note - args might change to tull_width and full_height...----diamond :: (Real u, Floating u) => u -> u -> LocShape u Diamond-diamond hw hh = -    makeShape (traceLinePoints . diamondPoints hw hh)-              (mkDiamond hw hh)-          ---- | 'rdiamond'  : @ round_length * half_width * half_height -> shape @------ Note - args might change to full_width and full_height...----rdiamond :: (Real u, Floating u) => u -> u -> u -> LocShape u Diamond-rdiamond round_dist hw hh = -    makeShape (roundEvery round_dist . diamondPoints hw hh)-              (mkDiamond hw hh)-         -----mkDiamond :: (Real u, Floating u) => u -> u -> ShapeConstructor u Diamond-mkDiamond hw hh = \ctm -> Diamond { dia_ctm = ctm, dia_hw = hw, dia_hh = hh }---diamondPoints :: (Real u, Floating u) => u -> u -> ShapeCTM u -> [Point2 u]-diamondPoints hw hh ctm = runShapeGeom ctm $ mapM projectPoint [ s, e, n, w ]-  where-    s = P2   0  (-hh)-    e = P2   hw    0-    n = P2   0    hh-    w = P2 (-hw)   0 -------------------------------------------------------------------------------------- Ellipse---data Ellipse u = Ellipse-      { ell_ctm     :: ShapeCTM u -      , ell_rx      :: !u-      , ell_ry      :: !u-      }--type DEllipse = Ellipse Double--type instance DUnit (Ellipse u) = u---runEllipse :: (u -> u -> ShapeGeom u a) -> Ellipse u -> a-runEllipse mf (Ellipse { ell_ctm = ctm, ell_rx = rx, ell_ry = ry }) = -   runShapeGeom ctm $ mf rx ry ----- | x_radius is the unit length.----scaleEll :: (Scale t, Fractional u, u ~ DUnit t) => u -> u -> t -> t-scaleEll rx ry = scale 1 (ry/rx) ---instance (Real u, Floating u) => CenterAnchor (Ellipse u) where-  center = runEllipse $ \_ _ -> shapeCenter---instance (Real u, Floating u) => RadialAnchor (Ellipse u) where-  radialAnchor theta = runEllipse $ \rx ry -> -    projectPoint $ scaleEll rx ry $ zeroPt .+^ avec theta rx---instance (Real u, Floating u) => CardinalAnchor (Ellipse u) where-  north = radialAnchor (0.5*pi)-  south = radialAnchor (1.5*pi)-  east  = radialAnchor  0-  west  = radialAnchor  pi---instance (Real u, Floating u) => CardinalAnchor2 (Ellipse u) where-  northeast = radialAnchor (0.25*pi)-  southeast = radialAnchor (1.75*pi)-  southwest = radialAnchor (1.25*pi)-  northwest = radialAnchor (0.75*pi)----- | 'ellipse'  : @ x_radii * y_radii -> shape @----ellipse :: (Real u, Floating u) => u -> u -> LocShape u Ellipse-ellipse rx ry = -    makeShape (traceCurvePoints . ellipsePoints rx ry)-              (mkEllipse rx ry)-          --mkEllipse :: (Real u, Floating u) => u -> u -> ShapeConstructor u Ellipse-mkEllipse rx ry = \ctm -> Ellipse { ell_ctm = ctm, ell_rx = rx, ell_ry = ry }---ellipsePoints :: (Real u, Floating u) => u -> u -> ShapeCTM u -> [Point2 u]-ellipsePoints rx ry ctm = -    runShapeGeom ctm $ mapM (projectPoint . scaleEll rx ry) all_points-  where-    all_points =  bezierCircle 2 rx zeroPt ---
+ src/Wumpus/Basic/System/FontLoader/Afm.hs view
@@ -0,0 +1,82 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.System.FontLoader.Afm+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Font loader / import shim 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.System.FontLoader.Afm+  ( +    loadAfmMetrics+  +  ) where++import Wumpus.Basic.Kernel+import Wumpus.Basic.System.FontLoader.Base.AfmV4Dot1Parser+import Wumpus.Basic.System.FontLoader.Base.Datatypes+import Wumpus.Basic.System.FontLoader.Base.FontLoadMonad+++import Wumpus.Core                              -- package: wumpus-core++import Control.Monad+import Data.Monoid++-- The file names of the Afm fonts match there PostScript names,+-- the only difference is the addition of a @.afm@ extension.+--++-- | 'loadAfmMetrics' : +-- @ path_to_afm_fonts * [font_name] -> IO (metrics, messages) @ +-- +-- Load the supplied list of fonts. +-- +-- Note - if a font fails to load a message is written to the +-- log and monospaced /fallback metrics/ are used.+--+loadAfmMetrics :: FilePath -> [FontName] -> IO (GlyphMetrics, [String])+loadAfmMetrics font_dir_path ns = +    liftM post $ runFontLoadIO $ sequenceAll $ map mkFun ns+  where+    mkFun = afmLoadFontCalcs font_dir_path  + +    post (Left err,ss) = (mempty, ss ++ [err])      -- unreachable...+    post (Right xs,ss) = (foldr insertFont mempty xs, ss)+++++afmLoadFontCalcs :: FilePath -> FontName -> FontLoadIO FontMetricsOps+afmLoadFontCalcs font_dir_path name = do+    logLoadMsg  $ "Loading " ++ name+    path        <- checkFontPath font_dir_path (name ++ ".afm")+    ans         <- runParserFLIO path afmV4Dot1Parser+    props       <- buildAfmFontProps  afm_mono_defaults_4_1 ans+    return $ FontMetricsOps name (buildMetricsOps afmUnitScale props)++++-- | These are values extracted from Courier in the core 14 fonts.+--+afm_mono_defaults_4_1 :: MonospaceDefaults AfmUnit+afm_mono_defaults_4_1 = +    MonospaceDefaults { default_letter_bbox  = bbox+                      , default_cap_height   = 562+                      , default_char_width   = V2 600 0+                      }+  where+    bbox = BBox (P2 (-23) (-250)) (P2 715 805)
+ src/Wumpus/Basic/System/FontLoader/Base/AfmParserBase.hs view
@@ -0,0 +1,210 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.System.FontLoader.Base.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.System.FontLoader.Base.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.System.FontLoader.Base.Datatypes++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)+    return $ AfmFile +              { afm_encoding        = getEncodingScheme info+              , afm_letter_bbox     = getFontBBox       info+              , afm_cap_height      = getCapHeight      info+              , 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/System/FontLoader/Base/AfmV2Parser.hs view
@@ -0,0 +1,65 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.System.FontLoader.Internal.AfmV2Parser+-- 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.System.FontLoader.Base.AfmV2Parser+  ( +    afmV2Parser++  ) where++import Wumpus.Basic.System.FontLoader.Base.AfmParserBase+import Wumpus.Basic.System.FontLoader.Base.Datatypes+import Wumpus.Basic.Utils.ParserCombinators++import Wumpus.Core                              -- package: wumpus-core++import Control.Applicative+++++--------------------------------------------------------------------------------+-- parser+++afmV2Parser :: CharParser AfmFile+afmV2Parser = 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/System/FontLoader/Base/AfmV4Dot1Parser.hs view
@@ -0,0 +1,63 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.System.FontLoader.Base.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.System.FontLoader.Base.AfmV4Dot1Parser+  ( +    +    afmV4Dot1Parser  +  ) where++import Wumpus.Basic.System.FontLoader.Base.AfmParserBase+import Wumpus.Basic.System.FontLoader.Base.Datatypes+import Wumpus.Basic.Utils.ParserCombinators++import Wumpus.Core                              -- package: wumpus-core++import Control.Applicative+++afmV4Dot1Parser :: CharParser AfmFile+afmV4Dot1Parser = 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/System/FontLoader/Base/Datatypes.hs view
@@ -0,0 +1,178 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.System.FontLoader.Base.Datatypes+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Datatypes+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.System.FontLoader.Base.Datatypes+  (++  -- * Afm Unit+    AfmUnit+  , afmValue+  , afmUnitScale+  +  -- * Glyph metrics++  , PSCharCode+  , PSEncodingScheme+  , AfmBoundingBox++  , AfmKey+  , GlobalInfo+  , AfmFile(..)+  , AfmGlyphMetrics(..)++  , MonospaceDefaults(..)++  , FontProps(..)+  , buildMetricsOps+  +  ) where+++import Wumpus.Basic.Kernel.Base.GlyphMetrics++import Wumpus.Core                              -- package: wumpus-core++import qualified Data.IntMap   as IntMap+import qualified Data.Map as Map++++-- | 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_letter_bbox     :: Maybe AfmBoundingBox+      , afm_cap_height      :: Maybe AfmUnit+      , afm_glyph_metrics   :: [AfmGlyphMetrics]+      }+  deriving (Show) +  +-- Note - for AfmFile BBox is a required field for version 4.1, +-- but it appears to be optional for version 2.0.+--+++data AfmGlyphMetrics = AfmGlyphMetrics+      { afm_char_code       :: !PSCharCode+      , afm_width_vector    :: !(Vec2 AfmUnit)+      , afm_char_name       :: !String+      }+  deriving (Eq,Show)+++-- | Monospace defaults are used if the font loader fails to +-- extract the necessary fields.+-- +-- The values are taken from the font correpsonding to Courier +-- in the distributed font files.+--+data MonospaceDefaults cu = MonospaceDefaults +      { default_letter_bbox  :: BoundingBox cu+      , default_cap_height   :: cu+      , default_char_width   :: Vec2 cu+      }+  deriving (Eq,Show)++++-- | The metrics read from a font file by a font loader. +-- +-- NOTE - FontProps is parametric on @cu@ - /Character Unit/ and +-- not on the usual @u@. A typical character unit is 'AfmUnit', +-- the unit of measurement for AFM files (1000th of a point).+--+-- The is the initial representation used by Wumpus-Basic as an+-- syntax tree when loading font files. +--+data FontProps cu = FontProps+       { fp_bounding_box        :: BoundingBox cu +       , fp_default_adv_vec     :: Vec2 cu+       , fp_adv_vecs            :: IntMap.IntMap (Vec2 cu)+       , fp_cap_height          :: cu+       }+++-- | Build a MetricsOps function table, from a character unit+-- scaling function and FontProps read from a file.+--+buildMetricsOps :: (cu -> PtSize) -> FontProps cu -> MetricsOps+buildMetricsOps fn (FontProps (BBox ll ur) (V2 vx vy) +                              vec_table    cap_height) = +    MetricsOps+      { get_bounding_box  = \sz -> BBox (scalePt sz ll) (scalePt sz ur)+      , get_cw_table      = \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/System/FontLoader/Base/FontLoadMonad.hs view
@@ -0,0 +1,205 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.System.FontLoader.Base.FontLoadMonad+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Font load monad handling IO (file system access), failure and +-- logging.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.System.FontLoader.Base.FontLoadMonad+  (+    FontLoadErr+  , FontLoadIO+  , runFontLoadIO+  , evalFontLoadIO+  , loadError+  , logLoadMsg+  , promoteIO+  , promoteEither+  , runParserFLIO++  , sequenceAll++  -- * Font loading++  , buildAfmFontProps+  , checkFontPath+  +  ) where++import Wumpus.Basic.System.FontLoader.Base.Datatypes+import Wumpus.Basic.Utils.HList+import Wumpus.Basic.Utils.ParserCombinators+++import Wumpus.Core                              -- package: wumpus-core+import Wumpus.Core.Text.GlyphIndices+++import Control.Monad+import qualified Data.IntMap            as IntMap+import qualified Data.Map as Map+import Data.Monoid+import System.Directory+import System.FilePath++++--------------------------------------------------------------------------------+-- FontLoadIO monad - IO plus Error++++type FontLoadErr        = String++newtype FontLoadLog     = FontLoadLog { getFontLoadLog :: H String }+++instance Monoid FontLoadLog where+  mempty        = FontLoadLog $ emptyH+  a `mappend` b = FontLoadLog $ getFontLoadLog a `appendH` getFontLoadLog b++++newtype FontLoadIO a = FontLoadIO { +          getFontLoadIO :: IO (Either FontLoadErr a, FontLoadLog ) }++instance Functor FontLoadIO where+  fmap f ma = FontLoadIO $ getFontLoadIO ma >>= \(a,w) -> return (fmap f a, w)+ +instance Monad FontLoadIO where+  return a = FontLoadIO $ return (Right a, mempty)+  m >>= k  = FontLoadIO $ getFontLoadIO m >>= fn +              where+                fn (Left err, w) = return (Left err, w)+                fn (Right a, w1) = getFontLoadIO (k a) >>= \(b,w2) -> +                                   return (b, w1 `mappend` w2)++runFontLoadIO :: FontLoadIO a -> IO (Either FontLoadErr a,[String])+runFontLoadIO ma = liftM post $ getFontLoadIO ma +  where+    post (ans,w) = (ans, toListH $ getFontLoadLog w)+++evalFontLoadIO :: FontLoadIO a -> IO (Either FontLoadErr a)+evalFontLoadIO ma = liftM post $ getFontLoadIO ma+  where+    post (ans,_) = ans+++loadError :: FontLoadErr -> FontLoadIO a+loadError msg = FontLoadIO $ return (Left msg, mempty)++logLoadMsg :: String -> FontLoadIO ()+logLoadMsg msg = FontLoadIO $ return (Right (), message1 msg ) +++message1 :: String -> FontLoadLog +message1 = FontLoadLog . wrapH+++-- | aka liftIO+promoteIO :: IO a -> FontLoadIO a+promoteIO ma = FontLoadIO $ ma >>= \a -> return (Right a, mempty)++promoteEither :: Either FontLoadErr a -> FontLoadIO a+promoteEither = either loadError return ++runParserFLIO :: FilePath -> Parser Char a -> FontLoadIO a+runParserFLIO filepath p = +   promoteIO (readFile filepath) >>= promoteEither . runParserEither p+++-- | The standard monadic @sequence@ would finish on first fail+-- for the FontLoadIO monad. As we want to be able to sequence+-- the loading of a list of fonts, this is not really the +-- behaviour we want for Wumpus. Instead we prefer to use fallback +-- metrics and produce an inaccurate drawing on a font load error+-- rather than fail and produce no drawing.+--+sequenceAll :: [FontLoadIO a] -> FontLoadIO [a]+sequenceAll = FontLoadIO . step+   where+    step []     = return (Right [], mempty)+    step (m:ms) = liftM2 cons (getFontLoadIO m) (step ms) ++cons :: (Either FontLoadErr a, FontLoadLog)+     -> (Either FontLoadErr [a], FontLoadLog)+     -> (Either FontLoadErr [a], FontLoadLog)+cons (Right a, w1)  (Right as, w2) = +    (Right $ a:as,  w1 `mappend` w2)++cons (Right a, w1)  (Left e2, w2) = +    (Right [a], w1 `mappend` w2 `mappend` message1 e2)++cons (Left e1, w1)  (Right as, w2) = +    (Right as, w1 `mappend` message1 e1 `mappend` w2)++cons (Left e1, w1)  (Left e2,  w2) = +    (Right [], w1 `mappend` message1 e1 `mappend` w2 `mappend` message1 e2)++++--------------------------------------------------------------------------------+++-- | Afm files do not have a default advance vec so use the +-- monospace default.+-- +-- Afm files hopefully have @CapHeight@ and @FontBBox@ properties+-- in the header. Use the monospace default only if they are +-- missing.+-- +buildAfmFontProps :: MonospaceDefaults AfmUnit +                  -> AfmFile +                  -> FontLoadIO (FontProps AfmUnit)+buildAfmFontProps defaults afm = do +    cap_height <- extractCapHeight defaults afm+    bbox       <- extractFontBBox  defaults afm +    return $ FontProps +               { fp_bounding_box    = bbox+               , fp_default_adv_vec = default_char_width defaults+               , fp_adv_vecs        = char_widths+               , fp_cap_height      = cap_height+               }  +  where+    char_widths = foldr fn IntMap.empty $ afm_glyph_metrics afm+ +    fn (AfmGlyphMetrics _ v ss) table = case Map.lookup ss ps_glyph_indices of+                                          Nothing -> table+                                          Just i  -> IntMap.insert i v table+++extractCapHeight :: MonospaceDefaults AfmUnit -> AfmFile -> FontLoadIO AfmUnit+extractCapHeight defaults afm = maybe errk return $ afm_cap_height afm+  where+    errk = logLoadMsg "WARNING - Could not extract CapHeight" >> +           return (default_cap_height defaults)+++extractFontBBox :: MonospaceDefaults AfmUnit -> AfmFile +                -> FontLoadIO (BoundingBox AfmUnit)+extractFontBBox defaults afm = maybe errk return $ afm_letter_bbox afm+  where+    errk = logLoadMsg "WARNING - Could not extract CapHeight" >> +           return (default_letter_bbox defaults)++++checkFontPath :: FilePath -> FilePath -> FontLoadIO FilePath+checkFontPath path_root font_file_name = +    let full_path = normalise (path_root </> font_file_name)+    in do { check <- promoteIO (doesFileExist full_path)+          ; if check then return full_path+                     else loadError $ "Could not resolve path: " ++ full_path+          }
+ src/Wumpus/Basic/System/FontLoader/Base/GSFontMap.hs view
@@ -0,0 +1,108 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.System.FontLoader.Base.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.System.FontLoader.Base.GSFontMap+  (+   +    GSFontMap(..)+  , gsMetricsFile+  , gsFontAlias+  , gsVersionNumber+  , ghostscript_fontmap_8_54++  ) 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"+++-- | A map from standard /Adode PostScript/ font name to the+-- equivalent GhostScript font and AFM file name.+--+-- It is expected that all GhostScript AFM files will be located+-- in the same directory.+--+data GSFontMap = GSFontMap+      { ghostscript_version :: String+      , ghostscript_fontmap :: 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 (ghostscript_fontmap mp)++-- | Get the GhostScript font name alias.+--+gsFontAlias :: GSFontMap -> String -> Maybe String+gsFontAlias mp name = fmap fst $ Map.lookup name (ghostscript_fontmap mp)+++-- | Get the GhostScript version number that the FontMap +-- represents.+--+gsVersionNumber :: GSFontMap -> String+gsVersionNumber = ghostscript_version +++-- | Map from PostScript font name to the corresponding +-- GhostScript name and file.+--+-- Naming is correct for GhostSCript version 8.54.+-- +ghostscript_fontmap_8_54 :: GSFontMap+ghostscript_fontmap_8_54 = GSFontMap "8.54" body+  where+    body = 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/System/FontLoader/GhostScript.hs view
@@ -0,0 +1,86 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.System.FontLoader.GhostScript+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Font loader / import shim 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.System.FontLoader.GhostScript+  ( ++    loadGSMetrics+  +  ) where++import Wumpus.Basic.Kernel+import Wumpus.Basic.System.FontLoader.Base.AfmV2Parser+import Wumpus.Basic.System.FontLoader.Base.Datatypes+import Wumpus.Basic.System.FontLoader.Base.FontLoadMonad+import Wumpus.Basic.System.FontLoader.Base.GSFontMap++import Wumpus.Core                              -- package: wumpus-core++import Control.Monad+import Data.Monoid+++-- | 'loadGSMetrics' : +-- @ path_to_gs_fonts * [font_name] -> IO (metrics, messages) @ +-- +-- Load the supplied list of fonts. +-- +-- Note - if a font fails to load a message is written to the +-- log and monospaced /fallback metrics/ are used.+--+loadGSMetrics :: FilePath -> [FontName] -> IO (GlyphMetrics, [String])+loadGSMetrics font_dir_path ns = +    liftM post $ runFontLoadIO $ sequenceAll $ map mkFun ns+  where+    mkFun = gsLoadFontCalcs font_dir_path ghostscript_fontmap_8_54 +    +    post (Left err,ss) = (mempty, ss ++ [err]) -- unreachable...+    post (Right xs,ss) = (foldr insertFont mempty xs, ss)+++gsLoadFontCalcs :: FilePath -> GSFontMap -> FontName +                -> FontLoadIO FontMetricsOps+gsLoadFontCalcs font_dir_path fm name = do+    logLoadMsg  $ "Loading " ++ name+    font_file   <- resolveFontFile fm name +    path        <- checkFontPath font_dir_path font_file+    ans         <- runParserFLIO path afmV2Parser+    props       <- buildAfmFontProps  ghostscript_mono_defaults_8_54 ans+    return $ FontMetricsOps name (buildMetricsOps afmUnitScale props)+++resolveFontFile :: GSFontMap -> FontName -> FontLoadIO FilePath+resolveFontFile fm name = maybe errk return $ gsMetricsFile fm name+  where+    errk = loadError $ "Could note resolve GhostScript alias for " ++ name+++-- | These are values extracted from the file @n022003l.afm@+-- which is the font @NimbusMonL-Regu@, GhostScript\'s eqivalent +-- font for the core 14 font Courier.+--+ghostscript_mono_defaults_8_54 :: MonospaceDefaults AfmUnit+ghostscript_mono_defaults_8_54 = +    MonospaceDefaults { default_letter_bbox  = bbox+                      , default_cap_height   = 563+                      , default_char_width   = V2 600 0+                      }+  where+    bbox = BBox (P2 (-46) (-273)) (P2 650 820)
− src/Wumpus/Basic/Text/LRText.hs
@@ -1,239 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Text.LRText--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC------ Left-to-right measured text. The text uses glyph metrics so it --- can be positioned accurately.--- -----------------------------------------------------------------------------------module Wumpus.Basic.Text.LRText-  ( --   -    singleLineBL-  , singleLineCC--  , multiAlignLeft-  , multiAlignCenter-  , multiAlignRight---  ) where---import Wumpus.Basic.Graphic--import Wumpus.Core                              -- package: wumpus-core-import Wumpus.Core.Text.GlyphIndices--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)---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. ------ 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))----- | 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))----- Build multi-line aligned text. ------ 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---- 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 --    empty_fallback   = InterimText1 (escapeString "") (hvec 0)-----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---- 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------- This isn't worth the complexity  to get to one traversal...--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--avMaxWidth :: Ord u => AdvanceVec u -> AdvanceVec u -> AdvanceVec u-avMaxWidth a@(V2 w1 _) b@(V2 w2 _) = if w2 > w1 then b else a--interimText1 :: FromPtSize u => String -> DrawingInfo (InterimText1 u)-interimText1 ss = let esc = escapeString ss in -    postpro (mk esc) $ textVector esc-  where-    mk a b = InterimText1 { text1_escaped = a-                          , text1_advance = b }---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---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------ 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--    moveDown1       = \pt -> pt .-^ vvec baseline_span--    step _  []      = []-    step pt (a:as)  = (a,pt) : step (moveDown1 pt) as-
− src/Wumpus/Basic/Utils/Intersection.hs
@@ -1,171 +0,0 @@-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Basic.Utils.Intersection--- Copyright   :  (c) Stephen Tetley 2010--- License     :  BSD3------ Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>--- Stability   :  highly unstable--- Portability :  GHC------ Intersection of line to line and line to plane--- --- -----------------------------------------------------------------------------------module Wumpus.Basic.Utils.Intersection-  ( -    LineSegment(..)-  , PointSlope-  , pointSlope-  , LineEqn-  , lineEqn-  , toLineEqn-  , findIntersect-  , intersection--  , rectangleLines-  , polygonLines-  , langle-  ) -  where--import Wumpus.Core                              -- package: wumpus-core--import Data.AffineSpace                         -- package: vector-space-import Data.VectorSpace----- WARNING - This module is not very good (neither particularly --- robust, nor efficient).--- --- I really need to find an algorithm that does this properly.-----data LineSegment u = LS (Point2 u) (Point2 u)-  deriving (Eq,Ord,Show)---data PointSlope u = PointSlope -      { _point_slope_point :: Point2 u-      , _point_slope_slope :: u-      }-  deriving (Eq,Show)--pointSlope :: Fractional u => Point2 u -> Radian -> PointSlope u -pointSlope pt theta = PointSlope pt (fromRadian $ tan theta)----- | Line in equational form, i.e. @Ax + By + C = 0@.-data LineEqn u = LineEqn -      { _line_eqn_A :: !u-      , _line_eqn_B :: !u-      , _line_eqn_C :: !u -      }-  deriving (Eq,Show)--lineEqn :: Num u => Point2 u -> Point2 u -> LineEqn u-lineEqn (P2 x1 y1) (P2 x2 y2) = LineEqn a b c -  where-    a = y1 - y2-    b = x2 - x1-    c = (x1*y2) - (x2*y1)---toLineEqn :: Num u => PointSlope u -> LineEqn u-toLineEqn (PointSlope (P2 x0 y0) m) = LineEqn m (-1) ((-m) * x0 + y0)-----data IntersectionResult u = Intersects u u | Contained | NoIntersect-  deriving (Eq,Show)----- Note the uses a /plane/ so is susceptible to picking the --- wrong quadrant...----findIntersect :: (Floating u, Real u, Ord u)-               => Point2 u -> Radian -> [LineSegment u] -> Maybe (Point2 u)-findIntersect ctr ang0 = step -  where-    theta       = circularModulo ang0-    eqn         = toLineEqn $ pointSlope ctr theta-    step []     = Nothing-    step (x:xs) = case intersection x eqn of -                     Just pt | quadrantCheck theta ctr pt -> Just pt-                     _       -> step xs---quadrantCheck :: (Real u, Floating u) -              => Radian -> Point2 u -> Point2 u -> Bool-quadrantCheck theta ctr pt = theta == langle ctr pt--intersection :: (Fractional u, Ord u) -             => LineSegment u -> LineEqn u -> Maybe (Point2 u)-intersection ls@(LS p q) eqn = case intersect1 ls eqn of-    Intersects fp fq -> let t = fp / (fp-fq) in Just $ affineComb p q t -    Contained        -> Just p-    NoIntersect      -> Nothing----intersect1 :: (Num u, Ord u) -           => LineSegment u -> LineEqn u -> IntersectionResult u-intersect1 (LS p q) eqn = -     if inters fp fq then Intersects fp fq-                     else if contained fp fq then Contained else NoIntersect-  where-    inters a b    = (a < 0 && b >= 0) || (a > 0 && b <= 0)-    contained a b = a == 0 && b == 0-    fp            = lineF p eqn-    fq            = lineF q eqn- -lineF :: Num u => Point2 u -> LineEqn u -> u-lineF (P2 x y) (LineEqn a b c) = a*x + b*y + c--affineComb :: Num u => Point2 u -> Point2 u -> u -> Point2 u-affineComb p q t = p .+^ t *^ (q .-. p)-----rectangleLines :: Num u => Point2 u -> u -> u -> [LineSegment u]-rectangleLines ctr hw hh = [LS br tr, LS tr tl, LS tl bl, LS bl br]-  where-    br = ctr .+^ (vec hw    (-hh))-    tr = ctr .+^ (vec hw    hh)-    tl = ctr .+^ (vec (-hw) hh)-    bl = ctr .+^ (vec (-hw) (-hh))---polygonLines :: [Point2 u] -> [LineSegment u]-polygonLines []     = error "polygonLines - emptyList"-polygonLines (x:xs) = step x xs -  where-    step a []        = [LS a x]-    step a (b:bs)    = LS a b : step b bs------ | Calculate the counter-clockwise angle between two points --- and the x-axis.----langle :: (Floating u, Real u) => Point2 u -> Point2 u -> Radian-langle (P2 x1 y1) (P2 x2 y2) = step (x2 - x1) (y2 - y1)-  where-    -- north-east quadrant -    step x y | pve x && pve y = toRadian $ atan (y/x)          -    -    -- north-west quadrant-    step x y | pve y          = pi     - (toRadian $ atan (y / abs x))--    -- south-east quadrant-    step x y | pve x          = (2*pi) - (toRadian $ atan (abs y / x)) --    -- otherwise... south-west quadrant-    step x y                  = pi     + (toRadian $ atan (y/x))--    pve a                     = signum a >= 0
src/Wumpus/Basic/VersionNumber.hs view
@@ -23,7 +23,7 @@  -- | Version number ----- > (0,13,0)+-- > (0,14,0) -- wumpus_basic_version :: (Int,Int,Int)-wumpus_basic_version = (0,13,0)+wumpus_basic_version = (0,14,0)
+ src/Wumpus/Drawing/Arrows.hs view
@@ -0,0 +1,28 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Arrows+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Shim module for arrow connectors and arrowheads.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Arrows+  ( ++    module Wumpus.Drawing.Arrows.Tips+  , module Wumpus.Drawing.Arrows.Connectors++  ) where++import Wumpus.Drawing.Arrows.Tips+import Wumpus.Drawing.Arrows.Connectors++
+ src/Wumpus/Drawing/Arrows/Connectors.hs view
@@ -0,0 +1,149 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Arrows.Connectors+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Draw arrows.+--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Arrows.Connectors+  ( ++    Connector+  , connector+  , leftArrow+  , rightArrow+  , dblArrow+  , leftrightArrow+  , strokeConnector+++  ) where++import Wumpus.Basic.Kernel+import Wumpus.Drawing.Arrows.Tips+import Wumpus.Drawing.Paths++import Wumpus.Core                      -- package: wumpus-core++import Control.Applicative++-- An arrowhead always know how to draw itself (filled triangle, +-- stroked barb, etc.)+--+-- A Path might will typically be drawn with openStroke,+-- eventually there might be scope for drawing +-- e.g. parallel lines  ====+--++-- A ConnectorPath gets wrapped with how it is drawn into+-- another type.+++data Connector u = Connector +      { connector_path  :: ConnectorPath u+      , opt_left_arrow  :: Maybe (Arrowhead u)+      , opt_right_arrow :: Maybe (Arrowhead u)+      }+++-- | connector with no arrow heads.+--+connector :: ConnectorPath u -> Connector u+connector cp = +    Connector { connector_path  = cp+              , opt_left_arrow  = Nothing+              , opt_right_arrow = Nothing+              }++leftArrow :: ConnectorPath u -> Arrowhead u -> Connector u+leftArrow cp la =+    Connector { connector_path  = cp+              , opt_left_arrow  = Just la+              , opt_right_arrow = Nothing+              }+++rightArrow :: ConnectorPath u -> Arrowhead u -> Connector u+rightArrow cp ra = +    Connector { connector_path  = cp+              , opt_left_arrow  = Nothing+              , opt_right_arrow = Just ra+              }++-- | Same tip both ends.+--+dblArrow :: ConnectorPath u -> Arrowhead u -> Connector u+dblArrow cp arw = leftrightArrow cp arw arw++leftrightArrow :: ConnectorPath u -> Arrowhead u -> Arrowhead u -> Connector u+leftrightArrow cp la ra =+    Connector { connector_path  = cp+              , opt_left_arrow  = Just la+              , opt_right_arrow = Just ra+              }++++strokeConnector :: (Real u, Floating u) +                => Connector u -> ConnectorImage u (Path u)+strokeConnector (Connector cpF opt_la opt_ra) =+    promoteR2 $ \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) +                 (fmap (bimapR (gfR . gfL)) $ drawP $ shortenPath dl dr pathc) +  where+    drawP       = openStroke . toPrimPath   +++-- for Paths.Base ?+--+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 +-- it has to wrap the tips back up as Graphics with @pure@ so they +-- can be concatenated to the drawn path as GraphicTrafos.+--+-- The Arrowhead type could be changed, so rather than returning +-- an Image (retract_distance, PrimGraphic) it returns +-- (retract_distance, GraphicTrafo) but that would burden all +-- arrowheads with some extra complexity.+-- +-- In short - the code here works but it isn\'t exemplary, and it +-- doesn\'t show whether or not GraphicTrafo is a valuable type or+-- if it is implemented correctly (as GraphicTrafo could having+-- different implementations according to how it regards the +-- DrawingCtx).+--++tipEval :: Num u +        => Maybe (Arrowhead u) -> Point2 u -> Radian+        -> CF (u, ArrowMark u)+tipEval Nothing    _  _     = return (0,unmarked)+tipEval (Just arw) pt theta = makeMark $ apply2R2 (getArrowhead arw) pt theta+++unmarked :: ArrowMark u+unmarked = id+++makeMark :: Image u a -> CF (a, ArrowMark u)+makeMark = fmap (\(a,prim) -> (a, (`oplus` prim)))+++
+ src/Wumpus/Drawing/Arrows/Tips.hs view
@@ -0,0 +1,505 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Arrows.Tips+-- 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 in future revisions.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Arrows.Tips+  ( +++    Arrowhead(..)++ +  , tri90+  , tri60+  , tri45+  , otri90+  , otri60+  , otri45++  , revtri90+  , revtri60+  , revtri45+  , orevtri90+  , orevtri60+  , orevtri45++  , barb90+  , barb60+  , barb45+  , revbarb90+  , revbarb60+  , revbarb45++  , perp++  , bracket++  , diskTip+  , odiskTip+  , squareTip+  , osquareTip+  , diamondTip+  , odiamondTip++  , curveTip+  , revcurveTip++  ) where++import Wumpus.Basic.Kernel+import Wumpus.Drawing.Paths++import Wumpus.Core                      -- package: wumpus-core++import Data.AffineSpace                 -- package: vector-space++import Control.Applicative+++-- | Encode an arrowhead as an image where the /answer/ is the+-- retract distance.+--+-- The retract distance is context sensitive - usually just on+-- the markHeight (or halfMarkHeight) so it has to be calculated+-- w.r.t. the DrawingCtx.+--+newtype Arrowhead u = Arrowhead { getArrowhead :: LocThetaImage u u }+++++-- | Tiplen is length of the tip \*along the line it follows\*. +--+-- > |\+-- > | \+-- > | /+-- > |/+-- > +-- > |  |  -- tip len+--++-- | Tip width is the distance between upper and lower +-- arrow points.+--+-- >       __+-- > |\    +-- > | \   tip+-- > | /   width+-- > |/    __+-- >       ++++-- | This one is for triangular tips defined by their tip angle+-- e.g. 90deg, 60deg, 45deg.+--+-- The tip width will be variable (tip length should be the +-- markHeight).+-- +triVecsByAngle :: Floating u => u -> Radian -> Radian -> (Vec2 u, Vec2 u)+triVecsByAngle tiplen halfang theta = (vec_to_upper, vec_to_lower)+  where+    hypo_len     = tiplen / (fromRadian $ cos halfang)+    rtheta       = pi + theta        -- theta in the opposite direction+    vec_to_upper = avec (circularModulo $ rtheta - halfang) hypo_len+    vec_to_lower = avec (circularModulo $ rtheta + halfang) hypo_len ++++-- | This one is for triangles when the tip height and tip width+-- are known.+--+triVecsByDist  :: (Real u, Floating u) +               => u -> u -> Radian -> (Vec2 u, Vec2 u)+triVecsByDist tiplen half_tipwidth theta = (vec_to_upper, vec_to_lower)+  where+    hypo_len     = sqrt $ (tiplen*tiplen) + (half_tipwidth*half_tipwidth)+    halfang      = toRadian $ atan (half_tipwidth / tiplen) +    rtheta       = pi + theta        -- theta in the opposite direction+    vec_to_upper = avec (circularModulo $ rtheta - halfang) hypo_len+    vec_to_lower = avec (circularModulo $ rtheta + halfang) hypo_len +++++{-+markHeightPlusLineWidth :: (Fractional u, FromPtSize u) => DrawingR u+markHeightPlusLineWidth = +    (\h lw -> h + realToFrac lw) <$> markHeight <*> lineWidth+-}+++markHeightLessLineWidth :: (Fractional u, FromPtSize u) => CF u+markHeightLessLineWidth = +    (\h lw -> h - realToFrac lw) <$> markHeight <*> getLineWidth+++-- noRetract ignores both the angle and the point.+--+-- Its common for the rectraction not to care about the angle or +-- the point and only care about the DrawingCtx.+--+noRetract :: Num u => LocThetaCF u u+noRetract = promoteR2 $ \_ _ -> pure 0 ++++--------------------------------------------------------------------------------++tipBody :: FromPtSize u => (Point2 u -> Radian -> u -> CF a) -> LocThetaCF u a+tipBody mf = promoteR2 $ \pt theta -> markHeight >>= \h -> mf pt theta h ++-- | Tripoints takes the \*tip length\* is the mark height.+--+-- This means that the 90deg tip has a tip width greater-than the+-- mark height (but that is okay - seemingly this is how TikZ +-- does it).+--+tripointsByAngle :: (Floating u, FromPtSize u)+                 => Radian -> LocThetaCF u (Point2 u, Point2 u)+tripointsByAngle triang = +    tipBody $ \pt theta h -> +      let (vup,vlo) = triVecsByAngle h (0.5*triang) theta+      in  pure (pt .+^ vup, pt .+^ vlo)+    ++revtripointsByAngle :: (Floating u, FromPtSize u)+                    => Radian +                    -> LocThetaCF u (Point2 u, Point2 u, Point2 u)+revtripointsByAngle triang = +    tipBody $ \pt theta h -> +      let theta'    = circularModulo $ pi+theta +          (vup,vlo) = triVecsByAngle h (0.5*triang) theta'+          back_tip  = pt .-^ avec theta h +      in pure (back_tip .+^ vup, back_tip, back_tip .+^ vlo)++++tripointsByDist :: (Real u, Floating u, FromPtSize u)+                => LocThetaCF u (Point2 u, Point2 u)+tripointsByDist = +    tipBody $ \pt theta h -> +      let (vup,vlo) = triVecsByDist h (0.5*h) theta+      in pure (pt .+^ vup, pt .+^ vlo)+  +++revtripointsByDist :: (Real u, Floating u, FromPtSize u)+                   => LocThetaCF u (Point2 u, Point2 u, Point2 u)+revtripointsByDist = +    tipBody $ \pt theta h -> +      let theta'    = circularModulo $ pi+theta +          (vup,vlo) = triVecsByDist h (0.5*h) theta'+          back_tip  = pt .-^ avec theta h +      in pure (back_tip .+^ vup, back_tip, back_tip .+^ vlo)++++++-- width = xchar_height+-- filled with stroke colour!++triTLG :: (Floating u, Real u, FromPtSize u)+       => Radian -> (PrimPath u -> Graphic u) -> LocThetaGraphic u+triTLG triang drawF = +    promoteR2 $ \pt theta ->+      localize bothStrokeColour $ +         apply2R2 (tripointsByAngle triang) pt theta >>= \(u,v) -> +           drawF $ vertexPath [pt,u,v]++++tri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+tri90 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeight) (triTLG (pi/2) filledPath)+++tri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+tri60 = Arrowhead $+    intoLocThetaImage (lift0R2 markHeight) (triTLG (pi/3) filledPath)+++tri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+tri45 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeight) (triTLG (pi/4) filledPath)++otri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+otri90 = Arrowhead $+    intoLocThetaImage (lift0R2 markHeight) (triTLG (pi/2) closedStroke)++otri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+otri60 = Arrowhead $   +    intoLocThetaImage (lift0R2 markHeight) (triTLG (pi/3) closedStroke)++otri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+otri45 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeight) (triTLG (pi/4) closedStroke)+++-- width = xchar_height+-- filled with stroke colour!++revtriTLG :: (Floating u, Real u, FromPtSize u)+          => Radian -> (PrimPath u -> Graphic u) -> LocThetaGraphic u+revtriTLG triang drawF = +    promoteR2 $ \pt theta -> +      localize bothStrokeColour $ +        apply2R2 (revtripointsByAngle triang) pt theta >>= \(u,pt',v) -> +           drawF $ vertexPath [u,pt',v]++++revtri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+revtri90 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeightLessLineWidth) +                      (revtriTLG (pi/2) filledPath)++revtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+revtri60 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeightLessLineWidth) +                      (revtriTLG (pi/3) filledPath)++revtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+revtri45 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeightLessLineWidth) +                      (revtriTLG (pi/4) filledPath)+++orevtri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+orevtri90 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeightLessLineWidth) +                      (revtriTLG (pi/2) closedStroke)++orevtri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+orevtri60 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeightLessLineWidth) +                      (revtriTLG (pi/3) closedStroke)++orevtri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+orevtri45 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeightLessLineWidth) +                      (revtriTLG (pi/4) closedStroke)++++barbTLG :: (Floating u, Real u, FromPtSize u) => Radian -> LocThetaGraphic u+barbTLG ang =  +    promoteR2 $ \pt theta -> +      apply2R2 (tripointsByAngle ang) pt theta >>= \(u,v) -> +        openStroke $ vertexPath [u,pt,v]++++barb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+barb90 = Arrowhead $ intoLocThetaImage noRetract (barbTLG (pi/2))++barb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+barb60 = Arrowhead $ intoLocThetaImage noRetract (barbTLG (pi/3))+++barb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+barb45 = Arrowhead $ intoLocThetaImage noRetract (barbTLG (pi/4))++++revbarbTLG :: (Floating u, Real u, FromPtSize u) => Radian -> LocThetaGraphic u+revbarbTLG ang = +    promoteR2 $ \pt theta -> +      apply2R2 (revtripointsByAngle ang) pt theta >>= \(u,pt',v) -> +        openStroke $ vertexPath [u,pt',v]++revbarb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+revbarb90 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeight) (revbarbTLG (pi/2))+++revbarb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+revbarb60 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeight) (revbarbTLG (pi/3))++revbarb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+revbarb45 = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeight) (revbarbTLG (pi/4))+++perpTLG :: (Floating u, FromPtSize u) => LocThetaGraphic u+perpTLG = +    tipBody $ \pt theta h -> +      let hh = 0.5*h in openStroke $ rperpPath hh pt theta+++rperpPath :: Floating u => u -> Point2 u -> Radian -> PrimPath u+rperpPath 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 $ intoLocThetaImage noRetract perpTLG++++bracketTLG :: (Floating u, FromPtSize u) => LocThetaGraphic u+bracketTLG = +    tipBody $ \pt theta h -> +      let hh = 0.5*h in openStroke $ rbracketPath hh pt theta+++rbracketPath :: Floating u => u -> Point2 u -> Radian -> PrimPath u+rbracketPath 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 $ intoLocThetaImage noRetract bracketTLG+++diskTLG :: (Floating u, FromPtSize u) +        => (u -> Point2 u -> Graphic u) -> LocThetaGraphic u+diskTLG drawF = +    tipBody $ \pt theta h -> let hh  = 0.5*h +                                 ctr = pt .-^ avec theta hh +                             in drawF hh ctr+++diskTip :: (Floating u, FromPtSize u) => Arrowhead u+diskTip = Arrowhead $ intoLocThetaImage (lift0R2 markHeight) (diskTLG drawF)+  where+    drawF r pt = localize bothStrokeColour $ filledDisk r `at` pt+++odiskTip :: (Floating u, FromPtSize u) => Arrowhead u+odiskTip = Arrowhead $ intoLocThetaImage (lift0R2 markHeight) (diskTLG drawF)+  where+    drawF r pt = strokedDisk r `at` pt+++squareTLG :: (Floating u, FromPtSize u) +        => (PrimPath u -> Graphic u) -> LocThetaGraphic u+squareTLG drawF = +    tipBody $ \pt theta h -> drawF $ rsquarePath pt theta (0.5*h)+++rsquarePath :: Floating u => Point2 u -> Radian -> u -> PrimPath u+rsquarePath pt theta hh = vertexPath [p0,p1,p2,p3]+  where+    p0 = displacePerpendicular     hh  theta pt+    p3 = displacePerpendicular   (-hh) theta pt+    p1 = displaceParallel      (-2*hh) theta p0+    p2 = displaceParallel      (-2*hh) theta p3+    ++squareTip :: (Floating u, FromPtSize u) => Arrowhead u+squareTip = Arrowhead $ intoLocThetaImage (lift0R2 markHeight) (squareTLG drawF)+  where+    drawF = localize bothStrokeColour . filledPath+++osquareTip :: (Floating u, FromPtSize u) => Arrowhead u+osquareTip = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeight) (squareTLG closedStroke)+++diamondTLG :: (Floating u, FromPtSize u) +           => (PrimPath u -> Graphic u) -> LocThetaGraphic u+diamondTLG drawF = +    tipBody $ \pt theta h -> drawF $ rdiamondPath pt theta (0.5*h)+ ++rdiamondPath :: Floating u => Point2 u -> Radian -> u -> PrimPath u+rdiamondPath pt theta hh = vertexPath [pt,p1,p2,p3]+  where+    ctr = displaceParallel       (-2*hh) theta pt+    p1  = displacePerpendicular     hh   theta ctr+    p3  = displacePerpendicular   (-hh)  theta ctr+    p2  = displaceParallel       (-4*hh) theta pt+         +++diamondTip :: (Floating u, FromPtSize u) => Arrowhead u+diamondTip = Arrowhead $ +    intoLocThetaImage (lift0R2 $ fmap (2*) markHeightLessLineWidth) +                      (diamondTLG drawF)+  where+    drawF = localize bothStrokeColour . filledPath+++odiamondTip :: (Floating u, FromPtSize u) => Arrowhead u+odiamondTip = Arrowhead $ +    intoLocThetaImage (lift0R2 $ fmap (2*) markHeight) (diamondTLG closedStroke)+++++-- Note - points flipped to get the second trapezium to +-- draw /underneath/.+--+curveTLG :: (Real u, Floating u, FromPtSize u) => LocThetaGraphic u+curveTLG = +    tipBody $ \pt theta h -> +      cxCurvePath pt theta (0.5*h) >>= \path ->+        localize (joinRound . capRound) (openStroke path)+++cxCurvePath :: (Real u, Floating u, FromPtSize u) +            => Point2 u -> Radian -> u -> DrawingInfo (PrimPath u)+cxCurvePath pt theta hh =+     apply2R2 tripointsByDist pt theta >>= \(tup,tlo) -> +          let (u1,u2) = trapezoidFromBasePoints (0.25*hh) 0.5 pt tup+              (l2,l1) = trapezoidFromBasePoints (0.25*hh) 0.5 tlo pt +          in pure $ toPrimPath $ curve tup u2 u1 pt `append` curve pt l1 l2 tlo+++++curveTip :: (Real u, Floating u, FromPtSize u) => Arrowhead u+curveTip = Arrowhead $ +    intoLocThetaImage (lift0R2 $ fmap realToFrac getLineWidth) curveTLG+++-- Note - points flipped to get the second trapezium to +-- draw /underneath/.+--+revcurveTLG :: (Real u, Floating u, FromPtSize u) => LocThetaGraphic u+revcurveTLG = +    tipBody $ \pt theta h ->+      cxRevcurvePath pt theta (0.5*h) >>= \path ->+        localize (joinRound . capRound) (openStroke path)++cxRevcurvePath :: (Real u, Floating u, FromPtSize u) +               => Point2 u -> Radian -> u -> DrawingInfo (PrimPath u)+cxRevcurvePath pt theta hh = +    apply2R2 revtripointsByDist pt theta >>= \(tup,p1,tlo) -> +      let (u1,u2) = trapezoidFromBasePoints (0.25*hh) 0.5 p1 tup+          (l2,l1) = trapezoidFromBasePoints (0.25*hh) 0.5 tlo p1+      in pure$ toPrimPath $ curve tup u2 u1 p1 `append` curve p1 l1 l2 tlo+++revcurveTip :: (Real u, Floating u, FromPtSize u) => Arrowhead u+revcurveTip = Arrowhead $ +    intoLocThetaImage (lift0R2 markHeight) revcurveTLG+
+ src/Wumpus/Drawing/Chains.hs view
@@ -0,0 +1,29 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Chains+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC +--+-- Shim module.+--+-- WARNING - very unstable.+--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Chains+  (+    module Wumpus.Drawing.Chains.Base+  , module Wumpus.Drawing.Chains.Derived+  ++  ) where+++import Wumpus.Drawing.Chains.Base+import Wumpus.Drawing.Chains.Derived
+ src/Wumpus/Drawing/Chains/Base.hs view
@@ -0,0 +1,161 @@+{-# LANGUAGE ExistentialQuantification  #-}+{-# LANGUAGE RankNTypes                 #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Chains.Base+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC +--+-- Generate points in an iterated chain.+--+-- WARNING - very unstable.+--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Chains.Base+  (+++    Chain+  , LocChain+  , chain+  , chainFrom+  , unchain+++  , AnaAlg(..)+  , IterAlg(..)++  , BivariateAlg+  , bivariate+  +  , SequenceAlg+  , iteration++  , bounded+  , pairOnXs+  , pairOnYs++  ) where++import Wumpus.Basic.Kernel++import Wumpus.Core                              -- package: wumpus-core+++-- Chain uses the Scaling monad, but it is not itself a monad.+++newtype Chain ux uy u = Chain { getChain :: Scaling ux uy u [Point2 u] }+++type LocChain ux uy u = Point2 u -> Chain ux uy u++++chain :: BivariateAlg ux uy -> Chain ux uy u+chain alg = Chain (scaledBivariatePt alg)++chainFrom :: Num u => BivariateAlg ux uy -> LocChain ux uy u+chainFrom alg start = Chain (scaledBivariateVec alg start)+++unchain :: ScalingContext ux uy u -> Chain ux uy u -> [Point2 u]+unchain ctx ch = runScaling ctx $ getChain ch+ ++-- | Chains are built as unfolds - AnaAlg avoids the pair +-- constructor in the usual definition of unfoldr and makes the+-- state strict.+--+-- It is expected that all Chains built on unfolds will terminate. +--+data AnaAlg st a = Done | Step a !st+++-- | IterAlg is a variant of AnaAlg that builds infinite +-- sequences (iterations).+-- +-- When lifted to a Chain an iteration is bounded by a count so+-- it will terminate.+--+data IterAlg st a = IterStep a !st +++data BivariateAlg ux uy = forall st. BivariateAlg+      { st_zero     :: st+      , gen_step    :: st -> AnaAlg st (ux,uy)+      }++bivariate :: st -> (st -> AnaAlg st (ux,uy)) -> BivariateAlg ux uy+bivariate st0 step_alg = BivariateAlg { st_zero = st0+                                      , gen_step = step_alg }+++scaledBivariatePt :: BivariateAlg ux uy -> Scaling ux uy u [Point2 u]+scaledBivariatePt (BivariateAlg { st_zero = st0, gen_step = step}) = +    go (step st0)   +  where+    go Done              = return []+    go (Step (x,y) next) = scalePt x y    >>= \pt   ->+                           go (step next) >>= \rest ->  +                           return  (pt:rest)++-- Note - cannot encode this with (.+^) from Data.AffineSpace.+-- The u (u ~ MonUnit m) extracted from the Scaling Context is +-- not compatible with the u that forms Points (u ~ Diff (Point2 u)).++scaledBivariateVec :: Num u +                   => BivariateAlg ux uy +                   -> Point2 u +                   -> Scaling ux uy u [Point2 u]+scaledBivariateVec (BivariateAlg { st_zero = st0, gen_step = step}) (P2 x0 y0) = +    go (step st0)   +  where+    go Done              = return []+    go (Step (x,y) next) = scaleVec x y   >>= \(V2 dx dy)   ->+                           go (step next) >>= \rest ->  +                           return (P2 (x0+dx) (y0+dy):rest)+++data SequenceAlg a = forall st. SequenceAlg+      { initial_st  :: st+      , iter_step   :: st -> IterAlg st a+      }++iteration :: (a -> a) -> a -> SequenceAlg a+iteration fn s0 = SequenceAlg { initial_st = s0, iter_step = step }+  where+    step s = IterStep s (fn s)+++bounded :: Int -> SequenceAlg (ux,uy) -> BivariateAlg ux uy+bounded n (SequenceAlg a0 fn) =+    BivariateAlg { st_zero     = (0,a0)+                 , gen_step    = gstep  }+  where+    gstep (i,s) | i < n = let (IterStep ans next) = fn s in Step ans (i+1,next)+    gstep _             = Done+++++pairOnXs :: (ux -> uy) -> SequenceAlg ux -> SequenceAlg (ux,uy)+pairOnXs fn (SequenceAlg { initial_st = s0, iter_step = step }) = +    SequenceAlg s0 step2+  where+    step2 s = let (IterStep a s') = step s in IterStep (a, fn a) s'+++pairOnYs :: (r -> l) -> SequenceAlg r -> SequenceAlg (l,r) +pairOnYs fn (SequenceAlg { initial_st = s0, iter_step = step }) = +    SequenceAlg  s0 step2+  where+    step2 s = let (IterStep a s') = step s in IterStep (fn a, a) s'+
+ src/Wumpus/Drawing/Chains/Derived.hs view
@@ -0,0 +1,129 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Chains.Derived+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC +--+-- Generate points in an iterated chain.+--+-- WARNING - very unstable.+--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Chains.Derived+  (+    +    univariateX+  , univariateY++  , tableDown+  , tableRight++  , horizontal+  , vertical++  , horizontals+  , verticals++  , rescale++  ) where++import Wumpus.Drawing.Chains.Base+++++univariateX :: (Fractional uy, Num ux, Num u) +            => [ux] -> LocChain ux uy u+univariateX zs = chainFrom $ bivariate (0,zs) gstep+  where+    gstep (_,[])     = Done +    gstep (n,x:xs)   = Step (x,n) (n+i,xs)+    len              = length zs+    i                = rescale 0 1 0 (fromIntegral $ len-1) 1+++univariateY :: (Fractional ux, Num uy, Num u) +            => [uy] -> LocChain ux uy u+univariateY zs = chainFrom $ bivariate (0,zs) gstep+  where+    gstep (_,[])     = Done +    gstep (n,y:ys)   = Step (n,y) (n+i,ys)+    len              = length zs+    i                = rescale 0 1 0 (fromIntegral $ len-1) 1++++--------------------------------------------------------------------------------+-- Tables+++tableDown :: Int -> Int -> Chain Int Int u+tableDown rows cols = +    chain $ bounded (rows*cols) (iteration (downstep rows) (0,rows-1))++++downstep :: Int -> (Int,Int) -> (Int,Int)+downstep row_count (x,y) | y == 0 = (x+1,row_count-1)+downstep _         (x,y)          = (x,y-1)++++tableRight :: Num u => Int -> Int -> Chain Int Int u+tableRight rows cols = +    chain $ bounded (rows*cols) (iteration (rightstep cols) (0,rows-1))+++rightstep :: Int -> (Int,Int) -> (Int,Int)+rightstep col_count (x,y) | x == (col_count-1) = (0,y-1)+rightstep _         (x,y)                      = (x+1,y)+++horizontal :: Int -> Chain Int Int u+horizontal count = chain $ bivariate 0 alg+  where+    alg st | st == count = Done+    alg st               = Step (st,0) (st+1)+++vertical :: Int -> Chain Int Int u+vertical count = chain $ bivariate 0 alg+  where+    alg st | st == count = Done+    alg st               = Step (0,st) (st+1)++++horizontals :: (Num ua, Num u) => [ua] -> LocChain ua ua u+horizontals xs0 = chainFrom $ bivariate xs0 alg+  where+    alg []     = Done+    alg (x:xs) = Step (x,0) xs+++verticals :: (Num ua, Num u)  => [ua] -> LocChain ua ua u+verticals ys0 = chainFrom $ bivariate ys0 alg+  where+    alg []     = Done+    alg (y:ys) = Step (0,y) ys+++--------------------------------------------------------------------------------+-- general helpers++rescale :: Fractional a => a -> a -> a -> a -> a -> a+rescale outmin outmax innmin innmax a = +    outmin + innpos * (outrange / innrange)  +  where+    outrange = outmax - outmin+    innrange = innmax - innmin+    innpos   = a - innmin +
+ src/Wumpus/Drawing/Colour/SVGColours.hs view
@@ -0,0 +1,625 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Colour.SVGColours+-- Copyright   :  (c) Stephen Tetley 2009-2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  unstable+-- Portability :  GHC+--+-- The SVG \'named colours\', as rgb [0,1] values +--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Colour.SVGColours +  (+    +  -- * Named colours+    alice_blue+  , antique_white+  , aqua+  , aquamarine+  , azure+  , beige+  , bisque+  , black+  , blanched_almond+  , blue+  , blue_violet+  , brown+  , burlywood+  , cadet_blue+  , chartreuse+  , chocolate+  , coral+  , cornflower_blue+  , cornsilk+  , crimson+  , cyan+  , dark_blue+  , dark_cyan+  , dark_goldenrod+  , dark_gray+  , dark_green+  , dark_grey+  , dark_khaki+  , dark_magenta+  , dark_olive_green+  , dark_orange+  , dark_orchid+  , dark_red+  , dark_salmon+  , dark_sea_green+  , dark_slate_blue+  , dark_slate_gray+  , dark_slate_grey+  , dark_turquoise+  , dark_violet+  , deep_pink+  , deep_sky_blue+  , dim_gray+  , dim_grey+  , dodger_blue+  , firebrick+  , floral_white+  , forest_green+  , fuchsia+  , gainsboro+  , ghost_white+  , gold+  , goldenrod+  , gray+  , grey+  , green+  , green_yellow+  , honeydew+  , hot_pink+  , indian_red+  , indigo+  , ivory+  , khaki+  , lavender+  , lavender_blush+  , lawn_green+  , lemon_chiffon+  , light_blue+  , light_coral+  , light_cyan+  , light_goldenrod_yellow+  , light_gray+  , light_green+  , light_grey+  , light_pink+  , light_salmon+  , light_sea_green+  , light_sky_blue+  , light_slate_gray+  , light_slate_grey+  , light_steel_blue+  , light_yellow+  , lime+  , lime_green+  , linen+  , magenta+  , maroon+  , medium_aquamarine+  , medium_blue+  , medium_orchid+  , medium_purple+  , medium_sea_green+  , medium_slate_blue+  , medium_spring_green+  , medium_turquoise+  , medium_violet_red+  , midnight_blue+  , mintcream+  , mistyrose+  , moccasin+  , navajo_white+  , navy+  , old_lace+  , olive+  , olive_drab+  , orange+  , orange_red+  , orchid+  , pale_goldenrod+  , pale_green+  , pale_turquoise+  , pale_violet_red+  , papaya_whip+  , peach_puff+  , peru+  , pink+  , plum+  , powder_blue+  , purple+  , red+  , rosy_brown+  , royal_blue+  , saddle_brown+  , salmon+  , sandy_brown+  , sea_green+  , seashell+  , sienna+  , silver+  , sky_blue+  , slate_blue+  , slate_gray+  , slate_grey+  , snow+  , spring_green+  , steel_blue+  , tan+  , teal+  , thistle+  , tomato+  , turquoise+  , violet+  , wheat+  , white+  , whitesmoke+  , yellow+  , yellow_green+  +  ) where+++import Wumpus.Core.Colour ( RGBi(..) )+++import Prelude ( )+  +++--------------------------------------------------------------------------------+  +alice_blue              :: RGBi+alice_blue              = RGBi 0xf0 0xf8 0xff++antique_white           :: RGBi +antique_white           = RGBi 0xfa 0xeb 0xd7++aqua                    :: RGBi+aqua                    = RGBi 0x00 0xff 0xff++aquamarine              :: RGBi+aquamarine              = RGBi 0x7f 0xff 0xd4++azure                   :: RGBi+azure                   = RGBi 0xf0 0xff 0xff++beige                   :: RGBi+beige                   = RGBi 0xf5 0xf5 0xdc++bisque                  :: RGBi+bisque                  = RGBi 0xff 0xe4 0xc4++black                   :: RGBi+black                   = RGBi 0x00 0x00 0x00++blanched_almond         :: RGBi+blanched_almond         = RGBi 0xff 0xeb 0xcd++blue                    :: RGBi+blue                    = RGBi 0x00 0x00 0xff++blue_violet             :: RGBi+blue_violet             = RGBi 0x8a 0x2b 0xe2++brown                   :: RGBi+brown                   = RGBi 0xa5 0x2a 0x2a++burlywood               :: RGBi+burlywood               = RGBi 0xde 0xb8 0x87++cadet_blue              :: RGBi+cadet_blue              = RGBi 0x5f 0x9e 0xa0++chartreuse              :: RGBi+chartreuse              = RGBi 0x7f 0xff 0x00++chocolate               :: RGBi+chocolate               = RGBi 0xd2 0x69 0x1e++coral                   :: RGBi+coral                   = RGBi 0xff 0x7f 0x50++cornflower_blue         :: RGBi+cornflower_blue         = RGBi 0x64 0x95 0xed++cornsilk                :: RGBi+cornsilk                = RGBi 0xff 0xf8 0xdc++crimson                 :: RGBi+crimson                 = RGBi 0xdc 0x14 0x3c++cyan                    :: RGBi+cyan                    = RGBi 0x00 0xff 0xff++dark_blue               :: RGBi+dark_blue               = RGBi 0x00 0x00 0x8b++dark_cyan               :: RGBi+dark_cyan               = RGBi 0x00 0x8b 0x8b++dark_goldenrod          :: RGBi+dark_goldenrod          = RGBi 0xb8 0x86 0x0b++dark_gray               :: RGBi+dark_gray               = RGBi 0xa9 0xa9 0xa9++dark_green              :: RGBi+dark_green              = RGBi 0x00 0x64 0x00++dark_grey               :: RGBi+dark_grey               = RGBi 0xa9 0xa9 0xa9++dark_khaki              :: RGBi+dark_khaki              = RGBi 0xbd 0xb7 0x6b++dark_magenta            :: RGBi+dark_magenta            = RGBi 0x8b 0x00 0x8b++dark_olive_green        :: RGBi+dark_olive_green        = RGBi 0x55 0x6b 0x2f++dark_orange             :: RGBi+dark_orange             = RGBi 0xff 0x8c 0x00++dark_orchid             :: RGBi+dark_orchid             = RGBi 0x99 0x32 0xcc++dark_red                :: RGBi+dark_red                = RGBi 0x8b 0x00 0x00++dark_salmon             :: RGBi+dark_salmon             = RGBi 0xe9 0x96 0x7a++dark_sea_green          :: RGBi+dark_sea_green          = RGBi 0x8f 0xbc 0x8f++dark_slate_blue         :: RGBi+dark_slate_blue         = RGBi 0x48 0x3d 0x8b++dark_slate_gray         :: RGBi+dark_slate_gray         = RGBi 0x2f 0x4f 0x4f++dark_slate_grey         :: RGBi+dark_slate_grey         = RGBi 0x2f 0x4f 0x4f++dark_turquoise          :: RGBi+dark_turquoise          = RGBi 0x00 0xce 0xd1++dark_violet             :: RGBi+dark_violet             = RGBi 0x94 0x00 0xd3++deep_pink               :: RGBi+deep_pink               = RGBi 0xff 0x14 0x93++deep_sky_blue           :: RGBi+deep_sky_blue           = RGBi 0x00 0xbf 0xff++dim_gray                :: RGBi+dim_gray                = RGBi 0x69 0x69 0x69++dim_grey                :: RGBi+dim_grey                = RGBi 0x69 0x69 0x69++dodger_blue             :: RGBi+dodger_blue             = RGBi 0x1e 0x90 0xff++firebrick               :: RGBi+firebrick               = RGBi 0xb2 0x22 0x22++floral_white            :: RGBi+floral_white            = RGBi 0xff 0xfa 0xf0++forest_green            :: RGBi+forest_green            = RGBi 0x22 0x8b 0x22++fuchsia                 :: RGBi+fuchsia                 = RGBi 0xff 0x00 0xff++gainsboro               :: RGBi+gainsboro               = RGBi 0xdc 0xdc 0xdc++ghost_white             :: RGBi+ghost_white             = RGBi 0xf8 0xf8 0xff++gold                    :: RGBi+gold                    = RGBi 0xff 0xd7 0x00++goldenrod               :: RGBi+goldenrod               = RGBi 0xda 0xa5 0x20++gray                    :: RGBi+gray                    = RGBi 0x80 0x80 0x80++green                   :: RGBi+green                   = RGBi 0x00 0x80 0x00++green_yellow            :: RGBi+green_yellow            = RGBi 0xad 0xff 0x2f++grey                    :: RGBi+grey                    = RGBi 0x80 0x80 0x80++honeydew                :: RGBi+honeydew                = RGBi 0xf0 0xff 0xf0++hot_pink                :: RGBi+hot_pink                = RGBi 0xff 0x69 0xb4++indian_red              :: RGBi+indian_red              = RGBi 0xcd 0x5c 0x5c++indigo                  :: RGBi+indigo                  = RGBi 0x4b 0x00 0x82++ivory                   :: RGBi+ivory                   = RGBi 0xff 0xff 0xf0++khaki                   :: RGBi+khaki                   = RGBi 0xf0 0xe6 0x8c++lavender                :: RGBi+lavender                = RGBi 0xe6 0xe6 0xfa++lavender_blush          :: RGBi+lavender_blush          = RGBi 0xff 0xf0 0xf5++lawn_green              :: RGBi+lawn_green              = RGBi 0x7c 0xfc 0x00++lemon_chiffon           :: RGBi+lemon_chiffon           = RGBi 0xff 0xfa 0xcd++light_blue              :: RGBi+light_blue              = RGBi 0xad 0xd8 0xe6++light_coral             :: RGBi+light_coral             = RGBi 0xf0 0x80 0x80++light_cyan              :: RGBi+light_cyan              = RGBi 0xe0 0xff 0xff++light_goldenrod_yellow  :: RGBi+light_goldenrod_yellow  = RGBi 0xfa 0xfa 0xd2++light_gray              :: RGBi+light_gray              = RGBi 0xd3 0xd3 0xd3++light_green             :: RGBi+light_green             = RGBi 0x90 0xee 0x90++light_grey              :: RGBi+light_grey              = RGBi 0xd3 0xd3 0xd3++light_pink              :: RGBi+light_pink              = RGBi 0xff 0xb6 0xc1++light_salmon            :: RGBi+light_salmon            = RGBi 0xff 0xa0 0x7a++light_sea_green         :: RGBi+light_sea_green         = RGBi 0x20 0xb2 0xaa++light_sky_blue          :: RGBi+light_sky_blue          = RGBi 0x87 0xce 0xfa++light_slate_gray        :: RGBi+light_slate_gray        = RGBi 0x77 0x88 0x99++light_slate_grey        :: RGBi+light_slate_grey        = RGBi 0x77 0x88 0x99++light_steel_blue        :: RGBi+light_steel_blue        = RGBi 0xb0 0xc4 0xde++light_yellow            :: RGBi+light_yellow            = RGBi 0xff 0xff 0xe0++lime                    :: RGBi+lime                    = RGBi 0x00 0xff 0x00++lime_green              :: RGBi+lime_green              = RGBi 0x32 0xcd 0x32++linen                   :: RGBi+linen                   = RGBi 0xfa 0xf0 0xe6++magenta                 :: RGBi+magenta                 = RGBi 0xff 0x00 0xff++maroon                  :: RGBi+maroon                  = RGBi 0x80 0x00 0x00++medium_aquamarine       :: RGBi+medium_aquamarine       = RGBi 0x66 0xcd 0xaa++medium_blue             :: RGBi+medium_blue             = RGBi 0x00 0x00 0xcd++medium_orchid           :: RGBi+medium_orchid           = RGBi 0xba 0x55 0xd3++medium_purple           :: RGBi+medium_purple           = RGBi 0x93 0x70 0xdb++medium_sea_green        :: RGBi+medium_sea_green        = RGBi 0x3c 0xb3 0x71++medium_slate_blue       :: RGBi+medium_slate_blue       = RGBi 0x7b 0x68 0xee++medium_spring_green     :: RGBi+medium_spring_green     = RGBi 0x00 0xfa 0x9a++medium_turquoise        :: RGBi+medium_turquoise        = RGBi 0x48 0xd1 0xcc++medium_violet_red       :: RGBi+medium_violet_red       = RGBi 0xc7 0x15 0x85++midnight_blue           :: RGBi+midnight_blue           = RGBi 0x19 0x19 0x70++mintcream               :: RGBi+mintcream               = RGBi 0xf5 0xff 0xfa++mistyrose               :: RGBi+mistyrose               = RGBi 0xff 0xe4 0xe1++moccasin                :: RGBi+moccasin                = RGBi 0xff 0xe4 0xb5++navajo_white            :: RGBi+navajo_white            = RGBi 0xff 0xde 0xad++navy                    :: RGBi+navy                    = RGBi 0x00 0x00 0x80++old_lace                :: RGBi+old_lace                = RGBi 0xfd 0xf5 0xe6++olive                   :: RGBi+olive                   = RGBi 0x80 0x80 0x00++olive_drab              :: RGBi+olive_drab              = RGBi 0x6b 0x8e 0x23++orange                  :: RGBi+orange                  = RGBi 0xff 0xa5 0x00++orange_red              :: RGBi+orange_red              = RGBi 0xff 0x45 0x00++orchid                  :: RGBi+orchid                  = RGBi 0xda 0x70 0xd6++pale_goldenrod          :: RGBi+pale_goldenrod          = RGBi 0xee 0xe8 0xaa++pale_green              :: RGBi+pale_green              = RGBi 0x98 0xfb 0x98++pale_turquoise          :: RGBi+pale_turquoise          = RGBi 0xaf 0xee 0xee++pale_violet_red         :: RGBi+pale_violet_red         = RGBi 0xdb 0x70 0x93++papaya_whip             :: RGBi+papaya_whip             = RGBi 0xff 0xef 0xd5++peach_puff              :: RGBi+peach_puff              = RGBi 0xff 0xda 0xb9++peru                    :: RGBi+peru                    = RGBi 0xcd 0x85 0x3f++pink                    :: RGBi+pink                    = RGBi 0xff 0xc0 0xcb++plum                    :: RGBi+plum                    = RGBi 0xdd 0xa0 0xdd++powder_blue             :: RGBi+powder_blue             = RGBi 0xb0 0xe0 0xe6++purple                  :: RGBi+purple                  = RGBi 0x80 0x00 0x80++red                     :: RGBi+red                     = RGBi 0xff 0x00 0x00++rosy_brown              :: RGBi+rosy_brown              = RGBi 0xbc 0x8f 0x8f++royal_blue              :: RGBi+royal_blue              = RGBi 0x41 0x69 0xe1++saddle_brown            :: RGBi+saddle_brown            = RGBi 0x8b 0x45 0x13++salmon                  :: RGBi+salmon                  = RGBi 0xfa 0x80 0x72++sandy_brown             :: RGBi+sandy_brown             = RGBi 0xf4 0xa4 0x60++sea_green               :: RGBi+sea_green               = RGBi 0x2e 0x8b 0x57++seashell                :: RGBi+seashell                = RGBi 0xff 0xf5 0xee++sienna                  :: RGBi+sienna                  = RGBi 0xa0 0x52 0x2d++silver                  :: RGBi+silver                  = RGBi 0xc0 0xc0 0xc0++sky_blue                :: RGBi+sky_blue                = RGBi 0x87 0xce 0xeb++slate_blue              :: RGBi+slate_blue              = RGBi 0x6a 0x5a 0xcd++slate_gray              :: RGBi+slate_gray              = RGBi 0x70 0x80 0x90++slate_grey              :: RGBi+slate_grey              = RGBi 0x70 0x80 0x90++snow                    :: RGBi+snow                    = RGBi 0xff 0xfa 0xfa++spring_green            :: RGBi+spring_green            = RGBi 0x00 0xff 0x7f++steel_blue              :: RGBi+steel_blue              = RGBi 0x46 0x82 0xb4++tan                     :: RGBi+tan                     = RGBi 0xd2 0xb4 0x8c++teal                    :: RGBi+teal                    = RGBi 0x00 0x80 0x80++thistle                 :: RGBi+thistle                 = RGBi 0xd8 0xbf 0xd8++tomato                  :: RGBi+tomato                  = RGBi 0xff 0x63 0x47++turquoise               :: RGBi+turquoise               = RGBi 0x40 0xe0 0xd0++violet                  :: RGBi+violet                  = RGBi 0xee 0x82 0xee++wheat                   :: RGBi+wheat                   = RGBi 0xf5 0xde 0xb3++white                   :: RGBi+white                   = RGBi 0xff 0xff 0xff++whitesmoke              :: RGBi+whitesmoke              = RGBi 0xf5 0xf5 0xf5++yellow                  :: RGBi+yellow                  = RGBi 0xff 0xff 0x00++yellow_green            :: RGBi+yellow_green            = RGBi 0x9a 0xcd 0x32+++++
+ src/Wumpus/Drawing/Colour/X11Colours.hs view
@@ -0,0 +1,1282 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Colour.X11Colours+-- Copyright   :  (c) Stephen Tetley 2009-2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  unstable+-- Portability :  GHC+--+-- The X11 \'named colours\', as rgb [0,1] values +--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Colour.X11Colours+  ( +  +  -- * Named X11 colours+    antique_white1+  , antique_white2+  , antique_white3+  , antique_white4+  , aquamarine1+  , aquamarine2+  , aquamarine3+  , aquamarine4+  , azure1+  , azure2+  , azure3+  , azure4+  , bisque1+  , bisque2+  , bisque3+  , bisque4+  , blue1+  , blue2+  , blue3+  , blue4+  , brown1+  , brown2+  , brown3+  , brown4+  , burlywood1+  , burlywood2+  , burlywood3+  , burlywood4+  , cadet_blue1+  , cadet_blue2+  , cadet_blue3+  , cadet_blue4+  , chartreuse1+  , chartreuse2+  , chartreuse3+  , chartreuse4+  , chocolate1+  , chocolate2+  , chocolate3+  , chocolate4+  , coral1+  , coral2+  , coral3+  , coral4+  , cornsilk1+  , cornsilk2+  , cornsilk3+  , cornsilk4+  , cyan1+  , cyan2+  , cyan3+  , cyan4+  , dark_goldenrod1+  , dark_goldenrod2+  , dark_goldenrod3+  , dark_goldenrod4+  , dark_olive_green1+  , dark_olive_green2+  , dark_olive_green3+  , dark_olive_green4+  , dark_orange1+  , dark_orange2+  , dark_orange3+  , dark_orange4+  , dark_orchid1+  , dark_orchid2+  , dark_orchid3+  , dark_orchid4+  , dark_sea_green1+  , dark_sea_green2+  , dark_sea_green3+  , dark_sea_green4+  , dark_slate_gray1+  , dark_slate_gray2+  , dark_slate_gray3+  , dark_slate_gray4+  , deep_pink1+  , deep_pink2+  , deep_pink3+  , deep_pink4+  , deep_sky_blue1+  , deep_sky_blue2+  , deep_sky_blue3+  , deep_sky_blue4+  , dodger_blue1+  , dodger_blue2+  , dodger_blue3+  , dodger_blue4+  , firebrick1+  , firebrick2+  , firebrick3+  , firebrick4+  , gold1+  , gold2+  , gold3+  , gold4+  , goldenrod1+  , goldenrod2+  , goldenrod3+  , goldenrod4+  , green1+  , green2+  , green3+  , green4+  , honeydew1+  , honeydew2+  , honeydew3+  , honeydew4+  , hot_pink1+  , hot_pink2+  , hot_pink3+  , hot_pink4+  , indian_red1+  , indian_red2+  , indian_red3+  , indian_red4+  , ivory1+  , ivory2+  , ivory3+  , ivory4+  , khaki1+  , khaki2+  , khaki3+  , khaki4+  , lavender_blush1+  , lavender_blush2+  , lavender_blush3+  , lavender_blush4+  , lemon_chiffon1+  , lemon_chiffon2+  , lemon_chiffon3+  , lemon_chiffon4+  , light_blue1+  , light_blue2+  , light_blue3+  , light_blue4+  , light_cyan1+  , light_cyan2+  , light_cyan3+  , light_cyan4+  , light_goldenrod1+  , light_goldenrod2+  , light_goldenrod3+  , light_goldenrod4+  , light_pink1+  , light_pink2+  , light_pink3+  , light_pink4+  , light_salmon1+  , light_salmon2+  , light_salmon3+  , light_salmon4+  , light_sky_blue1+  , light_sky_blue2+  , light_sky_blue3+  , light_sky_blue4+  , light_steel_blue1+  , light_steel_blue2+  , light_steel_blue3+  , light_steel_blue4+  , light_yellow1+  , light_yellow2+  , light_yellow3+  , light_yellow4+  , magenta1+  , magenta2+  , magenta3+  , magenta4+  , maroon1+  , maroon2+  , maroon3+  , maroon4+  , medium_orchid1+  , medium_orchid2+  , medium_orchid3+  , medium_orchid4+  , medium_purple1+  , medium_purple2+  , medium_purple3+  , medium_purple4+  , misty_rose1+  , misty_rose2+  , misty_rose3+  , misty_rose4+  , navajo_white1+  , navajo_white2+  , navajo_white3+  , navajo_white4+  , olive_drab1+  , olive_drab2+  , olive_drab3+  , olive_drab4+  , orange1+  , orange2+  , orange3+  , orange4+  , orange_red1+  , orange_red2+  , orange_red3+  , orange_red4+  , orchid1+  , orchid2+  , orchid3+  , orchid4+  , pale_green1+  , pale_green2+  , pale_green3+  , pale_green4+  , pale_turquoise1+  , pale_turquoise2+  , pale_turquoise3+  , pale_turquoise4+  , pale_violet_red1+  , pale_violet_red2+  , pale_violet_red3+  , pale_violet_red4+  , peach_puff1+  , peach_puff2+  , peach_puff3+  , peach_puff4+  , pink1+  , pink2+  , pink3+  , pink4+  , plum1+  , plum2+  , plum3+  , plum4+  , purple1+  , purple2+  , purple3+  , purple4+  , red1+  , red2+  , red3+  , red4+  , rosy_brown1+  , rosy_brown2+  , rosy_brown3+  , rosy_brown4+  , royal_blue1+  , royal_blue2+  , royal_blue3+  , royal_blue4+  , salmon1+  , salmon2+  , salmon3+  , salmon4+  , sea_green1+  , sea_green2+  , sea_green3+  , sea_green4+  , seashell1+  , seashell2+  , seashell3+  , seashell4+  , sienna1+  , sienna2+  , sienna3+  , sienna4+  , sky_blue1+  , sky_blue2+  , sky_blue3+  , sky_blue4+  , slate_blue1+  , slate_blue2+  , slate_blue3+  , slate_blue4+  , slate_gray1+  , slate_gray2+  , slate_gray3+  , slate_gray4+  , snow1+  , snow2+  , snow3+  , snow4+  , spring_green1+  , spring_green2+  , spring_green3+  , spring_green4+  , steel_blue1+  , steel_blue2+  , steel_blue3+  , steel_blue4+  , tan1+  , tan2+  , tan3+  , tan4+  , thistle1+  , thistle2+  , thistle3+  , thistle4+  , tomato1+  , tomato2+  , tomato3+  , tomato4+  , turquoise1+  , turquoise2+  , turquoise3+  , turquoise4+  , violet_red1+  , violet_red2+  , violet_red3+  , violet_red4+  , wheat1+  , wheat2+  , wheat3+  , wheat4+  , yellow1+  , yellow2+  , yellow3+  , yellow4++  ) where++import Wumpus.Core.Colour ( RGBi(..) )+++--------------------------------------------------------------------------------++antique_white1          :: RGBi+antique_white1          = RGBi 0xff 0xef 0xdb++antique_white2          :: RGBi+antique_white2          = RGBi 0xee 0xdf 0xcc++antique_white3          :: RGBi+antique_white3          = RGBi 0xcd 0xc0 0xb0++antique_white4          :: RGBi+antique_white4          = RGBi 0x8b 0x83 0x78++aquamarine1             :: RGBi+aquamarine1             = RGBi 0x7f 0xff 0xd4++aquamarine2             :: RGBi+aquamarine2             = RGBi 0x76 0xee 0xc6++aquamarine3             :: RGBi+aquamarine3             = RGBi 0x66 0xcd 0xaa++aquamarine4             :: RGBi+aquamarine4             = RGBi 0x45 0x8b 0x74++azure1                  :: RGBi+azure1                  = RGBi 0xf0 0xff 0xff++azure2                  :: RGBi+azure2                  = RGBi 0xe0 0xee 0xee++azure3                  :: RGBi+azure3                  = RGBi 0xc1 0xcd 0xcd++azure4                  :: RGBi+azure4                  = RGBi 0x83 0x8b 0x8b++bisque1                 :: RGBi+bisque1                 = RGBi 0xff 0xe4 0xc4++bisque2                 :: RGBi+bisque2                 = RGBi 0xee 0xd5 0xb7++bisque3                 :: RGBi+bisque3                 = RGBi 0xcd 0xb7 0x9e++bisque4                 :: RGBi+bisque4                 = RGBi 0x8b 0x7d 0x6b++blue1                   :: RGBi+blue1                   = RGBi 0x00 0x00 0xff++blue2                   :: RGBi+blue2                   = RGBi 0x00 0x00 0xee++blue3                   :: RGBi+blue3                   = RGBi 0x00 0x00 0xcd++blue4                   :: RGBi+blue4                   = RGBi 0x00 0x00 0x8b++brown1                  :: RGBi+brown1                  = RGBi 0xff 0x40 0x40++brown2                  :: RGBi+brown2                  = RGBi 0xee 0x3b 0x3b++brown3                  :: RGBi+brown3                  = RGBi 0xcd 0x33 0x33++brown4                  :: RGBi+brown4                  = RGBi 0x8b 0x23 0x23++burlywood1              :: RGBi+burlywood1              = RGBi 0xff 0xd3 0x9b++burlywood2              :: RGBi+burlywood2              = RGBi 0xee 0xc5 0x91++burlywood3              :: RGBi+burlywood3              = RGBi 0xcd 0xaa 0x7d++burlywood4              :: RGBi+burlywood4              = RGBi 0x8b 0x73 0x55++cadet_blue1             :: RGBi+cadet_blue1             = RGBi 0x98 0xf5 0xff++cadet_blue2             :: RGBi+cadet_blue2             = RGBi 0x8e 0xe5 0xee++cadet_blue3             :: RGBi+cadet_blue3             = RGBi 0x7a 0xc5 0xcd++cadet_blue4             :: RGBi+cadet_blue4             = RGBi 0x53 0x86 0x8b++chartreuse1             :: RGBi+chartreuse1             = RGBi 0x7f 0xff 0x00++chartreuse2             :: RGBi+chartreuse2             = RGBi 0x76 0xee 0x00++chartreuse3             :: RGBi+chartreuse3             = RGBi 0x66 0xcd 0x00++chartreuse4             :: RGBi+chartreuse4             = RGBi 0x45 0x8b 0x00++chocolate1              :: RGBi+chocolate1              = RGBi 0xff 0x7f 0x24++chocolate2              :: RGBi+chocolate2              = RGBi 0xee 0x76 0x21++chocolate3              :: RGBi+chocolate3              = RGBi 0xcd 0x66 0x1d++chocolate4              :: RGBi+chocolate4              = RGBi 0x8b 0x45 0x13++coral1                  :: RGBi+coral1                  = RGBi 0xff 0x72 0x56++coral2                  :: RGBi+coral2                  = RGBi 0xee 0x6a 0x50++coral3                  :: RGBi+coral3                  = RGBi 0xcd 0x5b 0x45++coral4                  :: RGBi+coral4                  = RGBi 0x8b 0x3e 0x2f++cornsilk1               :: RGBi+cornsilk1               = RGBi 0xff 0xf8 0xdc++cornsilk2               :: RGBi+cornsilk2               = RGBi 0xee 0xe8 0xcd++cornsilk3               :: RGBi+cornsilk3               = RGBi 0xcd 0xc8 0xb1++cornsilk4               :: RGBi+cornsilk4               = RGBi 0x8b 0x88 0x78++cyan1                   :: RGBi+cyan1                   = RGBi 0x00 0xff 0xff++cyan2                   :: RGBi+cyan2                   = RGBi 0x00 0xee 0xee++cyan3                   :: RGBi+cyan3                   = RGBi 0x00 0xcd 0xcd++cyan4                   :: RGBi+cyan4                   = RGBi 0x00 0x8b 0x8b++dark_goldenrod1         :: RGBi+dark_goldenrod1         = RGBi 0xff 0xb9 0x0f++dark_goldenrod2         :: RGBi+dark_goldenrod2         = RGBi 0xee 0xad 0x0e++dark_goldenrod3         :: RGBi+dark_goldenrod3         = RGBi 0xcd 0x95 0x0c++dark_goldenrod4         :: RGBi+dark_goldenrod4         = RGBi 0x8b 0x65 0x08++dark_olive_green1       :: RGBi+dark_olive_green1       = RGBi 0xca 0xff 0x70++dark_olive_green2       :: RGBi+dark_olive_green2       = RGBi 0xbc 0xee 0x68++dark_olive_green3       :: RGBi+dark_olive_green3       = RGBi 0xa2 0xcd 0x5a++dark_olive_green4       :: RGBi+dark_olive_green4       = RGBi 0x6e 0x8b 0x3d++dark_orange1            :: RGBi+dark_orange1            = RGBi 0xff 0x7f 0x00++dark_orange2            :: RGBi+dark_orange2            = RGBi 0xee 0x76 0x00++dark_orange3            :: RGBi+dark_orange3            = RGBi 0xcd 0x66 0x00++dark_orange4            :: RGBi+dark_orange4            = RGBi 0x8b 0x45 0x00++dark_orchid1            :: RGBi+dark_orchid1            = RGBi 0xbf 0x3e 0xff++dark_orchid2            :: RGBi+dark_orchid2            = RGBi 0xb2 0x3a 0xee++dark_orchid3            :: RGBi+dark_orchid3            = RGBi 0x9a 0x32 0xcd++dark_orchid4            :: RGBi+dark_orchid4            = RGBi 0x68 0x22 0x8b++dark_sea_green1         :: RGBi+dark_sea_green1         = RGBi 0xc1 0xff 0xc1++dark_sea_green2         :: RGBi+dark_sea_green2         = RGBi 0xb4 0xee 0xb4++dark_sea_green3         :: RGBi+dark_sea_green3         = RGBi 0x9b 0xcd 0x9b++dark_sea_green4         :: RGBi+dark_sea_green4         = RGBi 0x69 0x8b 0x69++dark_slate_gray1        :: RGBi+dark_slate_gray1        = RGBi 0x97 0xff 0xff++dark_slate_gray2        :: RGBi+dark_slate_gray2        = RGBi 0x8d 0xee 0xee++dark_slate_gray3        :: RGBi+dark_slate_gray3        = RGBi 0x79 0xcd 0xcd++dark_slate_gray4        :: RGBi+dark_slate_gray4        = RGBi 0x52 0x8b 0x8b++deep_pink1              :: RGBi+deep_pink1              = RGBi 0xff 0x14 0x93++deep_pink2              :: RGBi+deep_pink2              = RGBi 0xee 0x12 0x89++deep_pink3              :: RGBi+deep_pink3              = RGBi 0xcd 0x10 0x76++deep_pink4              :: RGBi+deep_pink4              = RGBi 0x8b 0x0a 0x50++deep_sky_blue1          :: RGBi+deep_sky_blue1          = RGBi 0x00 0xbf 0xff++deep_sky_blue2          :: RGBi+deep_sky_blue2          = RGBi 0x00 0xb2 0xee++deep_sky_blue3          :: RGBi+deep_sky_blue3          = RGBi 0x00 0x9a 0xcd++deep_sky_blue4          :: RGBi+deep_sky_blue4          = RGBi 0x00 0x68 0x8b++dodger_blue1            :: RGBi+dodger_blue1            = RGBi 0x1e 0x90 0xff++dodger_blue2            :: RGBi+dodger_blue2            = RGBi 0x1c 0x86 0xee++dodger_blue3            :: RGBi+dodger_blue3            = RGBi 0x18 0x74 0xcd++dodger_blue4            :: RGBi+dodger_blue4            = RGBi 0x10 0x4e 0x8b++firebrick1              :: RGBi+firebrick1              = RGBi 0xff 0x30 0x30++firebrick2              :: RGBi+firebrick2              = RGBi 0xee 0x2c 0x2c++firebrick3              :: RGBi+firebrick3              = RGBi 0xcd 0x26 0x26++firebrick4              :: RGBi+firebrick4              = RGBi 0x8b 0x1a 0x1a++gold1                   :: RGBi+gold1                   = RGBi 0xff 0xd7 0x00++gold2                   :: RGBi+gold2                   = RGBi 0xee 0xc9 0x00++gold3                   :: RGBi+gold3                   = RGBi 0xcd 0xad 0x00++gold4                   :: RGBi+gold4                   = RGBi 0x8b 0x75 0x00++goldenrod1              :: RGBi+goldenrod1              = RGBi 0xff 0xc1 0x25++goldenrod2              :: RGBi+goldenrod2              = RGBi 0xee 0xb4 0x22++goldenrod3              :: RGBi+goldenrod3              = RGBi 0xcd 0x9b 0x1d++goldenrod4              :: RGBi+goldenrod4              = RGBi 0x8b 0x69 0x14++green1                  :: RGBi+green1                  = RGBi 0x00 0xff 0x00++green2                  :: RGBi+green2                  = RGBi 0x00 0xee 0x00++green3                  :: RGBi+green3                  = RGBi 0x00 0xcd 0x00++green4                  :: RGBi+green4                  = RGBi 0x00 0x8b 0x00++honeydew1               :: RGBi+honeydew1               = RGBi 0xf0 0xff 0xf0++honeydew2               :: RGBi+honeydew2               = RGBi 0xe0 0xee 0xe0++honeydew3               :: RGBi+honeydew3               = RGBi 0xc1 0xcd 0xc1++honeydew4               :: RGBi+honeydew4               = RGBi 0x83 0x8b 0x83++hot_pink1               :: RGBi+hot_pink1               = RGBi 0xff 0x6e 0xb4++hot_pink2               :: RGBi+hot_pink2               = RGBi 0xee 0x6a 0xa7++hot_pink3               :: RGBi+hot_pink3               = RGBi 0xcd 0x60 0x90++hot_pink4               :: RGBi+hot_pink4               = RGBi 0x8b 0x3a 0x62++indian_red1             :: RGBi+indian_red1             = RGBi 0xff 0x6a 0x6a++indian_red2             :: RGBi+indian_red2             = RGBi 0xee 0x63 0x63++indian_red3             :: RGBi+indian_red3             = RGBi 0xcd 0x55 0x55++indian_red4             :: RGBi+indian_red4             = RGBi 0x8b 0x3a 0x3a++ivory1                  :: RGBi+ivory1                  = RGBi 0xff 0xff 0xf0++ivory2                  :: RGBi+ivory2                  = RGBi 0xee 0xee 0xe0++ivory3                  :: RGBi+ivory3                  = RGBi 0xcd 0xcd 0xc1++ivory4                  :: RGBi+ivory4                  = RGBi 0x8b 0x8b 0x83++khaki1                  :: RGBi+khaki1                  = RGBi 0xff 0xf6 0x8f++khaki2                  :: RGBi+khaki2                  = RGBi 0xee 0xe6 0x85++khaki3                  :: RGBi+khaki3                  = RGBi 0xcd 0xc6 0x73++khaki4                  :: RGBi+khaki4                  = RGBi 0x8b 0x86 0x4e++lavender_blush1         :: RGBi+lavender_blush1         = RGBi 0xff 0xf0 0xf5++lavender_blush2         :: RGBi+lavender_blush2         = RGBi 0xee 0xe0 0xe5++lavender_blush3         :: RGBi+lavender_blush3         = RGBi 0xcd 0xc1 0xc5++lavender_blush4         :: RGBi+lavender_blush4         = RGBi 0x8b 0x83 0x86++lemon_chiffon1          :: RGBi+lemon_chiffon1          = RGBi 0xff 0xfa 0xcd++lemon_chiffon2          :: RGBi+lemon_chiffon2          = RGBi 0xee 0xe9 0xbf++lemon_chiffon3          :: RGBi+lemon_chiffon3          = RGBi 0xcd 0xc9 0xa5++lemon_chiffon4          :: RGBi+lemon_chiffon4          = RGBi 0x8b 0x89 0x70++light_blue1             :: RGBi+light_blue1             = RGBi 0xbf 0xef 0xff++light_blue2             :: RGBi+light_blue2             = RGBi 0xb2 0xdf 0xee++light_blue3             :: RGBi+light_blue3             = RGBi 0x9a 0xc0 0xcd++light_blue4             :: RGBi+light_blue4             = RGBi 0x68 0x83 0x8b++light_cyan1             :: RGBi+light_cyan1             = RGBi 0xe0 0xff 0xff++light_cyan2             :: RGBi+light_cyan2             = RGBi 0xd1 0xee 0xee++light_cyan3             :: RGBi+light_cyan3             = RGBi 0xb4 0xcd 0xcd++light_cyan4             :: RGBi+light_cyan4             = RGBi 0x7a 0x8b 0x8b++light_goldenrod1        :: RGBi+light_goldenrod1        = RGBi 0xff 0xec 0x8b++light_goldenrod2        :: RGBi+light_goldenrod2        = RGBi 0xee 0xdc 0x82++light_goldenrod3        :: RGBi+light_goldenrod3        = RGBi 0xcd 0xbe 0x70++light_goldenrod4        :: RGBi+light_goldenrod4        = RGBi 0x8b 0x81 0x4c++light_pink1             :: RGBi+light_pink1             = RGBi 0xff 0xae 0xb9++light_pink2             :: RGBi+light_pink2             = RGBi 0xee 0xa2 0xad++light_pink3             :: RGBi+light_pink3             = RGBi 0xcd 0x8c 0x95++light_pink4             :: RGBi+light_pink4             = RGBi 0x8b 0x5f 0x65++light_salmon1           :: RGBi+light_salmon1           = RGBi 0xff 0xa0 0x7a++light_salmon2           :: RGBi+light_salmon2           = RGBi 0xee 0x95 0x72++light_salmon3           :: RGBi+light_salmon3           = RGBi 0xcd 0x81 0x62++light_salmon4           :: RGBi+light_salmon4           = RGBi 0x8b 0x57 0x42++light_sky_blue1         :: RGBi+light_sky_blue1         = RGBi 0xb0 0xe2 0xff++light_sky_blue2         :: RGBi+light_sky_blue2         = RGBi 0xa4 0xd3 0xee++light_sky_blue3         :: RGBi+light_sky_blue3         = RGBi 0x8d 0xb6 0xcd++light_sky_blue4         :: RGBi+light_sky_blue4         = RGBi 0x60 0x7b 0x8b++light_steel_blue1       :: RGBi+light_steel_blue1       = RGBi 0xca 0xe1 0xff++light_steel_blue2       :: RGBi+light_steel_blue2       = RGBi 0xbc 0xd2 0xee++light_steel_blue3       :: RGBi+light_steel_blue3       = RGBi 0xa2 0xb5 0xcd++light_steel_blue4       :: RGBi+light_steel_blue4       = RGBi 0x6e 0x7b 0x8b++light_yellow1           :: RGBi+light_yellow1           = RGBi 0xff 0xff 0xe0++light_yellow2           :: RGBi+light_yellow2           = RGBi 0xee 0xee 0xd1++light_yellow3           :: RGBi+light_yellow3           = RGBi 0xcd 0xcd 0xb4++light_yellow4           :: RGBi+light_yellow4           = RGBi 0x8b 0x8b 0x7a++magenta1                :: RGBi+magenta1                = RGBi 0xff 0x00 0xff++magenta2                :: RGBi+magenta2                = RGBi 0xee 0x00 0xee++magenta3                :: RGBi+magenta3                = RGBi 0xcd 0x00 0xcd++magenta4                :: RGBi+magenta4                = RGBi 0x8b 0x00 0x8b++maroon1                 :: RGBi+maroon1                 = RGBi 0xff 0x34 0xb3++maroon2                 :: RGBi+maroon2                 = RGBi 0xee 0x30 0xa7++maroon3                 :: RGBi+maroon3                 = RGBi 0xcd 0x29 0x90++maroon4                 :: RGBi+maroon4                 = RGBi 0x8b 0x1c 0x62++medium_orchid1          :: RGBi+medium_orchid1          = RGBi 0xe0 0x66 0xff++medium_orchid2          :: RGBi+medium_orchid2          = RGBi 0xd1 0x5f 0xee++medium_orchid3          :: RGBi+medium_orchid3          = RGBi 0xb4 0x52 0xcd++medium_orchid4          :: RGBi+medium_orchid4          = RGBi 0x7a 0x37 0x8b++medium_purple1          :: RGBi+medium_purple1          = RGBi 0xab 0x82 0xff++medium_purple2          :: RGBi+medium_purple2          = RGBi 0x9f 0x79 0xee++medium_purple3          :: RGBi+medium_purple3          = RGBi 0x89 0x68 0xcd++medium_purple4          :: RGBi+medium_purple4          = RGBi 0x5d 0x47 0x8b++misty_rose1             :: RGBi+misty_rose1             = RGBi 0xff 0xe4 0xe1++misty_rose2             :: RGBi+misty_rose2             = RGBi 0xee 0xd5 0xd2++misty_rose3             :: RGBi+misty_rose3             = RGBi 0xcd 0xb7 0xb5++misty_rose4             :: RGBi+misty_rose4             = RGBi 0x8b 0x7d 0x7b++navajo_white1           :: RGBi+navajo_white1           = RGBi 0xff 0xde 0xad++navajo_white2           :: RGBi+navajo_white2           = RGBi 0xee 0xcf 0xa1++navajo_white3           :: RGBi+navajo_white3           = RGBi 0xcd 0xb3 0x8b++navajo_white4           :: RGBi+navajo_white4           = RGBi 0x8b 0x79 0x5e++olive_drab1             :: RGBi+olive_drab1             = RGBi 0xc0 0xff 0x3e++olive_drab2             :: RGBi+olive_drab2             = RGBi 0xb3 0xee 0x3a++olive_drab3             :: RGBi+olive_drab3             = RGBi 0x9a 0xcd 0x32++olive_drab4             :: RGBi+olive_drab4             = RGBi 0x69 0x8b 0x22++orange1                 :: RGBi+orange1                 = RGBi 0xff 0xa5 0x00++orange2                 :: RGBi+orange2                 = RGBi 0xee 0x9a 0x00++orange3                 :: RGBi+orange3                 = RGBi 0xcd 0x85 0x00++orange4                 :: RGBi+orange4                 = RGBi 0x8b 0x5a 0x00++orange_red1             :: RGBi+orange_red1             = RGBi 0xff 0x45 0x00++orange_red2             :: RGBi+orange_red2             = RGBi 0xee 0x40 0x00++orange_red3             :: RGBi+orange_red3             = RGBi 0xcd 0x37 0x00++orange_red4             :: RGBi+orange_red4             = RGBi 0x8b 0x25 0x00++orchid1                 :: RGBi+orchid1                 = RGBi 0xff 0x83 0xfa++orchid2                 :: RGBi+orchid2                 = RGBi 0xee 0x7a 0xe9++orchid3                 :: RGBi+orchid3                 = RGBi 0xcd 0x69 0xc9++orchid4                 :: RGBi+orchid4                 = RGBi 0x8b 0x47 0x89++pale_green1             :: RGBi+pale_green1             = RGBi 0x9a 0xff 0x9a++pale_green2             :: RGBi+pale_green2             = RGBi 0x90 0xee 0x90++pale_green3             :: RGBi+pale_green3             = RGBi 0x7c 0xcd 0x7c++pale_green4             :: RGBi+pale_green4             = RGBi 0x54 0x8b 0x54++pale_turquoise1         :: RGBi+pale_turquoise1         = RGBi 0xbb 0xff 0xff++pale_turquoise2         :: RGBi+pale_turquoise2         = RGBi 0xae 0xee 0xee++pale_turquoise3         :: RGBi+pale_turquoise3         = RGBi 0x96 0xcd 0xcd++pale_turquoise4         :: RGBi+pale_turquoise4         = RGBi 0x66 0x8b 0x8b++pale_violet_red1        :: RGBi+pale_violet_red1        = RGBi 0xff 0x82 0xab++pale_violet_red2        :: RGBi+pale_violet_red2        = RGBi 0xee 0x79 0x9f++pale_violet_red3        :: RGBi+pale_violet_red3        = RGBi 0xcd 0x68 0x89++pale_violet_red4        :: RGBi+pale_violet_red4        = RGBi 0x8b 0x47 0x5d++peach_puff1             :: RGBi+peach_puff1             = RGBi 0xff 0xda 0xb9++peach_puff2             :: RGBi+peach_puff2             = RGBi 0xee 0xcb 0xad++peach_puff3             :: RGBi+peach_puff3             = RGBi 0xcd 0xaf 0x95++peach_puff4             :: RGBi+peach_puff4             = RGBi 0x8b 0x77 0x65++pink1                   :: RGBi+pink1                   = RGBi 0xff 0xb5 0xc5++pink2                   :: RGBi+pink2                   = RGBi 0xee 0xa9 0xb8++pink3                   :: RGBi+pink3                   = RGBi 0xcd 0x91 0x9e++pink4                   :: RGBi+pink4                   = RGBi 0x8b 0x63 0x6c++plum1                   :: RGBi+plum1                   = RGBi 0xff 0xbb 0xff++plum2                   :: RGBi+plum2                   = RGBi 0xee 0xae 0xee++plum3                   :: RGBi+plum3                   = RGBi 0xcd 0x96 0xcd++plum4                   :: RGBi+plum4                   = RGBi 0x8b 0x66 0x8b++purple1                 :: RGBi+purple1                 = RGBi 0x9b 0x30 0xff++purple2                 :: RGBi+purple2                 = RGBi 0x91 0x2c 0xee++purple3                 :: RGBi+purple3                 = RGBi 0x7d 0x26 0xcd++purple4                 :: RGBi+purple4                 = RGBi 0x55 0x1a 0x8b++red1                    :: RGBi+red1                    = RGBi 0xff 0x00 0x00++red2                    :: RGBi+red2                    = RGBi 0xee 0x00 0x00++red3                    :: RGBi+red3                    = RGBi 0xcd 0x00 0x00++red4                    :: RGBi+red4                    = RGBi 0x8b 0x00 0x00++rosy_brown1             :: RGBi+rosy_brown1             = RGBi 0xff 0xc1 0xc1++rosy_brown2             :: RGBi+rosy_brown2             = RGBi 0xee 0xb4 0xb4++rosy_brown3             :: RGBi+rosy_brown3             = RGBi 0xcd 0x9b 0x9b++rosy_brown4             :: RGBi+rosy_brown4             = RGBi 0x8b 0x69 0x69++royal_blue1             :: RGBi+royal_blue1             = RGBi 0x48 0x76 0xff++royal_blue2             :: RGBi+royal_blue2             = RGBi 0x43 0x6e 0xee++royal_blue3             :: RGBi+royal_blue3             = RGBi 0x3a 0x5f 0xcd++royal_blue4             :: RGBi+royal_blue4             = RGBi 0x27 0x40 0x8b+++salmon1                 :: RGBi+salmon1                 = RGBi 0xff 0x8c 0x69++salmon2                 :: RGBi+salmon2                 = RGBi 0xee 0x82 0x62++salmon3                 :: RGBi+salmon3                 = RGBi 0xcd 0x70 0x54++salmon4                 :: RGBi+salmon4                 = RGBi 0x8b 0x4c 0x39++sea_green1              :: RGBi+sea_green1              = RGBi 0x54 0xff 0x9f++sea_green2              :: RGBi+sea_green2              = RGBi 0x4e 0xee 0x94++sea_green3              :: RGBi+sea_green3              = RGBi 0x43 0xcd 0x80++sea_green4              :: RGBi+sea_green4              = RGBi 0x2e 0x8b 0x57++seashell1               :: RGBi+seashell1               = RGBi 0xff 0xf5 0xee++seashell2               :: RGBi+seashell2               = RGBi 0xee 0xe5 0xde++seashell3               :: RGBi+seashell3               = RGBi 0xcd 0xc5 0xbf++seashell4               :: RGBi+seashell4               = RGBi 0x8b 0x86 0x82++sienna1                 :: RGBi+sienna1                 = RGBi 0xff 0x82 0x47++sienna2                 :: RGBi+sienna2                 = RGBi 0xee 0x79 0x42++sienna3                 :: RGBi+sienna3                 = RGBi 0xcd 0x68 0x39++sienna4                 :: RGBi+sienna4                 = RGBi 0x8b 0x47 0x26++sky_blue1               :: RGBi+sky_blue1               = RGBi 0x87 0xce 0xff++sky_blue2               :: RGBi+sky_blue2               = RGBi 0x7e 0xc0 0xee++sky_blue3               :: RGBi+sky_blue3               = RGBi 0x6c 0xa6 0xcd++sky_blue4               :: RGBi+sky_blue4               = RGBi 0x4a 0x70 0x8b++slate_blue1             :: RGBi+slate_blue1             = RGBi 0x83 0x6f 0xff++slate_blue2             :: RGBi+slate_blue2             = RGBi 0x7a 0x67 0xee++slate_blue3             :: RGBi+slate_blue3             = RGBi 0x69 0x59 0xcd++slate_blue4             :: RGBi+slate_blue4             = RGBi 0x47 0x3c 0x8b++slate_gray1             :: RGBi+slate_gray1             = RGBi 0xc6 0xe2 0xff++slate_gray2             :: RGBi+slate_gray2             = RGBi 0xb9 0xd3 0xee++slate_gray3             :: RGBi+slate_gray3             = RGBi 0x9f 0xb6 0xcd++slate_gray4             :: RGBi+slate_gray4             = RGBi 0x6c 0x7b 0x8b++snow1                   :: RGBi+snow1                   = RGBi 0xff 0xfa 0xfa++snow2                   :: RGBi+snow2                   = RGBi 0xee 0xe9 0xe9++snow3                   :: RGBi+snow3                   = RGBi 0xcd 0xc9 0xc9++snow4                   :: RGBi+snow4                   = RGBi 0x8b 0x89 0x89++spring_green1           :: RGBi+spring_green1           = RGBi 0x00 0xff 0x7f++spring_green2           :: RGBi+spring_green2           = RGBi 0x00 0xee 0x76++spring_green3           :: RGBi+spring_green3           = RGBi 0x00 0xcd 0x66++spring_green4           :: RGBi+spring_green4           = RGBi 0x00 0x8b 0x45++steel_blue1             :: RGBi+steel_blue1             = RGBi 0x63 0xb8 0xff++steel_blue2             :: RGBi+steel_blue2             = RGBi 0x5c 0xac 0xee++steel_blue3             :: RGBi+steel_blue3             = RGBi 0x4f 0x94 0xcd++steel_blue4             :: RGBi+steel_blue4             = RGBi 0x36 0x64 0x8b++tan1                    :: RGBi+tan1                    = RGBi 0xff 0xa5 0x4f++tan2                    :: RGBi+tan2                    = RGBi 0xee 0x9a 0x49++tan3                    :: RGBi+tan3                    = RGBi 0xcd 0x85 0x3f++tan4                    :: RGBi+tan4                    = RGBi 0x8b 0x5a 0x2b++thistle1                :: RGBi+thistle1                = RGBi 0xff 0xe1 0xff++thistle2                :: RGBi+thistle2                = RGBi 0xee 0xd2 0xee++thistle3                :: RGBi+thistle3                = RGBi 0xcd 0xb5 0xcd++thistle4                :: RGBi+thistle4                = RGBi 0x8b 0x7b 0x8b++tomato1                 :: RGBi+tomato1                 = RGBi 0xff 0x63 0x47++tomato2                 :: RGBi+tomato2                 = RGBi 0xee 0x5c 0x42++tomato3                 :: RGBi+tomato3                 = RGBi 0xcd 0x4f 0x39++tomato4                 :: RGBi+tomato4                 = RGBi 0x8b 0x36 0x26++turquoise1              :: RGBi+turquoise1              = RGBi 0x00 0xf5 0xff++turquoise2              :: RGBi+turquoise2              = RGBi 0x00 0xe5 0xee++turquoise3              :: RGBi+turquoise3              = RGBi 0x00 0xc5 0xcd++turquoise4              :: RGBi+turquoise4              = RGBi 0x00 0x86 0x8b++violet_red1             :: RGBi+violet_red1             = RGBi 0xff 0x3e 0x96++violet_red2             :: RGBi+violet_red2             = RGBi 0xee 0x3a 0x8c++violet_red3             :: RGBi+violet_red3             = RGBi 0xcd 0x32 0x78++violet_red4             :: RGBi+violet_red4             = RGBi 0x8b 0x22 0x52++wheat1                  :: RGBi+wheat1                  = RGBi 0xff 0xe7 0xba++wheat2                  :: RGBi+wheat2                  = RGBi 0xee 0xd8 0xae++wheat3                  :: RGBi+wheat3                  = RGBi 0xcd 0xba 0x96++wheat4                  :: RGBi+wheat4                  = RGBi 0x8b 0x7e 0x66++yellow1                 :: RGBi+yellow1                 = RGBi 0xff 0xff 0x00++yellow2                 :: RGBi+yellow2                 = RGBi 0xee 0xee 0x00++yellow3                 :: RGBi+yellow3                 = RGBi 0xcd 0xcd 0x00++yellow4                 :: RGBi+yellow4                 = RGBi 0x8b 0x8b 0x00++++++
+ src/Wumpus/Drawing/Dots/AnchorDots.hs view
@@ -0,0 +1,280 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE ExistentialQuantification  #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Dots.AnchorDots+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Dots with anchors.+--+-- In many cases a surrounding circle is used to locate anchor+-- points - this could be improved to use the actual dot border +-- at some point.+--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Dots.AnchorDots+  ( ++  -- * Existential anchor type+    DotAnchor+ +  , DotLocImage+  , DDotLocImage++  -- * Dots with anchor points+  , dotChar+  , dotText+  , dotHLine+  , dotVLine+  , dotX+  , dotPlus+  , dotCross+  , dotDiamond+  , dotFDiamond++  , dotDisk+  , dotSquare+  , dotCircle+  , dotPentagon+  , dotStar++  , dotAsterisk+  , dotOPlus+  , dotOCross+  , dotFOCross++  , dotTriangle++  ) where++import Wumpus.Basic.Kernel+import Wumpus.Drawing.Text.LRText+import Wumpus.Drawing.Dots.Marks++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space+++import Control.Applicative++-- An existential thing that supports anchors.+-- This means any dot can retun the same (opaque) structure+--+-- But it does mean that which anchor class are supported is +-- fixed - the datatype needs a field for each one.+-- Supporting north, southeast etc. will also be tedious...+--+data DotAnchor u = forall s.  +                    DotAnchor { center_anchor   :: Point2 u+                              , radial_anchor   :: Radian   -> Point2 u+                              , cardinal_anchor :: Cardinal -> Point2 u }++data Cardinal = NN | NE | EE | SE | SS | SW | WW | NW+  deriving (Eq,Show) ++type instance DUnit (DotAnchor u) = u++instance CenterAnchor (DotAnchor u) where+  center (DotAnchor ca _ _) = ca++instance RadialAnchor (DotAnchor u) where+   radialAnchor theta (DotAnchor _ ra _) = ra theta++instance CardinalAnchor (DotAnchor u) where+   north (DotAnchor _ _ c1) = c1 NN+   south (DotAnchor _ _ c1) = c1 SS+   east  (DotAnchor _ _ c1) = c1 EE+   west  (DotAnchor _ _ c1) = c1 WW++++instance CardinalAnchor2 (DotAnchor u) where+   northeast (DotAnchor _ _ c1) = c1 NE+   southeast (DotAnchor _ _ c1) = c1 SE+   southwest (DotAnchor _ _ c1) = c1 SW+   northwest (DotAnchor _ _ c1) = c1 NW+++radialCardinal :: Floating u => u -> Point2 u -> Cardinal -> Point2 u+radialCardinal rad ctr NN = ctr .+^ (avec (pi/2)     rad) +radialCardinal rad ctr NE = ctr .+^ (avec (pi/4)     rad) +radialCardinal rad ctr EE = ctr .+^ (avec  0         rad) +radialCardinal rad ctr SE = ctr .+^ (avec (7/4 * pi) rad) +radialCardinal rad ctr SS = ctr .+^ (avec (6/4 * pi) rad) +radialCardinal rad ctr SW = ctr .+^ (avec (5/4 * pi) rad) +radialCardinal rad ctr WW = ctr .+^ (avec  pi        rad) +radialCardinal rad ctr NW = ctr .+^ (avec (3/4 * pi) rad) +++-- Rectangle cardinal points are at \"middles and corners\".+--++rectCardinal :: Floating u => u ->  u -> Point2 u -> Cardinal -> Point2 u+rectCardinal _  hh ctr NN = ctr .+^ (vvec hh) +rectCardinal hw hh ctr NE = ctr .+^ (vec  hw     hh) +rectCardinal hw _  ctr EE = ctr .+^ (hvec hw) +rectCardinal hw hh ctr SE = ctr .+^ (vec  hw    (-hh)) +rectCardinal _  hh ctr SS = ctr .+^ (vvec (-hh)) +rectCardinal hw hh ctr SW = ctr .+^ (vec  (-hw) (-hh) )+rectCardinal hw _  ctr WW = ctr .+^ (hvec (-hw)) +rectCardinal hw hh ctr NW = ctr .+^ (vec  (-hw)  hh) ++polyCardinal :: Floating u => (Radian -> Point2 u) -> Cardinal -> Point2 u+polyCardinal f NN = f (0.5  * pi)+polyCardinal f NE = f (0.25 * pi) +polyCardinal f EE = f 0 +polyCardinal f SE = f (1.75 * pi) +polyCardinal f SS = f (1.5  * pi) +polyCardinal f SW = f (1.25 * pi)+polyCardinal f WW = f pi +polyCardinal f NW = f (0.75 * pi) ++++rectangleAnchor :: (Real u, Floating u) => u -> u -> Point2 u -> DotAnchor u+rectangleAnchor hw hh ctr = +    DotAnchor { center_anchor   = ctr+              , radial_anchor   = fn  +              , cardinal_anchor = rectCardinal hw hh ctr }+  where+    fn theta =  maybe ctr id $ findIntersect ctr theta +                             $ rectangleLines ctr hw hh+++polygonAnchor :: (Real u, Floating u) => [Point2 u] -> Point2 u -> DotAnchor u+polygonAnchor ps ctr = +    DotAnchor { center_anchor   = ctr+              , radial_anchor   = fn  +              , cardinal_anchor = polyCardinal fn }+  where+    fn theta =  maybe ctr id $ findIntersect ctr theta $ polygonLines ps++++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 -> LocDrawingInfo u (DotAnchor u)+rectangleLDO w h = +    promoteR1 $ \pt -> pure $ rectangleAnchor (w*0.5) (h*0.5) pt+++circleAnchor :: Floating u => u -> Point2 u -> DotAnchor u+circleAnchor rad ctr = DotAnchor ctr +                                 (\theta -> ctr .+^ (avec theta rad))+                                 (radialCardinal rad ctr)++circleLDO :: (Floating u, FromPtSize u) => LocDrawingInfo u (DotAnchor u)+circleLDO = +    promoteR1 $ \pt -> +      markHeight >>= \diam -> pure $ circleAnchor (diam * 0.5) pt+++-- This might be better taking a function: ctr -> poly_points+-- ...+--+polygonLDO :: (Real u, Floating u, FromPtSize u) +           => (u -> Point2 u -> [Point2 u]) -> LocDrawingInfo u (DotAnchor u)+polygonLDO mk = +    promoteR1 $ \ctr -> +      markHeight >>= \h -> let ps = mk h ctr in pure $ polygonAnchor ps ctr+++--------------------------------------------------------------------------------++-- Is this more generally useful?+--+++type DotLocImage u = LocImage u (DotAnchor u) ++type DDotLocImage = DotLocImage Double ++dotChar :: (Floating u, Real u, FromPtSize u) => Char -> DotLocImage u+dotChar ch = dotText [ch]+++-- | Note - dotText now uses font metrics...+--+dotText :: (Floating u, Real u, FromPtSize u) => String -> DotLocImage u +dotText ss = fmap (bimapL bboxRectAnchor) (ctrCenterLine ss)+++dotHLine :: (Floating u, FromPtSize u) => DotLocImage u+dotHLine = intoLocImage circleLDO markHLine+++dotVLine :: (Floating u, FromPtSize u) => DotLocImage u+dotVLine = intoLocImage circleLDO markVLine+++dotX :: (Floating u, FromPtSize u) => DotLocImage u+dotX = intoLocImage circleLDO markX++dotPlus :: (Floating u, FromPtSize u) => DotLocImage u+dotPlus = intoLocImage circleLDO markPlus++dotCross :: (Floating u, FromPtSize u) => DotLocImage u+dotCross = intoLocImage circleLDO markCross++dotDiamond :: (Floating u, FromPtSize u) => DotLocImage u+dotDiamond = intoLocImage circleLDO markDiamond++dotFDiamond :: (Floating u, FromPtSize u) => DotLocImage u+dotFDiamond = intoLocImage circleLDO markFDiamond++++dotDisk :: (Floating u, FromPtSize u) => DotLocImage u+dotDisk = intoLocImage circleLDO markDisk+++dotSquare :: (Floating u, Real u, FromPtSize u) => DotLocImage u+dotSquare = +    lift0R1 markHeight >>= \h -> intoLocImage (rectangleLDO h h) markSquare+++++dotCircle :: (Floating u, FromPtSize u) => DotLocImage u+dotCircle = intoLocImage circleLDO markCircle+++dotPentagon :: (Floating u, FromPtSize u) => DotLocImage u+dotPentagon = intoLocImage circleLDO markPentagon++dotStar :: (Floating u, FromPtSize u) => DotLocImage u+dotStar = intoLocImage circleLDO markStar+++dotAsterisk :: (Floating u, FromPtSize u) => DotLocImage u+dotAsterisk = intoLocImage circleLDO markAsterisk++dotOPlus :: (Floating u, FromPtSize u) => DotLocImage u+dotOPlus = intoLocImage circleLDO markOPlus++dotOCross :: (Floating u, FromPtSize u) => DotLocImage u+dotOCross = intoLocImage circleLDO markOCross++dotFOCross :: (Floating u, FromPtSize u) => DotLocImage u+dotFOCross = intoLocImage circleLDO markFOCross+++dotTriangle :: (Real u, Floating u, FromPtSize u) => DotLocImage u+dotTriangle = intoLocImage (polygonLDO fn) markTriangle+  where +    fn h ctr = let (bl,br,top) = equilateralTrianglePoints h ctr in [bl,br,top]
+ src/Wumpus/Drawing/Dots/Marks.hs view
@@ -0,0 +1,238 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Dots.Marks+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Marks - dots without anchor handles.+--+-- The text and char marks need loaded glyph metrics for proper +-- centering. +--+-- \*\* WARNING \*\* - names are expected to change - filled and+-- background-filled marks need a naming convention.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Dots.Marks+  ( +++  -- * Marks+    markChar+  , markText++  , markHLine+  , markVLine+  , markX+  , markPlus+  , markCross+  , markDiamond+  , markFDiamond+  , markBDiamond +  , markDisk+  , markSquare+  , markCircle  +  , markPentagon+  , markStar+  , markAsterisk+  , markOPlus+  , markOCross+  , markFOCross+  , markTriangle++  ) where+++import Wumpus.Basic.Kernel+import Wumpus.Drawing.Text.LRText++import Wumpus.Core                      -- package: wumpus-core++import Data.AffineSpace                 -- package: vector-space+import Data.VectorSpace++import Control.Applicative++-- Marks should be the height of a lower-case letter...++-- NOTES+--+-- TikZ has both stroked and bordered (filled and outline-stroked)+-- marks e.g. square and square*+--+++++infixr 9 `renderPathWith`++renderPathWith :: LocDrawingInfo u (PrimPath u) +               -> (PrimPath u -> Graphic u) +               -> LocGraphic u+renderPathWith m k = m >>= (lift0R1 . k)++++markChar :: (Real u, Floating u, FromPtSize u) => Char -> LocGraphic u+markChar ch = markText [ch]+++++markText :: (Real u, Floating u, FromPtSize u) => String -> LocGraphic u+markText ss = fmap (replaceL uNil) $ ctrCenterLine ss+++++-- | Supplied point is the center.+--+axialLine :: Fractional u => Vec2 u -> LocGraphic u+axialLine v = moveStartPoint (\ctr -> ctr .-^ (0.5 *^ v)) (straightLine v)+++markHLine :: (Fractional u, FromPtSize u) => LocGraphic u +markHLine = lift0R1 markHeight >>= \h -> axialLine (hvec h)+++markVLine :: (Fractional u, FromPtSize u) => LocGraphic u +markVLine = lift0R1 markHeight >>= \h -> axialLine (vvec h) +++markX :: (Fractional u, FromPtSize u) => LocGraphic u+markX = lift0R1 markHeight >>= mkX +  where+    mkX h = let w = 0.75 * h+              in axialLine (vec w h) `oplus` axialLine (vec (-w) h)++++markPlus :: (Fractional u, FromPtSize u) =>  LocGraphic u+markPlus = markVLine `oplus` markHLine+++markCross :: (Floating u, FromPtSize u) =>  LocGraphic u+markCross = markHeight >>= mkCross+  where+    mkCross h = axialLine (avec ang h) `oplus` axialLine (avec (-ang) h)+    ang       = pi*0.25  ++-- Note - height is extended slightly to look good...++pathDiamond :: (Fractional u, FromPtSize u) +            => LocDrawingInfo u (PrimPath u)+pathDiamond = +    promoteR1 $ \pt -> +      markHeight >>= \h -> pure $ diamondPath (0.5*h) (0.66*h) pt++++-- closedStroke :: (a -> ctx -> prim) +-- pathDiamond  :: (ctx -> pt -> a)+-- ans          :: (ctx -> pt -> prim)++markDiamond :: (Fractional u, FromPtSize u) => LocGraphic u+markDiamond = pathDiamond `renderPathWith` closedStroke++markFDiamond :: (Fractional u, FromPtSize u) => LocGraphic u+markFDiamond = pathDiamond `renderPathWith` filledPath+++-- Note - the (const . fn) composition doesn\'t /tell/ much about+-- what is going on - though obviously it can be decoded - make +-- the function obvious to the second argument. +-- +-- A named combinator might be better.+--++markBDiamond :: (Fractional u, FromPtSize u) => LocGraphic u+markBDiamond = pathDiamond `renderPathWith` borderedPath+++-- | Note disk is filled.+--+markDisk :: (Fractional u, FromPtSize u) => LocGraphic u+markDisk = lift0R1 markHalfHeight >>= filledDisk ++++markSquare :: (Fractional u, FromPtSize u) => LocGraphic u+markSquare = +    lift0R1 markHeight >>= \h -> +    let d = 0.5*(-h) in moveStartPoint (displace d d) $ strokedRectangle h h+    +++markCircle :: (Fractional u, FromPtSize u) => LocGraphic u+markCircle = lift0R1 markHalfHeight >>= strokedDisk +++markBCircle :: (Fractional u, FromPtSize u) => LocGraphic u+markBCircle = lift0R1 markHalfHeight >>= borderedDisk ++++markPentagon :: (Floating u, FromPtSize u) => LocGraphic u+markPentagon = +    promoteR1 $ \pt -> +      markHeight >>= \h -> closedStroke $ vertexPath $ pentagonPath pt (0.5*h)+  where+    pentagonPath pt hh = polygonPoints 5 hh pt++ +++markStar :: (Floating u, FromPtSize u) => LocGraphic u +markStar = lift0R1 markHeight >>= \h -> starLines (0.5*h)++starLines :: Floating u => u -> LocGraphic u+starLines hh = +    promoteR1 $ \ctr -> step $ map (fn ctr) $ polygonPoints 5 hh ctr+  where+    fn p0 p1    = openStroke $ primPath p0 [lineTo p1]+    step (x:xs) = oconcat x xs+    step _      = error "starLines - unreachable"+++markAsterisk :: (Floating u, FromPtSize u) => LocGraphic u+markAsterisk = lift0R1 markHeight >>= asteriskLines++asteriskLines :: Floating u => u -> LocGraphic u+asteriskLines h = lineF1 `oplus` lineF2 `oplus` lineF3+  where+    ang     = (pi*2) / 6+    lineF1  = axialLine (vvec h)+    lineF2  = axialLine (avec ((pi*0.5) + ang)    h)+    lineF3  = axialLine (avec ((pi*0.5) + ang + ang) h)+++markOPlus :: (Fractional u, FromPtSize u) => LocGraphic u+markOPlus = markCircle `oplus` markPlus+++markOCross :: (Floating u, FromPtSize u) => LocGraphic u+markOCross = markCircle `oplus` markCross+++markFOCross :: (Floating u, FromPtSize u) => LocGraphic u+markFOCross = markCross `oplus` markBCircle +++-- bkCircle :: (Fractional u, FromPtSize u) => LocGraphic u+-- bkCircle = disk (fillAttr attr) (0.5*markHeight attr) ++++markTriangle :: (Floating u, FromPtSize u) => LocGraphic u+markTriangle = tripath `renderPathWith` closedStroke+  where+    tripath = promoteR1 $ \pt -> +                markHeight >>= \h -> pure $ equilateralTrianglePath h pt+
+ src/Wumpus/Drawing/Paths.hs view
@@ -0,0 +1,31 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Paths+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Shim import module for Paths.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Paths +  ( ++    module Wumpus.Drawing.Paths.Base+  , module Wumpus.Drawing.Paths.Connectors+  , module Wumpus.Drawing.Paths.Construction+  , module Wumpus.Drawing.Paths.ControlPoints++  ) where++import Wumpus.Drawing.Paths.Base+import Wumpus.Drawing.Paths.Connectors+import Wumpus.Drawing.Paths.Construction+import Wumpus.Drawing.Paths.ControlPoints+
+ src/Wumpus/Drawing/Paths/Base.hs view
@@ -0,0 +1,529 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Paths.Base+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Extended path type - more amenable for complex drawings than+-- the type in Wumpus-Core.+--+-- \*\* WARNING \*\* this module is an experiment, and may +-- change significantly or even be dropped from future revisions.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Paths.Base+  ( ++    Path+  , DPath+  , length+  , append+  , pconcat+  , line+  , curve+  , pivot+  , traceLinePoints+  , traceCurvePoints+  , curveByAngles++  , toPrimPath ++  , tipL+  , tipR++  , shortenBoth+  , shortenL+  , shortenR+  , directionL+  , directionR++  , midway+  , midway_+  , atstart+  , atstart_+  , atend+  , atend_++  , PathViewL(..)+  , DPathViewL+  , PathViewR(..)+  , DPathViewR+  , PathSegment(..)+  , DPathSegment+  , pathViewL+  , pathViewR++  ) where+++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace+import Data.VectorSpace++import Data.List ( foldl' ) +import Data.Sequence ( Seq, (><), ViewL(..), viewl+                     , ViewR(..), viewr, (<|) , (|>) )+import qualified Data.Sequence as S++import Prelude hiding ( length )++data Path u = Path { _path_length   :: u +                   , _path_start    :: Point2 u+                   , _path_elements :: Seq (PathSeg u)+                   , _path_end      :: Point2 u+                   }+  deriving (Eq,Ord,Show)++type DPath = Path Double++-- Annotating each segment with length is \*\* good \*\*.+-- Makes it much more efficient to find the midway point.+--+-- But what do we do about the start point:+--+-- a) put it in the segment - too much info in the type, allows +-- consistency problems vis-a-vis gaps in the path.+--+-- b) leave it out - too little info in the type, allows +-- consistency problems with length.+--+-- Option (a) is probably most convenient espcially as the +-- constructors won\'t be exported.++-- Annotation is length...+-- +data PathSeg u = LineSeg  { _line_length  :: u +                          , _line_start   :: Point2 u+                          , _line_end     :: Point2 u+                          }+               | CurveSeg { _curve_length :: u +                          , _curve_start  :: Point2 u+                          , _ctrl_pt_one  :: Point2 u+                          , _ctrl_pt_two  :: Point2 u+                          , _curve_end    :: Point2 u+                          }+  deriving (Eq,Ord,Show)+++type instance DUnit (Path u)    = u+type instance DUnit (PathSeg u) = u+++infixr 1 `append`++length :: Num u => Path u -> u+length (Path u _ _ _) = u++append :: Floating u => Path u -> Path u -> Path u+append (Path len1 start1 se1 end1) (Path len2 start2 se2 end2) +    | end1 == start2 = Path (len1+len2) start1 (se1 >< se2) end2 +    | otherwise      = let join      = lineSegment end1 start2+                           total_len = len1 + len2 + segmentLength join+                       in Path total_len start1 (se1 >< (join <| se2)) end2 ++pconcat :: Floating u => Path u -> [Path u] -> Path u+pconcat p0 ps = foldl' append p0 ps++segmentLength :: PathSeg u -> u+segmentLength (LineSeg u _ _)       = u+segmentLength (CurveSeg u _ _ _ _)  = u+++segmentStart :: PathSeg u -> Point2 u+segmentStart (LineSeg  _ p0 _)      = p0+segmentStart (CurveSeg _ p0 _ _ _)  = p0++segmentEnd :: PathSeg u -> Point2 u+segmentEnd (LineSeg  _ _ p1)        = p1+segmentEnd (CurveSeg _ _ _ _ p3)    = p3+++++lineSegment :: Floating u => Point2 u -> Point2 u -> PathSeg u +lineSegment p0 p1 = let v = vlength $ pvec p0 p1 in LineSeg v p0 p1++line :: Floating u => Point2 u -> Point2 u -> Path u +line p0 p1 = let v = vlength $ pvec p0 p1 +             in Path v p0 (S.singleton $ LineSeg v p0 p1) p1+   ++curve :: (Floating u, Ord u)+      => Point2 u -> Point2 u -> Point2 u -> Point2 u -> Path u +curve p0 p1 p2 p3 = let v = curveLength p0 p1 p2 p3+                    in Path v p0 (S.singleton $ CurveSeg v p0 p1 p2 p3) p3++-- | A draw a /straight line/ of length 0 at the supplied point. +--+-- This is /might/ be useful in concatenating curved paths+-- as it introduces and extra control point.+-- +pivot :: Floating u => Point2 u -> Path u +pivot p0 = Path 0 p0 (S.singleton $ LineSeg 0 p0 p0) p0+++-- | 'traceLinePoints' throws a runtime error if the supplied list+-- is empty. +--+traceLinePoints :: Floating u => [Point2 u] -> Path u+traceLinePoints []       = error "traceLinePoints - empty point list."+traceLinePoints [a]      = line a a+traceLinePoints (a:b:xs) = step (line a b) b xs+  where+    step acc _ []     = acc+    step acc e (y:ys) = step (acc `append` line e y) y ys+++-- | 'traceCurvePoints' consumes 4 points from the list on the +-- intial step (start, control1, control2, end) then steps +-- through the list taking 3 points at a time thereafter+-- (control1,control2, end). Leftover points are discarded.    +-- +-- 'traceCurvePoints' throws a runtime error if the supplied list+-- is has less than 4 elements (start, control1, control2, end). +--+traceCurvePoints :: (Floating u, Ord u) => [Point2 u] -> Path u+traceCurvePoints (a:b:c:d:xs) = step (curve a b c d) d xs+  where+    step acc p0 (x:y:z:zs) = step (acc `append` curve p0 x y z) z zs+    step acc _  _          = acc++traceCurvePoints _            = error "tracePointsCurve - less than 4 elems."+++curveByAngles :: (Floating u, Ord u) +              => Point2 u -> Radian -> Radian -> Point2 u -> Path u+curveByAngles start cin cout end = curve start (start .+^ v1) (end .+^ v2) end+  where+    sz     = 0.375 * (vlength $ pvec start end)+    v1     = avec cin  sz+    v2     = avec cout sz++++-- | Turn a Path into an ordinary PrimPath.+--+-- Assumes path is properly formed - i.e. end point of one +-- segment is the same point as the start point of the next+-- segment.+--+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 +                                    primPath start $ a : step2 (viewl se)++    step2 EmptyL                  = []+    step2 (e :< se)               = seg2 e : step2 (viewl se)+    +    seg1 (LineSeg  _ p0 p1)       = (p0, lineTo p1)+    seg1 (CurveSeg _ p0 p1 p2 p3) = (p0, curveTo p1 p2 p3)+ +    seg2 (LineSeg  _ _  p1)       = lineTo p1+    seg2 (CurveSeg _ _  p1 p2 p3) = curveTo p1 p2 p3++++--------------------------------------------------------------------------------+-- Curve length++data StrictCurve u = Curve !(Point2 u) !(Point2 u) !(Point2 u) !(Point2 u)++curveLength :: (Floating u, Ord u)      +            => Point2 u -> Point2 u -> Point2 u -> Point2 u -> u+curveLength p0 p1 p2 p3 = gravesenLength 0.1 $ Curve p0 p1 p2 p3+++-- | Jens Gravesen\'s bezier arc-length approximation. +--+-- Note this implementation is parametrized on error tolerance.+--+gravesenLength :: (Floating u, Ord u) => u -> StrictCurve u -> u+gravesenLength err_tol crv = step crv where+  step c = let l1 = ctrlPolyLength c+               l0 = cordLength c+           in if   l1-l0 > err_tol+              then let (a,b) = subdivide c in step a + step b+              else 0.5*l0 + 0.5*l1+++ctrlPolyLength :: Floating u => StrictCurve u -> u+ctrlPolyLength (Curve p0 p1 p2 p3) = len p0 p1 + len p1 p2 + len p2 p3+  where+    len pa pb = vlength $ pvec pa pb++cordLength :: Floating u => StrictCurve u -> u+cordLength (Curve p0 _ _ p3) = vlength $ pvec p0 p3+++-- | mid-point between two points+--+pointMidpoint :: Fractional u => Point2 u -> Point2 u -> Point2 u+pointMidpoint p0 p1 = p0 .+^ v1 ^/ 2 where v1 = p1 .-. p0+++-- | Curve subdivision via de Casteljau\'s algorithm.+--+subdivide :: Fractional u +          => StrictCurve u -> (StrictCurve u, StrictCurve u)+subdivide (Curve p0 p1 p2 p3) =+    (Curve p0 p01 p012 p0123, Curve p0123 p123 p23 p3)+  where+    p01   = pointMidpoint p0    p1+    p12   = pointMidpoint p1    p2+    p23   = pointMidpoint p2    p3+    p012  = pointMidpoint p01   p12+    p123  = pointMidpoint p12   p23+    p0123 = pointMidpoint p012  p123++-- | subdivide with an affine weight along the line...+--+subdividet :: Real u+           => u -> StrictCurve u -> (StrictCurve u, StrictCurve u)+subdividet t (Curve p0 p1 p2 p3) = +    (Curve p0 p01 p012 p0123, Curve p0123 p123 p23 p3)+  where+    p01   = affineCombination t p0    p1+    p12   = affineCombination t p1    p2+    p23   = affineCombination t p2    p3+    p012  = affineCombination t p01   p12+    p123  = affineCombination t p12   p23+    p0123 = affineCombination t p012  p123++affineCombination :: Real u => u -> Point2 u -> Point2 u -> Point2 u+affineCombination a p1 p2 = p1 .+^ a *^ (p2 .-. p1)++--------------------------------------------------------------------------------+-- tips ++tipL :: Path u -> Point2 u+tipL (Path _ sp _ _) = sp+++tipR :: Path u -> Point2 u+tipR (Path _ _ _ ep) = ep+++-- | Shorten both ends...+--+-- u should be less-than half the path length+--+shortenBoth :: (Real u, Floating u) => u -> Path u -> Path u+shortenBoth u p = shortenL u $ shortenR u p++--------------------------------------------------------------------------------+-- shorten from the left...++-- | Note - shortening a line from the left by +-- greater-than-or-equal its length is operationally equivalent +-- to making a zero-length line at the end point.+--+shortenL :: (Real u, Floating u) => u -> Path u -> Path u+shortenL n (Path u _ segs ep) +    | n >= u                  = line ep ep+    | otherwise               = step n (viewl segs)+  where+    step _ EmptyL     = line ep ep      -- should be unreachable+    step d (e :< se)  = let z  = segmentLength e in+                        case compare d z of+                          GT -> step (d-z) (viewl se)+                          EQ -> makeLeftPath (u-n) se ep+                          LT -> let e1 = shortenSegL d e+                                in Path (u-n) (segmentStart e1) (e1 <| se) ep+++makeLeftPath :: Floating u => u -> Seq (PathSeg u) -> Point2 u -> Path u+makeLeftPath u se ep = +    case viewl se of+      EmptyL   -> line ep ep+      (e :< _) -> Path u (segmentStart e) se ep+++shortenSegL :: (Real u, Floating u) => u -> PathSeg u -> PathSeg u+shortenSegL n (LineSeg  u p0 p1)        = +    LineSeg  (u-n) (shortenLineL n p0 p1) p1++shortenSegL n (CurveSeg u p0 p1 p2 p3)  = +    let (Curve p0' p1' p2' p3') = snd $ subdividet (n/u) (Curve p0 p1 p2 p3)+    in CurveSeg (u-n) p0' p1' p2' p3'+++shortenLineL :: (Real u, Floating u) +             => u -> Point2 u -> Point2 u -> Point2 u+shortenLineL n p0 p1 = p0 .+^ v+  where+    v0 = p1 .-. p0+    v  = avec (direction v0) n++++--------------------------------------------------------------------------------+-- shorten from the right ...+ +-- | Note - shortening a line from the right by +-- greater-than-or-equal its length is operationally equivalent +-- to making a zero-length line at the start point.+--+shortenR :: (Real u, Floating u) => u -> Path u -> Path u+shortenR n (Path u sp segs _) +    | n >= u                  = line sp sp+    | otherwise               = step n (viewr segs)+  where+    step _ EmptyR     = line sp sp      -- should be unreachable+    step d (se :> e)  = let z = segmentLength e in+                        case compare d z of+                          GT -> step (d-z) (viewr se)+                          EQ -> makeRightPath n sp se+                          LT -> let e1 = shortenSegR d e+                                in Path (u-n) sp (se |> e1) (segmentEnd e1)+                         ++makeRightPath :: Floating u => u -> Point2 u -> Seq (PathSeg u) -> Path u+makeRightPath u sp se = +    case viewr se of+      EmptyR   -> line sp sp+      (_ :> e) -> Path u sp se (segmentEnd e)++++shortenSegR :: (Real u, Floating u) => u -> PathSeg u -> PathSeg u+shortenSegR n (LineSeg  u p0 p1)        = +    LineSeg  (u-n) p0 (shortenLineR n p0 p1) ++shortenSegR n (CurveSeg u p0 p1 p2 p3)  = +    let (Curve p0' p1' p2' p3') = fst $ subdividet ((u-n)/u) (Curve p0 p1 p2 p3)+    in CurveSeg (u-n) p0' p1' p2' p3'+++shortenLineR :: (Real u, Floating u) +             => u -> Point2 u -> Point2 u -> Point2 u+shortenLineR n p0 p1 = p1 .+^ v+  where+    v0 = p0 .-. p1+    v  = avec (direction v0) n+++++--------------------------------------------------------------------------------+-- line direction++-- | Direction of empty path is considered to be 0.+--+directionL :: (Real u, Floating u) => Path u -> Radian+directionL (Path _ _ se _)  = step $ viewl se+  where+    step (LineSeg  _ p0 p1 :< _)      = lineDirection p1 p0  -- 1-to-0+    step (CurveSeg _ p0 p1 _ _ :< _)  = lineDirection p1 p0+    step _                            = 0       -- should be unreachable+++-- | Direction of empty path is considered to be 0.+--+directionR :: (Real u, Floating u) => Path u -> Radian+directionR (Path _ _ se _) = step $ viewr se+  where+    step (_ :> LineSeg  _ p0 p1)      = lineDirection p0 p1+    step (_ :> CurveSeg _ _  _ p2 p3) = lineDirection p2 p3+    step _                            = 0       -- should be unreachable             +++++--------------------------------------------------------------------------------+++-- Return direction as well because the calculation is expensive...+--+midway :: (Real u, Floating u) => Path u -> (Point2 u, Radian)+midway pa@(Path u sp _ _) +    | u == 0    = (sp,0)+    | otherwise = let pa1 = shortenR (u/2) pa in (tipR pa1, directionR pa1)++-- Just the midway point.+--+midway_ :: (Real u, Floating u) => Path u -> Point2 u+midway_ = fst . midway+++atstart :: (Real u, Floating u) => Path u -> (Point2 u, Radian)+atstart pa@(Path _ sp _ _) = (sp, directionL pa)++atstart_ :: Path u -> Point2 u+atstart_ (Path _ sp _ _) = sp+++atend :: (Real u, Floating u) => Path u -> (Point2 u, Radian)+atend pa@(Path _ _ _ ep) = (ep, directionR pa)+ ++atend_ :: Path u -> Point2 u+atend_ (Path _ _ _ ep) = ep+++-- nearstart, nearend, verynear ...+++--------------------------------------------------------------------------------++data PathViewL u = PathOneL (PathSegment u)+                 | PathSegment u :<< Path u+  deriving (Eq,Ord,Show) ++type DPathViewL = PathViewL Double++data PathViewR u = PathOneR (PathSegment u)+                 | Path u :>> PathSegment u+  deriving (Eq,Ord,Show) ++type DPathViewR = PathViewR Double+++data PathSegment u = Line1  (Point2 u) (Point2 u)+                   | Curve1 (Point2 u) (Point2 u) (Point2 u) (Point2 u)+  deriving (Eq,Ord,Show) ++type DPathSegment = PathSegment Double++type instance DUnit (PathViewL u)   = u+type instance DUnit (PathViewR u)   = u+type instance DUnit (PathSegment u) = u++pathViewL :: Num u => Path u -> PathViewL u+pathViewL (Path u _ segs ep) = go (viewl segs)+  where+    go EmptyL                   = error "pathViewL - (not) unreachable."+     +    go (LineSeg v p0 p1 :< se)+        | S.null se             = PathOneL (Line1 p0 p1)+        | otherwise             = Line1 p0 p1 :<< Path (u-v) p1 se ep++    go (CurveSeg v p0 p1 p2 p3 :< se) +        | S.null se             = PathOneL (Curve1 p0 p1 p2 p3)+        | otherwise             = Curve1 p0 p1 p2 p3 :<< Path (u-v) p3 se ep+++pathViewR :: Num u => Path u -> PathViewR u+pathViewR (Path u _ segs ep) = go (viewr segs)+  where+    go EmptyR                   = error "pathViewR - (not) unreachable."++    go (se :> LineSeg v p0 p1) +        | S.null se             = PathOneR (Line1 p0 p1)+        | otherwise             = Path (u-v) p1 se ep :>> Line1 p0 p1++    go (se :> CurveSeg v p0 p1 p2 p3) +        | S.null se             = PathOneR (Curve1 p0 p1 p2 p3)+        | otherwise             = Path (u-v) p3 se ep :>> Curve1 p0 p1 p2 p3+
+ src/Wumpus/Drawing/Paths/Connectors.hs view
@@ -0,0 +1,206 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Paths.Connectors+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Library of connector paths...+--+-- \*\* WARNING \*\* this module is experimental and may change +-- significantly in future revisions.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Paths.Connectors +  ( ++    ConnectorPath+  , DConnectorPath++  , connLine++  , connRightVH+  , connRightHV+  , connRightVHV+  , connRightHVH++  , connIsosceles+  , connIsosceles2+  , connLightningBolt+++  , connIsoscelesCurve+  , connSquareCurve+  , connUSquareCurve++  , connTrapezoidCurve+  , connZSquareCurve+  , connUZSquareCurve++  ) where++import Wumpus.Drawing.Paths.Base+import Wumpus.Drawing.Paths.ControlPoints++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space++import Prelude hiding ( length )++++type ConnectorPath u = Point2 u -> Point2 u -> Path u++type DConnectorPath = ConnectorPath Double++--------------------------------------------------------------------------------++-- | Connect with a straight line.+--+connLine :: Floating u => ConnectorPath u+connLine = line++-- | Right-angled connector - go vertical, then go horizontal.+--+connRightVH :: Floating u => ConnectorPath u+connRightVH p1@(P2 x1 _) p2@(P2 _ y2) = +    let mid = P2 x1 y2 in traceLinePoints [p1, mid, p2]++-- | Right-angled connector - go horizontal, then go vertical.+--+connRightHV :: Floating u => ConnectorPath u+connRightHV p1@(P2 _ y1) p2@(P2 x2 _) = +    let mid = P2 x2 y1 in traceLinePoints [p1, mid, p2]++-- | Right-angled connector - go vertical for the supplied +-- distance, go horizontal, go vertical again for the +-- remaining distance.+-- +connRightVHV :: Floating u => u -> ConnectorPath u+connRightVHV v p1@(P2 x1 _) p2@(P2 x2 _) = traceLinePoints [p1, a1, a2, p2]+  where+    a1 = p1 .+^ vvec v+    a2 = a1 .+^ hvec (x2 - x1)+++-- | Right-angled connector - go horizontal for the supplied +-- distance, go verical, go horizontal again for the +-- remaining distance.+-- +connRightHVH :: Floating u => u -> ConnectorPath u+connRightHVH h p1@(P2 _ y1) p2@(P2 _ y2) = traceLinePoints [p1,a1,a2,p2]+  where+    a1 = p1 .+^ hvec h+    a2 = a1 .+^ vvec (y2 - y1)+++-- | /Triangular/ joint.+-- +-- @u@ is the altitude of the triangle.+--+connIsosceles :: (Real u, Floating u) => u -> ConnectorPath u +connIsosceles dy p1 p2 = traceLinePoints [p1, mid_pt, p2]+  where+    mid_pt  = midpointIsosceles dy p1 p2++++-- | Double /triangular/ joint.+-- +-- @u@ is the altitude of the triangle.+--+connIsosceles2 :: (Real u, Floating u) => u -> ConnectorPath u +connIsosceles2 u p1 p2 = traceLinePoints [ p1, cp1, cp2, p2 ]+  where+    (cp1,cp2) = dblpointIsosceles u p1 p2+++-- | /Lightning bolt/ joint - a two joint connector with an /axis/+-- perpendicular to the connector direction.+-- +-- @u@ is the half length of the of the axis.+--+connLightningBolt :: (Real u, Floating u) => u -> ConnectorPath u +connLightningBolt u p1 p2 = traceLinePoints [ p1, cp1, cp2, p2 ]+  where+    cp1 = midpointIsosceles   u  p1 p2+    cp2 = midpointIsosceles (-u) p1 p2++--------------------------------------------------------------------------------++++-- | Form a curve inside an isosceles triangle. +--+-- The two Bezier control points take the same point - the+-- altitude of the triangle. The curve tends to be quite shallow+-- relative to the altitude.+--+-- @u@ is the altitude of the triangle.+--+connIsoscelesCurve :: (Real u, Floating u) => u -> ConnectorPath u +connIsoscelesCurve u p1 p2 = traceCurvePoints [p1, control_pt, control_pt, p2]+  where+    control_pt  = midpointIsosceles u p1 p2+    +++-- | Form a curve inside a square. +--+-- The two Bezier control points take the /top/ corners. The+-- curve tends to be very deep.+-- +connSquareCurve :: (Real u, Floating u) => ConnectorPath u +connSquareCurve p1 p2 = traceCurvePoints [p1, cp1, cp2, p2]+  where+    (cp1,cp2) = squareFromBasePoints p1 p2++-- | Form a curve inside a square. +--+-- As per 'connSquareCurve' but the curve is drawn /underneath/+-- the line formed between the start and end points.+-- +-- (Underneath is modulo the direction, of course).+-- +connUSquareCurve :: (Real u, Floating u) => ConnectorPath u +connUSquareCurve p1 p2 = traceCurvePoints [p1, cp1, cp2, p2]+  where+    (cp1,cp2) = usquareFromBasePoints p1 p2++++-- | altitude * ratio_to_base +--+-- Form a curve inside a trapeziod.+-- +connTrapezoidCurve :: (Real u, Floating u) => u -> u -> ConnectorPath u +connTrapezoidCurve u ratio_to_base p1 p2 = traceCurvePoints [p1, cp1, cp2, p2]+  where+    (cp1,cp2)  = trapezoidFromBasePoints u ratio_to_base p1 p2+++-- | Make a curve within a square, following the corner points as+-- a Z.+--+connZSquareCurve :: (Real u, Floating u) => ConnectorPath u +connZSquareCurve p1 p2 = traceCurvePoints [p1,cp1,cp2,p2]+   where+     (cp1,cp2)  = squareFromCornerPoints p1 p2 +      +-- | Make a curve within a square, following the corner points as+-- a Z.+--+-- The order of tracing flips the control points, so this is an+-- /underneath/ version of 'connZSquareCurve'.+-- +connUZSquareCurve :: (Real u, Floating u) => ConnectorPath u +connUZSquareCurve p1 p2 = traceCurvePoints [p1,cp2,cp1,p2]+   where+     (cp1,cp2)  = squareFromCornerPoints p1 p2 
+ src/Wumpus/Drawing/Paths/Construction.hs view
@@ -0,0 +1,160 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Paths.Construction+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Build paths monadically.+--+-- \*\* WARNING \*\* this module is an experiment, and may +-- change significantly or even be dropped from future revisions.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Paths.Construction+  ( ++    PathM+  , runPath+  , execPath++  , tip++  , lineto+  , rlineto+  , hline+  , vline++  , bezierto+  , curveto++  , verticalHorizontal+  , horizontalVertical++  ) where++import Wumpus.Basic.Utils.HList+import Wumpus.Drawing.Paths.Base++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space++import Control.Applicative+import Data.List+++-- Are connectors and paths quite different things?+--+-- It looks like they are - connectors always know start and end +-- points.+--+++-- State monad version is quite good - it ameliorates the problem+-- of joining to the end point of an empty path...++data St u = St+      { current_point :: Point2 u +      , path_acc      :: H (Path u)+      }+++newtype PathM u a = PathM { getPathM :: St u -> (a,St u) }+++instance Functor (PathM u) where+  fmap f mf = PathM $ \s -> let (a,s1) = getPathM mf s in (f a,s1)+++instance Applicative (PathM u) where+  pure a    = PathM $ \s -> (a,s)+  mf <*> ma = PathM $ \s -> let (f,s1) = getPathM mf s+                                (a,s2) = getPathM ma s1+                            in (f a,s2)++instance Monad (PathM u) where+  return a  = PathM $ \s -> (a,s)+  m >>= k   = PathM $ \s -> let (a,s1) = getPathM m s in+                            (getPathM . k) a s1++++-- Running the path is (probably) agnostic to the DrawingCtx.+--+runPath :: Floating u => Point2 u -> PathM u a -> (a, Path u)+runPath start mf = +    let (a,s') = getPathM mf s in (a, post $ toListH $ path_acc s')+  where+    s = St { current_point = start+           , path_acc      = emptyH+           }+    post []     = line start start+    post (x:xs) = foldl' append x xs  ++execPath :: Floating u => Point2 u -> PathM u a -> Path u+execPath start mf = snd $ runPath start mf++snocline :: Floating u => Vec2 u -> PathM u ()+snocline v = PathM $ \(St pt ac) -> let ep = pt .+^ v +                                    in ((), St ep (ac `snocH` line pt ep))+++tip :: PathM u (Point2 u)+tip = PathM $ \s -> (current_point s,s)+++lineto :: Floating u => Point2 u -> PathM u ()+lineto pt = PathM $ \(St p0 ac) -> ((), St pt (ac `snocH` line p0 pt))++rlineto :: Floating u => Vec2 u -> PathM u ()+rlineto (V2 dx dy) = tip >>= \(P2 x y) -> lineto (P2 (x+dx) (y+dy))+++hline :: Floating u => u -> PathM u ()+hline len = snocline (hvec len) ++vline :: Floating u => u -> PathM u ()+vline len = snocline (vvec len) ++++bezierto :: (Floating u, Ord u) +         => Point2 u -> Point2 u -> Point2 u -> PathM u ()+bezierto c1 c2 ep = PathM $ \(St p0 ac) -> +    ((), St ep (ac `snocH` curve p0 c1 c2 ep))++++++--+++curveto :: (Floating u, Ord u) +        => Radian -> Radian -> Point2 u -> PathM u ()+curveto cin cout end = PathM $ \(St p0 ac) -> +    let seg  = curveByAngles p0 cin cout end +        ac1  = ac `snocH` seg+        end1 = tipR seg+    in ((), St end1 ac1) +++++verticalHorizontal :: Floating u => Point2 u -> PathM u ()+verticalHorizontal (P2 x y) = +    tip >>= \(P2 x0 _) -> lineto (P2 x0 y) >> lineto (P2 x y)++horizontalVertical :: Floating u => Point2 u -> PathM u ()+horizontalVertical (P2 x y) = +    tip >>= \(P2 _ y0) -> lineto (P2 x y0) >> lineto (P2 x y)+
+ src/Wumpus/Drawing/Paths/ControlPoints.hs view
@@ -0,0 +1,189 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Paths.ControlPoints+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Collection of point manufacturing functions.+--+-- \*\* WARNING \*\* this module is experimental and may change +-- significantly in future revisions.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Paths.ControlPoints+  ( ++    midpointIsosceles+  , dblpointIsosceles++  , rectangleFromBasePoints+  , squareFromBasePoints+  , usquareFromBasePoints++  , trapezoidFromBasePoints++  , squareFromCornerPoints++  ) where++import Wumpus.Basic.Kernel++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space+++++-- | 'midpointIsosceles' : +-- @ altitude * start_pt * end_pt -> mid_pt @+--+-- Triangular midpoint.+-- +-- @u@ is the altitude of the triangle - negative values of u +-- form the triangle below the line.+--+midpointIsosceles :: (Real u, Floating u) +                  => u -> Point2 u -> Point2 u -> Point2 u+midpointIsosceles u p1@(P2 x1 y1) p2@(P2 x2 y2) = +    mid_pt .+^ avec perp_ang u+  where+    mid_pt    = P2 (x1 + 0.5*(x2-x1)) (y1 + 0.5*(y2-y1))+    perp_ang  = (pi*0.5) + direction (pvec p1 p2) ++++-- | 'dblpointIsosceles' : +-- @ altitude * start_pt * end_pt * (third_pt, two_thirds_pt) @+-- +-- Double triangular joint - one joint at a third of the line+-- length, the other at two thirds.+-- +dblpointIsosceles :: (Real u, Floating u) +                      => u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)  +dblpointIsosceles u p1@(P2 x1 y1) p2@(P2 x2 y2) = +    (mid1 .+^ avec perp_ang u, mid2 .-^ avec perp_ang u)+  where+    mid1      = P2 (x1 + 0.33*(x2-x1)) (y1 + 0.33*(y2-y1))+    mid2      = P2 (x1 + 0.66*(x2-x1)) (y1 + 0.66*(y2-y1))+    perp_ang  = (pi*0.5) + direction (pvec p1 p2) +++--------------------------------------------------------------------------------++++-- | 'rectangleFromBasePoints' : +-- @ altitude * start_pt * end_pt * (top_left, top_right) @+-- +-- Control points forming a rectangle. +--+-- The two manufactured control points form the top corners, +-- so the supplied points map as @start_point == bottom_left@ and +-- @end_point == bottom_right@.+--+rectangleFromBasePoints :: (Real u, Floating u) +                  => u -> Point2 u -> Point2 u -> (Point2 u, Point2 u)+rectangleFromBasePoints u p1 p2 = (cp1, cp2)+  where+    base_vec  = pvec p1 p2+    theta     = direction base_vec+    cp1       = displacePerpendicular u theta p1+    cp2       = displacePerpendicular u theta p2+++-- | 'squareFromBasePoints' : +-- @ start_pt -> end_pt -> (top_left, top_right) @+-- +-- Control points forming a square - side_len derived from the +-- distance between start and end points.+--+-- The two manufactured control points form the top corners, +-- so the supplied points map as @start_point == bottom_left@ and +-- @end_point == bottom_right@.+--+squareFromBasePoints :: (Real u, Floating u) +                     => Point2 u -> Point2 u -> (Point2 u, Point2 u)+squareFromBasePoints p1 p2 = rectangleFromBasePoints side_len p1 p2+  where+    side_len  = vlength $ pvec p1 p2+++-- | 'usquareFromBasePoints' : +-- @ start_pt -> end_pt -> (bottom_left, bottom_right) @+-- +-- Control points forming a square - side_len derived from the +-- distance between start and end points.+--+-- As per 'squareFromBasePoints' but the square is drawn +-- /underneath/ the line formed between the start and end points.+-- (Underneath is modulo the direction, of course).+--+-- The two manufactured control points form the /bottom/ corners, +-- so the supplied points map as @start_point == top_left@ and +-- @end_point == top_right@.+-- +usquareFromBasePoints :: (Real u, Floating u) +                      => Point2 u -> Point2 u -> (Point2 u, Point2 u)+usquareFromBasePoints p1 p2 = rectangleFromBasePoints side_len p1 p2+  where+    side_len  = negate $ vlength $ pvec p1 p2++++++-- | 'trapezoidFromBasePoints' : +-- @ altitude * ratio_to_base * start_pt * end_pt -> (top_left, top_right) @+--+-- Control points form an isosceles trapezoid.+--+-- The two manufactured control points form the top corners, +-- so the supplied points map as @start_point == bottom_left@ and +-- @end_point == bottom_right@.+-- +trapezoidFromBasePoints :: (Real u, Floating u) +                        => u -> u -> Point2 u -> Point2 u +                        -> (Point2 u, Point2 u) +trapezoidFromBasePoints u ratio_to_base p1 p2 = (cp1, cp2)+  where+    base_vec  = pvec p1 p2+    base_len  = vlength base_vec+    theta     = direction base_vec+    half_ulen = 0.5 * ratio_to_base * base_len+    base_mid  = displaceParallel (0.5 * base_len) theta p1+    ubase_mid = displacePerpendicular u theta base_mid+    cp1       = displaceParallel (-half_ulen) theta ubase_mid+    cp2       = displaceParallel   half_ulen  theta ubase_mid+++++-- | 'squareFromCornerPoints' : +-- @ altitude * start_pt * end_pt * (top_left, bottom_right) @+-- +-- Control points forming a square bisected by the line from +-- start_pt to end_pt. +--+-- The two manufactured control points form the top_left and+-- bottom_right corners, so the supplied points map as +-- @start_point == bottom_left@ and @end_point == top_right@.+--+squareFromCornerPoints :: (Real u, Floating u) +                       => Point2 u -> Point2 u -> (Point2 u, Point2 u) +squareFromCornerPoints p1 p2 = (cp1, cp2)+  where+    base_vec  = pvec p1 p2+    half_len  = 0.5 * (vlength base_vec)+    theta     = direction base_vec+    base_mid  = displaceParallel half_len theta p1+    cp1       = displacePerpendicular   half_len  theta base_mid+    cp2       = displacePerpendicular (-half_len) theta base_mid+
+ src/Wumpus/Drawing/Paths/RoundCorners.hs view
@@ -0,0 +1,120 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Paths.RoundCorners+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Drawing round cornered polygons.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Paths.RoundCorners+  ( +    cornerCurve+  , illustratePath+  , roundEvery++  ) where++import Wumpus.Basic.Kernel+import Wumpus.Drawing.Colour.SVGColours+import Wumpus.Drawing.Paths.Base hiding ( length )+++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space+++-- | The length of the control-point vector wants to be slighly +-- longer than half of /d/ (d - being the distance between the +-- /truncated/ points and the corner).+--+cornerCurve :: (Real u, Floating u) +            => Point2 u -> Point2 u -> Point2 u -> Path u+cornerCurve p1 p2 p3 = curve p1 cp1 cp2 p3+  where+    len1 = 0.6 *  (vlength $ pvec p1 p2)+    len2 = 0.6 *  (vlength $ pvec p3 p2)+    cp1  = p1 .+^ (avec (langle p1 p2) len1)+    cp2  = p3 .+^ (avec (langle p3 p2) len2)+++-- | 'roundEvery' throws a runtime error if the input list has+-- less than 3 eleemnts.+--+roundEvery :: (Real u, Floating u) +           => u -> [Point2 u] -> Path u +roundEvery u (start:b:c:xs) = step (twoParts u start b c) (b:c:xs)+  where+    step acc (m:n:o:ps)     = step (acc `append` twoParts u m n o) (n:o:ps)+    step acc [n,o]          = acc `append` twoParts u n o start+                                  `append` twoParts u o start b +    step acc _              = acc++roundEvery _ _              = error "roundEvery - input list too short."+++-- | Two parts - line and corner curve...+--+twoParts :: (Real u, Floating u) +         => u ->  Point2 u -> Point2 u -> Point2 u -> Path u+twoParts u a b c = line p1 p2 `append` cornerCurve p2 b p3+  where+    p1 = a .+^ (avec (direction $ pvec a b) u)+    p2 = b .+^ (avec (direction $ pvec b a) u)+    p3 = b .+^ (avec (direction $ pvec b c) u)+ +++--------------------------------------------------------------------------------+-- ++-- This needs moving outside of the Path modules as it has +-- dependencies on SVGColour and Graphic (the Path modules should+-- be /neutral/ to wards depenedencies on other parts of +-- Wumpus-Basic).+--++illustratePath :: Fractional u => Path u -> Graphic u+illustratePath = localize (strokeColour black) . step1 . pathViewL+  where+    step1 (PathOneL e)  = drawPath1 e+    step1 (e :<< se)    = drawPathBoth e `oplus` rest (pathViewL se)++    rest (PathOneL e)   = drawPath1 e+    rest (e :<< se)     = drawPath1 e `oplus` rest (pathViewL se)++drawPathBoth :: Fractional u => PathSegment u -> Graphic u+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++drawPath1 (Curve1 p1 p2 p3 p4) =  +    oconcat (bezierCtrl p1 p2) [ bezierCtrl p4 p3, curveBetween p1 p2 p3 p4+                               , 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 `at` p2)+++pathPoint :: Num u => Point2 u -> Graphic u+pathPoint pt = localize bothStrokeColour (filledDisk 1 `at` pt)+
+ src/Wumpus/Drawing/Shapes.hs view
@@ -0,0 +1,27 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Shapes+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Shim module for Shapes.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Shapes+  ( +    module Wumpus.Drawing.Shapes.Base+  , module Wumpus.Drawing.Shapes.Coordinate+  , module Wumpus.Drawing.Shapes.Derived++  ) where++import Wumpus.Drawing.Shapes.Base+import Wumpus.Drawing.Shapes.Coordinate+import Wumpus.Drawing.Shapes.Derived hiding ( mkRectangle )
+ src/Wumpus/Drawing/Shapes/Base.hs view
@@ -0,0 +1,227 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Shapes.Base+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Common core for shapes+-- +-- \*\* WARNING \*\* - the types of Shapes are not ideal and are +-- pending revision.+--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Shapes.Base+  ( +++    Shape+  , LocShape+  , makeShape++  , ShapeConstructor++  , borderedShape+  , filledShape+  , strokedShape++  -- * ShapeCTM +  , ShapeCTM+  , makeShapeCTM++  , ShapeGeom+  , runShapeGeom+  , askCTM+  , projectPoint+  , shapeCenter+  , shapeAngle++  ) where++import Wumpus.Basic.Kernel+import Wumpus.Drawing.Paths++import Wumpus.Core                              -- package: wumpus-core+++import Control.Applicative+++-- Currently shapes that aren\'t paths:+--+-- > Coordinate+-- > FreeLabel+--+-- Alternative +--+-- > out_fun :: ShapeCTM u -> (Path u,sh)+--+-- All shapes expect FreeLabel are oblivious to the +-- DrawingContext for the /shape/+--++newtype ShapeR u a = ShapeR { getShapeR :: ShapeCTM u -> a }++runShapeR :: ShapeCTM u -> ShapeR u a -> a+runShapeR ctm sf = getShapeR sf ctm+++data Shape u t =  Shape +      { shape_ctm   :: ShapeCTM u +      , path_fun    :: ShapeR u (Path u)+      , cons_fun    :: ShapeR u (t u)+      }++type instance DUnit (Shape u sh) = u+++type LocShape u t = Point2 u -> Shape u t++type ShapeConstructor u t = ShapeCTM u -> t u +++makeShape :: Num u +          => (ShapeCTM u -> Path u) -> (ShapeCTM u -> t u) -> LocShape u t+makeShape pf mkf = \pt -> Shape { shape_ctm = makeShapeCTM pt+                                , path_fun  = ShapeR pf+                                , cons_fun  = ShapeR mkf+                                } +++shapeImage :: Num u => (PrimPath u -> Graphic u) -> Shape u t -> Image u (t u)+shapeImage drawF (Shape { shape_ctm = ctm, path_fun = pf, cons_fun = objf }) = +    liftA2 fn (pure $ runShapeR ctm objf) +              (drawF $ toPrimPath $ runShapeR ctm pf)+  where+    fn a (_,b) = (a,b)++borderedShape :: Num u => Shape u t -> Image u (t u)+borderedShape = shapeImage borderedPath++filledShape :: Num u => Shape u t -> Image u (t u)+filledShape = shapeImage filledPath++strokedShape :: Num u => Shape u t -> Image u (t u)+strokedShape = shapeImage closedStroke ++++instance (Real u, Floating u) => Rotate (Shape u sh) where+  rotate r = updateCTM (rotate r)++instance (Real u, Floating u) => RotateAbout (Shape u sh) where+  rotateAbout r pt = updateCTM (rotateAbout r pt)++instance Num u => Scale (Shape u sh) where+  scale sx sy = updateCTM (scale sx sy)++instance Num u => Translate (Shape u sh) where+  translate dx dy = updateCTM (translate dx dy)+++updateCTM :: (ShapeCTM u -> ShapeCTM u) -> Shape u sh -> Shape u sh+updateCTM fn (Shape ctm pf mkf) = Shape (fn ctm) pf mkf++--------------------------------------------------------------------------------+-- CTM++-- Note - all shapes need a location (usually/always the center)+-- so this needs to be stored in the CTM.+--++data ShapeCTM u = ShapeCTM +      { ctm_center              :: Point2 u+      , ctm_scale_x             :: !u+      , ctm_scale_y             :: !u+      , ctm_rotation            :: Radian+      }+  deriving (Eq,Ord,Show)+++type instance DUnit (ShapeCTM u) = u++makeShapeCTM :: Num u => Point2 u -> ShapeCTM u+makeShapeCTM pt = ShapeCTM { ctm_center   = pt+                           , ctm_scale_x  = 1+                           , ctm_scale_y  = 1+                           , ctm_rotation = 0 }++++++instance Num u => Scale (ShapeCTM u) where+  scale sx sy = (\s x y -> s { ctm_scale_x = x*sx, ctm_scale_y = y*sy })+                  <*> ctm_scale_x <*> ctm_scale_y+++instance Rotate (ShapeCTM u) where+  rotate ang = (\s i -> s { ctm_rotation = circularModulo $ i+ang })+                  <*> ctm_rotation++instance (Real u, Floating u) => RotateAbout (ShapeCTM u) where+  rotateAbout ang pt = +    (\s ctr i -> s { ctm_rotation = circularModulo $ i+ang+                   , ctm_center   = rotateAbout ang pt ctr })+      <*> ctm_center <*> ctm_rotation+++instance Num u => Translate (ShapeCTM u) where+  translate dx dy = (\s (P2 x y) -> s { ctm_center = P2 (x+dx) (y+dy) })+                      <*> ctm_center+++--------------------------------------------------------------------------------++newtype ShapeGeom u a = ShapeGeom { getShapeGeom :: ShapeCTM u -> a }+++type instance MonUnit (ShapeGeom u) = u+++instance Functor (ShapeGeom u) where+  fmap f ma = ShapeGeom $ \ctx -> let a = getShapeGeom ma ctx in f a++instance Applicative (ShapeGeom u) where+  pure a    = ShapeGeom $ \_   -> a+  mf <*> ma = ShapeGeom $ \ctx -> let f = getShapeGeom mf ctx+                                      a = getShapeGeom ma ctx+             			  in (f a)++instance Monad (ShapeGeom u) where+  return a = ShapeGeom $ \_   -> a+  m >>= k  = ShapeGeom $ \ctx -> let a = getShapeGeom m ctx+    	     	                 in (getShapeGeom . k) a ctx++++runShapeGeom :: ShapeCTM u -> ShapeGeom u a -> a+runShapeGeom ctm mf = getShapeGeom mf ctm++askCTM :: ShapeGeom u (ShapeCTM u)+askCTM = ShapeGeom $ \ctm -> ctm++shapeCenter :: ShapeGeom u (Point2 u)+shapeCenter = ShapeGeom $ \ctm -> ctm_center ctm++shapeAngle :: ShapeGeom u Radian+shapeAngle = ShapeGeom $ \ctm -> ctm_rotation ctm++++projectPoint :: (Real u, Floating u) => Point2 u -> ShapeGeom u (Point2 u)+projectPoint (P2 x y) = ShapeGeom $ +    \(ShapeCTM { ctm_center   = (P2 dx dy)+               , ctm_scale_x  = sx+               , ctm_scale_y  = sy+               , ctm_rotation = theta }) -> +    translate dx dy $ rotate theta $ P2 (sx*x) (sy*y)+
+ src/Wumpus/Drawing/Shapes/Coordinate.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE TypeFamilies               #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Shapes.Coordinate+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- 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.Drawing.Shapes.Coordinate+  (+    CoordinateAnchor+  , DCoordinateAnchor+  , Coordinate+  , DCoordinate+  , coordinate++  , coordinateDot+  , coordinateX++  ) where++import Wumpus.Basic.Kernel+import Wumpus.Drawing.Shapes.Base++import Wumpus.Core                              -- package: wumpus-core++import Control.Applicative+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++newtype CoordinateAnchor u = CoordinateAnchor { getCoordAnchor :: ShapeCTM u }+  deriving (Eq,Ord,Show)++type DCoordinateAnchor = CoordinateAnchor Double++type instance DUnit (CoordinateAnchor u) = u++newtype Coordinate u = Coordinate { getCoordinate :: CoordinateAnchor u }+  deriving (Eq,Ord,Show)++type DCoordinate = Coordinate Double++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 = 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 = cMap (translate dx dy)++++coordinate :: Num u => LocCoordinate u+coordinate = Coordinate . CoordinateAnchor . makeShapeCTM+++coordinateDot :: (Real u, Floating u, FromPtSize u) +              => Coordinate u -> Image u (CoordinateAnchor u)+coordinateDot x = liftA2 fn  (return $ getCoordinate x) (drawDot x)+  where+    fn a (_,b) = (a,b)++++-- | 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 = liftA2 fn (return $ getCoordinate x) (drawX x)+  where+    fn a (_,b) = (a,b)++++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/Drawing/Shapes/Derived.hs view
@@ -0,0 +1,371 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE TypeSynonymInstances       #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Shapes.Derived+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Simple shapes - rectangle, circle diamond, ellipse.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Shapes.Derived+  ( +    Rectangle+  , DRectangle+  , rectangle+  , rrectangle++  , mkRectangle   -- hidden in Shim module++  , Circle+  , DCircle+  , circle++  , Diamond+  , DDiamond+  , diamond+  , rdiamond++  , Ellipse+  , DEllipse+  , ellipse+++  ) where++import Wumpus.Basic.Kernel+import Wumpus.Drawing.Paths+import Wumpus.Drawing.Paths.RoundCorners+import Wumpus.Drawing.Shapes.Base++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space +import Data.VectorSpace++import Control.Applicative+++-- Note - Specific shapes - Rectangle, Circle, etc. - should _NOT_+-- have affine instances. +--+-- Transformations should only operate on the Shape type. Once a+-- Shape has been drawn the resultant Rectangle, Circle... cannot +-- be further transformed, as this would dis-associate the Anchors+-- from the Graphic.+--++--------------------------------------------------------------------------------+-- Rectangle++data Rectangle u = Rectangle +      { rect_ctm    :: ShapeCTM u+      , rect_hw     :: !u+      , rect_hh     :: !u +      }+  deriving (Eq,Ord,Show)++type DRectangle = Rectangle Double+++type instance DUnit (Rectangle u) = u+++runRectangle :: (u -> u -> ShapeGeom u a) -> Rectangle u -> a+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+  center = runRectangle (\ _ _ -> shapeCenter)+++instance (Real u, Floating u) => CardinalAnchor (Rectangle u) where+  north = runRectangle $ \_  hh -> projectPoint $ P2 0 hh+  south = runRectangle $ \_  hh -> projectPoint $ P2 0 (-hh)+  east  = runRectangle $ \hw _  -> projectPoint $ P2 hw 0+  west  = runRectangle $ \hw _  -> projectPoint $ P2 (-hw) 0++instance (Real u, Floating u) => CardinalAnchor2 (Rectangle u) where+  northeast = runRectangle $ \hw hh -> projectPoint $ P2 hw hh+  southeast = runRectangle $ \hw hh -> projectPoint $ P2 hw (-hh)+  southwest = runRectangle $ \hw hh -> projectPoint $ P2 (-hw) (-hh)+  northwest = runRectangle $ \hw hh -> projectPoint $ P2 (-hw) hh+++instance (Real u, Floating u) => RadialAnchor (Rectangle u) where+  radialAnchor theta = runRectangle $ \hw hh -> +    projectPoint $ rectangleIntersect hw hh theta++-- Note - the answer needs projecting with the CTM...+--+rectangleIntersect :: (Real u, Floating u) +                   => u -> u -> Radian -> Point2 u+rectangleIntersect hw hh theta = +    maybe zeroPt id $ findIntersect zeroPt theta $ rectangleLines zeroPt hw hh +++-- | 'rectangle'  : @ width * height -> shape @+--+rectangle :: (Real u, Floating u) => u -> u -> LocShape u Rectangle+rectangle w h = +    makeShape (traceLinePoints . rectanglePoints (0.5*w) (0.5*h))+              (mkRectangle (0.5*w) (0.5*h))+          ++-- | 'rectangle'  : @ round_length * width * height -> shape @+--+rrectangle :: (Real u, Floating u) => u -> u -> u -> LocShape u Rectangle+rrectangle round_dist w h = +    makeShape (roundEvery round_dist . rectanglePoints (0.5*w) (0.5*h))+              (mkRectangle (0.5*w) (0.5*h))+         ++++mkRectangle :: u -> u -> ShapeConstructor u Rectangle+mkRectangle hw hh = \ctm -> +    Rectangle { rect_ctm = ctm, rect_hw = hw, rect_hh = hh }++++rectanglePoints :: (Real u, Floating u) => u -> u -> ShapeCTM u -> [Point2 u]+rectanglePoints hw hh ctm = runShapeGeom ctm $ mapM projectPoint [se,ne,nw,sw]+  where+    se = P2   hw  (-hh)+    ne = P2   hw    hh+    nw = P2 (-hw)   hh+    sw = P2 (-hw) (-hh) ++++++--------------------------------------------------------------------------------+-- Circle++data Circle u = Circle +      { circ_ctm    :: ShapeCTM u+      , circ_radius :: !u +      }+  deriving (Eq,Show)+  +type DCircle = Circle Double++type instance DUnit (Circle u) = u++runCircle :: (u -> ShapeGeom u a) -> Circle u -> a+runCircle mf (Circle { circ_ctm =ctm, circ_radius = radius }) = +   runShapeGeom ctm $ mf radius +++instance (Real u, Floating u) => CenterAnchor (Circle u) where+  center = runCircle (\_ -> shapeCenter)+++instance (Real u, Floating u) => CardinalAnchor (Circle u) where+  north = runCircle $ \r -> projectPoint $ P2 0    r+  south = runCircle $ \r -> projectPoint $ P2 0  (-r)+  east  = runCircle $ \r -> projectPoint $ P2 r    0+  west  = runCircle $ \r -> projectPoint $ P2 (-r) 0+++instance (Real u, Floating u) => CardinalAnchor2 (Circle u) where+  northeast = radialAnchor (0.25*pi)+  southeast = radialAnchor (1.75*pi)+  southwest = radialAnchor (1.25*pi)+  northwest = radialAnchor (0.75*pi)+++instance (Real u, Floating u) => RadialAnchor (Circle u) where+  radialAnchor theta = runCircle $ \r -> projectPoint $ zeroPt .+^ avec theta r++++-- | 'circle'  : @ radius -> shape @+--+circle :: (Real u, Floating u) => u -> LocShape u Circle+circle radius = makeShape (traceCurvePoints . circlePoints radius)+                          (mkCircle radius)+          +++mkCircle :: u -> ShapeConstructor u Circle+mkCircle radius = \ctm -> Circle { circ_ctm = ctm, circ_radius = radius }+++circlePoints :: (Real u, Floating u) => u -> ShapeCTM u -> [Point2 u]+circlePoints radius ctm = runShapeGeom ctm $ mapM projectPoint all_points+  where+    all_points  = bezierCircle 2 radius zeroPt ++++--------------------------------------------------------------------------------+-- Diamond+++data Diamond u = Diamond +      { dia_ctm   :: ShapeCTM u+      , dia_hw    :: !u+      , dia_hh    :: !u+      }++type DDiamond = Diamond Double++type instance DUnit (Diamond u) = u++++runDiamond :: (u -> u -> ShapeGeom u a) -> Diamond u -> a+runDiamond mf (Diamond { dia_ctm = ctm, dia_hw = hw, dia_hh = hh }) = +   runShapeGeom ctm $ mf hw hh +++instance (Real u, Floating u) => CenterAnchor (Diamond u) where+  center = runDiamond (\_ _ -> shapeCenter)++instance (Real u, Floating u) => CardinalAnchor (Diamond u) where+  north = runDiamond $ \_  hh -> projectPoint $ P2 0 hh+  south = runDiamond $ \_  hh -> projectPoint $ P2 0 (-hh)+  east  = runDiamond $ \hw _  -> projectPoint $ P2 hw 0+  west  = runDiamond $ \hw _  -> projectPoint $ P2 (-hw) 0++instance (Real u, Floating u, Fractional u) => CardinalAnchor2 (Diamond u) where+  northeast x = midpoint (north x) (east x)+  southeast x = midpoint (south x) (east x)+  southwest x = midpoint (south x) (west x)+  northwest x = midpoint (north x) (west x)++++instance (Real u, Floating u) => RadialAnchor (Diamond u) where+   radialAnchor = diamondIntersect++-- Utils.Intersection needs improving...+++diamondIntersect :: (Real u, Floating u) +                 => Radian -> Diamond u -> Point2 u+diamondIntersect theta = runDiamond $ \hw hh ->  +    (\ctr ctm -> let ps = diamondPoints hw hh ctm +                 in maybe ctr id $ findIntersect ctr theta $ polygonLines ps)+      <$> shapeCenter <*> askCTM +++midpoint :: Fractional u => Point2 u -> Point2 u -> Point2 u+midpoint p1 p2 = let v = 0.5 *^ pvec p1 p2 in p1 .+^ v++-- | 'diamond'  : @ half_width * half_height -> shape @+--+-- Note - args might change to tull_width and full_height...+--+diamond :: (Real u, Floating u) => u -> u -> LocShape u Diamond+diamond hw hh = +    makeShape (traceLinePoints . diamondPoints hw hh)+              (mkDiamond hw hh)+          ++-- | 'rdiamond'  : @ round_length * half_width * half_height -> shape @+--+-- Note - args might change to full_width and full_height...+--+rdiamond :: (Real u, Floating u) => u -> u -> u -> LocShape u Diamond+rdiamond round_dist hw hh = +    makeShape (roundEvery round_dist . diamondPoints hw hh)+              (mkDiamond hw hh)+         +++++mkDiamond :: (Real u, Floating u) => u -> u -> ShapeConstructor u Diamond+mkDiamond hw hh = \ctm -> Diamond { dia_ctm = ctm, dia_hw = hw, dia_hh = hh }+++diamondPoints :: (Real u, Floating u) => u -> u -> ShapeCTM u -> [Point2 u]+diamondPoints hw hh ctm = runShapeGeom ctm $ mapM projectPoint [ s, e, n, w ]+  where+    s = P2   0  (-hh)+    e = P2   hw    0+    n = P2   0    hh+    w = P2 (-hw)   0 +++--------------------------------------------------------------------------------+-- Ellipse+++data Ellipse u = Ellipse+      { ell_ctm     :: ShapeCTM u +      , ell_rx      :: !u+      , ell_ry      :: !u+      }++type DEllipse = Ellipse Double++type instance DUnit (Ellipse u) = u+++runEllipse :: (u -> u -> ShapeGeom u a) -> Ellipse u -> a+runEllipse mf (Ellipse { ell_ctm = ctm, ell_rx = rx, ell_ry = ry }) = +   runShapeGeom ctm $ mf rx ry +++-- | x_radius is the unit length.+--+scaleEll :: (Scale t, Fractional u, u ~ DUnit t) => u -> u -> t -> t+scaleEll rx ry = scale 1 (ry/rx) +++instance (Real u, Floating u) => CenterAnchor (Ellipse u) where+  center = runEllipse $ \_ _ -> shapeCenter+++instance (Real u, Floating u) => RadialAnchor (Ellipse u) where+  radialAnchor theta = runEllipse $ \rx ry -> +    projectPoint $ scaleEll rx ry $ zeroPt .+^ avec theta rx+++instance (Real u, Floating u) => CardinalAnchor (Ellipse u) where+  north = radialAnchor (0.5*pi)+  south = radialAnchor (1.5*pi)+  east  = radialAnchor  0+  west  = radialAnchor  pi+++instance (Real u, Floating u) => CardinalAnchor2 (Ellipse u) where+  northeast = radialAnchor (0.25*pi)+  southeast = radialAnchor (1.75*pi)+  southwest = radialAnchor (1.25*pi)+  northwest = radialAnchor (0.75*pi)+++-- | 'ellipse'  : @ x_radii * y_radii -> shape @+--+ellipse :: (Real u, Floating u) => u -> u -> LocShape u Ellipse+ellipse rx ry = +    makeShape (traceCurvePoints . ellipsePoints rx ry)+              (mkEllipse rx ry)+          ++mkEllipse :: (Real u, Floating u) => u -> u -> ShapeConstructor u Ellipse+mkEllipse rx ry = \ctm -> Ellipse { ell_ctm = ctm, ell_rx = rx, ell_ry = ry }+++ellipsePoints :: (Real u, Floating u) => u -> u -> ShapeCTM u -> [Point2 u]+ellipsePoints rx ry ctm = +    runShapeGeom ctm $ mapM (projectPoint . scaleEll rx ry) all_points+  where+    all_points =  bezierCircle 2 rx zeroPt +++
+ src/Wumpus/Drawing/Text/LRText.hs view
@@ -0,0 +1,399 @@+{-# LANGUAGE TypeFamilies               #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Text.LRText+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC+--+-- Left-to-right measured text. The text uses glyph metrics so it +-- can be positioned accurately.+-- +-- \*\* WARNING \*\* - the API for this module has not been +-- decided. The function names are expected to change.+-- +--------------------------------------------------------------------------------++module Wumpus.Drawing.Text.LRText+  ( ++    baseCenterLine+  , baseLeftLine+  , baseRightLine++  , rbaseCenterLine+  , rbaseLeftLine+  , rbaseRightLine++  , ctrCenterLine+  , baseCenterEscChar++  , multiAlignLeft+  , multiAlignCenter+  , multiAlignRight++  , rmultiAlignLeft+  , rmultiAlignCenter+  , rmultiAlignRight+ ++  ) where+++import Wumpus.Basic.Kernel++import Wumpus.Core                              -- package: wumpus-core+import Wumpus.Core.Text.GlyphIndices++import Data.AffineSpace                         -- package: vector-space+import Data.VectorSpace++import Control.Applicative+import Data.Char+import qualified Data.Map               as Map+import Data.Maybe +++-- Note - BoundedLocThetaGraphic is probably an adequate type+-- even though the same text will have a different bounding box+-- if it is rotated (the sides of the BBox are always parallel to +-- the x and y axes even if the text is not parrale to the +-- x-axis). +-- +-- I cannot think of any compelling graphics that need a more +-- accurate type. The execption is text cannot have exact anchors +-- however this is a moot /if/ text is considered as a labelling +-- of an existing rectangle (which may or may not have been +-- rotated).+--++++-- One line of multiline text+--+data OnelineText u = OnelineText EscapedText (AdvanceVec u)+++-- | max_width * oneline_text -> LocThetaGraphic+--+type LocThetaDrawOneline u = u -> OnelineText u -> LocThetaGraphic u+++-- | max_width * oneline_text -> LocThetaGraphic+--+type BoundedLocThetaOneline u = u -> OnelineText u -> BoundedLocThetaGraphic u+++-- | Draw one line of left-aligned text, knowing the max_width +-- of all the lines of text.+--+-- All left-aligned text is moved left by half the max_width.+--+-- Note - implicit point is baseline-center, this is perhaps +-- unintituitive given the functions name but it is an +-- advantage for drawing multi-line text.+-- +drawLeftAligned :: Floating u => LocThetaDrawOneline u+drawLeftAligned max_width (OnelineText esc _) = +    promoteR2 $ \baseline_ctr theta -> +       let mv = displaceParallel ((-0.5) * max_width) theta+       in apply2R2 (rescapedline esc) (mv baseline_ctr) theta+       +++-- | Draw one line of center-aligned text. Center aligned text is +-- oblivious to the max_width of all the lines of text.+--+-- Each line of center-aligned text is moved left by half its +-- advance vector.+--+-- Implicit point is baseline-center.+--+drawCenterAligned :: Floating u => LocThetaDrawOneline u+drawCenterAligned _ (OnelineText esc av) = +    promoteR2 $ \baseline_ctr theta -> +       let mv = displaceParallel (negate $ 0.5 * advanceH av) theta+       in apply2R2 (rescapedline esc) (mv baseline_ctr) theta+       ++-- | Draw one line of right-aligned text, knowing the max_width +-- of all the lines of text.+--+-- Each right-aligned text line is moved by the width component +-- of the advance vector minus half the max width.+--+-- Note - implicit point is baseline-center, this is perhaps +-- unintituitive given the functions name but it is an +-- advantage for drawing multi-line text.+-- +drawRightAligned :: Floating u => LocThetaDrawOneline u+drawRightAligned max_width (OnelineText esc av) = +    promoteR2 $ \baseline_ctr theta -> +      let mv = displaceParallel ((0.5 * max_width) - advanceH av) theta+      in apply2R2 (rescapedline esc) (mv baseline_ctr) theta+++++-- Impilict point is baseline-center.+--+onelineBBox :: (Real u, Floating u, FromPtSize u) +            => OnelineText u -> LocThetaDrawingInfo u (BoundingBox u)+onelineBBox (OnelineText _ av) = +    promoteR2 $ \baseline_ctr theta -> +      glyphHeightRange >>= \(ymin, ymax) ->+        let hw = 0.5 * advanceH av +            bl = baseline_ctr .+^ vec (-hw) ymin+            tr = baseline_ctr .+^ vec hw    ymax+        in pure $ centerOrthoBBox theta (BBox bl tr)++++++-- This should have max_width as a param...+--+makeMoveableLine :: (Real u, Floating u, FromPtSize u) +                 => LocThetaDrawOneline u +                 -> BoundedLocThetaOneline u+makeMoveableLine drawF max_width oline =+      intoLocThetaImage (onelineBBox oline) (drawF max_width oline)++onelineAlg :: (Real u, Floating u, FromPtSize u) +           => DisplaceFun u +           -> LocThetaDrawOneline u +           -> EscapedText+           -> BoundedLocThetaGraphic u+onelineAlg ptMoveF drawF esc = +   promoteR2 $ \pt theta -> +     onelineEscText esc >>= \ans@(OnelineText _ av) ->+       let max_width = advanceH av+           move      = ptMoveF max_width ans theta +       in apply2R2 (makeMoveableLine drawF max_width ans) (move pt) theta++++++-- | Draw 1 line...+--+-- Impilict point is baseline-left.+--++baseLeftLine :: (Real u, Floating u, FromPtSize u) +              => String -> BoundedLocGraphic u+baseLeftLine ss = rbaseLeftLine ss `rot` 0++++-- | Draw 1 line...+--+-- Impilict point is baseline-center.+--+baseCenterLine :: (Real u, Floating u, FromPtSize u) +               => String -> BoundedLocGraphic u+baseCenterLine ss = rbaseCenterLine ss `rot` 0+++++-- | Draw 1 line...+--+-- Impilict point is baseline-right.+--+baseRightLine :: (Real u, Floating u, FromPtSize u) +              => String -> BoundedLocGraphic u+baseRightLine ss = rbaseRightLine ss `rot` 0++++rbaseLeftLine :: (Real u, Floating u, FromPtSize u) +              => String -> BoundedLocThetaGraphic u+rbaseLeftLine ss = +    onelineAlg leftToCenter drawLeftAligned (escapeString ss)+++rbaseCenterLine :: (Real u, Floating u, FromPtSize u) +                => String -> BoundedLocThetaGraphic u+rbaseCenterLine ss = +    onelineAlg centerToCenter drawCenterAligned (escapeString ss)+++rbaseRightLine :: (Real u, Floating u, FromPtSize u) +              => String -> BoundedLocThetaGraphic u+rbaseRightLine ss = +    onelineAlg rightToCenter drawRightAligned (escapeString ss)+++-- Note - assumes the ymin of the font is 0 or less.+--+ctrCenterLine :: (Real u, Floating u, FromPtSize u) +              => String -> BoundedLocGraphic u+ctrCenterLine ss =+    glyphHeightRange >>= \(ymin, ymax) -> +      let hh = 0.5 * ymax - ymin in +        moveStartPoint (displaceV $ negate $ hh - abs ymin) $ baseCenterLine ss++++baseCenterEscChar :: (Real u, Floating u, FromPtSize u) +                  => EscapedChar -> BoundedLocGraphic u+baseCenterEscChar esc = body `rot` 0+  where+    body = onelineAlg centerToCenter drawCenterAligned (wrapEscChar esc)+++++++-- | max_width * interim_text * theta -> (Point -> Point)+--+type DisplaceFun u = u -> OnelineText u -> Radian -> PointDisplace u++centerToCenter :: DisplaceFun u+centerToCenter _ _ _ = id++leftToCenter :: Floating u => DisplaceFun u+leftToCenter max_width _ theta =+    displaceParallel (0.5 * max_width) theta++rightToCenter :: Floating u => DisplaceFun u+rightToCenter max_width (OnelineText _ av) theta =+    displaceParallel ((0.5 * max_width) - advanceH av) theta+++++multiAlignLeft :: (Floating u, Real u, Ord u, FromPtSize u)+               => String+               -> BoundedLocGraphic u+multiAlignLeft ss = rmultiAlignLeft ss `rot` 0+++multiAlignCenter :: (Floating u, Real u, Ord u, FromPtSize u)+                 => String+                 -> BoundedLocGraphic u+multiAlignCenter ss = rmultiAlignCenter ss `rot` 0+++++multiAlignRight :: (Floating u, Real u, Ord u, FromPtSize u)+                => String+                -> BoundedLocGraphic u+multiAlignRight ss = rmultiAlignRight ss `rot` 0+++rmultiAlignLeft :: (Floating u, Real u, Ord u, FromPtSize u)+               => String+               -> BoundedLocThetaGraphic u+rmultiAlignLeft = multilineTEXT (makeMoveableLine drawLeftAligned)+++rmultiAlignCenter :: (Floating u, Real u, Ord u, FromPtSize u)+                  => String+                  -> BoundedLocThetaGraphic u+rmultiAlignCenter = multilineTEXT (makeMoveableLine drawCenterAligned)+++rmultiAlignRight :: (Floating u, Real u, Ord u, FromPtSize u)+                 => String+                 -> BoundedLocThetaGraphic u+rmultiAlignRight = multilineTEXT (makeMoveableLine drawRightAligned)++++multilineTEXT :: (Floating u, Ord u, FromPtSize u)+              => BoundedLocThetaOneline u+              -> String+              -> BoundedLocThetaGraphic u+multilineTEXT _  [] = lift1R2 emptyBoundedLocGraphic+multilineTEXT mf ss = +    lift0R2 (linesToInterims ss) >>= \(max_av, itexts) -> +      centralPoints (length itexts) >>= \pts -> +        zipMultis (advanceH max_av) mf itexts pts+++      ++zipMultis :: (Ord u, FromPtSize u)+          => u+          -> BoundedLocThetaOneline u+          -> [OnelineText u] -> [Point2 u]+          -> BoundedLocThetaGraphic u+zipMultis _     _  []     _       = lift1R2 $ emptyBoundedLocGraphic+zipMultis _     _  _      []      = lift1R2 $ emptyBoundedLocGraphic+zipMultis max_w mf (a:as) (b:bs) = step a b as bs+  where+    mkGraphic itext pt        = promoteR2 $ \_ theta -> +                                  apply2R2 (mf max_w itext) pt theta+    step r s (r2:rs) (s2:ss)  = liftA2 oplus (mkGraphic r s) (step r2 s2 rs ss)+    step r s _       _        = mkGraphic r s+++++-- | @ana@ is an /anacrusis/ factor - if there are even points+-- half the baseline_spacing is added to get the top point+--+centralPoints :: Floating u => Int -> LocThetaDrawingInfo u [Point2 u]+centralPoints n | n < 2     = promoteR2 $ \ctr _  -> return [ctr]+                | even n    = body (n `div` 2) (0.5*)+                | otherwise = body (n `div` 2) (0 *) +  where+    body halfn ana  = promoteR2 $ \ctr theta -> +                        baselineSpacing >>= \h ->+                          let y0  = (h * fromIntegral halfn) + ana h+                              top = displacePerpendicular y0 theta ctr+                          in pure $ trailPoints n h theta top+        +++trailPoints :: Floating u => Int -> u -> Radian -> Point2 u -> [Point2 u]+trailPoints n height theta top = take n $ iterate fn top+  where+    fn pt = displacePerpendicular (-height) theta pt++++--------------------------------------------------------------------------------++-- This isn't worth the complexity to get down to one traversal...++linesToInterims :: (FromPtSize u, Ord u) +                => String -> DrawingInfo (AdvanceVec u, [OnelineText u])+linesToInterims = fmap post . mapM (onelineEscText . escapeString) . lines+  where+    post xs                    = let vmax = foldr fn (hvec 0) xs in (vmax,xs)+    fn (OnelineText _ av) vmax = avMaxWidth av vmax++avMaxWidth :: Ord u => AdvanceVec u -> AdvanceVec u -> AdvanceVec u+avMaxWidth a@(V2 w1 _) b@(V2 w2 _) = if w2 > w1 then b else a++onelineEscText :: FromPtSize u => EscapedText -> DrawingInfo (OnelineText u)+onelineEscText esc = fmap (OnelineText esc) $ textVector esc++++textVector :: FromPtSize u => EscapedText -> DrawingInfo (AdvanceVec u)+textVector esc = +    cwLookupTable >>= \table -> +       let cs = destrEscapedText id esc +       in pure $ foldr (\c v -> v ^+^ (charWidth table c)) (vec 0 0) cs+     +   +++charWidth :: FromPtSize u +          => CharWidthTable u -> EscapedChar -> AdvanceVec u+charWidth fn (CharLiteral c) = fn $ ord c+charWidth fn (CharEscInt i)  = fn i+charWidth fn (CharEscName s) = fn ix+  where+    ix = fromMaybe (-1) $ Map.lookup s ps_glyph_indices
+ src/Wumpus/Drawing/Text/SafeFonts.hs view
@@ -0,0 +1,167 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Text.SafeFonts+-- Copyright   :  (c) Stephen Tetley 2009-2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- 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.Drawing.Text.SafeFonts+  ( +  -- * Times Roman+    times_roman+  , times_italic+  , times_bold+  , times_bold_italic++  -- * Helvetica+  , helvetica+  , helvetica_oblique+  , helvetica_bold+  , helvetica_bold_oblique++  -- * Courier+  , courier+  , courier_oblique+  , courier_bold+  , courier_bold_oblique++  -- * Symbol+  , symbol++  ) where++++import Wumpus.Core+import Wumpus.Core.Text.StandardEncoding+import Wumpus.Core.Text.Symbol++-- Supported fonts are:+--+-- Times-Roman  Times-Italic       Times-Bold      Times-BoldItalic+-- Helvetica    Helvetica-Oblique  Helvetica-Bold  Helvetica-Bold-Oblique+-- Courier      Courier-Oblique    Courier-Bold    Courier-Bold-Oblique+-- Symbol++--------------------------------------------------------------------------------+-- ++-- | Times-Roman+-- +times_roman :: FontFace+times_roman = +    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 standard_encoding+                       +-- | Times Bold+--+times_bold :: FontFace+times_bold = +    FontFace "Times-Bold" "Times New Roman" SVG_BOLD standard_encoding++-- | Times Bold Italic+--+times_bold_italic :: FontFace+times_bold_italic = FontFace "Times-BoldItalic" +                             "Times New Roman" +                             SVG_BOLD_ITALIC +                             standard_encoding+++--------------------------------------------------------------------------------+-- Helvetica++-- | Helvetica +--+helvetica :: FontFace+helvetica = FontFace "Helvetica" "Helvetica" SVG_REGULAR standard_encoding+++-- | Helvetica Oblique+--+helvetica_oblique :: FontFace+helvetica_oblique = +    FontFace "Helvetica-Oblique" "Helvetica" SVG_OBLIQUE standard_encoding++-- | Helvetica Bold+-- +helvetica_bold :: FontFace+helvetica_bold = +    FontFace "Helvetica-Bold" "Helvetica" SVG_BOLD standard_encoding+++-- | Helvetica Bold Oblique+--+helvetica_bold_oblique :: FontFace+helvetica_bold_oblique = FontFace "Helvetica-Bold-Oblique" +                                  "Helvetica" +                                  SVG_BOLD_OBLIQUE +                                  standard_encoding++++--------------------------------------------------------------------------------++-- | Courier+-- +courier :: FontFace+courier = FontFace "Courier" "Courier New" SVG_REGULAR standard_encoding++-- | Courier Oblique+-- +courier_oblique :: FontFace+courier_oblique = +    FontFace "Courier-Oblique" "Courier New" SVG_OBLIQUE standard_encoding++-- | Courier Bold+-- +courier_bold :: FontFace+courier_bold = +    FontFace "Courier-Bold" "Courier New" SVG_BOLD standard_encoding+++-- | Courier Bold Oblique+-- +courier_bold_oblique :: FontFace+courier_bold_oblique = FontFace "Courier-Bold-Oblique" +                                "Courier New" +                                SVG_BOLD_OBLIQUE +                                standard_encoding++--------------------------------------------------------------------------------+-- Symbol++-- | Symbol+--+-- 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_encoding+++++
+ src/Wumpus/Drawing/Turtle/TurtleClass.hs view
@@ -0,0 +1,91 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Turtle.TurtleClass+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC +--+-- Turtle monad and monad transformer.+--+-- The Turtle monad embodies the LOGO style of imperative +-- drawing - sending commands to update the a cursor.+--+-- While Wumpus generally aims for a more compositional,+-- \"coordinate-free\" style of drawing, some types of diagram +-- are more easily expressed in the LOGO style.+--+-- Note - as turtle drawing with Wumpus is a /local effect/, +-- there is only one instance of TurtleM. Potentially TurtleM +-- will be removed and the functions implemented directly. +--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Turtle.TurtleClass+  (++    Coord++  , TurtleM(..)++  , setsLoc+  , setsLoc_++  -- * movement+  , resetLoc+  , moveLeft+  , moveRight+  , moveUp+  , moveDown+  , nextLine+ ++  ) where++++type Coord = (Int,Int)+++class Monad m => TurtleM m where+  getLoc     :: m (Int,Int)+  setLoc     :: (Int,Int) -> m ()+  getOrigin  :: m (Int,Int)+  setOrigin  :: (Int,Int) -> m ()++++setsLoc :: TurtleM m => (Coord -> (a,Coord)) -> m a+setsLoc f = getLoc      >>= \coord -> +            let (a,coord') = f coord in setLoc coord' >> return a++setsLoc_ :: TurtleM m => (Coord -> Coord) -> m ()+setsLoc_ f = getLoc     >>= \coord ->  setLoc (f coord)+++resetLoc    :: TurtleM m => m ()+resetLoc    = getOrigin >>= setLoc+++moveRight   :: TurtleM m => m ()+moveRight   = setsLoc_ $ \(x,y)-> (x+1, y)+++moveLeft    :: TurtleM m => m ()+moveLeft    = setsLoc_ $ \(x,y) -> (x-1,y)++moveUp      :: TurtleM m => m ()+moveUp      = setsLoc_ $ \(x,y) -> (x,y+1)++moveDown    :: TurtleM m => m ()+moveDown    = setsLoc_ $ \(x,y) -> (x ,y-1)+++nextLine    :: TurtleM m => m ()+nextLine    = getOrigin >>= \(ox,_) ->+              setsLoc_ $ \(_,y) -> (ox,y-1)+
+ src/Wumpus/Drawing/Turtle/TurtleMonad.hs view
@@ -0,0 +1,140 @@+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE UndecidableInstances       #-}+{-# LANGUAGE TypeSynonymInstances       #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Drawing.Turtle.TurtleMonad+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  stephen.tetley@gmail.com+-- Stability   :  unstable+-- Portability :  GHC +--+-- Turtle monad transformer.+--+-- The Turtle monad embodies the LOGO style of imperative +-- drawing - sending commands to update the a cursor.+--+-- While Wumpus generally aims for a more compositional,+-- \"coordinate-free\" style of drawing, some types of +-- diagram are more easily expressed in the LOGO style.+--+-- Turtle is only a transformer - it is intended to be run within+-- a 'Drawing'.+--+--------------------------------------------------------------------------------++module Wumpus.Drawing.Turtle.TurtleMonad+  (+    -- * Re-exports+    module Wumpus.Drawing.Turtle.TurtleClass++  -- * Turtle transformer+  , TurtleT+  , runTurtleT++   +  ) where++import Wumpus.Basic.Kernel+import Wumpus.Drawing.Turtle.TurtleClass++++import Control.Applicative+import Control.Monad+++-- Note - if Turtle is now just a /local effect/ monad is the +-- Turtle class still needed? Afterall, there is (probably)+-- only ever going to be one instance.+--++-- Turtle is a Reader / State monad+-- +-- The env is the horizontal and vertical move distances.+-- +-- The state is the current coordinate and the origin.+--++data TurtleState = TurtleState +      { _turtle_origin   :: (Int,Int)+      , _current_coord   :: (Int,Int)+      }++type TurtleScalingT u m a = ScalingT Int Int u m a++newtype TurtleT u m a = TurtleT { +          getTurtleT :: TurtleState -> TurtleScalingT u m (a, TurtleState) }++type instance MonUnit (TurtleT u m) = u+    +++-- Functor++++instance Monad m => Functor (TurtleT u m) where+  fmap f m = TurtleT $ \s -> getTurtleT m s >>= \(a,s') ->+                             return (f a, s')+++-- Applicative ++instance Monad m => Applicative (TurtleT u m) where+  pure a    = TurtleT $ \s -> return (a,s)+  mf <*> ma = TurtleT $ \s -> getTurtleT mf s  >>= \(f,s')  ->+                              getTurtleT ma s' >>= \(a,s'') ->+                              return (f a,s'') +++-- Monad ++instance Monad m => Monad (TurtleT u m) where+  return a = TurtleT $ \s -> return (a,s)+  m >>= k  = TurtleT $ \s -> getTurtleT m s        >>= \(a,s')  ->+                             (getTurtleT . k) a s' >>= \(b,s'') ->+                             return (b,s'')+++++instance Monad m => TurtleM (TurtleT u m) where+  getLoc      = TurtleT $ \s@(TurtleState _ c) -> return (c,s)+  setLoc c    = TurtleT $ \(TurtleState o _)   -> return ((),TurtleState o c)+  getOrigin   = TurtleT $ \s@(TurtleState o _) -> return (o,s)+  setOrigin o = TurtleT $ \(TurtleState _ c)   -> return ((),TurtleState o c)+++runTurtleT :: (Monad m, Num u) +           => (Int,Int) -> ScalingContext Int Int u -> TurtleT u m a -> m a+runTurtleT ogin cfg mf = +    runScalingT cfg (getTurtleT mf st0) >>= \(a,_) -> return a+  where +    st0 = TurtleState ogin ogin ++++----------------------------------------------------------------------------------+-- Cross instances++instance DrawingCtxM m => DrawingCtxM (TurtleT u m) where+  askDC           = TurtleT $ \s -> askDC >>= \ ctx -> return (ctx,s)+  localize upd mf = TurtleT $ \s -> localize upd (getTurtleT mf s)+++-- This needs undecidable instances...++instance (Monad m, TraceM m, u ~ MonUnit m) => TraceM (TurtleT u m) where+  trace a  = TurtleT $ \s -> trace a >> return ((),s)+++instance (Monad m, u ~ MonUnit m, Num u) => PointSupplyM (TurtleT u m) where+  position = TurtleT $ \s@(TurtleState _ (x,y)) -> scalePt x y >>= \pt -> return (pt,s)+
wumpus-basic.cabal view
@@ -1,5 +1,5 @@ name:             wumpus-basic-version:          0.13.0+version:          0.14.0 license:          BSD3 license-file:     LICENSE copyright:        Stephen Tetley <stephen.tetley@gmail.com>@@ -15,13 +15,16 @@   and more experimental (unfortunately the only thing consistent    about the API is that it consistently changes...).    .-  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). +  Version 0.14.0 breaks up Wumpus-Basic into two /layers/ - +  @Wumpus.Basic@ for core data types, general utilities and +  /System/ utilities (currently only font loading); the other +  layer, @Wumpus.Drawing@, is for for specific drawing +  \"objects\" - arrowheads, dots, and the like. The APIs of the +  @Drawing@ modules have not been given much attention as the +  underlying graphic types have changed, they are due for +  substantial revision. This includes modules that were previously+  considered fairly stable such as the @Basic.SafeFonts@ module +  which no longer seems very /SVG safe/.    .   NOTE - many of the demos now use font metrics. Font metrics for   the \"Core 14\" PostScript fonts are distributed as @*.afm@ @@ -38,17 +41,37 @@   Core 14 AFM metrics:   <https://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/Core14_AFMs.tar>   .-  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.+  Also note that Wumpus uses fallback metrics (derived from the+  monospaced Courier font) when font loading fails, rather than+  throwing a terminal error. Applications should ideally check+  the font loading log to ensure that fonts have loaded correctly+  (the demos print this log to standard out).   .   Changelog:   .-  0.12.0 to 0.13.0:+  v0.13.0 to v0.14.0:   .+  * Re-organised module hierarchy, Wumpus-Basic is now divided +    into two layers - Basic (Font loader, utils, kernel drawing) +    and Drawing - /constructed/ graphic objects like arrows, dots, +    etc.+  .+  * Re-designed the /ContextFunction/ function types. Context+    functions with different numbers of /static arguments/ are +    now separate newtypes. This has allowed a major cull of the +    combinators operating on context functions (@prepro@, +    @postpro@, @situ@, etc.) and now only a handful of special+    combinators are needed. As the newtypes are instances of +    Monad and Applicative the usual Applicative and Monad +    combinators are now more readily useful.+  .+  * Work on the font loader code to improve its robustness, and +    improved error signalling on load failure. Loading glyph +    metrics now returns both the metrics (possibly fallback +    metrics if parsing failed) and a log.+  .+  v0.12.0 to v0.13.0:+  .   * Major changes to @Basic.Graphic@ modules. @DrawingR@ is      renamed @Drawing@ and is substantially re-worked. Graphic      /functional/ types are now encapulated in the Drawing @@ -93,64 +116,70 @@ library   hs-source-dirs:     src   build-depends:      base            <  5, -                      containers      >= 0.3     && <= 0.4,+                      containers      >= 0.3     && <= 0.6,                       directory       >= 1.0     && <  2.0,                        filepath        >= 1.1     && <  2.0,                       vector-space    >= 0.6     && <  1.0,-                      wumpus-core     == 0.40.0+                      wumpus-core     == 0.41.0       exposed-modules:-    Wumpus.Basic.Arrows,-    Wumpus.Basic.Arrows.Connectors,-    Wumpus.Basic.Arrows.Tips,-    Wumpus.Basic.Chains,-    Wumpus.Basic.Chains.Base,-    Wumpus.Basic.Chains.Derived,-    Wumpus.Basic.Colour.SVGColours,-    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.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,-    Wumpus.Basic.Paths.Base,-    Wumpus.Basic.Paths.Connectors,-    Wumpus.Basic.Paths.Construction,-    Wumpus.Basic.Paths.ControlPoints,-    Wumpus.Basic.Paths.RoundCorners,-    Wumpus.Basic.SafeFonts,-    Wumpus.Basic.Shapes,-    Wumpus.Basic.Shapes.Base,-    Wumpus.Basic.Shapes.Coordinate,-    Wumpus.Basic.Shapes.Derived,-    Wumpus.Basic.Text.LRText,+    Wumpus.Basic.Kernel,+    Wumpus.Basic.Kernel.Base.Anchors,+    Wumpus.Basic.Kernel.Base.BaseDefs,+    Wumpus.Basic.Kernel.Base.ContextFun,+    Wumpus.Basic.Kernel.Base.DrawingContext,+    Wumpus.Basic.Kernel.Base.GlyphMetrics,+    Wumpus.Basic.Kernel.Base.QueryDC,+    Wumpus.Basic.Kernel.Base.ScalingContext,+    Wumpus.Basic.Kernel.Base.UpdateDC,+    Wumpus.Basic.Kernel.Base.WrappedPrimitive,+    Wumpus.Basic.Kernel.Geometry.Intersection,+    Wumpus.Basic.Kernel.Geometry.Paths,+    Wumpus.Basic.Kernel.Objects.AdvanceGraphic,+    Wumpus.Basic.Kernel.Objects.BaseObjects,+    Wumpus.Basic.Kernel.Objects.Bounded,+    Wumpus.Basic.Kernel.Objects.Connector,+    Wumpus.Basic.Kernel.Objects.Drawing,+    Wumpus.Basic.Kernel.Objects.Graphic,+    Wumpus.Basic.Kernel.Objects.TraceDrawing,+    Wumpus.Basic.System.FontLoader.Afm,+    Wumpus.Basic.System.FontLoader.GhostScript,+    Wumpus.Basic.System.FontLoader.Base.AfmParserBase,+    Wumpus.Basic.System.FontLoader.Base.AfmV2Parser,+    Wumpus.Basic.System.FontLoader.Base.AfmV4Dot1Parser,+    Wumpus.Basic.System.FontLoader.Base.Datatypes,+    Wumpus.Basic.System.FontLoader.Base.FontLoadMonad,+    Wumpus.Basic.System.FontLoader.Base.GSFontMap,     Wumpus.Basic.Utils.HList,     Wumpus.Basic.Utils.FormatCombinators,-    Wumpus.Basic.Utils.Intersection,     Wumpus.Basic.Utils.ParserCombinators,     Wumpus.Basic.Utils.TokenParsers,-    Wumpus.Basic.VersionNumber+    Wumpus.Basic.VersionNumber,+    Wumpus.Drawing.Arrows,+    Wumpus.Drawing.Arrows.Connectors,+    Wumpus.Drawing.Arrows.Tips,+    Wumpus.Drawing.Chains,+    Wumpus.Drawing.Chains.Base,+    Wumpus.Drawing.Chains.Derived,+    Wumpus.Drawing.Colour.SVGColours,+    Wumpus.Drawing.Colour.X11Colours,+    Wumpus.Drawing.Dots.AnchorDots,+    Wumpus.Drawing.Dots.Marks,+    Wumpus.Drawing.Paths,+    Wumpus.Drawing.Paths.Base,+    Wumpus.Drawing.Paths.Connectors,+    Wumpus.Drawing.Paths.Construction,+    Wumpus.Drawing.Paths.ControlPoints,+    Wumpus.Drawing.Paths.RoundCorners,+    Wumpus.Drawing.Shapes,+    Wumpus.Drawing.Shapes.Base,+    Wumpus.Drawing.Shapes.Coordinate,+    Wumpus.Drawing.Shapes.Derived,+    Wumpus.Drawing.Text.LRText,+    Wumpus.Drawing.Text.SafeFonts,+    Wumpus.Drawing.Turtle.TurtleClass,+    Wumpus.Drawing.Turtle.TurtleMonad    other-modules: