Note - whilst the Picture types support the Eq class the implementations are not efficient, e.g. In the case of Primitive, one of the constructors has to unwind a functional Hughes list. The Eq instance is considered a legacy feature (or burden) as the types have expanded.
Picture is a rose tree. Leaves themselves are attributed with colour, line-width etc. The unit of a Picture is fixed to Double representing PostScript's Point unit. Output is always gewnerated with PostScript points - other units are converted to PostScript points before building the Picture.
By attributing leaves with their drawing properties, Wumpus's picture representaion is not directly matched to PostScript. PostScript has a global graphics state (that allows local modifaction) from where drawing properties are inherited. Wumpus has no attribute inheritance.
Omitting some details of the list representation, Picture is a simple non-empty rose tree via:
tree = Leaf [primitive] | Picture [tree]
Set the font delta for SVG rendering.
Note - this does not change the default colour or font style. It is solely a backdoor into the SVG renderer to potential allow some code size reductions.
Wumpus's drawings are built from two fundamental primitives: paths (straight 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
Wumpus does not follow PostScript employing arc as a general path primitive - arcs 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.
Clipping is represented by a pair of the clipping path and the primitive embedded within the path.
To represent XLink hyperlinks, Primitives can be annotated with some a hyperlink (likewise a passive font change for better SVG code generation) and grouped - a hyperlinked arrow would want the tip and the arrow body both to be incorporated in thelink even though they are two drawing primitives.
This means that Primitives aren't strictly primitive as the actual implementation is a tree.
Primitives can be grouped with hyperlinks in SVG output.
Note - this is always printed as
types of xlink can be modelled with the unrestrained
PrimPath - a list of path segments and a CTM (translation matrix).
The start point of the path forms the (dx,dy) of the CTM. The CTM is otherwise hidden from the public constructors of this data type.
Note - the PrimPath type does not support concatenation. It is expected that all PrimPaths will be created in one go, and client code defines a higher-level path type that supports concatenation, splitting etc.
Primitively paths can be built like this:
path1 :: PrimPath path1 = absPrimPath zeroPt [ absLineTo (P2 0 60) , absLineTo (P2 40 100) , absLineTo (P2 80 60) , absLineTo (P2 80 0) , absLineTo (P2 60 0) , absLineTo (P2 60 30) , absCurveTo (P2 60 50) (P2 50 60) (P2 40 60) , absCurveTo (P2 30 60) (P2 20 50) (P2 20 30) , absLineTo (P2 20 0) ]
Although it's generally expected that PrimPaths will be
constructed by traversing a higher-level path object and
collecting calls to the
in a list.
PrimPathSegment - either a relative cubic Bezier curve-to or a relative line-to.
AbsPathSegment - either a cubic Bezier curve or a line.
Note this data type is transitory - it is only used as a convenience to build relative paths. Hence the unit type is parametric.
Label - represented by baseline-left point and text.
Baseline-left is the dx * dy of the PrimCTM.
A Char (possibly escaped) paired with its displacement from the previous KerningChar.
|Format u => Format (Matrix3'3 u)|
|Format u => Format (Point2 u)|
|Format u => Format (Vec2 u)|
|Format u => Format (BoundingBox u)|
stringformat : String -> Doc
The format combinators are not exported by Wumpus-Core,
however for debugging unit types might need to be made
instances of the
To define Format instances render the unit type to a String
instance Format Pica where format a = stringformat (show a)