packages feed

wumpus-basic 0.10.0 → 0.11.0

raw patch · 26 files changed

+1189/−779 lines, 26 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Wumpus.Basic.Arrows: arrowBarb45 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowBarb60 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowBarb90 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowOTri45 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowOTri60 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowOTri90 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowPerp :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowRBracket :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowTri45 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowTri60 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: arrowTri90 :: (Real u, Floating u, FromPtSize u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Arrows: cline :: (Num u) => Connector u -> ConnImage u (Path u)
- Wumpus.Basic.Graphic.Base: intoConnImage :: ConnDrawingR u a -> ConnGraphic u -> ConnImage u a
- Wumpus.Basic.Graphic.Base: type ConnDrawingR u a = Point2 u -> Point2 u -> DrawingR a
- Wumpus.Basic.Graphic.Base: type ConnGraphic u = Point2 u -> Point2 u -> Graphic u
- Wumpus.Basic.Graphic.Base: type ConnImage u a = Point2 u -> Point2 u -> Image u a
- Wumpus.Basic.Graphic.Base: type DConnDrawingR a = ConnDrawingR Double a
- Wumpus.Basic.Graphic.Base: type DConnGraphic = ConnGraphic Double
- Wumpus.Basic.Graphic.Base: type DConnImage a = ConnImage Double a
- Wumpus.Basic.Graphic.Drawing: conn :: ConnImage u a -> Point2 u -> LocImage u a
- Wumpus.Basic.Graphic.Query: lineSpacing :: (Applicative m, DrawingCtxM m, Fractional u) => m u
- Wumpus.Basic.Paths.Base: EmptyPathL :: PathViewL u
- Wumpus.Basic.Paths.Base: EmptyPathR :: PathViewR u
- Wumpus.Basic.Paths.Base: instance (Floating u) => Monoid (Path u)
- Wumpus.Basic.Paths.Base: midpoint :: (Real u, Floating u) => Path u -> Maybe (Point2 u, Radian)
- Wumpus.Basic.Paths.Base: toPrimPathU :: Path u -> PrimPath u
- Wumpus.Basic.Paths.Base: tracePoints :: (Floating u) => [Point2 u] -> Path u
- Wumpus.Basic.Paths.Connectors: type Connector u = Point2 u -> Point2 u -> Path u
- Wumpus.Basic.SafeFonts: courierBold :: FontFace
- Wumpus.Basic.SafeFonts: courierBoldOblique :: FontFace
- Wumpus.Basic.SafeFonts: courierOblique :: FontFace
- Wumpus.Basic.SafeFonts: helveticaBold :: FontFace
- Wumpus.Basic.SafeFonts: helveticaBoldOblique :: FontFace
- Wumpus.Basic.SafeFonts: helveticaOblique :: FontFace
- Wumpus.Basic.SafeFonts: timesBold :: FontFace
- Wumpus.Basic.SafeFonts: timesBoldItalic :: FontFace
- Wumpus.Basic.SafeFonts: timesItalic :: FontFace
- Wumpus.Basic.SafeFonts: timesRoman :: FontFace
- Wumpus.Basic.Shapes.Base: data ShapeLabel u
- Wumpus.Basic.Shapes.Base: drawShape :: Shape u sh -> Image u sh
- Wumpus.Basic.Shapes.Base: nolabel :: ShapeLabel u
- Wumpus.Basic.Shapes.Base: out_fun :: Shape u sh -> ShapeCTM u -> Image u sh
- Wumpus.Basic.Shapes.Base: runShapeLabel :: ShapeCTM u -> ShapeLabel u -> Graphic u
- Wumpus.Basic.Shapes.Base: shapelabel :: (Real u, Floating u, FromPtSize u) => String -> ShapeLabel u
- Wumpus.Basic.Shapes.Derived: coordinate :: (Real u, Floating u) => Shape u (Coordinate u)
- Wumpus.Basic.Shapes.Derived: data Coordinate u
- Wumpus.Basic.Shapes.Derived: data FreeLabel u
- Wumpus.Basic.Shapes.Derived: freelabel :: (Real u, Floating u, FromPtSize u) => String -> Shape u (FreeLabel u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (FreeLabel u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor2 (FreeLabel u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (Coordinate u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CenterAnchor (FreeLabel u)
- Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (FreeLabel u)
- Wumpus.Basic.Shapes.Derived: lcircle :: (Real u, Floating u, FromPtSize u) => u -> String -> Shape u (Circle u)
- Wumpus.Basic.Shapes.Derived: ldiamond :: (Real u, Floating u, FromPtSize u) => u -> u -> String -> Shape u (Diamond u)
- Wumpus.Basic.Shapes.Derived: lellipse :: (Real u, Floating u, FromPtSize u) => u -> u -> String -> Shape u (Ellipse u)
- Wumpus.Basic.Shapes.Derived: lrectangle :: (Real u, Floating u, FromPtSize u) => u -> u -> String -> Shape u (Rectangle u)
- Wumpus.Basic.Shapes.Derived: type DCoordinate = Coordinate Double
- Wumpus.Basic.Shapes.Derived: type DFreeLabel = FreeLabel Double
+ 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 :: DrawingR u -> ThetaLocGraphic u -> Arrowhead u
+ Wumpus.Basic.Arrows.Tips: arrow_draw :: Arrowhead u -> ThetaLocGraphic u
+ Wumpus.Basic.Arrows.Tips: arrowheadTip :: Arrowhead u -> Radian -> LocGraphic u
+ Wumpus.Basic.Arrows.Tips: data Arrowhead u
+ Wumpus.Basic.Arrows.Tips: retract_dist :: Arrowhead u -> DrawingR u
+ Wumpus.Basic.Graphic.Base: intoConnectorImage :: ConnectorDrawingR u a -> ConnectorGraphic u -> ConnectorImage u a
+ Wumpus.Basic.Graphic.Base: type ConnectorDrawingR u a = Point2 u -> Point2 u -> DrawingR a
+ Wumpus.Basic.Graphic.Base: type ConnectorGraphic u = Point2 u -> Point2 u -> Graphic u
+ Wumpus.Basic.Graphic.Base: type ConnectorImage u a = Point2 u -> Point2 u -> Image u a
+ Wumpus.Basic.Graphic.Base: type DConnectorDrawingR a = ConnectorDrawingR Double a
+ Wumpus.Basic.Graphic.Base: type DConnectorGraphic = ConnectorGraphic Double
+ Wumpus.Basic.Graphic.Base: type DConnectorImage a = ConnectorImage Double a
+ Wumpus.Basic.Graphic.Base: type DThetaLocDrawingR a = ThetaLocDrawingR Double a
+ Wumpus.Basic.Graphic.Base: type DThetaLocGraphic = ThetaLocGraphic Double
+ Wumpus.Basic.Graphic.Base: type DThetaLocImage a = ThetaLocImage Double a
+ Wumpus.Basic.Graphic.Base: type ThetaLocDrawingR u a = Radian -> LocDrawingR u a
+ Wumpus.Basic.Graphic.Base: type ThetaLocGraphic u = Radian -> LocGraphic u
+ Wumpus.Basic.Graphic.Base: type ThetaLocImage u a = Radian -> LocImage u a
+ Wumpus.Basic.Graphic.Drawing: drawi_ :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => Image u a -> m ()
+ Wumpus.Basic.Graphic.Drawing: evalDrawing :: DrawingContext -> Drawing u a -> a
+ Wumpus.Basic.Graphic.Drawing: evalDrawingT :: (Monad m) => DrawingContext -> DrawingT u m a -> m a
+ Wumpus.Basic.Graphic.Drawing: xdrawi_ :: (TraceM m, DrawingCtxM m, u ~ (MonUnit m)) => XLink -> Image u a -> m ()
+ Wumpus.Basic.Graphic.Query: baselineSpacing :: (DrawingCtxM m, Fractional u) => m u
+ Wumpus.Basic.Graphic.Query: monoDefaultPadding :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoMultiLineTextHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => Int -> m 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: 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: pconcat :: (Floating u) => Path u -> [Path u] -> Path 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.Connectors: type ConnectorPath u = Point2 u -> Point2 u -> Path u
+ Wumpus.Basic.SafeFonts: courier_bold :: FontFace
+ Wumpus.Basic.SafeFonts: courier_bold_oblique :: FontFace
+ Wumpus.Basic.SafeFonts: courier_oblique :: FontFace
+ Wumpus.Basic.SafeFonts: helvetica_bold :: FontFace
+ Wumpus.Basic.SafeFonts: helvetica_bold_oblique :: FontFace
+ Wumpus.Basic.SafeFonts: helvetica_oblique :: 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: borderedShape :: (Num u) => Shape u t -> Image u (t u)
+ Wumpus.Basic.Shapes.Base: cons_fun :: Shape u t -> ShapeCTM u -> t u
+ Wumpus.Basic.Shapes.Base: filledShape :: (Num u) => Shape u t -> Image u (t u)
+ Wumpus.Basic.Shapes.Base: instance (Ord u) => Ord (ShapeCTM u)
+ Wumpus.Basic.Shapes.Base: path_fun :: Shape u t -> ShapeCTM u -> Path u
+ Wumpus.Basic.Shapes.Base: strokedShape :: (Num u) => Shape u t -> Image u (t u)
+ Wumpus.Basic.Shapes.Base: type ShapeConstructor u t = ShapeCTM u -> t u
+ Wumpus.Basic.Shapes.Coordinate: coordinate :: (Num u) => Point2 u -> Coordinate u
+ Wumpus.Basic.Shapes.Coordinate: coordinateMark :: (Real u, Floating 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 (Eq u) => Eq (Coordinate u)
+ Wumpus.Basic.Shapes.Coordinate: instance (Eq u) => Eq (CoordinateAnchor 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 (Real u, Floating u) => CenterAnchor (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: instance (Ord u) => Ord (Rectangle u)
+ Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor (Ellipse u)
+ Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => CardinalAnchor2 (Ellipse u)
+ Wumpus.Basic.Shapes.Derived: instance (Real u, Floating u) => RadialAnchor (Ellipse u)
+ Wumpus.Basic.Shapes.Derived: mkRectangle :: u -> u -> ShapeConstructor u Rectangle
+ Wumpus.Basic.Shapes.Derived: rdiamond :: (Real u, Floating u) => u -> u -> u -> Shape u Diamond
+ Wumpus.Basic.Shapes.Derived: rrectangle :: (Real u, Floating u) => u -> u -> u -> Shape u Rectangle
+ Wumpus.Basic.Shapes.Plaintext: data Plaintext u
+ Wumpus.Basic.Shapes.Plaintext: data PlaintextAnchor u
+ Wumpus.Basic.Shapes.Plaintext: drawText :: (Real u, Floating u, FromPtSize u) => Plaintext u -> Image u (PlaintextAnchor u)
+ Wumpus.Basic.Shapes.Plaintext: instance (Eq u) => Eq (Plaintext u)
+ Wumpus.Basic.Shapes.Plaintext: instance (Num u) => Translate (Plaintext u)
+ Wumpus.Basic.Shapes.Plaintext: instance (Ord u) => Ord (Plaintext u)
+ Wumpus.Basic.Shapes.Plaintext: instance (Real u, Floating u) => CardinalAnchor (PlaintextAnchor u)
+ Wumpus.Basic.Shapes.Plaintext: instance (Real u, Floating u) => CardinalAnchor2 (PlaintextAnchor u)
+ Wumpus.Basic.Shapes.Plaintext: instance (Real u, Floating u) => CenterAnchor (PlaintextAnchor u)
+ Wumpus.Basic.Shapes.Plaintext: instance (Real u, Floating u) => RadialAnchor (PlaintextAnchor u)
+ Wumpus.Basic.Shapes.Plaintext: instance (Show u) => Show (Plaintext u)
+ Wumpus.Basic.Shapes.Plaintext: instance Rotate (Plaintext u)
+ Wumpus.Basic.Shapes.Plaintext: plaintext :: (Num u) => String -> Plaintext u
+ Wumpus.Basic.Shapes.Plaintext: type DPlaintext = Plaintext Double
+ Wumpus.Basic.Shapes.Plaintext: type DPlaintextAnchor = PlaintextAnchor Double
- Wumpus.Basic.Arrows.Tips: barb45 :: (Floating u, Real u, FromPtSize u) => Radian -> LocGraphic 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) => Radian -> LocGraphic 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) => Radian -> LocGraphic u
+ Wumpus.Basic.Arrows.Tips: barb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: otri45 :: (Floating u, Real u, FromPtSize u) => Radian -> LocGraphic 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) => Radian -> LocGraphic 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) => Radian -> LocGraphic u
+ Wumpus.Basic.Arrows.Tips: otri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: perp :: (Floating u, FromPtSize u) => Radian -> LocGraphic u
+ Wumpus.Basic.Arrows.Tips: perp :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: rbracket :: (Floating u, FromPtSize u) => Radian -> LocGraphic u
+ Wumpus.Basic.Arrows.Tips: rbracket :: (Floating u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Arrows.Tips: tri45 :: (Floating u, Real u, FromPtSize u) => Radian -> LocGraphic 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) => Radian -> LocGraphic 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) => Radian -> LocGraphic u
+ Wumpus.Basic.Arrows.Tips: tri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u
- Wumpus.Basic.Graphic.Base: class (Monad m) => DrawingCtxM m :: (* -> *)
+ Wumpus.Basic.Graphic.Base: class (Applicative m, Monad m) => DrawingCtxM m :: (* -> *)
- Wumpus.Basic.Graphic.Query: borderedAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, StrokeAttr, RGBi)
+ Wumpus.Basic.Graphic.Query: borderedAttr :: (DrawingCtxM m) => m (RGBi, StrokeAttr, RGBi)
- Wumpus.Basic.Graphic.Query: fillAttr :: (Applicative m, DrawingCtxM m) => m RGBi
+ Wumpus.Basic.Graphic.Query: fillAttr :: (DrawingCtxM m) => m RGBi
- Wumpus.Basic.Graphic.Query: fontSize :: (Applicative m, DrawingCtxM m) => m Int
+ Wumpus.Basic.Graphic.Query: fontSize :: (DrawingCtxM m) => m Int
- Wumpus.Basic.Graphic.Query: lineWidth :: (Applicative m, DrawingCtxM m) => m Double
+ Wumpus.Basic.Graphic.Query: lineWidth :: (DrawingCtxM m) => m Double
- Wumpus.Basic.Graphic.Query: markHalfHeight :: (Applicative m, DrawingCtxM m, Fractional u, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: markHalfHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: markHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: markHeight :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoCharWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoCharWidth :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoDescenderDepth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoDescenderDepth :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoLowerxHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoLowerxHeight :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoNumeralHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoNumeralHeight :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoSpacerWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoSpacerWidth :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoTextDimensions :: (Applicative m, DrawingCtxM m, Num u, Ord u, FromPtSize u) => String -> m (u, u)
+ Wumpus.Basic.Graphic.Query: monoTextDimensions :: (DrawingCtxM m, Num u, Ord u, FromPtSize u) => String -> m (u, u)
- Wumpus.Basic.Graphic.Query: monoTextHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u
+ Wumpus.Basic.Graphic.Query: monoTextHeight :: (DrawingCtxM m, FromPtSize u) => m u
- Wumpus.Basic.Graphic.Query: monoTextLength :: (Applicative m, DrawingCtxM m, FromPtSize u) => String -> m u
+ Wumpus.Basic.Graphic.Query: monoTextLength :: (DrawingCtxM m, FromPtSize u) => String -> m u
- Wumpus.Basic.Graphic.Query: monoTextWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => Int -> m u
+ Wumpus.Basic.Graphic.Query: monoTextWidth :: (DrawingCtxM m, FromPtSize u) => Int -> m u
- Wumpus.Basic.Graphic.Query: monoVecToCenter :: (Applicative m, DrawingCtxM m, Fractional u, Ord u, FromPtSize u) => String -> m (Vec2 u)
+ Wumpus.Basic.Graphic.Query: monoVecToCenter :: (DrawingCtxM m, Fractional u, Ord u, FromPtSize u) => String -> m (Vec2 u)
- Wumpus.Basic.Graphic.Query: strokeAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, StrokeAttr)
+ Wumpus.Basic.Graphic.Query: strokeAttr :: (DrawingCtxM m) => m (RGBi, StrokeAttr)
- Wumpus.Basic.Graphic.Query: textAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, FontAttr)
+ Wumpus.Basic.Graphic.Query: textAttr :: (DrawingCtxM m) => m (RGBi, FontAttr)
- Wumpus.Basic.Graphic.Query: withBorderedAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> StrokeAttr -> RGBi -> a) -> m a
+ Wumpus.Basic.Graphic.Query: withBorderedAttr :: (DrawingCtxM m) => (RGBi -> StrokeAttr -> RGBi -> a) -> m a
- Wumpus.Basic.Graphic.Query: withFillAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> a) -> m a
+ Wumpus.Basic.Graphic.Query: withFillAttr :: (DrawingCtxM m) => (RGBi -> a) -> m a
- Wumpus.Basic.Graphic.Query: withStrokeAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> StrokeAttr -> a) -> m a
+ Wumpus.Basic.Graphic.Query: withStrokeAttr :: (DrawingCtxM m) => (RGBi -> StrokeAttr -> a) -> m a
- Wumpus.Basic.Graphic.Query: withTextAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> FontAttr -> a) -> m a
+ Wumpus.Basic.Graphic.Query: withTextAttr :: (DrawingCtxM m) => (RGBi -> FontAttr -> a) -> m a
- Wumpus.Basic.Paths.Base: tipL :: Path u -> Maybe (Point2 u)
+ Wumpus.Basic.Paths.Base: tipL :: Path u -> Point2 u
- Wumpus.Basic.Paths.Base: tipR :: Path u -> Maybe (Point2 u)
+ Wumpus.Basic.Paths.Base: tipR :: Path u -> Point2 u
- Wumpus.Basic.Paths.Base: toPrimPath :: Path u -> Maybe (PrimPath u)
+ Wumpus.Basic.Paths.Base: toPrimPath :: Path u -> PrimPath u
- Wumpus.Basic.Paths.Connectors: connect :: (Floating u) => Connector u
+ Wumpus.Basic.Paths.Connectors: connect :: (Floating u) => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: curveconn :: (Floating u, Ord u) => Radian -> Radian -> Connector u
+ Wumpus.Basic.Paths.Connectors: curveconn :: (Floating u, Ord u) => Radian -> Radian -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: hvconn :: (Floating u) => Connector u
+ Wumpus.Basic.Paths.Connectors: hvconn :: (Floating u) => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: hvhconn :: (Floating u) => u -> Connector u
+ Wumpus.Basic.Paths.Connectors: hvhconn :: (Floating u) => u -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: joint :: (Real u, Floating u) => u -> Connector u
+ Wumpus.Basic.Paths.Connectors: joint :: (Real u, Floating u) => u -> ConnectorPath u
- Wumpus.Basic.Paths.Connectors: vhconn :: (Floating u) => Connector u
+ Wumpus.Basic.Paths.Connectors: vhconn :: (Floating u) => ConnectorPath u
- Wumpus.Basic.Paths.Connectors: vhvconn :: (Floating u) => u -> Connector u
+ Wumpus.Basic.Paths.Connectors: vhvconn :: (Floating u) => u -> ConnectorPath u
- Wumpus.Basic.Shapes.Base: Shape :: ShapeCTM u -> (ShapeCTM u -> Image u sh) -> Shape u sh
+ Wumpus.Basic.Shapes.Base: Shape :: ShapeCTM u -> (ShapeCTM u -> Path u) -> (ShapeCTM u -> t u) -> Shape u t
- Wumpus.Basic.Shapes.Base: data Shape u sh
+ Wumpus.Basic.Shapes.Base: data Shape u t
- Wumpus.Basic.Shapes.Base: src_ctm :: Shape u sh -> ShapeCTM u
+ Wumpus.Basic.Shapes.Base: src_ctm :: Shape u t -> ShapeCTM u
- Wumpus.Basic.Shapes.Derived: circle :: (Real u, Floating u) => u -> Shape u (Circle u)
+ Wumpus.Basic.Shapes.Derived: circle :: (Real u, Floating u) => u -> Shape u Circle
- Wumpus.Basic.Shapes.Derived: diamond :: (Real u, Floating u) => u -> u -> Shape u (Diamond u)
+ Wumpus.Basic.Shapes.Derived: diamond :: (Real u, Floating u) => u -> u -> Shape u Diamond
- Wumpus.Basic.Shapes.Derived: ellipse :: (Real u, Floating u) => u -> u -> Shape u (Ellipse u)
+ Wumpus.Basic.Shapes.Derived: ellipse :: (Real u, Floating u) => u -> u -> Shape u Ellipse
- Wumpus.Basic.Shapes.Derived: rectangle :: (Real u, Floating u) => u -> u -> Shape u (Rectangle u)
+ Wumpus.Basic.Shapes.Derived: rectangle :: (Real u, Floating u) => u -> u -> Shape u Rectangle

