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 +18/−16
- demo/Arrowheads.hs +6/−6
- demo/ClipPic.hs +6/−7
- demo/ColourChartUtils.hs +2/−2
- demo/ColourCharts.hs +2/−2
- demo/Connectors.hs +6/−6
- demo/DotPic.hs +18/−15
- demo/DrawingCompo.hs +2/−3
- demo/FeatureModel.hs +17/−15
- demo/FontPic.hs +6/−6
- demo/LeftRightText.hs +103/−32
- demo/PetriNet.hs +51/−19
- demo/Symbols.hs +5/−5
- src/Wumpus/Basic/Arrows.hs +0/−28
- src/Wumpus/Basic/Arrows/Connectors.hs +0/−148
- src/Wumpus/Basic/Arrows/Tips.hs +0/−485
- src/Wumpus/Basic/Chains.hs +0/−29
- src/Wumpus/Basic/Chains/Base.hs +0/−161
- src/Wumpus/Basic/Chains/Derived.hs +0/−129
- src/Wumpus/Basic/Colour/SVGColours.hs +0/−625
- src/Wumpus/Basic/Colour/X11Colours.hs +0/−1282
- src/Wumpus/Basic/Dots/AnchorDots.hs +0/−244
- src/Wumpus/Basic/Dots/Marks.hs +0/−229
- src/Wumpus/Basic/DrawingComposition.hs +0/−458
- src/Wumpus/Basic/FontLoader/AfmLoader.hs +0/−62
- src/Wumpus/Basic/FontLoader/AfmParserBase.hs +0/−215
- src/Wumpus/Basic/FontLoader/AfmV2Parser.hs +0/−67
- src/Wumpus/Basic/FontLoader/AfmV4Dot1Parser.hs +0/−67
- src/Wumpus/Basic/FontLoader/Base.hs +0/−222
- src/Wumpus/Basic/FontLoader/GSFontMap.hs +0/−87
- src/Wumpus/Basic/FontLoader/GSLoader.hs +0/−63
- src/Wumpus/Basic/Graphic.hs +0/−43
- src/Wumpus/Basic/Graphic/Anchors.hs +0/−158
- src/Wumpus/Basic/Graphic/Base.hs +0/−232
- src/Wumpus/Basic/Graphic/ContextFunction.hs +0/−718
- src/Wumpus/Basic/Graphic/Drawing.hs +0/−124
- src/Wumpus/Basic/Graphic/DrawingContext.hs +0/−324
- src/Wumpus/Basic/Graphic/GlyphMetrics.hs +0/−110
- src/Wumpus/Basic/Graphic/GraphicOperations.hs +0/−399
- src/Wumpus/Basic/Graphic/GraphicTypes.hs +0/−441
- src/Wumpus/Basic/Graphic/Query.hs +0/−264
- src/Wumpus/Basic/Graphic/ScalingContext.hs +0/−191
- src/Wumpus/Basic/Graphic/TraceDrawing.hs +0/−329
- src/Wumpus/Basic/Kernel.hs +57/−0
- src/Wumpus/Basic/Kernel/Base/Anchors.hs +238/−0
- src/Wumpus/Basic/Kernel/Base/BaseDefs.hs +281/−0
- src/Wumpus/Basic/Kernel/Base/ContextFun.hs +541/−0
- src/Wumpus/Basic/Kernel/Base/DrawingContext.hs +152/−0
- src/Wumpus/Basic/Kernel/Base/GlyphMetrics.hs +117/−0
- src/Wumpus/Basic/Kernel/Base/QueryDC.hs +263/−0
- src/Wumpus/Basic/Kernel/Base/ScalingContext.hs +195/−0
- src/Wumpus/Basic/Kernel/Base/UpdateDC.hs +244/−0
- src/Wumpus/Basic/Kernel/Base/WrappedPrimitive.hs +149/−0
- src/Wumpus/Basic/Kernel/Geometry/Intersection.hs +172/−0
- src/Wumpus/Basic/Kernel/Geometry/Paths.hs +114/−0
- src/Wumpus/Basic/Kernel/Objects/AdvanceGraphic.hs +106/−0
- src/Wumpus/Basic/Kernel/Objects/BaseObjects.hs +191/−0
- src/Wumpus/Basic/Kernel/Objects/Bounded.hs +140/−0
- src/Wumpus/Basic/Kernel/Objects/Connector.hs +74/−0
- src/Wumpus/Basic/Kernel/Objects/Drawing.hs +563/−0
- src/Wumpus/Basic/Kernel/Objects/Graphic.hs +470/−0
- src/Wumpus/Basic/Kernel/Objects/TraceDrawing.hs +338/−0
- src/Wumpus/Basic/Monads/TurtleClass.hs +0/−91
- src/Wumpus/Basic/Monads/TurtleMonad.hs +0/−140
- src/Wumpus/Basic/Paths.hs +0/−31
- src/Wumpus/Basic/Paths/Base.hs +0/−529
- src/Wumpus/Basic/Paths/Connectors.hs +0/−206
- src/Wumpus/Basic/Paths/Construction.hs +0/−160
- src/Wumpus/Basic/Paths/ControlPoints.hs +0/−189
- src/Wumpus/Basic/Paths/RoundCorners.hs +0/−121
- src/Wumpus/Basic/SafeFonts.hs +0/−167
- src/Wumpus/Basic/Shapes.hs +0/−27
- src/Wumpus/Basic/Shapes/Base.hs +0/−226
- src/Wumpus/Basic/Shapes/Coordinate.hs +0/−136
- src/Wumpus/Basic/Shapes/Derived.hs +0/−372
- src/Wumpus/Basic/System/FontLoader/Afm.hs +82/−0
- src/Wumpus/Basic/System/FontLoader/Base/AfmParserBase.hs +210/−0
- src/Wumpus/Basic/System/FontLoader/Base/AfmV2Parser.hs +65/−0
- src/Wumpus/Basic/System/FontLoader/Base/AfmV4Dot1Parser.hs +63/−0
- src/Wumpus/Basic/System/FontLoader/Base/Datatypes.hs +178/−0
- src/Wumpus/Basic/System/FontLoader/Base/FontLoadMonad.hs +205/−0
- src/Wumpus/Basic/System/FontLoader/Base/GSFontMap.hs +108/−0
- src/Wumpus/Basic/System/FontLoader/GhostScript.hs +86/−0
- src/Wumpus/Basic/Text/LRText.hs +0/−239
- src/Wumpus/Basic/Utils/Intersection.hs +0/−171
- src/Wumpus/Basic/VersionNumber.hs +2/−2
- src/Wumpus/Drawing/Arrows.hs +28/−0
- src/Wumpus/Drawing/Arrows/Connectors.hs +149/−0
- src/Wumpus/Drawing/Arrows/Tips.hs +505/−0
- src/Wumpus/Drawing/Chains.hs +29/−0
- src/Wumpus/Drawing/Chains/Base.hs +161/−0
- src/Wumpus/Drawing/Chains/Derived.hs +129/−0
- src/Wumpus/Drawing/Colour/SVGColours.hs +625/−0
- src/Wumpus/Drawing/Colour/X11Colours.hs +1282/−0
- src/Wumpus/Drawing/Dots/AnchorDots.hs +280/−0
- src/Wumpus/Drawing/Dots/Marks.hs +238/−0
- src/Wumpus/Drawing/Paths.hs +31/−0
- src/Wumpus/Drawing/Paths/Base.hs +529/−0
- src/Wumpus/Drawing/Paths/Connectors.hs +206/−0
- src/Wumpus/Drawing/Paths/Construction.hs +160/−0
- src/Wumpus/Drawing/Paths/ControlPoints.hs +189/−0
- src/Wumpus/Drawing/Paths/RoundCorners.hs +120/−0
- src/Wumpus/Drawing/Shapes.hs +27/−0
- src/Wumpus/Drawing/Shapes/Base.hs +227/−0
- src/Wumpus/Drawing/Shapes/Coordinate.hs +141/−0
- src/Wumpus/Drawing/Shapes/Derived.hs +371/−0
- src/Wumpus/Drawing/Text/LRText.hs +399/−0
- src/Wumpus/Drawing/Text/SafeFonts.hs +167/−0
- src/Wumpus/Drawing/Turtle/TurtleClass.hs +91/−0
- src/Wumpus/Drawing/Turtle/TurtleMonad.hs +140/−0
- wumpus-basic.cabal +92/−63
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: