{-# LANGUAGE TypeFamilies #-} {-# OPTIONS -Wall #-} -- Acknowledgment - the Arrow diagram is taken from Ross -- Paterson\'s slides /Arrows and Computation/. -- NOTE - this example now rather out-of-date. Wumpus-Drawing has -- some new features to make node/connector drawing a bit easier. module ArrowCircuit where import Wumpus.Drawing.Connectors import qualified Wumpus.Drawing.Connectors.ConnectorPaths as C import Wumpus.Drawing.Shapes import Wumpus.Drawing.Text.DirectionZero import Wumpus.Drawing.Text.StandardFontDefs import Wumpus.Basic.Kernel -- package: wumpus-basic import Wumpus.Basic.System.FontLoader import Wumpus.Core -- package: wumpus-core import Data.AffineSpace -- package: vector-space import System.Directory main :: IO () main = simpleFontLoader main1 >> return () main1 :: FontLoader -> IO () main1 loader = do createDirectoryIfMissing True "./out/" base_metrics <- loader [ Right times_roman_family ] printLoadErrors base_metrics let pic1 = runCtxPictureU (makeCtx base_metrics) circuit_pic writeEPS "./out/arrow_circuit.eps" pic1 writeSVG "./out/arrow_circuit.svg" pic1 makeCtx :: FontLoadResult -> DrawingContext makeCtx = set_font times_roman . metricsContext 11 -- Note - quite a bit of this diagram was produced /by eye/, -- rather than using anchors directly - e.g. the placing of the -- ptext labels and the anchors displaced by vectors. -- -- Note `at` currently does not work for Shapes. circuit_pic :: CtxPicture circuit_pic = drawTracing body body :: TraceDrawing Double () body = do a1 <- drawi $ rrectangle 12 66 30 `at` P2 0 72 atext a1 "CONST 0" a2 <- drawi $ (strokedShape $ circle 16) `at` P2 120 60 atext a2 "IF" a3 <- drawi $ (strokedShape $ circle 16) `at` P2 240 28 atext a3 "+1" a4 <- drawi $ (strokedShape $ rectangle 66 30) `at` P2 120 0 atext a4 "DELAY 0" connWith conn_line (east a1) ((.+^ hvec 76) $ east a1) connWith conn_line (east a2) ((.+^ hvec 180) $ east a2) connWith conn_line ((.+^ vvec 40) $ north a2) (north a2) connWith conn_line ((.+^ vvec 16) $ north a3) (north a3) connWith conna_right (south a3) (east a4) connWith conna_orthovbar (west a4) (southwest a2) ptext (P2 40 10) "next" ptext (P2 152 100) "reset" ptext (P2 252 72) "output" return () -- Note - need a variant of /bar/ that draws UDLR only. connWith :: ( Real u, Floating u, InterpretUnit u ) => ArrowConnector u -> Anchor u -> Anchor u -> TraceDrawing u () connWith con a0 a1 = localize double_point_size $ drawc a0 a1 (ignoreAns con) atext :: ( CenterAnchor (t u), u ~ DUnit (t u) , Real u, Floating u, InterpretUnit u) => t u -> String -> TraceDrawing u () atext ancr ss = draw $ textline CENTER ss `at` (center ancr) ptext :: (Floating u, InterpretUnit u) => Point2 u -> String -> TraceDrawing u () ptext pt ss = localize (font_attr times_italic 14) $ draw $ textline CENTER ss `at` pt -- Note - return type is a LocImage not a shape... -- rrectangle :: (Real u, Floating u, InterpretUnit u, Tolerance u) => Double -> u -> u -> LocImage u (Rectangle u) rrectangle _r w h = strokedShape (rectangle w h) -- This should have round corners but they are currently -- disabled pending a re-think. {- localize (round_corner_factor r) $ -} -- Cf. Parsec\'s Token module... conn_line :: (Real u, Floating u, InterpretUnit u, Tolerance u) => ArrowConnector u conn_line = renderConnectorConfig default_connector_props $ makeSglArrConn C.conn_line conna_orthovbar :: (Real u, Floating u, InterpretUnit u, Tolerance u) => ArrowConnector u conna_orthovbar = renderConnectorConfig default_connector_props $ makeSglArrConn C.conna_orthovbar conna_right :: (Real u, Floating u, InterpretUnit u, Tolerance u) => ArrowConnector u conna_right = renderConnectorConfig default_connector_props $ makeSglArrConn C.conna_right makeSglArrConn :: ConnectorPathSpec u -> ConnectorConfig u makeSglArrConn cspec = ConnectorConfig { conn_arrowl = Nothing , conn_arrowr = Just tri45 , conn_path_spec = cspec }