Files

CHANGES view
@@ -1,5 +1,46 @@  +0.10.0 to 0.11.0:+ +  * Reworked arrowheads and connectors - connectors are now +    configurable: there are functions to make connectors with +    a left arrowhead, right arrowhead, none or both.  ++  * Reworked shapes - internally shapes now create a @Path@ rather +    than a @Graphic@ this means the path can be manipulated (e.g. +    round cornered rectangles, diamonds... can be constructed).+    @Coordinate@ is no longer a @Shape@ - it is now similar object +    but of a different type. Likewise, @FreeLabel@ has been +    replaced by @Plaintext@ which is not a @Shape@, but has some +    similar properties.++  * @Basic.Paths.Base@ - @Path@ type changed, @PathEmpty@ +    constructor removed so empty paths cannot be created. This +    allows a better API for taking points on a path. It also +    means @Path@ is no longer an instance of Monoid. Type changes +    to various functions (e.g. @tipR@, @tipL@) reflecting that as +    paths cannot now be empty, functions on them can generally be +    total. @toPrimPathU@ removed as converting to a PrimPath as +    now always /safe/. @tracePoints@ renamed @traceLinePoints@, +    @tracePointsCurve@ renamed @traceCurvePoints@, @midpoint@ +    renamed @midway@.++  * @Basic.Graphic@ - the types @ConnDrawingR@, @ConnGraphic@ etc.+    have had their names expanded to @ConnectorDrawingR@, +    @ConnectorGraphic@... ++  * @Basic.SafeFont@ - font names changed to use underscore +    separators rather than camelCase. Wumpus generally uses +    underscored names for /constants/.++  * Removed @conn@ from @Basic.Graphic.Drawing@. Connectors should +    be used instead.++  * The class @DrawingCtxM@ now has @Applicative@ as a superclass. ++  * @lineSpacing@ renamed @baselineSpacing@.++ 0.9.0 to 0.10.0:    * @Basic.Graphic.BaseClasses@ and @Basic.Graphic.BaseTypes@ 
+ demo/ArrowCircuit.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE TypeFamilies               #-}+{-# OPTIONS -Wall #-}+++-- Acknowledgment - the Arrow diagram is taken from Ross +-- Paterson\'s slides /Arrows and Computation/.+++module ArrowCircuit where++import Wumpus.Basic.Anchors+import Wumpus.Basic.Arrows+import Wumpus.Basic.Graphic+import Wumpus.Basic.Paths +import Wumpus.Basic.SafeFonts+import Wumpus.Basic.Shapes++import Wumpus.Core                      -- package: wumpus-core++import Data.AffineSpace++import System.Directory+++main :: IO ()+main = do +    createDirectoryIfMissing True "./out/"+    writeEPS_latin1 "./out/arrow_circuit.eps" pic1+    writeSVG_latin1 "./out/arrow_circuit.svg" pic1 ++times_ctx :: DrawingContext+times_ctx = fontface times_roman $ standardContext 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.+--+         +pic1 :: Picture Double +pic1 = liftToPictureU $ execDrawing times_ctx $ do+    a1 <- drawi $ strokedShape $ translate 0   72 $ rrectangle 12 66 30+    atext a1 "CONST 0"+    a2 <- drawi $ strokedShape $ translate 120 60 $ circle 16+    atext a2 "IF"+    a3 <- drawi $ strokedShape $ translate 240 28 $ circle 16+    atext a3 "+1"+    a4 <- drawi $ strokedShape $ translate 120  0 $ rectangle 66 30+    atext a4 "DELAY 0"+    connWith connect (east a1) (east a1 .+^ hvec 76)+    connWith connect (east a2) (east a2 .+^ hvec 180)+    connWith connect (north a2 .+^ vvec 40) (north a2)+    connWith connect (north a3 .+^ vvec 16) (north a3)  +    connWith vhconn  (south a3) (east a4)+    connWith (hvhconn (-30)) (west a4)  (southwest a2)+    ptext (P2  40  10) "next"+    ptext (P2 152 100) "reset"+    ptext (P2 252  72) "output"+    return ()+++-- Note - conn from Basic.Graphic is now questionable...++connWith :: ( TraceM m, DrawingCtxM m, u ~ MonUnit m+            , Real u, Floating u, FromPtSize u ) +         => ConnectorPath u -> Point2 u -> Point2 u -> m ()+connWith con p0 p1 = localize doublesize $ +    drawi_ $ strokeConnector (rightArrow con tri45) p0 p1+++atext :: ( CenterAnchor t, DUnit t ~ u+         , Real u, Floating u, FromPtSize u+         , TraceM m, DrawingCtxM m, u ~ MonUnit m )+      => t -> String -> m ()+atext ancr ss = let (P2 x y) = center ancr in+   drawi_ $ drawText $ translate x y $ plaintext ss+++ptext :: ( Real u, Floating u, FromPtSize u+         , TraceM m, DrawingCtxM m, u ~ MonUnit m )+      => Point2 u -> String -> m ()+ptext (P2 x y) ss = localize (fontsize 14 . fontface times_italic) $ +    drawi_ $ drawText $ translate x y $ plaintext ss
demo/ClipPic.hs view
@@ -40,7 +40,7 @@ pic = pic1 `nextToV` (stackOver [cpic1, cpic2, cpic3] cpic4)  fillPath :: Num u => Path u -> Graphic u-fillPath = filledPath . toPrimPathU+fillPath = filledPath . toPrimPath  pic1 :: DPicture pic1 = liftToPictureU $ execDrawing pic_drawing_ctx $ @@ -61,16 +61,16 @@      ps = unchain (coordinateScalingContext 86 16) $ tableDown 18 8  cpic1 :: DPicture -cpic1 = clip (toPrimPathU path01) (background black)+cpic1 = clip (toPrimPath path01) (background black)    cpic2 :: DPicture -cpic2 = clip (toPrimPathU path02) (background medium_violet_red)+cpic2 = clip (toPrimPath path02) (background medium_violet_red)  cpic3 :: DPicture -cpic3 = clip (toPrimPathU path03) (background black)+cpic3 = clip (toPrimPath path03) (background black)  cpic4 :: DPicture -cpic4 = clip (toPrimPathU path04) (background black)+cpic4 = clip (toPrimPath path04) (background black)   iheartHaskell :: Num u => FromPtSize u => Point2 u -> Drawing u () 
demo/FontPic.hs view
@@ -74,18 +74,18 @@  times_pic :: Picture Double times_pic = -    fontPicture [ (steel_blue,  timesRoman)-                , (indian_red1, timesItalic)-                , (steel_blue,  timesBold)-                , (indian_red1, timesBoldItalic)+    fontPicture [ (steel_blue,  times_roman)+                , (indian_red1, times_italic)+                , (steel_blue,  times_bold)+                , (indian_red1, times_bold_italic)                 ]   helvetica_pic :: Picture Double helvetica_pic =      fontPicture [ (steel_blue,  helvetica)-                , (indian_red1, helveticaOblique)-                , (steel_blue,  helveticaBold)-                , (indian_red1, helveticaBoldOblique)+                , (indian_red1, helvetica_oblique)+                , (steel_blue,  helvetica_bold)+                , (indian_red1, helvetica_bold_oblique)                 ]   @@ -95,9 +95,9 @@ courier_pic :: Picture Double courier_pic =      fontPicture [ (steel_blue,  courier)-                , (indian_red1, courierOblique)-                , (steel_blue,  courierBold)-                , (indian_red1, courierBoldOblique)+                , (indian_red1, courier_oblique)+                , (steel_blue,  courier_bold)+                , (indian_red1, courier_bold_oblique)                 ]   
demo/PetriNet.hs view
@@ -46,20 +46,20 @@               tl2    <- transition 210 0               r      <- place 280 0               tl3    <- transition 350 0-              connector (east pw)  (west tu1)              -              connector (east tu1) (west rtw)-              connector (east rtw) (west tu2)-              connector (east tu2) (west w)-              connector (east w)   (west tu3)+              connector' (east pw)  (west tu1)              +              connector' (east tu1) (west rtw)+              connector' (east rtw) (west tu2)+              connector' (east tu2) (west w)+              connector' (east w)   (west tu3)               connectorC 32 (north tu3) (north pw)-              connector (east pr)  (west tl1)              -              connector (east tl1) (west rtr)-              connector (east rtr) (west tl2)-              connector (east tl2) (west r)-              connector (east r)   (west tl3)+              connector' (east pr)  (west tl1)              +              connector' (east tl1) (west rtr)+              connector' (east rtr) (west tl2)+              connector' (east tl2) (west r)+              connector' (east r)   (west tl3)               connectorC (-32) (south tl3) (south pr)-              connector (southwest res) (northeast tl2)-              connector (northwest tl3) (southeast res)+              connector' (southwest res) (northeast tl2)+              connector' (northwest tl3) (southeast res)               connectorD 6    (southwest tu3) (northeast res)               connectorD (-6) (southwest tu3) (northeast res)                connectorD 6    (northwest res) (southeast tu2)@@ -81,33 +81,32 @@  place :: (Real u, Floating u, DrawingCtxM m, TraceM m, u ~ MonUnit m)        => u -> u -> m (Circle u)-place x y = greenFill $ drawi $ drawShape $ translate x y $ circle 14+place x y = greenFill $ drawi $ borderedShape $ translate x y $ circle 14  transition :: (Real u, Floating u, DrawingCtxM m, TraceM m, u ~ MonUnit m)             => u -> u -> m (Rectangle u)-transition x y = greenFill $ drawi $ drawShape $ translate x y $ rectangle 32 22+transition x y = greenFill $ drawi $ borderedShape $ translate x y $ rectangle 32 22 -connector :: ( Real u, Floating u, FromPtSize u-             , DrawingCtxM m, TraceM m, u ~ MonUnit m )-          => Point2 u -> Point2 u -> m ()-connector p1 p2 = do-   _ <- drawi $ arrowTri60 connect `conn` p1 $ p2-   return ()  ++connector' :: ( TraceM m, DrawingCtxM m, u ~ MonUnit m+         , Real u, Floating u, FromPtSize u ) +      => Point2 u -> Point2 u -> m ()+connector' p0 p1 = drawi_ $ strokeConnector (rightArrow connect 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 p1 p2 = do-    _ <- drawi $ arrowTri60 (vhvconn v) `conn` p1 $ p2-    return ()+connectorC v p0 p1 = +    drawi_ $ strokeConnector (rightArrow (vhvconn 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 p1 p2 = do-    _ <- drawi $ arrowTri60 (joint u) `conn` p1 $ p2-    return ()+connectorD u p0 p1 = +    drawi_ $ strokeConnector (rightArrow (joint u) tri45) p0 p1   lblParensParens :: Num u => LocGraphic u@@ -118,8 +117,8 @@   lblBold' :: Num u => String -> LocGraphic u-lblBold' ss = localize (fontface helveticaBold) . textline ss+lblBold' ss = localize (fontface helvetica_bold) . textline ss   lblBold :: (Fractional u, Ord u, FromPtSize u) => String -> LocGraphic u-lblBold ss = localize (fontface helveticaBold) . centermonoTextline ss+lblBold ss = localize (fontface helvetica_bold) . centermonoTextline ss
− demo/Shapes.hs
@@ -1,37 +0,0 @@-{-# OPTIONS -Wall #-}---module Shapes where--import Wumpus.Basic.Colour.SVGColours-import Wumpus.Basic.Graphic                     -- package: wumpus-basic-import Wumpus.Basic.Shapes.Base-import Wumpus.Basic.Shapes.Derived--import Wumpus.Core                              -- package: wumpus-core---import System.Directory----main :: IO ()-main = do -    createDirectoryIfMissing True "./out/"-    writeEPS_latin1 "./out/shapes01.eps" pic1-    writeSVG_latin1 "./out/shapes01.svg" pic1-    --pic1 :: DPicture-pic1 = liftToPictureU $ execDrawing (standardContext 14) $ do-         _ <- drawi $ drawShape $ translate 220 10 $ rotate30-                                                   $ lrectangle 90 30 "Rectangle"-         _ <- drawi $ drawShape $ translate 100  0 $ lcircle 10 "C0"-   -         _ <- localize (strokeColour red) $ -                       drawi $ drawShape $ translate 220 10 $ rotate30 $ coordinate-         _ <- drawi $ drawShape $ translate 0   40 $ ldiamond 10 10 "d1"-         _ <- drawi $ drawShape $ translate 400 50 $ lrectangle 20 100 "R2"-         return ()--
demo/Symbols.hs view
@@ -29,7 +29,7 @@     writeSVG_latin1 "./out/symbols.svg" pic1  std_ctx :: DrawingContext-std_ctx = fontface timesRoman $ standardContext 12+std_ctx = fontface times_roman $ standardContext 12  pic1 :: DPicture  pic1 = liftToPictureU $ execDrawing std_ctx $ do
src/Wumpus/Basic/Arrows.hs view
@@ -10,173 +10,19 @@ -- Stability   :  highly unstable -- Portability :  GHC ----- Draw arrows.------ \*\* WARNING \*\* - the types are /wrong/ here and need more --- thought.+-- Shim module for arrow connectors and arrowheads. --  --------------------------------------------------------------------------------  module Wumpus.Basic.Arrows   ( -    cline --  , arrowTri90-  , arrowTri60-  , arrowTri45-  , arrowOTri90-  , arrowOTri60-  , arrowOTri45--  , arrowBarb90-  , arrowBarb60-  , arrowBarb45-    -  , arrowPerp-  , arrowRBracket+    module Wumpus.Basic.Arrows.Tips+  , module Wumpus.Basic.Arrows.Connectors    ) where  import Wumpus.Basic.Arrows.Tips-import Wumpus.Basic.Graphic-import Wumpus.Basic.Paths-import Wumpus.Basic.Utils.Intersection ( langle )--import Wumpus.Core                      -- package: wumpus-core--import Control.Applicative-import Data.Monoid--liftConnector :: Connector u -> ConnDrawingR u (Path u)-liftConnector pF p1 p2 = pure $ pF p1 p2--cline :: Num u => Connector u -> ConnImage u (Path u)-cline pathF = intoConnImage (liftConnector pathF) (pathGraphic pathF)---- ... No - can\'t a add tips to this one.----pathGraphic :: Num u => Connector u -> ConnGraphic u-pathGraphic bpath = \p1 p2 -> openStroke $ toPrimPathU $ bpath p1 p2----- Here the path is already shortened - we have accounted for the--- points already, so it is just a graphic. -lineTipR :: Num u => Path u -> Graphic u -> Graphic u-lineTipR bpath arrtip = openStroke (toPrimPathU bpath) `mappend` arrtip-   ------ | Returns two items:--- --- 1. Shorten the line by the line width - this stops the path--- tip puncturing the arrow head (particulary visible on open --- triangle tips).--- --- 2. Calculate the direction back along the line at half the --- lower_x_height - this gets a good angle for the tip on curved--- path segments.----rightPathProps :: (Real u, Floating u, FromPtSize u) -               => Connector u -> ConnDrawingR u (Path u,Radian)-rightPathProps pathF p1 p2 = -    (\h sw -> (shortenPath h sw, calcTheta h))-      <$> markHeight <*> lineWidth-  where-    long_path          = pathF p1 p2  -    shortenPath lxh sw = shortenR (lxh + (realToFrac sw)) long_path -    calcTheta lxh      = directionR $ shortenR (0.5*lxh) long_path-----triTipRight :: (Real u, Floating u, FromPtSize u) -            => Connector u -> (Radian -> LocGraphic u) -> ConnImage u (Path u) -triTipRight pathF tipF p1 p2 =-    rightPathProps pathF p1 p2          >>= \(shortF,theta) -> -    lineTipR shortF (tipF theta p2)     >>= \arrow_pic      ->-    return (pathF p1 p2, arrow_pic)------- This version does not /retract/ the path...----barbTipRight :: (Real u, Floating u, FromPtSize u) -             => Connector u -> (Radian -> LocGraphic u) -> ConnImage u (Path u)  -barbTipRight pathF tipF p1 p2 = -    rightPathProps pathF p1 p2          >>= \(_,theta) -> -    lineTipR path_zero (tipF theta p2)  >>= \arrow_pic  ->-    return (path_zero, arrow_pic)-  where-    path_zero = pathF p1 p2----arrowTri90 :: (Real u, Floating u, FromPtSize u) -           => Connector u -> ConnImage u (Path u)-arrowTri90 pathF = triTipRight pathF tri90- -          ---arrowTri60 :: (Real u, Floating u, FromPtSize u) -           => Connector u -> ConnImage u (Path u)-arrowTri60 pathF = triTipRight pathF tri60-- -arrowTri45 :: (Real u, Floating u, FromPtSize u) -           => Connector u -> ConnImage u (Path u)-arrowTri45 pathF = triTipRight pathF tri45---arrowOTri90 :: (Real u, Floating u, FromPtSize u) -            => Connector u -> ConnImage u (Path u)-arrowOTri90 pathF = triTipRight pathF otri90-     --arrowOTri60 :: (Real u, Floating u, FromPtSize u) -            => Connector u -> ConnImage u (Path u)-arrowOTri60 pathF = triTipRight pathF otri60 ----arrowOTri45 :: (Real u, Floating u, FromPtSize u) -            => Connector u -> ConnImage u (Path u)-arrowOTri45 pathF = triTipRight pathF otri45----arrowBarb90 :: (Real u, Floating u, FromPtSize u) -            => Connector u -> ConnImage u (Path u)-arrowBarb90 pathF = barbTipRight pathF barb90--arrowBarb60 :: (Real u, Floating u, FromPtSize u) -            => Connector u -> ConnImage u (Path u)-arrowBarb60 pathF = barbTipRight pathF barb60--arrowBarb45 :: (Real u, Floating u, FromPtSize u) -            => Connector u -> ConnImage u (Path u)-arrowBarb45 pathF = barbTipRight pathF barb45---                     -arrowPerp :: (Real u, Floating u, FromPtSize u) -          => Connector u -> ConnImage u (Path u)-arrowPerp pathF p1 p2 = -    lineTipR path_zero perp_tip >>= \arrow_pic -> return (path_zero, arrow_pic)-  where-    path_zero = pathF  p1 p2-    theta     = langle p1 p2-    perp_tip  = perp theta p2+import Wumpus.Basic.Arrows.Connectors  -arrowRBracket :: (Real u, Floating u, FromPtSize u) -              => Connector u -> ConnImage u (Path u)-arrowRBracket pathF p1 p2 = -    lineTipR path_zero perp_tip >>= \arrow_pic -> return (path_zero, arrow_pic)-  where-    path_zero = pathF  p1 p2-    theta     = langle p1 p2-    perp_tip  = rbracket theta p2
+ src/Wumpus/Basic/Arrows/Connectors.hs view
@@ -0,0 +1,136 @@+{-# 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.+--+-- \*\* WARNING \*\* - the types are /wrong/ here and need more +-- thought.+-- +--------------------------------------------------------------------------------++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 Data.Monoid++-- An arrowhead always know how to draws itself (filled tri, +-- 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.+++-- larrow :: Arrowhead u -> ConnectorPath u -> WrappedConnector u+++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) = \p0 p1 ->+    let pathc = cpF p0 p1 in +    (fn pathc opt_la p0 opt_ra p1) >>= \grafic ->+    intoImage (return pathc) grafic+  where+    fn pathc ma p0 mb p1 = do +       (path1,tipl) <- applyTipL ma p0 pathc+       (path2,tipr) <- applyTipR mb p1 path1+       return $ (openStroke $ toPrimPath path2) `mappend` tipl `mappend` tipr+   +++applyTipL :: (Real u, Floating u) +          => Maybe (Arrowhead u) -> Point2 u -> Path u +          -> DrawingR (Path u, Graphic u)+applyTipL Nothing    _   pathc = return (pathc,mempty)+applyTipL (Just arw) ptL pathc = +    retract_dist arw >>= \ dx -> +    if dx > 0 then return (shortenL dx pathc, grafik) +              else return (pathc, grafik)+  where+    grafik = (arrow_draw arw) (directionL pathc) ptL++applyTipR :: (Real u, Floating u) +          => Maybe (Arrowhead u) -> Point2 u -> Path u +          -> DrawingR (Path u, Graphic u)+applyTipR Nothing    _   pathc = return (pathc,mempty)+applyTipR (Just arw) ptR pathc = +    retract_dist arw >>= \dx -> +    if dx > 0 then return (shortenR dx pathc, grafik) +              else return (pathc, grafik)+  where+    grafik = (arrow_draw arw) (directionR pathc) ptR +
src/Wumpus/Basic/Arrows/Tips.hs view
@@ -20,8 +20,10 @@ module Wumpus.Basic.Arrows.Tips   (  +    Arrowhead(..)+  , arrowheadTip -    tri90+  , tri90   , tri60   , tri45   , otri90@@ -46,8 +48,15 @@  import Control.Applicative +data Arrowhead u = Arrowhead+      { retract_dist :: DrawingR u+      , arrow_draw   :: ThetaLocGraphic u +      }  +arrowheadTip :: Arrowhead u -> Radian -> LocGraphic u+arrowheadTip (Arrowhead _ gf) theta = gf theta+ -- | Tiplen is length of the tip \*along the line it follows\*.  -- -- > |\@@ -85,6 +94,7 @@     vec_to_lower = avec (circularModulo $ rtheta + halfang) hypo_len   +{- -- | This one is for triangles when the tip height and tip width -- are known. --@@ -97,8 +107,17 @@     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 +-}  +++mark_height_plus_line_width :: (Fractional u, FromPtSize u) => DrawingR u+mark_height_plus_line_width = +    (\h lw -> h + realToFrac lw) <$> markHeight <*> lineWidth+++ --------------------------------------------------------------------------------  -- | Tripoints takes the \*tip length\* is the mark height.@@ -108,22 +127,22 @@ -- does it!). -- tripointsByAngle :: (Floating u, FromPtSize u)-                 => Radian -> Radian -> LocDrawingR u (Point2 u, Point2 u)+                 => Radian ->  ThetaLocDrawingR u (Point2 u, Point2 u) tripointsByAngle triang theta tip =      (\h -> let (vupper,vlower) = triVecsByAngle h (0.5*triang) theta            in  (tip .+^ vupper, tip .+^ vlower))       <$> markHeight  -+{- tripointsByDist :: (Real u, Floating u, FromPtSize u)-                => (u -> u) -> (u -> u) -> Radian -                -> LocDrawingR u (Point2 u, Point2 u)+                => (u -> u) -> (u -> u)  +                -> ThetaLocDrawingR u (Point2 u, Point2 u) tripointsByDist lenF halfwidthF theta tip =      (\h -> let (vup,vlo) = triVecsByDist (lenF h) (halfwidthF $ 0.5*h) theta            in  (tip .+^ vup, tip .+^ vlo))       <$> markHeight-+-}   @@ -131,11 +150,8 @@ -- filled with stroke colour!  triAng :: (Floating u, Real u, FromPtSize u)-      => Radian -      -> Radian-      -> (PrimPath u -> Graphic u) -      -> LocGraphic u-triAng triang theta gf pt = +       => Radian -> (PrimPath u -> Graphic u) -> ThetaLocGraphic u+triAng triang gf theta pt =      tripointsByAngle triang theta pt >>= \(u,v) ->      localize bothStrokeColour (gf $  vertexPath [pt,u,v]) @@ -143,65 +159,59 @@  -- TODO - maybe filling needs to use swapColours -tri90 :: (Floating u, Real u, FromPtSize u)-      => Radian -> LocGraphic u-tri90 theta = triAng (pi/2) theta filledPath+tri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+tri90 = Arrowhead markHeight (triAng (pi/2) filledPath)  -tri60 :: (Floating u, Real u, FromPtSize u)-      => Radian -> LocGraphic u-tri60 theta = triAng (pi/3) theta filledPath+tri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+tri60 = Arrowhead markHeight (triAng (pi/3) filledPath)  -tri45 :: (Floating u, Real u, FromPtSize u)-      => Radian -> LocGraphic u-tri45 theta = triAng (pi/4) theta filledPath+tri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+tri45 = Arrowhead markHeight (triAng (pi/4) filledPath) +otri90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+otri90 = Arrowhead mark_height_plus_line_width (triAng (pi/2) closedStroke) -otri90 :: (Floating u, Real u, FromPtSize u)-      => Radian -> LocGraphic u-otri90 theta = triAng (pi/2) theta closedStroke+otri60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+otri60 = Arrowhead mark_height_plus_line_width (triAng (pi/3) closedStroke) +otri45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+otri45 = Arrowhead mark_height_plus_line_width (triAng (pi/4) closedStroke) -otri60 :: (Floating u, Real u, FromPtSize u)-      => Radian -> LocGraphic u-otri60 theta = triAng (pi/3) theta closedStroke -otri45 :: (Floating u, Real u, FromPtSize u)-      => Radian -> LocGraphic u-otri45 theta = triAng (pi/4) theta closedStroke -barbAng :: (Floating u, Real u, FromPtSize u)-      => Radian -> Radian -> LocGraphic u+barbAng :: (Floating u, Real u, FromPtSize u) => Radian -> ThetaLocGraphic u barbAng ang theta pt =      tripointsByAngle ang theta pt >>= \(u,v) ->      openStroke (vertexPath [u,pt,v])  -barb90 :: (Floating u, Real u, FromPtSize u) -       => Radian -> LocGraphic u-barb90 = barbAng (pi/2)+barb90 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+barb90 = Arrowhead (pure 0) (barbAng (pi/2)) -barb60 :: (Floating u, Real u, FromPtSize u) -       => Radian -> LocGraphic u-barb60 = barbAng (pi/3)+barb60 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+barb60 = Arrowhead (pure 0) (barbAng (pi/3)) -barb45 :: (Floating u, Real u, FromPtSize u) -       => Radian -> LocGraphic u-barb45 = barbAng (pi/4) +barb45 :: (Floating u, Real u, FromPtSize u) => Arrowhead u+barb45 = Arrowhead (pure 0) (barbAng (pi/4))  -perp :: (Floating u, FromPtSize u) => Radian -> LocGraphic u-perp theta pt =  ++perpAng :: (Floating u, FromPtSize u) => ThetaLocGraphic u+perpAng theta pt =       markHeight >>= \ h ->      let v = makeV h in openStroke $ vertexPath [ pt .+^ v, pt .-^ v]   where     makeV h  = avec (theta + pi/2) (0.5 * h)  -rbracket :: (Floating u, FromPtSize u) => Radian -> LocGraphic u-rbracket theta pt = markHalfHeight >>= \hh -> +perp :: (Floating u, FromPtSize u) => Arrowhead u+perp = Arrowhead (pure 0) perpAng++rbracketAng :: (Floating u, FromPtSize u) => ThetaLocGraphic u+rbracketAng theta pt = markHalfHeight >>= \hh ->     runDirection theta $       displacePerp   hh  pt >>= \p1 ->      displacePara (-hh) p1 >>= \p0 ->@@ -209,3 +219,6 @@      displacePara (-hh) p2 >>= \p3 ->      return (openStroke $ vertexPath [p0,p1,p2,p3])     ++rbracket :: (Floating u, FromPtSize u) => Arrowhead u+rbracket = Arrowhead (pure 0) rbracketAng
src/Wumpus/Basic/Graphic/Base.hs view
@@ -16,9 +16,10 @@ --  -- Base classes for monadic drawing. ----- Note on suffix names. Function types suffixed @F@ are functions --- from same-to-same, e.g.:+-- Notes on prefix and suffix names: --+-- Function types suffixed @F@ are functions from same-to-same, e.g.:+-- -- > type Point2F u = Point2 u -> Point2 u -- -- Functional types subfixed @R@ are functions from some static @@ -28,6 +29,12 @@ -- -- The suffix @M@ is used for classes defining monadic actions. --+-- The prefix @Loc@ indicates a functional type +-- /from Point2 to something.../+-- +-- The prefix @ThetaLoc@ indicates a functional type +-- /from Direction (radian) then Point to something.../+-- -- \*\* WARNING \*\* - some names are expected to change. -- --------------------------------------------------------------------------------@@ -77,15 +84,22 @@   , intoLocImage   , xlinkImage -  , ConnDrawingR-  , DConnDrawingR-  , ConnGraphic-  , DConnGraphic-  , ConnImage-  , DConnImage+  , ConnectorDrawingR+  , DConnectorDrawingR+  , ConnectorGraphic+  , DConnectorGraphic+  , ConnectorImage+  , DConnectorImage -  , intoConnImage+  , intoConnectorImage +  , ThetaLocDrawingR+  , DThetaLocDrawingR+  , ThetaLocGraphic+  , DThetaLocGraphic+  , ThetaLocImage+  , DThetaLocImage+   ) where  import Wumpus.Basic.Graphic.DrawingContext@@ -114,7 +128,7 @@ class Monad m => TraceM (m :: * -> *) where   trace  :: HPrim (MonUnit m) -> m () -class Monad m => DrawingCtxM (m :: * -> *) where+class (Applicative m, Monad m) => DrawingCtxM (m :: * -> *) where   askDC    :: m DrawingContext   localize :: (DrawingContext -> DrawingContext) -> m a -> m a @@ -306,28 +320,46 @@ -------------------------------------------------------------------------------- -- -type ConnDrawingR u a = Point2 u -> Point2 u -> DrawingR a+type ConnectorDrawingR u a = Point2 u -> Point2 u -> DrawingR a -type DConnDrawingR a = ConnDrawingR Double a+type DConnectorDrawingR a = ConnectorDrawingR Double a --- | ConnGraphic is a connector drawn between two points +-- | ConnectorGraphic is a connector drawn between two points  -- contructing a Graphic. ---type ConnGraphic u = Point2 u -> Point2 u -> Graphic u+type ConnectorGraphic u = Point2 u -> Point2 u -> Graphic u -type DConnGraphic = ConnGraphic Double+type DConnectorGraphic = ConnectorGraphic Double  -- | ConImage is a connector drawn between two points  -- constructing an Image. ---type ConnImage u a = Point2 u -> Point2 u -> Image u a+type ConnectorImage u a = Point2 u -> Point2 u -> Image u a -type DConnImage a = ConnImage Double a+type DConnectorImage a = ConnectorImage Double a  -intoConnImage :: ConnDrawingR u a -> ConnGraphic u -> ConnImage u a-intoConnImage f g p1 p2 = DrawingR $ \ctx -> +intoConnectorImage :: ConnectorDrawingR u a +                   -> ConnectorGraphic u +                   -> ConnectorImage u a+intoConnectorImage f g p1 p2 = DrawingR $ \ctx ->      let a = getDrawingR (f p1 p2) ctx; o = getDrawingR (g p1 p2) ctx in (a,o)++++type ThetaLocDrawingR u a = Radian -> LocDrawingR u a ++type DThetaLocDrawingR a = ThetaLocDrawingR Double a++-- | A function from /Radian -\> Point -\> Graphic/...+--+type ThetaLocGraphic u = Radian -> LocGraphic u++type DThetaLocGraphic = ThetaLocGraphic Double++type ThetaLocImage u a = Radian -> LocImage u a++type DThetaLocImage a = ThetaLocImage Double a    
src/Wumpus/Basic/Graphic/Drawing.hs view
@@ -27,8 +27,10 @@   , DrawingT   , runDrawing   , execDrawing+  , evalDrawing   , runDrawingT   , execDrawingT+  , evalDrawingT    , runFdcDrawing   , execFdcDrawing@@ -42,11 +44,12 @@   , draw   , xdraw   , drawi+  , drawi_   , xdrawi+  , xdrawi_    , at   , ati-  , conn    , node   , nodei@@ -181,17 +184,36 @@ runDrawing :: DrawingContext -> Drawing u a -> (a, HPrim u) runDrawing ctx ma = getDrawing ma ctx mempty +-- | Run the drawing returning only the output it produces, drop+-- any answer from the monadic computation.+-- execDrawing :: DrawingContext -> Drawing u a -> HPrim u execDrawing ctx ma = snd $ runDrawing ctx ma +-- | Run the drawing ignoring the output it produces, return the +-- answer from the monadic computation.+--+-- Note - this useful for testing, generally one would want the +-- opposite behaviour (return the drawing, ignore than the +-- answer).+-- +evalDrawing :: DrawingContext -> Drawing u a -> a+evalDrawing ctx ma = fst $ runDrawing ctx ma  + runDrawingT :: Monad m => DrawingContext -> DrawingT u m a -> m (a, HPrim u)  runDrawingT ctx ma = getDrawingT ma ctx mempty  execDrawingT :: Monad m => DrawingContext -> DrawingT u m a -> m (HPrim u) execDrawingT ctx ma = liftM snd $ runDrawingT ctx ma ++evalDrawingT :: Monad m => DrawingContext -> DrawingT u m a -> m a+evalDrawingT ctx ma = liftM fst $ runDrawingT ctx ma+++ -- | Run the Drawing generating a Picture /within/ a  -- \"font delta context\" using the font-family and font-size  -- from the intial DrawingContext.@@ -300,6 +322,12 @@ drawi img = askDC >>= \ctx ->              let (a,o) = runImage ctx img in trace 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) @@ -307,6 +335,11 @@ xdrawi xl img = drawi (xlinkImage xl img)  +-- | Forgetful 'xdrawi'.+--+xdrawi_ ::  (TraceM m, DrawingCtxM m, u ~ MonUnit m) +        => XLink -> Image u a -> m ()+xdrawi_ xl img = xdrawi xl img >> return ()   infixr 1 `at`, `ati`@@ -317,11 +350,11 @@ ati = ($)  -+{- infixl 1 `conn`-conn :: ConnImage u a -> Point2 u -> LocImage u a+conn :: ConnectorImage u a -> Point2 u -> LocImage u a conn = ($)-+-}  node :: (TraceM m, DrawingCtxM m, PointSupplyM m, u ~ MonUnit m)       => LocGraphic u -> m ()
src/Wumpus/Basic/Graphic/PrimGraphic.hs view
@@ -119,6 +119,11 @@ borderedPath pp =      withBorderedAttr $ \frgb attr srgb -> singleH $ fillStroke frgb attr srgb pp ++-- Note - clipping needs a picture as well as a path, so there is+-- no analogous @clippedPath@ function.++ -------------------------------------------------------------------------------- --  @@ -142,11 +147,13 @@   --- | Point is the baseline left of the bottom line.+-- | Point is the baseline left of the bottom line, text is +-- left-aligned. -- textlineMulti :: Fractional u => [String] -> LocGraphic u textlineMulti xs baseline_left = liftM snd $ -    lineSpacing >>= \dy -> foldrM (foldStep dy) (baseline_left,mempty) xs+    baselineSpacing >>= \dy -> +    foldrM (foldStep dy) (baseline_left,mempty) xs   where     foldStep dy str (pt,gfic) = (\a -> (pt .+^ vvec dy, a `mappend` gfic))                                     <$> textline str pt
src/Wumpus/Basic/Graphic/Query.hs view
@@ -34,7 +34,7 @@   , fontSize   , markHeight   , markHalfHeight-  , lineSpacing+  , baselineSpacing    --    , monoCharWidth@@ -46,6 +46,8 @@   , monoLowerxHeight   , monoDescenderDepth   , monoTextDimensions+  , monoMultiLineTextHeight+  , monoDefaultPadding   , monoVecToCenter     ) where @@ -58,37 +60,34 @@ import Control.Applicative  -textAttr :: (Applicative m, DrawingCtxM m) => m (RGBi,FontAttr)+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 :: (Applicative m, DrawingCtxM m) -             => (RGBi -> FontAttr -> a) -> m a+withTextAttr :: DrawingCtxM m => (RGBi -> FontAttr -> a) -> m a withTextAttr fn = fn <$> asksDC stroke_colour <*> asksDC font_props  -strokeAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, StrokeAttr)+strokeAttr :: DrawingCtxM m => m (RGBi, StrokeAttr) strokeAttr = (,) <$> asksDC stroke_colour <*> asksDC stroke_props -withStrokeAttr :: (Applicative m, DrawingCtxM m) -               => (RGBi -> StrokeAttr -> a) -> m a+withStrokeAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> a) -> m a withStrokeAttr fn = fn <$> asksDC stroke_colour <*> asksDC stroke_props  -fillAttr :: (Applicative m, DrawingCtxM m) => m RGBi+fillAttr :: DrawingCtxM m => m RGBi fillAttr = asksDC fill_colour -withFillAttr :: (Applicative m, DrawingCtxM m) => (RGBi -> a) -> m a+withFillAttr :: DrawingCtxM m => (RGBi -> a) -> m a withFillAttr fn = fn <$> asksDC fill_colour -borderedAttr :: (Applicative m, DrawingCtxM m) => m (RGBi, StrokeAttr, RGBi)+borderedAttr :: DrawingCtxM m => m (RGBi, StrokeAttr, RGBi) borderedAttr = (,,) <$> asksDC fill_colour <*> asksDC stroke_props                                             <*> asksDC stroke_colour -withBorderedAttr :: (Applicative m, DrawingCtxM m) -                 => (RGBi -> StrokeAttr -> RGBi -> a) -> m a+withBorderedAttr :: DrawingCtxM m => (RGBi -> StrokeAttr -> RGBi -> a) -> m a withBorderedAttr fn =      fn <$> asksDC fill_colour <*> asksDC stroke_props                                <*> asksDC stroke_colour@@ -96,28 +95,21 @@   -lineWidth :: (Applicative m, DrawingCtxM m) => m Double+lineWidth :: DrawingCtxM m => m Double lineWidth = line_width <$> asksDC stroke_props -fontSize :: (Applicative m, DrawingCtxM m) => m Int+fontSize :: DrawingCtxM m => m Int fontSize = font_size <$> asksDC font_props    --- Maybe these functions are better as queries - i.e. functions--- of type DrawingR, e.g.--- --- > lineSpacing :: Fractional u => DrawingR u--- --- Then the /client/ can just bound the answer directly--- rather than using ------ > askDF lineSpacing >>= \u -> ...--- -lineSpacing :: (Applicative m, DrawingCtxM m, Fractional u) => m u-lineSpacing = +-- | 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 @@ -127,12 +119,11 @@ -- Arrowheads, dots etc. should generally be drawn at the mark  -- height. -- -markHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u+markHeight :: (DrawingCtxM m, FromPtSize u) => m u markHeight = (fromPtSize . xcharHeight . font_size) <$> asksDC font_props  -markHalfHeight :: (Applicative m, DrawingCtxM m, Fractional u, FromPtSize u) -               => m u+markHalfHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) => m u markHalfHeight = (0.5*) <$> markHeight  @@ -146,28 +137,28 @@  -------------------------------------------------------------------------------- -withFontSize :: (Applicative m, DrawingCtxM m) => (FontSize -> u) -> m u+withFontSize :: DrawingCtxM m => (FontSize -> u) -> m u withFontSize fn = (fn . font_size) <$> asksDC font_props -monoCharWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u+monoCharWidth :: (DrawingCtxM m, FromPtSize u) => m u monoCharWidth = withFontSize (fromPtSize . charWidth) -monoSpacerWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u+monoSpacerWidth :: (DrawingCtxM m, FromPtSize u) => m u monoSpacerWidth = withFontSize (fromPtSize . spacerWidth)  -monoTextWidth :: (Applicative m, DrawingCtxM m, FromPtSize u) => Int -> m u+monoTextWidth :: (DrawingCtxM m, FromPtSize u) => Int -> m u monoTextWidth n = withFontSize $ \sz -> fromPtSize $ textWidth sz n  -monoTextLength :: (Applicative m, DrawingCtxM m, FromPtSize u) => String -> m u+monoTextLength :: (DrawingCtxM m, FromPtSize u) => String -> m u monoTextLength ss = monoTextWidth $ charCount ss  -monoTextHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u+monoTextHeight :: (DrawingCtxM m, FromPtSize u) => m u monoTextHeight = withFontSize (fromPtSize . textHeight) -monoNumeralHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u+monoNumeralHeight :: (DrawingCtxM m, FromPtSize u) => m u monoNumeralHeight = withFontSize (fromPtSize . numeralHeight)  @@ -175,10 +166,10 @@ --   -- \'x\' has no ascenders or descenders.  -- -monoLowerxHeight :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u+monoLowerxHeight :: (DrawingCtxM m, FromPtSize u) => m u monoLowerxHeight = withFontSize (fromPtSize . xcharHeight) -monoDescenderDepth :: (Applicative m, DrawingCtxM m, FromPtSize u) => m u+monoDescenderDepth :: (DrawingCtxM m, FromPtSize u) => m u monoDescenderDepth = withFontSize (fromPtSize . descenderDepth)  @@ -188,7 +179,7 @@ -- Note - the width will generally be a over-estimate for  -- non-monospaced fonts. -- -monoTextDimensions :: (Applicative m, DrawingCtxM m, Num u, Ord u, FromPtSize u)+monoTextDimensions :: (DrawingCtxM m, Num u, Ord u, FromPtSize u)                    => String -> m (u,u) monoTextDimensions ss =      (\sz -> post $ textBounds sz zeroPt ss) @@ -197,9 +188,22 @@     post bb = (boundaryWidth bb, boundaryHeight bb)  +monoMultiLineTextHeight :: (DrawingCtxM m, Fractional u, FromPtSize u) +                        => Int -> m u+monoMultiLineTextHeight n | n < 0   = pure 0+monoMultiLineTextHeight n           = +    (\h lsf -> h + (fromIntegral $ n-1) * (h * realToFrac lsf))+      <$> monoTextHeight <*> asksDC line_spacing_factor+ ++-- | 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 :: ( Applicative m, DrawingCtxM m-                   , Fractional u, Ord u, FromPtSize u ) +--+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/Paths/Base.hs view
@@ -26,15 +26,16 @@     Path   , DPath   , length+  , append+  , pconcat   , line   , curve-  , tracePoints+  , traceLinePoints+  , traceCurvePoints   , curveByAngles    , toPrimPath -  , toPrimPathU -   , tipL   , tipR @@ -44,7 +45,12 @@   , directionL   , directionR -  , midpoint+  , midway+  , midway_+  , atstart+  , atstart_+  , atend+  , atend_    , PathViewL(..)   , DPathViewL@@ -63,16 +69,14 @@ import Data.AffineSpace import Data.VectorSpace -import Data.Maybe-import Data.Monoid+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 = PathEmpty -            | Path { _path_length   :: u +data Path u = Path { _path_length   :: u                     , _path_start    :: Point2 u                    , _path_elements :: Seq (PathSeg u)                    , _path_end      :: Point2 u@@ -82,7 +86,7 @@ type DPath = Path Double  -- Annotating each segment with length is \*\* good \*\*.--- Makes it much more efficient to find the midpoint.+-- Makes it much more efficient to find the midway point. -- -- But what do we do about the start point: --@@ -116,24 +120,17 @@   length :: Num u => Path u -> u-length PathEmpty      = 0 length (Path u _ _ _) = u  append :: Floating u => Path u -> Path u -> Path u-append PathEmpty b         = b-append a         PathEmpty = a 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  --instance Floating u => Monoid (Path u) where-  mempty  = PathEmpty-  mappend = append--+pconcat :: Floating u => Path u -> [Path u] -> Path u+pconcat p0 ps = foldl' append p0 ps  segmentLength :: PathSeg u -> u segmentLength (LineSeg u _ _)       = u@@ -164,16 +161,35 @@ 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 --tracePoints :: Floating u => [Point2 u] -> Path u-tracePoints []       = PathEmpty-tracePoints [a]      = line a a-tracePoints (a:b:xs) = step (line a b) b xs+-- | '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 `mappend` line e y) y ys+    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@@ -186,21 +202,16 @@  -- | Turn a Path into an ordinary PrimPath. ----- An empty path returns Nothing - the path representation in --- Wumpus-Core does not allow empty paths - a path must always--- have at least start point.--- -- 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 :: Path u -> Maybe (PrimPath u)-toPrimPath PathEmpty         = Nothing+toPrimPath :: Path u -> PrimPath u toPrimPath (Path _ _ segs _) = step1 $ viewl segs   where-    step1 EmptyL                  = Nothing+    step1 EmptyL                  = error "toPrimPath - (not) unreachable."     step1 (e :< se)               = let (start,a) = seg1 e in -                                    Just $ path start $ a : step2 (viewl se)+                                    path start $ a : step2 (viewl se)      step2 EmptyL                  = []     step2 (e :< se)               = seg2 e : step2 (viewl se)@@ -210,11 +221,6 @@       seg2 (LineSeg  _ _  p1)       = lineTo p1     seg2 (CurveSeg _ _  p1 p2 p3) = curveTo p1 p2 p3- -toPrimPathU :: Path u -> PrimPath u-toPrimPathU = fromMaybe errK . toPrimPath-  where-    errK = error "toPathU - empty Path"   @@ -250,7 +256,7 @@ cordLength (Curve p0 _ _ p3) = vlength $ pvec p0 p3  --- | midpoint between two points+-- | mid-point between two points -- pointMidpoint :: Fractional u => Point2 u -> Point2 u -> Point2 u pointMidpoint p0 p1 = p0 .+^ v1 ^/ 2 where v1 = p1 .-. p0@@ -290,31 +296,34 @@ -------------------------------------------------------------------------------- -- tips  -tipL :: Path u -> Maybe (Point2 u)-tipL PathEmpty       = Nothing-tipL (Path _ sp _ _) = Just sp+tipL :: Path u -> Point2 u+tipL (Path _ sp _ _) = sp  -tipR :: Path u -> Maybe (Point2 u)-tipR PathEmpty       = Nothing-tipR (Path _ _ _ ep) = Just ep+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 _ PathEmpty          = PathEmpty shortenL n (Path u _ segs ep) -    | n >= u                  = PathEmpty+    | n >= u                  = line ep ep     | otherwise               = step n (viewl segs)   where-    step _ EmptyL     = PathEmpty+    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)@@ -323,10 +332,10 @@                                 in Path (u-n) (segmentStart e1) (e1 <| se) ep  -makeLeftPath :: u -> Seq (PathSeg u) -> Point2 u -> Path u+makeLeftPath :: Floating u => u -> Seq (PathSeg u) -> Point2 u -> Path u makeLeftPath u se ep =      case viewl se of-      EmptyL   -> PathEmpty +      EmptyL   -> line ep ep       (e :< _) -> Path u (segmentStart e) se ep  @@ -351,13 +360,16 @@ -------------------------------------------------------------------------------- -- 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 _ PathEmpty          = PathEmpty shortenR n (Path u sp segs _) -    | n >= u                  = PathEmpty+    | n >= u                  = line sp sp     | otherwise               = step n (viewr segs)   where-    step _ EmptyR     = PathEmpty+    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)@@ -366,10 +378,10 @@                                 in Path (u-n) sp (se |> e1) (segmentEnd e1)                           -makeRightPath :: u -> Point2 u -> Seq (PathSeg u) -> Path u+makeRightPath :: Floating u => u -> Point2 u -> Seq (PathSeg u) -> Path u makeRightPath u sp se =      case viewr se of-      EmptyR   -> PathEmpty +      EmptyR   -> line sp sp       (_ :> e) -> Path u sp se (segmentEnd e)  @@ -399,33 +411,22 @@ -- | Direction of empty path is considered to be 0. -- directionL :: (Real u, Floating u) => Path u -> Radian-directionL PathEmpty        = 0 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+    step _                            = 0       -- should be unreachable   -- | Direction of empty path is considered to be 0. -- directionR :: (Real u, Floating u) => Path u -> Radian-directionR PathEmpty       = 0 directionR (Path _ _ se _) = step $ viewr se   where     step (_ :> LineSeg  _ p0 p1)      = lineDirection p0 p1     step (_ :> CurveSeg _ _  _ p2 p3) = lineDirection p2 p3-    step _                            = 0+    step _                            = 0       -- should be unreachable              -{---- Note - previously Paths were using this version of --- lineDirection--- --- Needs testing as to whether the new one does what is expected. ----lineDirection :: (Real u, Floating u) => Point2 u -> Point2 u -> Radian-lineDirection p0 p1 = direction (pvec p0 p1)--}   @@ -434,22 +435,44 @@  -- Return direction as well because the calculation is expensive... ---midpoint :: (Real u, Floating u) => Path u -> Maybe (Point2 u, Radian)-midpoint pa = let u = length pa in-  if u == 0 then Nothing -            else let pa1 = shortenR (u/2) pa -                 in fmap (\a -> (a,directionR pa1)) $ tipR pa1+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 = EmptyPathL+data PathViewL u = PathOneL (PathSegment u)                  | PathSegment u :<< Path u   deriving (Eq,Ord,Show)   type DPathViewL = PathViewL Double -data PathViewR u = EmptyPathR+data PathViewR u = PathOneR (PathSegment u)                  | Path u :>> PathSegment u   deriving (Eq,Ord,Show)  @@ -467,16 +490,29 @@ type instance DUnit (PathSegment u) = u  pathViewL :: Num u => Path u -> PathViewL u-pathViewL PathEmpty          = EmptyPathL-pathViewL (Path u _ segs ep) = case viewl segs of-    EmptyL                         -> EmptyPathL -    (LineSeg v p0 p1 :< se)        -> Line1 p0 p1 :<< Path (u-v) p1 se ep-    (CurveSeg v p0 p1 p2 p3 :< se) -> Curve1 p0 p1 p2 p3 :<< Path (u-v) p3 se ep+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 PathEmpty          = EmptyPathR-pathViewR (Path u _ segs ep) = case viewr segs of-    EmptyR                         -> EmptyPathR-    (se :> LineSeg v p0 p1)        -> Path (u-v) p1 se ep :>> Line1 p0 p1-    (se :> CurveSeg v p0 p1 p2 p3) -> Path (u-v) p3 se ep :>> Curve1 p0 p1 p2 p3+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 view
@@ -20,7 +20,7 @@ module Wumpus.Basic.Paths.Connectors    (  -    Connector+    ConnectorPath   , connect   , vhconn   , hvconn@@ -41,39 +41,39 @@  import Prelude hiding ( length ) -type Connector u = Point2 u -> Point2 u -> Path u+type ConnectorPath u = Point2 u -> Point2 u -> Path u -connect :: Floating u => Connector u+connect :: Floating u => ConnectorPath u connect = line -vhconn :: Floating u => Connector u+vhconn :: Floating u => ConnectorPath u vhconn p1@(P2 x1 _) p2@(P2 _ y2) = -    let mid = P2 x1 y2 in tracePoints [p1, mid, p2]+    let mid = P2 x1 y2 in traceLinePoints [p1, mid, p2] -hvconn :: Floating u => Connector u+hvconn :: Floating u => ConnectorPath u hvconn p1@(P2 _ y1) p2@(P2 x2 _) = -    let mid = P2 x2 y1 in tracePoints [p1, mid, p2]+    let mid = P2 x2 y1 in traceLinePoints [p1, mid, p2] -vhvconn :: Floating u => u -> Connector u-vhvconn v p1@(P2 x1 _) p2@(P2 x2 _) = tracePoints [p1, a1, a2, p2]+vhvconn :: Floating u => u -> ConnectorPath u+vhvconn v p1@(P2 x1 _) p2@(P2 x2 _) = traceLinePoints [p1, a1, a2, p2]   where     a1 = p1 .+^ vvec v     a2 = a1 .+^ hvec (x2 - x1)  -hvhconn :: Floating u => u -> Connector u-hvhconn h p1@(P2 _ y1) p2@(P2 _ y2) = tracePoints [p1,a1,a2,p2]+hvhconn :: Floating u => u -> ConnectorPath u+hvhconn h p1@(P2 _ y1) p2@(P2 _ y2) = traceLinePoints [p1,a1,a2,p2]   where     a1 = p1 .+^ hvec h     a2 = a1 .+^ vvec (y2 - y1) -curveconn :: (Floating u, Ord u) => Radian -> Radian -> Connector u+curveconn :: (Floating u, Ord u) => Radian -> Radian -> ConnectorPath u curveconn r1 r2 p1 p2 = curveByAngles p1 r1 r2 p2  -joint :: (Real u, Floating u) => u -> Connector u +joint :: (Real u, Floating u) => u -> ConnectorPath u  joint u p1@(P2 x1 y1) p2@(P2 x2 y2) = -    tracePoints [p1, mid_pt .+^ avec perp_ang u, p2]+    traceLinePoints [p1, mid_pt .+^ avec perp_ang u, p2]   where     mid_pt    = P2 (x1 + 0.5*(x2-x1)) (y1 + 0.5*(y2-y1))     perp_ang  = (pi*0.5) + direction (pvec p2 p1) 
src/Wumpus/Basic/Paths/Construction.hs view
@@ -42,14 +42,14 @@   ) 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.Maybe-import Data.Monoid+import Data.List   -- Are connectors and paths quite different things?@@ -60,11 +60,11 @@   -- State monad version is quite good - it ameliorates the problem--- of joing to the end point of an empty path...+-- of joining to the end point of an empty path...  data St u = St       { current_point :: Point2 u -      , path_acc      :: Path u+      , path_acc      :: H (Path u)       }  @@ -91,18 +91,21 @@ -- 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, path_acc s')+runPath start mf = +    let (a,s') = getPathM mf s in (a, post $ toListH $ path_acc s')   where     s = St { current_point = start-           , path_acc      = mempty+           , 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 `mappend` line pt ep))+                                    in ((), St ep (ac `snocH` line pt ep))   tip :: PathM u (Point2 u)@@ -110,7 +113,7 @@   lineto :: Floating u => Point2 u -> PathM u ()-lineto pt = PathM $ \(St p0 ac) -> ((), St pt (ac `mappend` line p0 pt))+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))@@ -127,7 +130,7 @@ bezierto :: (Floating u, Ord u)           => Point2 u -> Point2 u -> Point2 u -> PathM u () bezierto c1 c2 ep = PathM $ \(St p0 ac) -> -    ((), St ep (ac `mappend` curve p0 c1 c2 ep))+    ((), St ep (ac `snocH` curve p0 c1 c2 ep))   @@ -140,8 +143,8 @@         => Radian -> Radian -> Point2 u -> PathM u () curveto cin cout end = PathM $ \(St p0 ac) ->      let seg  = curveByAngles p0 cin cout end -        ac1  = ac `mappend` seg-        end1 = fromMaybe end $ tipR ac1+        ac1  = ac `snocH` seg+        end1 = tipR seg     in ((), St end1 ac1)   
src/Wumpus/Basic/Paths/RoundCorners.hs view
@@ -34,7 +34,6 @@  import Data.Monoid - -- | 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).@@ -49,22 +48,26 @@     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 `mappend` twoParts u m n o) (n:o:ps)-    step acc [n,o]          = acc `mappend` twoParts u n o start-                                  `mappend` twoParts u o start b +    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 _ _              = mempty +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 `mappend` cornerCurve p2 b p3+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)@@ -84,11 +87,11 @@ illustratePath :: Fractional u => Path u -> Graphic u illustratePath = localize (strokeColour black) . step1 . pathViewL   where-    step1 EmptyPathL = mempty-    step1 (e :<< se) = drawPathBoth e `mappend` rest (pathViewL se)+    step1 (PathOneL e)  = drawPath1 e+    step1 (e :<< se)    = drawPathBoth e `mappend` rest (pathViewL se) -    rest EmptyPathL = mempty-    rest (e :<< se) = drawPath1 e `mappend` rest (pathViewL se)+    rest (PathOneL e)   = drawPath1 e+    rest (e :<< se)     = drawPath1 e `mappend` rest (pathViewL se)  drawPathBoth :: Fractional u => PathSegment u -> Graphic u drawPathBoth pa@(Line1 p1 _)      = drawPath1 pa `mappend` pathPoint p1@@ -99,8 +102,8 @@     straightLineBetween p1 p2 `mappend` pathPoint p2  drawPath1 (Curve1 p1 p2 p3 p4) =  -    mconcat [ bezierCtrl p1 p2, bezierCtrl p4 p3, curveBetween p1 p2 p3 p4-            , pathPoint p4]+    mconcat [bezierCtrl p1 p2, bezierCtrl p4 p3, curveBetween p1 p2 p3 p4+                             , pathPoint p4 ]   bezierCtrl :: Fractional u => Point2 u -> Point2 u -> Graphic u
src/Wumpus/Basic/SafeFonts.hs view
@@ -18,22 +18,22 @@ module Wumpus.Basic.SafeFonts   (    -- * Times Roman-    timesRoman-  , timesItalic-  , timesBold-  , timesBoldItalic+    times_roman+  , times_italic+  , times_bold+  , times_bold_italic    -- * Helvetica   , helvetica-  , helveticaOblique-  , helveticaBold-  , helveticaBoldOblique+  , helvetica_oblique+  , helvetica_bold+  , helvetica_bold_oblique    -- * Courier   , courier-  , courierOblique-  , courierBold-  , courierBoldOblique+  , courier_oblique+  , courier_bold+  , courier_bold_oblique    -- * Symbol   , symbol@@ -56,29 +56,29 @@  -- | Times-Roman -- -timesRoman :: FontFace-timesRoman = +times_roman :: FontFace+times_roman =      FontFace "Times-Roman" "Times New Roman" SVG_REGULAR latin1_font_encoder  -- | Times Italic ---timesItalic :: FontFace-timesItalic = +times_italic :: FontFace+times_italic =      FontFace "Times-Italic" "Times New Roman" SVG_ITALIC latin1_font_encoder                         -- | Times Bold ---timesBold :: FontFace-timesBold = +times_bold :: FontFace+times_bold =      FontFace "Times-Bold" "Times New Roman" SVG_BOLD latin1_font_encoder  -- | Times Bold Italic ---timesBoldItalic :: FontFace-timesBoldItalic = FontFace "Times-BoldItalic" -                           "Times New Roman" -                           SVG_BOLD_ITALIC -                           latin1_font_encoder+times_bold_italic :: FontFace+times_bold_italic = FontFace "Times-BoldItalic" +                             "Times New Roman" +                             SVG_BOLD_ITALIC +                             latin1_font_encoder   --------------------------------------------------------------------------------@@ -92,24 +92,24 @@  -- | Helvetica Oblique ---helveticaOblique :: FontFace-helveticaOblique = +helvetica_oblique :: FontFace+helvetica_oblique =      FontFace "Helvetica-Oblique" "Helvetica" SVG_OBLIQUE latin1_font_encoder  -- | Helvetica Bold -- -helveticaBold :: FontFace-helveticaBold = +helvetica_bold :: FontFace+helvetica_bold =      FontFace "Helvetica-Bold" "Helvetica" SVG_BOLD latin1_font_encoder   -- | Helvetica Bold Oblique ---helveticaBoldOblique :: FontFace-helveticaBoldOblique = FontFace "Helvetica-Bold-Oblique" -                                "Helvetica" -                                SVG_BOLD_OBLIQUE -                                latin1_font_encoder+helvetica_bold_oblique :: FontFace+helvetica_bold_oblique = FontFace "Helvetica-Bold-Oblique" +                                  "Helvetica" +                                  SVG_BOLD_OBLIQUE +                                  latin1_font_encoder   @@ -122,24 +122,24 @@  -- | Courier Oblique -- -courierOblique :: FontFace-courierOblique = +courier_oblique :: FontFace+courier_oblique =      FontFace "Courier-Oblique" "Courier New" SVG_OBLIQUE latin1_font_encoder  -- | Courier Bold -- -courierBold :: FontFace-courierBold = +courier_bold :: FontFace+courier_bold =      FontFace "Courier-Bold" "Courier New" SVG_BOLD latin1_font_encoder   -- | Courier Bold Oblique -- -courierBoldOblique :: FontFace-courierBoldOblique = FontFace "Courier-Bold-Oblique" -                              "Courier New" -                              SVG_BOLD_OBLIQUE -                              latin1_font_encoder+courier_bold_oblique :: FontFace+courier_bold_oblique = FontFace "Courier-Bold-Oblique" +                                "Courier New" +                                SVG_BOLD_OBLIQUE +                                latin1_font_encoder  -------------------------------------------------------------------------------- -- Symbol
+ src/Wumpus/Basic/Shapes.hs view
@@ -0,0 +1,29 @@+{-# 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+  , module Wumpus.Basic.Shapes.Plaintext++  ) where++import Wumpus.Basic.Shapes.Base+import Wumpus.Basic.Shapes.Coordinate+import Wumpus.Basic.Shapes.Derived hiding ( mkRectangle )+import Wumpus.Basic.Shapes.Plaintext
src/Wumpus/Basic/Shapes/Base.hs view
@@ -14,6 +14,9 @@ -- -- Common core for shapes -- +-- \*\* WARNING \*\* - the types of Shapes and Plaintext are not+-- ideal and are pending revision.+-- --------------------------------------------------------------------------------  module Wumpus.Basic.Shapes.Base@@ -21,8 +24,11 @@       Shape(..)+  , ShapeConstructor -  , drawShape+  , borderedShape+  , filledShape+  , strokedShape    -- * ShapeCTM    , ShapeCTM(..)@@ -31,23 +37,16 @@   , ctmDisplace   , ctmCenter -  , ShapeLabel-  , runShapeLabel-  , nolabel-  , shapelabel    ) where  import Wumpus.Basic.Graphic-+import Wumpus.Basic.Paths  import Wumpus.Core                              -- package: wumpus-core -import Data.AffineSpace                         -- package: vector-space - import Control.Applicative-import Data.Monoid   -- | Note - this formulation prevents rounded corner shapes...@@ -65,21 +64,32 @@ -- DrawingContext for the /shape/ -- -data Shape u sh =  Shape -      { src_ctm :: ShapeCTM u -      , out_fun :: ShapeCTM u -> Image u sh+data Shape u t =  Shape +      { src_ctm   :: ShapeCTM u +      , path_fun  :: ShapeCTM u -> Path u+      , cons_fun   :: ShapeCTM u -> t u       }  type instance DUnit (Shape u sh) = u  +type ShapeConstructor u t = ShapeCTM u -> t u    -drawShape :: Shape u sh -> Image u sh-drawShape (Shape { src_ctm = ctm, out_fun = fn }) = fn ctm +borderedShape :: Num u => Shape u t -> Image u (t u)+borderedShape (Shape { src_ctm = ctm, path_fun = pf, cons_fun = objf }) = +   intoImage (pure $ objf ctm) (borderedPath $ toPrimPath $ pf ctm) +filledShape :: Num u => Shape u t -> Image u (t u)+filledShape (Shape { src_ctm = ctm, path_fun = pf, cons_fun = objf }) = +   intoImage (pure $ objf ctm) (filledPath $ toPrimPath $ pf ctm) +strokedShape :: Num u => Shape u t -> Image u (t u)+strokedShape (Shape { src_ctm = ctm, path_fun = pf, cons_fun = objf }) = +   intoImage (pure $ objf ctm) (closedStroke $ toPrimPath $ pf ctm)++ instance (Real u, Floating u) => Rotate (Shape u sh) where   rotate r = updateCTM (rotateCTM r) @@ -90,7 +100,7 @@   translate x y = updateCTM (translateCTM x y)  updateCTM :: (ShapeCTM u -> ShapeCTM u) -> Shape u sh -> Shape u sh-updateCTM fn (Shape ctm out) = Shape (fn ctm) out+updateCTM fn (Shape ctm pf mkf) = Shape (fn ctm) pf mkf  -------------------------------------------------------------------------------- -- CTM@@ -106,7 +116,7 @@       , ctm_scale_y             :: !u       , ctm_rotation            :: Radian       }-  deriving (Eq,Show)+  deriving (Eq,Ord,Show)  type instance DUnit (ShapeCTM u) = u @@ -150,28 +160,3 @@ ctmCenter = ctmDisplace zeroPt  -newtype ShapeLabel u = ShapeLabel { getShapeLabel :: ShapeCTM u -> Graphic u }--runShapeLabel :: ShapeCTM u -> ShapeLabel u -> Graphic u-runShapeLabel ctm sl = getShapeLabel sl ctm--nolabel :: ShapeLabel u-nolabel = ShapeLabel $ \_ -> mempty---- | No scaling - change font size if needed.----shapelabel :: (Real u, Floating u, FromPtSize u) -             => String -> ShapeLabel u-shapelabel text = -   ShapeLabel $ \(ShapeCTM { ctm_trans_x=dx, ctm_trans_y=dy-                           , ctm_rotation = ang }) ->-                   monoVecToCenter text >>= \v -> -                   let ctr = P2 dx dy; bl = ctr .-^ v in -                   rotTextline ang text (rotateAbout ang ctr bl)---rotTextline :: (Real u, Floating u) => Radian -> String -> LocGraphic u-rotTextline theta ss baseline_left = -    withTextAttr $ \rgb attr -> -        singleH $ rotatePrim theta $ textlabel rgb attr ss baseline_left-     
+ src/Wumpus/Basic/Shapes/Coordinate.hs view
@@ -0,0 +1,88 @@+{-# 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+--+-- Coordinate is a bit like a shape but does not generate a path +-- and cannot be scaled or rotated (it can be translated).+-- +-- \*\* WARNING \*\* - the types of Shapes and Coordinate are not+-- ideal and are pending revision.+--+--------------------------------------------------------------------------------++module Wumpus.Basic.Shapes.Coordinate+  (+    CoordinateAnchor+  , DCoordinateAnchor+  , Coordinate+  , DCoordinate+  , coordinate++  , coordinateMark++  ) where++import Wumpus.Basic.Anchors+import Wumpus.Basic.Graphic++import Wumpus.Core                              -- package: wumpus-core++++++--------------------------------------------------------------------------------+-- | Coordinate++data CoordinateAnchor u = CoordinateAnchor+      { coord_x   :: !u+      , coord_y   :: !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+++instance (Real u, Floating u) => CenterAnchor (CoordinateAnchor u) where+  center (CoordinateAnchor x y) = P2 x y++instance Num u => Translate (Coordinate u) where+  translate dx dy = Coordinate . fn . getCoordinate +    where +      fn (CoordinateAnchor x y) = CoordinateAnchor (x+dx) (y+dy)++-- Need a differentiation at the type level between a coord+-- that can be translated (moved) and a coord that anchors...++coordinate :: Num u => Point2 u -> Coordinate u+coordinate (P2 x y) = Coordinate $ CoordinateAnchor { coord_x = x, coord_y = y }++-- Note - should @coordinate@ take a point, Shapes don\'t.+++coordinateMark :: (Real u, Floating u) +               => Coordinate u -> Image u (CoordinateAnchor u)+coordinateMark x = intoImage (return $ getCoordinate x) (drawCoord x)++drawCoord :: (Real u, Floating u) => Coordinate u -> Graphic u+drawCoord coord = +   localize bothStrokeColour $ filledEllipse 2 2 (center $ getCoordinate coord)+
src/Wumpus/Basic/Shapes/Derived.hs view
@@ -13,7 +13,10 @@ -- Stability   :  highly unstable -- Portability :  GHC --+-- Simple shapes - rectangle, circle diamond, ellipse. -- +-- \*\* WARNING \*\* - the types of Shapes and Plaintext are not+-- ideal and are pending revision. --  -------------------------------------------------------------------------------- @@ -22,35 +25,31 @@     Rectangle   , DRectangle   , rectangle-  , lrectangle+  , rrectangle +  , mkRectangle   -- hidden in Shim module+   , Circle   , DCircle   , circle-  , lcircle -  , Coordinate-  , DCoordinate-  , coordinate    , Diamond   , DDiamond   , diamond-  , ldiamond+  , rdiamond +   , Ellipse   , DEllipse   , ellipse-  , lellipse -  , FreeLabel-  , DFreeLabel-  , freelabel    ) where  import Wumpus.Basic.Anchors-import Wumpus.Basic.Graphic+import Wumpus.Basic.Paths+import Wumpus.Basic.Paths.RoundCorners import Wumpus.Basic.Shapes.Base import Wumpus.Basic.Utils.Intersection @@ -58,9 +57,11 @@  import Data.AffineSpace                         -- package: vector-space  -import Data.Monoid +remapPoints :: (Real u, Floating u) => [Point2 u] -> ShapeCTM u -> [Point2 u]+remapPoints xs ctm = map (ctmDisplace `flip` ctm) xs + -------------------------------------------------------------------------------- -- Rectangle @@ -69,7 +70,7 @@       , rect_hw     :: !u       , rect_hh     :: !u        }-  deriving (Eq,Show)+  deriving (Eq,Ord,Show)  type DRectangle = Rectangle Double @@ -104,37 +105,43 @@     where        ctr = ctmCenter $ rect_ctm rect -rectangle :: (Real u, Floating u) => u -> u -> Shape u (Rectangle u)-rectangle w h = Shape { src_ctm = identityCTM-                      , out_fun = outputRect (0.5*w) (0.5*h) nolabel-                      } +-- | 'rectangle'  : @ width * height -> shape @+--+rectangle :: (Real u, Floating u) => u -> u -> Shape u Rectangle+rectangle w h = +    Shape { src_ctm   = identityCTM+          , path_fun  = traceLinePoints . rectanglePoints (0.5*w) (0.5*h)+          , cons_fun  = mkRectangle (0.5*w) (0.5*h)  +          } -lrectangle :: (Real u, Floating u, FromPtSize u) -           => u -> u -> String -> Shape u (Rectangle u)-lrectangle w h ss = Shape { src_ctm = identityCTM-                          , out_fun = outputRect (0.5*w) (0.5*h) (shapelabel ss)-                          }+-- | 'rectangle'  : @ round_length * width * height -> shape @+--+rrectangle :: (Real u, Floating u) => u -> u -> u -> Shape u Rectangle+rrectangle round_dist w h = +    Shape { src_ctm   = identityCTM+          , path_fun  = roundEvery round_dist . rectanglePoints (0.5*w) (0.5*h)+          , cons_fun  = mkRectangle (0.5*w) (0.5*h)  +          }  -outputRect :: (Real u, Floating u) -           => u -> u -> ShapeLabel u -> ShapeCTM u -> Image u (Rectangle u)-outputRect hw hh shl ctm = intoImage (return a) (drawRect a `mappend` label) -  where-    a     = Rectangle { rect_ctm = ctm, rect_hw = hw, rect_hh = hh }-    label = runShapeLabel ctm shl +mkRectangle :: u -> u -> ShapeConstructor u Rectangle+mkRectangle hw hh = \ctm -> +    Rectangle { rect_ctm = ctm, rect_hw = hw, rect_hh = hh } -drawRect :: (Real u, Floating u) => Rectangle u -> Graphic u-drawRect = borderedPath . rectPath  -rectPath :: (Real u, Floating u) => Rectangle u -> PrimPath u-rectPath rect = vertexPath [ southwest rect-                           , southeast rect-                           , northeast rect-                           , northwest rect-                           ]+-- Note - the Paths modules should define a function for building+-- rectangles (and polygons, bezier curves / ellipses ...)+--+rectanglePoints :: (Real u, Floating u) => u -> u -> ShapeCTM u -> [Point2 u]+rectanglePoints hw hh = remapPoints [ se, ne, nw, sw ]+  where+    se = P2   hw  (-hh)+    ne = P2   hw    hh+    nw = P2 (-hw)   hh+    sw = P2 (-hw) (-hh)    @@ -162,86 +169,46 @@ calcCircPoint f (Circle { circ_ctm = ctm, circ_radius = rad }) =     let pt = f rad in ctmDisplace pt ctm -instance (Real u, Floating u) => CardinalAnchor (Circle u) where-  north = calcCircPoint $ \ r -> P2 0  r-  south = calcCircPoint $ \ r -> P2 0 (-r)-  east  = calcCircPoint $ \ r -> P2 r  0-  west  = calcCircPoint $ \ r -> P2 (-r) 0 + instance (Real u, Floating u) => RadialAnchor (Circle u) where   radialAnchor theta = calcCircPoint $ \r -> zeroPt .+^ avec theta r +instance (Real u, Floating u) => CardinalAnchor (Circle u) where+  north = calcCircPoint $ \r -> P2 0    r+  south = calcCircPoint $ \r -> P2 0  (-r)+  east  = calcCircPoint $ \r -> P2 r    0+  west  = calcCircPoint $ \r -> 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) --circle :: (Real u, Floating u) => u -> Shape u (Circle u)-circle radius = Shape { src_ctm = identityCTM-                      , out_fun = outputCirc radius nolabel-                      }---lcircle :: (Real u, Floating u, FromPtSize u) -        => u -> String -> Shape u (Circle u)-lcircle radius ss = Shape { src_ctm = identityCTM-                          , out_fun = outputCirc radius (shapelabel ss)-                          }--outputCirc :: (Real u, Floating u) -           => u -> ShapeLabel u -> ShapeCTM u -> Image u (Circle u)-outputCirc rad shl ctm = intoImage (return a) (drawCirc a `mappend` label) -  where-    a     = Circle { circ_ctm = ctm, circ_radius = rad }-    label = runShapeLabel ctm shl+-- | 'circle'  : @ radius -> shape @+--+circle :: (Real u, Floating u) => u -> Shape u Circle+circle radius = +    Shape { src_ctm  = identityCTM+          , path_fun = traceCurvePoints . circlePoints radius+          , cons_fun = mkCircle radius+          }  -drawCirc :: (Real u, Floating u) => Circle u -> Graphic u-drawCirc = borderedPath . circlePath+mkCircle :: u -> ShapeConstructor u Circle+mkCircle radius = \ctm -> Circle { circ_ctm = ctm, circ_radius = radius }  -circlePath :: (Real u, Floating u) => Circle u -> PrimPath u-circlePath = curvedPath . circlePoints --circlePoints :: (Real u, Floating u) => Circle u -> [Point2 u]-circlePoints (Circle { circ_ctm=ctm, circ_radius=radius }) = map fn all_points+circlePoints :: (Real u, Floating u) => u -> ShapeCTM u -> [Point2 u]+circlePoints radius ctm = map fn all_points   where     fn pt       = ctmDisplace pt ctm     all_points  = bezierCircle 2 radius zeroPt   ------------------------------------------------------------------------------------ | Coordinate -data Coordinate u = Coordinate-      { coord_ctm   :: ShapeCTM u -      }--type DCoordinate = Coordinate Double--type instance DUnit (Coordinate u) = u--instance (Real u, Floating u) => CenterAnchor (Coordinate u) where-  center = ctmCenter . coord_ctm---coordinate :: (Real u, Floating u) => Shape u (Coordinate u)-coordinate = Shape { src_ctm = identityCTM-                   , out_fun = outputCoord-                   }--outputCoord :: (Real u, Floating u) => ShapeCTM u -> Image u (Coordinate u)-outputCoord ctm = intoImage (return a) (drawCoord a) -  where-    a = Coordinate { coord_ctm = ctm }---drawCoord :: (Real u, Floating u) => Coordinate u -> Graphic u-drawCoord coord = localize swapColours $ filledEllipse 2 2 (center coord)- -------------------------------------------------------------------------------- -- Diamond @@ -261,6 +228,10 @@   center = ctmCenter . dia_ctm  ++++ calcDiaPoint :: (Real u, Floating u)               => (u -> u -> Point2 u) -> Diamond u -> Point2 u calcDiaPoint f (Diamond { dia_ctm = ctm, dia_hw = hw, dia_hh = hh }) =@@ -272,35 +243,47 @@   east  = calcDiaPoint $ \ hw _  -> P2 hw 0   west  = calcDiaPoint $ \ hw _  -> P2 (-hw) 0 -diamond :: (Real u, Floating u) => u -> u -> Shape u (Diamond u)-diamond hw hh = Shape { src_ctm = identityCTM-                      , out_fun = outputDia hw hh nolabel-                      }  -ldiamond :: (Real u, Floating u, FromPtSize u) -         => u -> u -> String -> Shape u (Diamond u)-ldiamond hw hh ss = Shape { src_ctm = identityCTM-                          , out_fun = outputDia hw hh (shapelabel ss)-                          } +-- | 'diamond'  : @ half_width * half_height -> shape @+--+-- Note - args might change to tull_width and full_height...+--+diamond :: (Real u, Floating u) => u -> u -> Shape u Diamond+diamond hw hh = +    Shape { src_ctm  = identityCTM+          , path_fun = traceLinePoints . diamondPoints hw hh+          , cons_fun = 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 -> Shape u Diamond+rdiamond round_dist hw hh = +    Shape { src_ctm  = identityCTM+          , path_fun = roundEvery round_dist . diamondPoints hw hh+          , cons_fun = mkDiamond hw hh+          } -outputDia :: (Real u, Floating u) -          => u -> u -> ShapeLabel u -> ShapeCTM u -> Image u (Diamond u)-outputDia hw hh shl ctm = intoImage (return a) (drawDia a `mappend` label) -  where-    a     = Diamond { dia_ctm = ctm, dia_hw = hw, dia_hh = hh }-    label = runShapeLabel ctm shl -drawDia :: (Real u, Floating u) => Diamond u -> Graphic u-drawDia = borderedPath . diamondPath  -diamondPath :: (Real u, Floating u) => Diamond u -> PrimPath u-diamondPath dia = vertexPath [ south dia, east dia, north dia, west dia ]+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 = remapPoints [ s, e, n, w ]+  where+    s = P2   0  (-hh)+    e = P2   hw    0+    n = P2   0    hh+    w = P2 (-hw)   0 ++ -------------------------------------------------------------------------------- -- Ellipse @@ -321,91 +304,52 @@   center = ctmCenter . ell_ctm  -ellipse :: (Real u, Floating u) => u -> u -> Shape u (Ellipse u)-ellipse rx ry = Shape { src_ctm = identityCTM-                      , out_fun = outputEll rx ry nolabel-                      }--lellipse :: (Real u, Floating u, FromPtSize u) -         => u -> u -> String -> Shape u (Ellipse u)-lellipse rx ry ss = Shape { src_ctm = identityCTM-                          , out_fun = outputEll rx ry (shapelabel ss)-                          }-+calcEllPoint :: (Real u, Floating u) +              => (u -> Point2 u) -> Ellipse u -> Point2 u+calcEllPoint f (Ellipse { ell_ctm = ctm, ell_rx = rx, ell_ry = ry }) =+    let p   = f rx; p'  = scaleEll rx ry p+    in ctmDisplace p' ctm -outputEll :: (Real u, Floating u) -          => u -> u -> ShapeLabel u -> ShapeCTM u -> Image u (Ellipse u)-outputEll rx ry shl ctm = intoImage (return a) (drawEll a `mappend` label)-  where-    a     = Ellipse { ell_ctm = ctm, ell_rx = rx, ell_ry = ry }-    label = runShapeLabel ctm shl+instance (Real u, Floating u) => RadialAnchor (Ellipse u) where+  radialAnchor theta = calcEllPoint $ \rx -> zeroPt .+^ avec theta rx  -drawEll :: (Real u, Floating u) => Ellipse u -> Graphic u-drawEll = borderedPath . ellipsePath+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  -ellipsePath :: (Real u, Floating u) => Ellipse u -> PrimPath u-ellipsePath = curvedPath . ellipsePoints--ellipsePoints :: (Real u, Floating u) => Ellipse u -> [Point2 u]-ellipsePoints (Ellipse { ell_ctm=ctm, ell_rx=rx, ell_ry=ry }) = -    map (ctmDisplace `flip` ctm) all_points-  where-    all_points  = map (rescale rx ry) $ bezierCircle 2 rx zeroPt +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)  --- | x_radius is the unit length.+-- | 'ellipse'  : @ x_radii * y_radii -> shape @ ---rescale :: (Scale t, Fractional u, u ~ DUnit t) => u -> u -> t -> t-rescale rx ry = scale 1 (ry/rx) +ellipse :: (Real u, Floating u) => u -> u -> Shape u Ellipse+ellipse rx ry = +    Shape { src_ctm  = identityCTM+          , path_fun = traceCurvePoints . ellipsePoints rx ry+          , cons_fun = mkEllipse rx ry  +          }  ------------------------------------------------------------------------------------ Free label --- Free label is a rectangle that /is not drawn/, the --- constructor should always create some text.--newtype FreeLabel u = FreeLabel { getFreeLabel :: Rectangle u }---type DFreeLabel = FreeLabel Double+mkEllipse :: (Real u, Floating u) => u -> u -> ShapeConstructor u Ellipse+mkEllipse rx ry = \ctm -> Ellipse { ell_ctm = ctm, ell_rx = rx, ell_ry = ry } -type instance DUnit (FreeLabel u) = u+ellipsePoints :: (Real u, Floating u) => u -> u -> ShapeCTM u -> [Point2 u]+ellipsePoints rx ry ctm = +    map ((ctmDisplace `flip` ctm) . scaleEll rx ry) $ bezierCircle 2 rx zeroPt   -instance (Real u, Floating u) => CenterAnchor (FreeLabel u) where-  center = center . getFreeLabel+-- | 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) => CardinalAnchor (FreeLabel u) where-  north = north . getFreeLabel-  south = south . getFreeLabel-  east  = east . getFreeLabel-  west  = west . getFreeLabel--instance (Real u, Floating u) => CardinalAnchor2 (FreeLabel u) where-  northeast = northeast . getFreeLabel-  southeast = southeast . getFreeLabel-  southwest = southwest . getFreeLabel-  northwest = northwest . getFreeLabel--instance (Real u, Floating u) => RadialAnchor (FreeLabel u) where-  radialAnchor theta = radialAnchor theta . getFreeLabel--freelabel :: (Real u, Floating u, FromPtSize u) -          => String -> Shape u (FreeLabel u)-freelabel ss = Shape { src_ctm = identityCTM-                     , out_fun = outputStringLbl ss-                     }--outputStringLbl :: (Real u, Floating u, FromPtSize u) -                => String -> ShapeCTM u -> Image u (FreeLabel u)-outputStringLbl ss ctm = -    intoImage (monoTextDimensions ss >>= \(w,h) -> return (mkrect w h)) label-  where-    mkrect w h = FreeLabel $ Rectangle { rect_ctm = ctm-                                       , rect_hw  = 0.5*w-                                       , rect_hh  = 0.5*h }-    label = runShapeLabel ctm (shapelabel ss)
+ src/Wumpus/Basic/Shapes/Plaintext.hs view
@@ -0,0 +1,150 @@+{-# LANGUAGE TypeFamilies               #-}+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module      :  Wumpus.Basic.Shapes.Plaintext+-- Copyright   :  (c) Stephen Tetley 2010+-- License     :  BSD3+--+-- Maintainer  :  Stephen Tetley <stephen.tetley@gmail.com>+-- Stability   :  highly unstable+-- Portability :  GHC+--+-- Plaintext is a bit like a shape but does not generate a path +-- and cannot be scaled (it can be rotated or translated).+--+-- \*\* WARNING \*\* - the types of Shapes and Plaintext are not+-- ideal and are pending revision.+-- +--------------------------------------------------------------------------------++module Wumpus.Basic.Shapes.Plaintext+  (++    PlaintextAnchor+  , DPlaintextAnchor+  , Plaintext+  , DPlaintext++  , plaintext+  , drawText++  ) where++import Wumpus.Basic.Anchors+import Wumpus.Basic.Graphic+import Wumpus.Basic.Shapes.Base+import Wumpus.Basic.Shapes.Derived++import Wumpus.Core                              -- package: wumpus-core++import Data.AffineSpace                         -- package: vector-space++import Control.Applicative+++++--------------------------------------------------------------------------------+-- Free label++-- Free label is a rectangle that /is not drawn/, the +-- constructor should always create some text.++newtype PlaintextAnchor u = PlaintextAnchor  { getPlaintext :: Rectangle u }+++type DPlaintextAnchor = PlaintextAnchor Double++type instance DUnit (PlaintextAnchor u) = u+++data Plaintext u = Plaintext+      { text_text :: String     -- Note - generalize this for multi-line...+      , text_x    :: !u+      , text_y    :: !u+      , text_ang  :: !Radian+      }+  deriving (Eq,Ord,Show)++type DPlaintext = Plaintext Double++type instance DUnit (Plaintext u) = u+++instance (Real u, Floating u) => CenterAnchor (PlaintextAnchor u) where+  center = center . getPlaintext+++instance (Real u, Floating u) => CardinalAnchor (PlaintextAnchor u) where+  north = north . getPlaintext+  south = south . getPlaintext+  east  = east . getPlaintext+  west  = west . getPlaintext++instance (Real u, Floating u) => CardinalAnchor2 (PlaintextAnchor u) where+  northeast = northeast . getPlaintext+  southeast = southeast . getPlaintext+  southwest = southwest . getPlaintext+  northwest = northwest . getPlaintext++instance (Real u, Floating u) => RadialAnchor (PlaintextAnchor u) where+  radialAnchor theta = radialAnchor theta . getPlaintext++++instance Rotate (Plaintext u) where+  rotate dr = (\s i -> s { text_ang = i+dr }) <*> text_ang++-- Note - cannot scale Plaintext+++instance Num u => Translate (Plaintext u) where+  translate dx dy = (\s x y -> s { text_x = x+dx, text_y = y+dy }) +                      <*> text_x <*> text_y++++plaintext :: Num u => String -> Plaintext u+plaintext ss = Plaintext { text_text  = ss+                         , text_x     = 0+                         , text_y     = 0+                         , text_ang   = 0 }+++++drawText :: (Real u, Floating u, FromPtSize u)+         => Plaintext u -> Image u (PlaintextAnchor u)+drawText x = intoImage (oneLineRect x) (drawOneLine x)++++oneLineRect :: (Fractional u, Ord u, FromPtSize u) +        => Plaintext u -> DrawingR (PlaintextAnchor u)+oneLineRect ptext = +    monoTextDimensions (text_text ptext) >>= \(w,h) -> +    return (PlaintextAnchor $ mkRectangle (0.5*w) (0.5*h) ctm)+  where+    ctm = ShapeCTM { ctm_trans_x    = text_x ptext+                   , ctm_trans_y    = text_y ptext+                   , ctm_scale_x    = 1+                   , ctm_scale_y    = 1+                   , ctm_rotation   = text_ang ptext+                   }++drawOneLine :: (Real u, Floating u, FromPtSize u) +            => Plaintext u -> Graphic u +drawOneLine (Plaintext { text_text = ss, text_x=dx, text_y=dy+                       , text_ang = ang }) =+    monoVecToCenter ss >>= \v -> +    let ctr = P2 dx dy; bl = ctr .-^ v in +    rotTextline ang ss (rotateAbout ang ctr bl)++++rotTextline :: (Real u, Floating u) => Radian -> String -> LocGraphic u+rotTextline theta ss baseline_left = +    withTextAttr $ \rgb attr -> +        singleH $ rotatePrim theta $ textlabel rgb attr ss baseline_left
src/Wumpus/Basic/VersionNumber.hs view
@@ -23,7 +23,7 @@  -- | Version number ----- > (0,10,0)+-- > (0,11,0) -- wumpus_basic_version :: (Int,Int,Int)-wumpus_basic_version = (0,10,0)+wumpus_basic_version = (0,11,0)
wumpus-basic.cabal view
@@ -1,5 +1,5 @@ name:             wumpus-basic-version:          0.10.0+version:          0.11.0 license:          BSD3 license-file:     LICENSE copyright:        Stephen Tetley <stephen.tetley@gmail.com>@@ -16,55 +16,67 @@   .   Some of the modules (SafeFonts, SVGColours, X11Colours) are   relatively stable. The core modules of @Basic.Graphic@ (@Base@,-  @PrimGraphic@, @DrawingContext@) are quite weather-beaten if -  not exactly stable, although the newer modules -  (@ScalingContext@, @DirectionContext@) are still quite green.-  Other modules (Paths, Chains, Shapes) are essentially sketches -  and may be radically different in subsequent updates.+  @PrimGraphic@, @DrawingContext@) seem to support a good set+  primitive functions, but the exact types of drawing objects do +  not feel right at the moment. Other modules (Paths, Chains, +  Shapes) are essentially sketches and are expected to be+  substantially revised in subsequent updates.   .+  Version 0.11.0 is an interim release. It is expected that the +  next release will substantially rework Shapes and likely change+  the @Graphic.Base@ types. As quite a large amount of code has +  already changed since version 0.10.0 (to support better +  arrowheads and connectors) it seems sensible to release 0.11.0 +  now, rather than have a huge delta after Shapes have been +  reworked again. The current versions of @Wumpus-Tree@ and +  @Wumpus-Microprint@ will work with version 0.11.0 if their +  respective @.cabal@ files are edited to bump the version number. +  There will be no matching releases to work automatically with +  version 0.11.0 of Wumpus-Basic.   .   Changelog:   .-  0.9.0 to 0.10.0:-  .-  * @Basic.Graphic.BaseClasses@ and @Basic.Graphic.BaseTypes@ -    merged into same module so they can depend on each other -    without orphans instances.+  0.10.0 to 0.11.0:+  . +  * Reworked arrowheads and connectors - connectors are now +    configurable: there are functions to make connectors with +    a left arrowhead, right arrowhead, none or both.     .-  * @DrawingF@ renamed to @DrawingR@, the related type synonyms-    have also been changed, e.g. @LocDrawingF@ is now -    @LocDrawingR@.+  * Reworked shapes - internally shapes now create a @Path@ rather +    than a @Graphic@ this means the path can be manipulated (e.g. +    round cornered rectangles, diamonds... can be constructed).+    @Coordinate@ is no longer a @Shape@ - it is now similar object +    but of a different type. Likewise, @FreeLabel@ has been +    replaced by @Plaintext@ which is not a @Shape@, but has some +    similar properties. Unfortunately, the Shape types are still +    difficult to work with and a larger reworking is still +    necessary.   .-  * Method names in the @DrawingCtxM@ class changed - @askCtx@ is-    now @askDC@, @localCtx@ is now @localize@. Removed the -    functions @askDF@, @asksDF@, @pureDF@ that worked for -    @DrawingF@ (now @DrawingR@), @DrawingR@ now uses the -    Applicative\'s @pure@ and the @DrawingCtxM@ class for these -    functionalities.+  * @Basic.Paths.Base@ - @Path@ type changed, @PathEmpty@ +    constructor removed so empty paths cannot be created. This +    allows a better API for taking points on a path. It also +    means @Path@ is no longer an instance of Monoid. Type changes +    to various functions (e.g. @tipR@, @tipL@) reflecting that as +    paths cannot now be empty, functions on them can generally be +    total. @toPrimPathU@ removed as converting to a PrimPath as +    now always /safe/. @tracePoints@ renamed @traceLinePoints@, +    @tracePointsCurve@ renamed @traceCurvePoints@, @midpoint@ +    renamed @midway@.   .-  * @Basic.Graphic.DrawingContext@ - renamed @primary_colour@ to-    @stroke_colour@ and @secondary_colour@ to @fill_colour@. The -    setter functions has been similarly renamed.+  * @Basic.Graphic@ - the types @ConnDrawingR@, @ConnGraphic@ etc.+    have had their names expanded to @ConnectorDrawingR@, +    @ConnectorGraphic@...    .-  * Added the type synonym @DrawingContextF@ to -    @Basic.Graphic.DrawingContext@. Changed relevant function-    signatures to use it.+  * @Basic.SafeFont@ - font names changed to use underscore +    separators rather than camelCase. Wumpus generally uses +    underscored names for /constants/.   .-  * Re-worked the Path modules - base types entirely different,-    connectors entirely different, monadic path construction -    largely the same.+  * Removed @conn@ from @Basic.Graphic.Drawing@. Connectors should +    be used instead.   .-  * Initial work on round cornered paths.-  . -  * Removed the type class @TextAnchor@ from @Basic.Anchors@. -    This was a left-over from a previous implementation of -    Shapes and is not relevant to the current implementation.-  . -  * Added @DirectionContext@ to @Basic.Graphic@.+  * The class @DrawingCtxM@ now has @Applicative@ as a superclass.    .-  * @localLG@ removed it can be acheived with composition --    @localize upd . loc_graphic_function@. @lgappend@ is also -    removed - it can be recreated applicatively.+  * @lineSpacing@ renamed @baselineSpacing@.   .   . build-type:         Simple@@ -74,14 +86,14 @@ extra-source-files:   CHANGES,   LICENSE,-  demo/DotPic.hs,+  demo/ArrowCircuit.hs,   demo/ClipPic.hs,   demo/ColourCharts.hs,   demo/ColourDefns.hs,+  demo/DotPic.hs,   demo/FontPic.hs,   demo/PetriNet.hs,   demo/Picture.hs,-  demo/Shapes.hs,   demo/Symbols.hs  library@@ -95,6 +107,7 @@   exposed-modules:     Wumpus.Basic.Anchors,     Wumpus.Basic.Arrows,+    Wumpus.Basic.Arrows.Connectors,     Wumpus.Basic.Arrows.Tips,     Wumpus.Basic.Chains,     Wumpus.Basic.Chains.Base,@@ -119,8 +132,11 @@     Wumpus.Basic.Paths.Construction,     Wumpus.Basic.Paths.RoundCorners,     Wumpus.Basic.SafeFonts,+    Wumpus.Basic.Shapes,     Wumpus.Basic.Shapes.Base,+    Wumpus.Basic.Shapes.Coordinate,     Wumpus.Basic.Shapes.Derived,+    Wumpus.Basic.Shapes.Plaintext,     Wumpus.Basic.Text.LRSymbol,     Wumpus.Basic.Text.LRText,     Wumpus.Basic.Utils.HList,