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





This module re-exports types and functions from Wumpus.Core.PictureInternal but makes them opaque. Contructors are provided by Wumpus.Core.Picture.

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 types

data Picture Source

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]

data FontCtx Source

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.


data Primitive Source

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 arc command.

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.

data XLink Source

Primitives can be grouped with hyperlinks in SVG output.

Note - this is always printed as xlink:href=.... Other types of xlink can be modelled with the unrestrained SvgAnno type.

data PrimPath Source

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 absCurevTo and absLineTo functions in a list.

data PrimPathSegment Source

PrimPathSegment - either a relative cubic Bezier curve-to or a relative line-to.

data AbsPathSegment Source

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.

data PrimLabel Source

Label - represented by baseline-left point and text.

Baseline-left is the dx * dy of the PrimCTM.

type KerningChar = (Double, EscapedChar)Source

A Char (possibly escaped) paired with its displacement from the previous KerningChar.

stringformat :: String -> DocSource

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 Format class.

To define Format instances render the unit type to a String then use stringformat, e.g:

 instance Format Pica where
   format a = stringformat (show a)