packages feed

wumpus-core 0.33.0 → 0.34.0

raw patch · 16 files changed

+152/−116 lines, 16 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

demo/Latin1Pic.hs view
@@ -20,8 +20,10 @@ -- supports escapes as either numbers or names... -- pic1 :: DPicture-pic1 = frame [ helveticaLabel "mystère"      (P2 0 40)-             , helveticaLabel "myst&#egrave;re"   (P2 0 20)+pic1 = frame [ helveticaLabel "mystère"      (P2 0 60)+             , helveticaLabel "myst&#egrave;re"   (P2 0 40)+             , helveticaLabel "myst&#0o350;re"    (P2 0 20)+             , helveticaLabel "myst&#0XE8;re"     (P2 0 00)              ]   
src/Wumpus/Core.hs view
@@ -12,46 +12,15 @@ -- -- Common interface to Wumpus.Core. ----- This module re-exports types and functions from:------ * "Wumpus.Core.AffineTrans"------ * "Wumpus.Core.BoundingBox"------ * "Wumpus.Core.Colour"------ * "Wumpus.Core.FontSize"------ * "Wumpus.Core.Geometry"------ * "Wumpus.Core.GraphicsState"------ * "Wumpus.Core.OutputPostScript"------ * "Wumpus.Core.OutputSVG"------ * "Wumpus.Core.Picture"------ * "Wumpus.Core.PictureLanguage"------ * "Wumpus.Core.PtSize"------ * "Wumpus.Core.TextEncoder"------ * "Wumpus.Core.TextLatin1"------ * "Wumpus.Core.TextSymbolFont"------ * "Wumpus.Core.VersionNumber"------ * "Wumpus.Core.WumpusTypes"+-- This is a /shim/ module re-exporting types and functions from+-- the exposed Wumpus-Core modules. In most cases, importing just +-- this module should be sufficient to use Wumpus-Core.  ----- Named colours ( black, white etc.) are hidden from +-- Named colours ( black, white etc.) are hidden from the module -- "Wumpus.Core.Colour" to avoid collisions with modules that--- define colour sets (e.g. all the SVG colours). If needed, --- the module can be imported directly.--- ---+-- define colour sets (e.g. all the SVG colours). If named +-- colours are needed, "Wumpus.Core.Colour" can be imported +-- directly. --  -------------------------------------------------------------------------------- 
src/Wumpus/Core/AffineTrans.hs view
@@ -18,16 +18,23 @@ -- The common affine transformations represented as type classes - -- scaling, rotation, translation. ----- Unlike other functional graphics systems (e.g. Clastic), Wumpus--- performs the affine transformations as matrix operations. This --- simplifies the implementation of pictures --- ("Wumpus.Core.PictureInternal"). When a picture is composed and --- transformed, transformations will be performed only on the --- bounding box in Wumpus but the transformation of the --- picture content (paths or text labels) will be communicated to --- PostScript or SVG to render. This is because Wumpus has no --- access to the paths that make fonts so cannot transform them --- directly.+-- Internally, when a picture is composed and transformed, Wumpus+-- only transforms the bounding box - transformations of the +-- picture content (paths or text labels) are communicated to +-- PostScript or SVG for final rendering. This is because Wumpus +-- has no access to the paths that make fonts so cannot transform +-- them directly.+--+-- As well as Pictures, some elements - e.g. Vectors, Points and +-- BoundingBoxes - are also instances of the affine classes. The+-- implementation of the instances considers that under +-- transformation these objects are implicitly within the standard +-- affine frame (origin at point zero and unit basis vectors for +-- the horizontal and vertical). +--+-- This assumption cannot hold for primitives because text is +-- special in PostScript and SVG, so there are no instances of +-- the affine classes for Primitive or PrimElement. --  -- To generate efficient PostScript, Wumpus relies on the matrix -- representations of the affine transformations being invertible.
src/Wumpus/Core/BoundingBox.hs view
@@ -14,8 +14,7 @@ -- Bounding box with no notion of \'empty\'. -- -- Empty pictures cannot be created with Wumpus. This greatly --- simplifies the implementation of pictures themselves and--- bounding boxes.+-- simplifies the implementation of pictures and bounding boxes. --  -------------------------------------------------------------------------------- 
src/Wumpus/Core/Colour.hs view
@@ -13,9 +13,12 @@ -- Colour represented as RGB with each component in the range  -- [0..255]. -- --- Note - the predifined colours are hidden when importing the--- /top-level/ module @Wumpus.Core@, import this module directly--- to use them.+-- Note - the predefined colours are hidden when importing the+-- /top-level/ shim module @Wumpus.Core@, import +-- @Wumpus.Core.Colour@ directly to use them.+--+-- PostScript has no support for RGB-alpha and hence does not+-- transparency. Thus Wumpus in turn cannot support transparency. -- -------------------------------------------------------------------------------- 
src/Wumpus/Core/FontSize.hs view
@@ -13,14 +13,16 @@ -- Font size calculation for Label\'s and their bounding boxes. --  -- Calculations are based on metrics derived from Courier at --- 48pt. As Courier is a monospaced font, bounding boxes --- calculated for other font families will usually have longer --- width than is necessary for the printed text. +-- 48pt. As Courier is a monospaced font, applying these metrics+-- to other font families will usually produce over-estimates+-- (bounding boxes will be longer than the true visual length+-- of the text). --  -- This is a deficiency of Wumpus, and limits its text handling--- capabilities (for example, text cannot be automatically --- centered). However, alternatives would need access to font --- metrics - this would require a font loader and add +-- capabilities - for example, text cannot be reliably centered+-- as its true length is not known. However, more powerful +-- alternatives would need access to the metrics embedded within+-- font files. This would require a font loader and add  -- significant implementation complexity. --  --------------------------------------------------------------------------------
src/Wumpus/Core/GraphicsState.hs view
@@ -10,25 +10,17 @@ -- Stability   :  unstable -- Portability :  GHC ----- Data types for stroke and label attributes and type classes --- for conversion to PostScript\'s colour and matrix --- representations. +-- Data types for stroke and label attributes.  --  -- Wumpus represents pictures as trees - a leaf represents a  -- path or text label. All attributes of a path or text label  -- (colour, stroke width, font, ...) are stored in the leaf. So -- a picture is a leaf labelled tree. -- --- By contrast, PostScript maintains a /graphics state/. A +-- By contrast, PostScript maintains a global /graphics state/. A  -- PostScript program is free to modify the graphics state --- anywhere in the program. Stroke width is a general property  --- shared by all elements (initially it has the default value 1).--- Only stroked paths actually regard stroke width, fonts and --- filled and clipping paths ignore it. PostScript allows more --- control over the graphics state by allowing the current state--- to be saved and restored with the @gsave@ and @grestore@. --- This is useful for modularity but is a comparatively expensive--- procedure.+-- anywhere in the program and subsequent elements are all drawn +-- according to the modified graphics state.  -- -- When Wumpus renders Pictures as PostScript it maintains a  -- limited graphics state with just current colour and current 
src/Wumpus/Core/OutputPostScript.hs view
@@ -98,7 +98,10 @@ setsGS :: (GraphicsState -> GraphicsState) -> PsMonad () setsGS fn = PsMonad $ \_ s -> ((),fn s) +resetGS :: PsMonad ()+resetGS = PsMonad $ \ _ _ -> ((),zeroGS) + setsSA :: (StrokeAttr -> StrokeAttr) -> PsMonad () setsSA fn = getsGS gs_stroke_attr >>= \sa ->              setsGS (\s -> s { gs_stroke_attr = fn sa })@@ -251,12 +254,19 @@ -- Note - PostScript ignotes any FontCtx changes via the @Group@ -- constructor. --+-- Also - because Clip uses gsave grestore it has to resetGS on+-- ending, otherwise the next picture will be diffing against+-- a modified state (in Wumpus land) that contradicts the PostScript +-- state. +-- picture :: (Real u, Floating u, PSUnit u) => Picture u -> PsMonad Doc picture (Leaf    (_,xs) ones)   = bracketTrafos xs $ oneConcat primElement ones picture (Picture (_,xs) ones)   = bracketTrafos xs $ oneConcat picture ones-picture (Clip    (_,xs) cp pic) = bracketTrafos xs $-                                    (vconcat <$> clipPath cp <*> picture pic) picture (Group   (_,xs) _ pic) = bracketTrafos xs (picture pic)+picture (Clip    (_,xs) cp pic) = bracketTrafos xs $+    (\d1 d2 -> vcat [ps_gsave,d1,d2,ps_grestore])+      <$> clipPath cp <*> picture pic <* resetGS+   oneConcat :: (a -> PsMonad Doc) -> OneList a -> PsMonad Doc
src/Wumpus/Core/OutputSVG.hs view
@@ -18,14 +18,10 @@ -- 1. The coordinate space of SVG is /origin top-left/, for  -- PostScript it is /origin bottom-left/. -- --- 2. Clipping in PostScript works by changing the graphics state--- Clip a path, then all subsequent drawing be rendered only --- when it is within the clip bounds. Clearly using clipping --- paths within a @gsave ... grestore@ block is a good idea...------ SVG uses /tagging/. A clipPath element is declared and named --- then referenced in subsequent elements via the clip-path --- attribute - @clip-path=\"url(#clip_path_tag)\"@.+-- 2. Clipping in SVG uses /tagging/. A clipPath element is +-- declared and named, subsequent elements within the clipping +-- area reference it via the clip-path attribute - +-- @clip-path=\"url(#clip_path_tag)\"@. -- -- --------------------------------------------------------------------------------@@ -211,7 +207,9 @@ drawXLink (XLink href) doc = elem_a_xlink href doc  clipPath :: PSUnit u => String -> PrimPath u -> SvgMonad Doc-clipPath clip_id pp = (\doc -> elem_clipPath (attr_id clip_id) doc) <$> path pp+clipPath clip_id pp = +    (\doc -> elem_clipPath (attr_id clip_id) (elem_path_no_attrs doc)) +      <$> path pp   primPath :: PSUnit u => PathProps -> PrimPath u -> SvgMonad Doc
src/Wumpus/Core/Picture.hs view
@@ -476,9 +476,13 @@ -- neither picture will be moved. -- picOver :: (Num u, Ord u) => Picture u -> Picture u -> Picture u-a `picOver` b = Picture (bb,[]) (cons a $ one b)+a `picOver` b = Picture (bb,[]) (cons b $ one a)    where     bb = boundary a `append` boundary b++-- picOver note - draw b, put b first in the list, so it draws +-- first in the output (this is also @behind@ in the Z-Order).+  -- | 'picMoveBy' : @ picture -> vector -> picture @ -- 
src/Wumpus/Core/PictureInternal.hs view
@@ -115,11 +115,8 @@ -- Omitting some details, Picture is a simple non-empty  -- leaf-labelled rose tree via: -- --- > Leaf primitives | Picture [tree]+-- > tree = Leaf [primitive] | Picture [tree] ----- Where OneList is a variant of the standard list type that --- disallows empty lists.---  -- The additional constructors are convenience: -- -- @Clip@ nests a picture (tree) inside a clipping path.@@ -137,10 +134,15 @@ type DPicture = Picture Double  -- | To represent XLink hyperlinks, Primitives in a Leaf are --- encoded in a tree rather a list.+-- actualy encoded in a tree rather a list. ----- (This is rather unfortunate as it expends an extra wrapper--- for ever element regardless of whether hyerlinks are needed).+-- As a design, this is rather unfortunate as it demands an extra +-- wrapper for ever element regardless of whether hyperlinks are +-- actually used. But it does mean that one hyperlink can cover a +-- complex graphic element - for example an arrow might be drawn +-- with one or more paths, plus extra (filled or stroked) paths +-- for the tip and tail, but each element should be within the +-- link.  -- data PrimElement u = Atom             (Primitive u)                    | XLinkGroup XLink (OneList (PrimElement u))@@ -190,8 +192,8 @@   deriving (Eq,Show)                   -- | Wumpus\'s drawings are built from two fundamental --- primitives: paths (line segments and Bezier curves) and --- labels (single lines of text). +-- 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 @@ -649,7 +651,7 @@ -- | Rotate a Primitive. --  -- Note - this is not an affine transformation as Primitives are--- not regarded as being in an affine frame.+-- not regarded as being within an affine frame. -- -- * Paths are rotated about their start point. --@@ -679,7 +681,7 @@ -- | Scale a Primitive. --  -- Note - this is not an affine transformation as Primitives are--- not regarded as being in an affine frame.+-- not regarded as being within an affine frame. -- -- An affine scaling uniformly scales all the elements in a  -- Picture. It is just a change of the Picture\'s basis vectors.@@ -749,8 +751,8 @@ --  -- This is a visually intuitive interpretation - Primitives are -- not in an affine space (they have an origin, i.e. the location --- (0,0), but don\'t not basis vectors) so manipulating them --- cannot follow the standard affine interpretation.+-- (0,0), but do not have tangible basis vectors) so manipulating +-- them cannot follow the standard affine interpretation. --  rotatePath :: (Real u, Floating u) => Radian -> PrimPath u -> PrimPath u rotatePath ang (PrimPath start xs) = PrimPath start $ map (mapSeg fn) xs 
src/Wumpus/Core/SVGDoc.hs view
@@ -27,6 +27,7 @@   , elem_a_xlink     , elem_clipPath   , elem_path+  , elem_path_no_attrs   , elem_text   , elem_tspan   , elem_ellipse@@ -169,6 +170,12 @@ elem_path attrs path = svgElem "path" (attrs <+> svgAttr "d" path)  +-- | @ \<path d=... /\> @+--+elem_path_no_attrs :: Doc -> Doc+elem_path_no_attrs path = svgElem "path" (svgAttr "d" path)++ -- | @ \<text ... >...\</text\> @ -- elem_text :: Doc -> Doc -> Doc@@ -381,7 +388,7 @@ -- | @ clip_path="url(#...)" @ -- attr_clip_path :: String -> Doc-attr_clip_path ss = svgAttr "transform" (text "url" <> parens (text $ '#':ss)) +attr_clip_path ss = svgAttr "clip-path" (text "url" <> parens (text $ '#':ss))    -- | @ transform="..." @
src/Wumpus/Core/TextInternal.hs view
@@ -125,20 +125,49 @@ --  lexer :: String -> [TextChunk] lexer []            = []+lexer ('&':'#':cs)  = escStart cs+lexer (c:cs)        = let (ss,rest) = span (/= '&') cs +                      in TextSpan (c:ss) : lexer rest -lexer ('&':'#':xs)  = esc xs+escStart :: String -> [TextChunk]+escStart ('0':'o':cs)           = escOct cs+escStart ('0':'O':cs)           = escOct cs+escStart ('0':'x':cs)           = escHex cs+escStart ('0':'X':cs)           = escHex cs+escStart (c:cs) | isDigit c     = escDec (digitToInt c) cs+escStart (c:cs)                 = let (ss,rest) = span isAlphaNum cs +                                  in TextEscName (c:ss) : chompToSemi rest+escStart []                     = [] ++-- | One digit consumed already...+--+escDec :: Int -> String -> [TextChunk]+escDec n (c:cs) | isDigit c = escDec (n*10 + digitToInt c) cs+escDec n cs     | n > 0     = TextEscInt n : chompToSemi cs+                | otherwise = chompToSemi cs++escHex :: String -> [TextChunk]+escHex = step 0   where-    esc (c:cs) | isDigit c = let (s,cs') = span isDigit cs -                             in  intval (c:s) cs'-               | otherwise = let (s,cs') = span isAlpha cs -                             in TextEscName (c:s) : optsemi cs'-    esc []                 = []+    step n (c:cs) | isHexDigit c = step (n*16 + digitToInt c) cs+    step n cs     | n > 0        = TextEscInt n : chompToSemi cs+                  | otherwise    = chompToSemi cs  -    optsemi (';':cs)   = lexer cs      -- let ill-formed go through-    optsemi cs         = lexer cs -    intval [] rest  = optsemi rest-    intval cs rest  = TextEscInt (read cs) : optsemi rest+escOct :: String -> [TextChunk]+escOct = step 0+  where+    step n (c:cs) | isHexDigit c = step (n*8 + digitToInt c) cs+    step n cs     | n > 0        = TextEscInt n : chompToSemi cs+                  | otherwise    = chompToSemi cs  -lexer (x:xs)        = let (s,xs') = span (/= '&') xs -                      in TextSpan (x:s) : lexer xs'+++-- The last two conditions both indicate ill-formed input, but it+-- is /best/ if the lexer does not throw errors.+-- +chompToSemi :: String -> [TextChunk]+chompToSemi (';':cs) = lexer cs+chompToSemi (_:cs)   = chompToSemi cs           +chompToSemi []       = []+
src/Wumpus/Core/VersionNumber.hs view
@@ -22,7 +22,7 @@  -- | Version number. ----- > (0,33,0)+-- > (0,34,0) -- wumpus_core_version :: (Int,Int,Int)-wumpus_core_version = (0,33,0)+wumpus_core_version = (0,34,0)
src/Wumpus/Core/WumpusTypes.hs view
@@ -12,7 +12,7 @@ -- -- This module re-exports types and functions from  -- "Wumpus.Core.PictureInternal" but makes them opaque. -+-- Contructors are provided by "Wumpus.Core.Picture". --  -------------------------------------------------------------------------------- 
wumpus-core.cabal view
@@ -1,5 +1,5 @@ name:             wumpus-core-version:          0.33.0+version:          0.34.0 license:          BSD3 license-file:     LICENSE copyright:        Stephen Tetley <stephen.tetley@gmail.com>@@ -37,7 +37,7 @@   Wumpus might be limited compared to other systems. However,    the design permits a fairly simple implementation, which is a    priority. -  .+  .     .   \[1\] Because the output is simple, straight-line PostScript    code, it is possible to use GraphicsMagick or a similar tool @@ -46,6 +46,18 @@   .   Changelog:   .+  0.33.0 to 0.34.0:+  .+  * Clipping paths fixed. Previously they did not work for SVG or+    PostScript.+  .+  * @picOver@ fixed. Drawing order was changed in version 0.33.0, +    but @picOver@ was not updated accordingly (so it actually +    started drawing pictures /under/). It now works correctly.+  .+  * The lexer for escape characters embedded in label strings has +    been rewritten. It now supports octal and hexadecimal codes.+  .     0.32.0 to 0.33.0:   .   * Major change - reworked support for text encoding. Encoding