wumpus-core-0.12.0: Pure Haskell PostScript and SVG generation.

Stabilityhighly unstable
MaintainerStephen Tetley <stephen.tetley@gmail.com>



Common interface to Wumpus.Core...



data Picture u Source

Picture is a leaf attributed tree - where atttibutes are colour, line-width etc. It is parametric on the unit type of points (typically Double).

Wumpus's Picture, being a leaf attributed tree, is not ideally matched to PostScript's picture representation, which might be considered a node attributed tree if you recast graphics state updates as syntactic commands encountered during top-down evaluation.

Currently this mismatch means that the PostScript code generated by Wumpus has significant overuse of PostScript's gsave and grestore.

At some point a tree-rewriting step might be added to coalesce some of the repeated graphics state updates.

Apropos the constructors, Picture is a simple non-empty leaf-labelled rose tree via

 Single (aka leaf) | Picture (OneList tree)

Where OneList is a variant of the standard list type that disallows empty lists.

The additional constructors are convenience:

PickBlank has a bounding box but no content and is useful for some picture language operations (e.g. hsep).

Clip nests a picture (tree) inside a clipping path.


Eq u => Eq (Picture u) 
Show u => Show (Picture u) 
(Num u, Pretty u) => Pretty (Picture u) 
Num u => Blank (Picture u) 
(Num u, Ord u, Horizontal (Picture u), Vertical (Picture u)) => Move (Picture u) 
(Num u, Ord u) => Composite (Picture u) 
(Num u, Ord u) => Vertical (Picture u) 
(Num u, Ord u) => Horizontal (Picture u) 
(Num u, Ord u) => Translate (Picture u) 
(Num u, Ord u) => Scale (Picture u) 
(Floating u, Real u) => RotateAbout (Picture u) 
(Floating u, Real u) => Rotate (Picture u) 
Boundary (Picture u) 

data Primitive u Source

Wumpus's drawings are built from two fundamental primitives: paths (line segments and Bezier curves) and labels (single lines of text).

Ellipses are a included as a primitive only for optimization - drawing a reasonable circle with Bezier curves needs at least eight curves. This is inconvenient for drawing dots which can otherwise be drawn with a single arc command.

Wumpus does not follow PostScript and employ arcs as general path primitives - they are used only to draw ellipses. This is because arcs do not enjoy the nice properties of Bezier curves, whereby the affine transformation of a Bezier curve can simply be achieved by the affine transformation of it's control points.

Ellipses are represented by their center, half-width and half-height. Half-width and half-height are used so the bounding box can be calculated using only multiplication, and thus initially only obliging a Num constraint on the unit. Though typically for affine transformations a Fractional constraint is also obliged.


Eq u => Eq (Primitive u) 
Show u => Show (Primitive u) 
Pretty u => Pretty (Primitive u) 
(Fractional u, Ord u) => Boundary (Primitive u) 

data Path u Source


Eq u => Eq (Path u) 
Show u => Show (Path u) 
Semigroup (Path u)

Paths are sensibly a Semigroup - there is no notion of empty path.

Pretty u => Pretty (Path u) 
Pointwise (Path u) 
(Num u, Ord u) => Boundary (Path u) 

data PathSegment u Source


data Label u Source


Eq u => Eq (Label u) 
Show u => Show (Label u) 
Pretty u => Pretty (Label u) 

data DrawPath Source

Note when drawn filled and drawn stroked the same polygon will have (slightly) different size:

  • A filled shape fills within the boundary of the shape
  • A stroked shape draws a pen line around the boundary of the shape. The actual size depends on the thickness of the line (stroke width).