packages feed

wumpus-core 0.21.0 → 0.22.0

raw patch · 14 files changed

+273/−874 lines, 14 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Wumpus.Core.FontSize: capHeight :: (Fractional u) => FontSize -> u
- Wumpus.Core.FontSize: courier48_body_height :: (Num u) => u
- Wumpus.Extra.PictureLanguage: (-//-) :: (Vertical a, Composite a, Num u, u ~ (PUnit a)) => a -> a -> a
- Wumpus.Extra.PictureLanguage: (-<-) :: (Horizontal a, Composite a, Num u, u ~ (PUnit a)) => a -> a -> a
- Wumpus.Extra.PictureLanguage: (->-) :: (Horizontal a, Composite a, Num u, u ~ (PUnit a)) => a -> a -> a
- Wumpus.Extra.PictureLanguage: (-@-) :: (Horizontal a, Vertical a, Composite a, Move a, Fractional u, u ~ (PUnit a)) => a -> a -> a
- Wumpus.Extra.PictureLanguage: HBottom :: HAlign
- Wumpus.Extra.PictureLanguage: HCenter :: HAlign
- Wumpus.Extra.PictureLanguage: HTop :: HAlign
- Wumpus.Extra.PictureLanguage: VCenter :: VAlign
- Wumpus.Extra.PictureLanguage: VLeft :: VAlign
- Wumpus.Extra.PictureLanguage: VRight :: VAlign
- Wumpus.Extra.PictureLanguage: above :: (Vertical a, Composite a, Num u, u ~ (PUnit a)) => a -> a -> a
- Wumpus.Extra.PictureLanguage: alignH :: (Fractional u, Composite a, Horizontal a, Vertical a, Move a, u ~ (PUnit a)) => HAlign -> a -> a -> a
- Wumpus.Extra.PictureLanguage: alignV :: (Fractional u, Composite a, Horizontal a, Vertical a, Move a, u ~ (PUnit a)) => VAlign -> a -> a -> a
- Wumpus.Extra.PictureLanguage: at :: (Move a, u ~ (PUnit a)) => a -> Point2 u -> a
- Wumpus.Extra.PictureLanguage: below :: (Vertical a, Composite a, Num u, u ~ (PUnit a)) => a -> a -> a
- Wumpus.Extra.PictureLanguage: beneath :: (Composite a) => a -> a -> a
- Wumpus.Extra.PictureLanguage: blank :: (Blank a) => PUnit a -> PUnit a -> a
- Wumpus.Extra.PictureLanguage: bottomBound :: (Vertical a) => a -> PUnit a
- Wumpus.Extra.PictureLanguage: bottomleft :: (Horizontal a, Vertical a, u ~ (PUnit a)) => a -> Point2 u
- Wumpus.Extra.PictureLanguage: bottomright :: (Horizontal a, Vertical a, u ~ (PUnit a)) => a -> Point2 u
- Wumpus.Extra.PictureLanguage: center :: (Horizontal a, Vertical a, Fractional u, u ~ (PUnit a)) => a -> Point2 u
- Wumpus.Extra.PictureLanguage: centeredAt :: (Horizontal a, Vertical a, Move a, Composite a, Blank a, Fractional u, u ~ (PUnit a)) => a -> Point2 u -> a
- Wumpus.Extra.PictureLanguage: class Blank a
- Wumpus.Extra.PictureLanguage: class Composite a
- Wumpus.Extra.PictureLanguage: class Horizontal a
- Wumpus.Extra.PictureLanguage: class Move a
- Wumpus.Extra.PictureLanguage: class Vertical a
- Wumpus.Extra.PictureLanguage: data HAlign
- Wumpus.Extra.PictureLanguage: data VAlign
- Wumpus.Extra.PictureLanguage: hcat :: (Horizontal a, Composite a, Num u, u ~ (PUnit a)) => a -> [a] -> a
- Wumpus.Extra.PictureLanguage: hcatA :: (Fractional u, Horizontal a, Vertical a, Composite a, Move a, u ~ (PUnit a)) => HAlign -> a -> [a] -> a
- Wumpus.Extra.PictureLanguage: hsep :: (Num u, Composite a, Horizontal a, Blank a, u ~ (PUnit a)) => u -> a -> [a] -> a
- Wumpus.Extra.PictureLanguage: hsepA :: (Fractional u, Horizontal a, Vertical a, Composite a, Move a, Blank a, u ~ (PUnit a)) => HAlign -> u -> a -> [a] -> a
- Wumpus.Extra.PictureLanguage: hspace :: (Num u, Composite a, Horizontal a, Blank a, u ~ (PUnit a)) => u -> a -> a -> a
- Wumpus.Extra.PictureLanguage: instance (Num u, Ord u) => Blank (Picture u)
- Wumpus.Extra.PictureLanguage: instance (Num u, Ord u) => Composite (Picture u)
- Wumpus.Extra.PictureLanguage: instance (Num u, Ord u) => Horizontal (Picture u)
- Wumpus.Extra.PictureLanguage: instance (Num u, Ord u) => Move (Picture u)
- Wumpus.Extra.PictureLanguage: instance (Num u, Ord u) => Vertical (Picture u)
- Wumpus.Extra.PictureLanguage: instance Eq HAlign
- Wumpus.Extra.PictureLanguage: instance Eq VAlign
- Wumpus.Extra.PictureLanguage: instance Show HAlign
- Wumpus.Extra.PictureLanguage: instance Show VAlign
- Wumpus.Extra.PictureLanguage: leftBound :: (Horizontal a) => a -> PUnit a
- Wumpus.Extra.PictureLanguage: move :: (Move a) => PUnit a -> PUnit a -> a -> a
- Wumpus.Extra.PictureLanguage: moveH :: (Horizontal a) => PUnit a -> a -> a
- Wumpus.Extra.PictureLanguage: moveV :: (Vertical a) => PUnit a -> a -> a
- Wumpus.Extra.PictureLanguage: multilabel :: (Real u, Floating u, TextLabel t) => t -> u -> VAlign -> [String] -> Point2 u -> Picture u
- Wumpus.Extra.PictureLanguage: over :: (Composite a) => a -> a -> a
- Wumpus.Extra.PictureLanguage: rightBound :: (Horizontal a) => a -> PUnit a
- Wumpus.Extra.PictureLanguage: stackOnto :: (Composite a) => [a] -> a -> a
- Wumpus.Extra.PictureLanguage: stackOntoCenter :: (Horizontal a, Vertical a, Composite a, Move a, Fractional u, u ~ (PUnit a)) => [a] -> a -> a
- Wumpus.Extra.PictureLanguage: topBound :: (Vertical a) => a -> PUnit a
- Wumpus.Extra.PictureLanguage: topleft :: (Horizontal a, Vertical a, u ~ (PUnit a)) => a -> Point2 u
- Wumpus.Extra.PictureLanguage: topright :: (Horizontal a, Vertical a, u ~ (PUnit a)) => a -> Point2 u
- Wumpus.Extra.PictureLanguage: vcat :: (Vertical a, Composite a, Num u, u ~ (PUnit a)) => a -> [a] -> a
- Wumpus.Extra.PictureLanguage: vcatA :: (Fractional u, Horizontal a, Vertical a, Composite a, Move a, u ~ (PUnit a)) => VAlign -> a -> [a] -> a
- Wumpus.Extra.PictureLanguage: vsep :: (Num u, Composite a, Vertical a, Blank a, u ~ (PUnit a)) => u -> a -> [a] -> a
- Wumpus.Extra.PictureLanguage: vsepA :: (Fractional u, Horizontal a, Vertical a, Composite a, Move a, Blank a, u ~ (PUnit a)) => VAlign -> u -> a -> [a] -> a
- Wumpus.Extra.PictureLanguage: vspace :: (Num u, Composite a, Vertical a, Blank a, u ~ (PUnit a)) => u -> a -> a -> a
+ Wumpus.Core.FontSize: courier48_ascender_height :: (Num u) => u
+ Wumpus.Core.FontSize: courier48_numeral_height :: (Num u) => u
+ Wumpus.Core.FontSize: courier48_xheight :: (Num u) => u
+ Wumpus.Core.FontSize: numeralHeight :: (Fractional u) => FontSize -> u
+ Wumpus.Core.FontSize: xcharHeight :: (Fractional u) => FontSize -> u
+ Wumpus.Core.Geometry: vec :: (Num u) => u -> u -> Vec2 u
+ Wumpus.Core.WumpusTypes: class (Num a) => PSUnit a
+ Wumpus.Core.WumpusTypes: dtrunc :: (PSUnit a) => a -> String
+ Wumpus.Core.WumpusTypes: toDouble :: (PSUnit a) => a -> Double

Files

CHANGES view
@@ -1,11 +1,33 @@ +0.21.0 to 0.22.0:++  * Moved the deprecated module @Wumpus.Extra.PictureLanguage@+    into the package Wumpus-Basic along with the example +    @Picture.hs@.++  * Added vec as a synonym for the constructor V2.++  * Changed some of the Core.FontSize to use better terminology. +    Thus some of the constants have changed. Added a new example+    @FontMetrics.hs@ to illustrate how FontSize works. +    Particularly, the function @capHeight@ has been replaced with+    the function @numeralHeight@ which has better semantics.++  * The CTM data type and ToCTM class are now hidden in the+    top-level import module @Wumpus.Core@. They can be accessed+    by importing @Wumpus.Core.GraphicsState@ directly.++  * Exposed the PSUnit type class. ++ 0.20.0 to 0.21.0: -  * Removed the instances of the Affine transformation. They have-    been replaced with special transformation functions: -    @rotatePrimitive@, @scalePrimitive@, @translatePrimitive@.-    As Primitives are not in an affine frame until they are lifted -    to Pictures the affine instances had ill-conceived semantics.+  * Removed the Primitive instances of the Affine transformation +    classes. They have been replaced with special transformation +    functions: @rotatePrimitive@, @scalePrimitive@, +    @translatePrimitive@. As Primitives are not in an affine +    frame until they are lifted to Pictures the affine instances +    had ill-conceived semantics.    * Due to changes to accommodate the new non-affine       transformations, many of the class obligations have changed 
+ demo/FontMetrics.hs view
@@ -0,0 +1,75 @@+{-# OPTIONS -Wall #-}++module FontMetrics where++import Wumpus.Core++import Data.AffineSpace                 -- package: vector-space++import System.Directory++++main :: IO ()+main = do +    createDirectoryIfMissing True "./out/"+    writeEPS_latin1 "./out/font_metrics.eps" metrics_pic+    writeSVG_latin1 "./out/font_metrics.svg" metrics_pic++++peru :: PSRgb+peru = RGB3 0.804  0.522  0.247++plum :: PSRgb+plum = RGB3 0.867  0.627  0.867++black :: PSRgb+black = RGB3 0 0 0 ++courier_attr :: FontAttr+courier_attr = FontAttr "Courier" "Courier New" SVG_REGULAR 48++metrics_pic :: DPicture+metrics_pic = char_pic `picOver` lines_pic++lines_pic   :: DPicture+lines_pic   = frameMulti $ +    [ ascender_line, numeral_line, xheight_line, baseline, descender_line ]+  where+    descender_pos   = 0 - courier48_descender_depth+  +    ascender_line   = haxis peru (descender_pos + courier48_height)+    numeral_line    = haxis peru courier48_numeral_height+    xheight_line    = haxis peru courier48_xheight+    baseline        = haxis peru 0+    descender_line  = haxis peru descender_pos++++char_pic :: Picture Double+char_pic = frameMulti $ zipWith ($) chars (iterate (.+^ hvec 32) zeroPt)+  where+    chars = (map letter "ABXabdgjxy12") ++ [agraveU]++type PrimF = DPoint2 -> DPrimitive++bodyHeight  :: PrimF+bodyHeight  = vertLine peru courier48_numeral_height++agraveU     :: PrimF+agraveU     = textlabel (black, courier_attr) "&#Agrave"++letter :: Char -> DPoint2 -> DPrimitive+letter ch pt = textlabel (black, courier_attr) [ch] pt+++vertLine :: DRGB -> Double -> DPoint2 -> DPrimitive+vertLine rgb height pt = ostroke rgb $ vertexPath [pt, pt .+^ vvec height]++haxis :: DRGB -> Double -> DPrimitive+haxis rgb ypos = +    ostroke (rgb, dash_attr) $ vertexPath [ pt, pt .+^ hvec 440 ]+  where+    dash_attr = DashPattern (Dash 0 [(2,2)])+    pt        = P2 0 ypos
demo/LabelPic.hs view
@@ -1,9 +1,9 @@+{-# LANGUAGE TypeFamilies               #-} {-# OPTIONS -Wall #-}  module LabelPic where  import Wumpus.Core-import Wumpus.Extra.PictureLanguage  import System.Directory @@ -12,11 +12,20 @@   drawBounds :: (Floating u, Real u) => Picture u -> Picture u-drawBounds p        = p `over` (frame $ cstroke () ph) +drawBounds p        = p `picOver` (frame $ cstroke () ph)    where     ph            = vertexPath $ [bl,br,tr,tl]     (bl,br,tr,tl) = corners $ boundary p ++-- | The center of a picture.+center :: (Boundary a, Fractional u, DUnit a ~ u) => a -> Point2 u+center a = P2 hcenter vcenter +  where  +    BBox (P2 x0 y0) (P2 x1 y1) = boundary a+    hcenter                    = x0 + 0.5 * (x1 - x0)+    vcenter                    = y0 + 0.5 * (y1 - y0)+ --------------------------------------------------------------------------------  @@ -32,7 +41,7 @@   lbl1 :: Picture Double-lbl1 = line1 -//- line2 where+lbl1 = line1 `picBeside` line2 where   line1 = frame (textlabel attrs "Hello" zeroPt)   line2 = frame (textlabel attrs "World" zeroPt)   attrs = (peru, FontAttr "Helvetica" "Helvetica" SVG_REGULAR 12) @@ -48,16 +57,18 @@     writeEPS_latin1 "./out/label02.eps" p1     writeSVG_latin1 "./out/label02.svg" p1   where-    p1 = lbl1 ->- lbl1 ->- (rotateAbout (pi/4) (center lbl1) lbl1) ->- lbl1+    p1 = lbl1 `picBeside` lbl1 +              `picBeside` (rotateAbout (pi/4) (center lbl1) lbl1) +              `picBeside` lbl1  demo03 :: IO () demo03 = do      writeEPS_latin1 "./out/label03.eps" p1     writeSVG_latin1 "./out/label03.svg" p1   where-    p1 = (drawBounds lbl1) ->- -         (drawBounds lbl1) ->- -         (drawBounds $ rotateAbout (pi/4) (center lbl1) lbl1) ->- +    p1 = (drawBounds lbl1) `picBeside` +         (drawBounds lbl1) `picBeside` +         (drawBounds $ rotateAbout (pi/4) (center lbl1) lbl1) `picBeside`           (drawBounds lbl1)  @@ -67,9 +78,9 @@     writeEPS_latin1 "./out/label04.eps" p1     writeSVG_latin1 "./out/label04.svg" p1   where-    p1 =        (drawBounds lbl1) -         `over` (drawBounds $ scale 2 2 lbl1)-         `over` (drawBounds $ scale 3 3 lbl1)+    p1 =           (drawBounds lbl1) +         `picOver` (drawBounds $ scale 2 2 lbl1)+         `picOver` (drawBounds $ scale 3 3 lbl1)   @@ -91,16 +102,20 @@     writeEPS_latin1 "./out/label05.eps" p1     writeSVG_latin1 "./out/label05.svg" p1   where-    p1 = uniformScale 10 $ stackOntoCenter [bigA, bigB] bigT+    p1 = uniformScale 10 $ bigA `picOver` bigB `picOver` bigT  + demo06 :: IO () demo06 = do      writeEPS_latin1 "./out/label06.eps" p1     writeSVG_latin1 "./out/label06.svg" p1   where-    p1 = hsep 20 (fn 'a') (map fn "abcdefg")-    fn = drawBounds . bigLetter peru+    p1 = pA `picBeside` pB `picBeside` pC `picBeside` pA+    +    pA = drawBounds bigA+    pB = drawBounds $ uniformScale 2 bigB+    pC = drawBounds $ picMoveBy `flip` (vec 0 10) $ bigLetter peru 'C'   demo07 :: IO ()@@ -108,53 +123,15 @@     writeEPS_latin1 "./out/label07.eps" p1     writeSVG_latin1 "./out/label07.svg" p1   where-    p1 = pA ->- pB ->- pC ->- pA-    -    pA = drawBounds bigA-    pB = drawBounds $ uniformScale 2 bigB-    pC = drawBounds $ move 0 10 $ bigLetter peru 'C'---demo08 :: IO ()-demo08 = do -    writeEPS_latin1 "./out/label08.eps" p1-    writeSVG_latin1 "./out/label08.svg" p1-  where-    p1 = hcat pA [pA, pB, pC]+    p1 = pA `picBeside` pB `picBeside` pC          pA = drawBounds bigA     pB = drawBounds $ uniformScale 2 bigB-    pC = drawBounds $ move 0 10 $ bigLetter peru 'C'--demo09 :: IO ()-demo09 = do -    writeEPS_latin1 "./out/label09.eps" p1-    writeSVG_latin1 "./out/label09.svg" p1-  where-    p1 = (bigA `above` bigB) ->- (bigA `below` bigB) -    -demo10 :: IO ()-demo10 = do -    writeEPS_latin1 "./out/label10.eps" p1-    writeSVG_latin1 "./out/label10.svg" p1-  where-    p1 :: Picture Double-    p1 = frame $ textlabel () "myst&#egrave;re" zeroPt--demo11 :: IO ()-demo11 = do-    writeEPS_latin1 "./out/label11.eps" pic-    writeSVG_latin1 "./out/label11.svg" pic-  where-    pic :: Picture Double-    pic = p1 `over` p2-    p1  = multilabel plum 3 VLeft ["Hello", "from", "Wumpus"] (P2 50 50)-    p2  = bigA `at` P2 50 50+    pC = drawBounds $ picMoveBy `flip` (vec 0 10) $ bigLetter peru 'C'   main :: IO () main = do    createDirectoryIfMissing True "./out/"   sequence_ [ demo01, demo02, demo03, demo04, demo05-            , demo06, demo07, demo08, demo09, demo10-            , demo11 ]  +            , demo06, demo07 ]
− demo/Picture.hs
@@ -1,207 +0,0 @@-{-# OPTIONS -Wall #-}--module Picture where--import Wumpus.Core-import Wumpus.Extra.PictureLanguage--import System.Directory---main :: IO ()-main = do -    createDirectoryIfMissing True "./out/"-    sequence_  [ demo01, demo02, demo03, demo04, demo05-               , demo06, demo07, demo08, demo09, demo10-               , demo11, demo12, demo13, demo14 ]--peru :: PSRgb-peru = RGB3 0.804  0.522  0.247--plum :: PSRgb-plum = RGB3 0.867  0.627  0.867--black :: PSRgb-black = RGB3 0 0 0 ---square :: DPicture -square = frame $ cstroke () $ vertexPath-  [ P2 0 0, P2 40 0, P2 40 40, P2 0 40 ]--funnyshape :: DPicture-funnyshape = frame $ cstroke () $ vertexPath-  [ P2 0 0, P2 20 0, P2 20 10, P2 30 10, P2 30 20, P2 0 20 ]---demo01 :: IO ()-demo01 = do -  writePS_latin1  "./out/picture01.ps"    [funnyshape ->- square]-  writeSVG_latin1 "./out/picture01.svg" $ funnyshape ->- square---pic1 :: Picture Double-pic1 = square ->- (funnyshape ->- funnyshape) ->- square--squares :: Picture Double-squares = square ->- square ->- square--demo02 :: IO ()-demo02 = do -   writePS_latin1  "./out/picture02.ps"  [squares]-   writeSVG_latin1 "./out/picture02.svg" squares -    --demo03 :: IO ()-demo03 = do -    writeEPS_latin1 "./out/picture03.eps" p1 -    writeSVG_latin1 "./out/picture03.svg" p1-  where     -    p1 = square ->- (rotate45About (center squares) squares) ->- square---demo04 :: IO ()-demo04 = do -    writeEPS_latin1 "./out/picture04.eps" p1-    writeSVG_latin1 "./out/picture04.svg" p1-  where-    p1 = square -//- squares-   --demo05 :: IO ()-demo05 = do -    writeEPS_latin1 "./out/picture05.eps" p1-    writeSVG_latin1 "./out/picture05.svg" p1-  where-    p1 = square `over` (rotate (pi/4) squares)-   --demo06 :: IO ()-demo06 = do -    writeEPS_latin1 "./out/picture06.eps" p1-    writeSVG_latin1 "./out/picture06.svg" p1-  where-    p1 = square `over` (rotate45 square)----- Note the move via @at@ is not apparent when SVG file is --- viewed with Mozilla or Chrome - check picture7a.svg--- We only see that the move has /worked/ when we compose--- with with `over` a square at the origin. --demo07 :: IO ()-demo07 = do -    writeEPS_latin1 "./out/picture07.eps" p1-    writeSVG_latin1 "./out/picture07.svg" p1-    writeSVG_latin1 "./out/picture07a.svg" p2-  where-    p1 = square `over` p2-    p2 = (square `at` (P2 100 30))  -@- (rotate45 square)---demo08 :: IO ()-demo08 = do -    writeEPS_latin1 "./out/picture08.eps" p1-    writeSVG_latin1 "./out/picture08.svg" p1-  where-    p1 = hspace 20 square square--mkFilledSquare :: (PSColour c, Fill c) => c -> Double -> DPicture -mkFilledSquare col n = frame $ fill col $ vertexPath-  [ P2 0 0, P2 n 0, P2 n n, P2 0 n ]---demo09 :: IO ()-demo09 = do -    writeEPS_latin1 "./out/picture09.eps" p1-    writeSVG_latin1 "./out/picture09.svg" p1-  where-    p1 = (alignH HTop s1 s2) `op` s3-    s1 = uniformScale 1.5  $ mkFilledSquare plum 40-    s2 = uniformScale 1.75 $ mkFilledSquare peru 40-    s3 = scale 3 1.5       $ mkFilledSquare black 40-    op = alignH HBottom- --demo10 :: IO ()-demo10 = do -    writeEPS_latin1 "./out/picture10.eps" p1-    writeSVG_latin1 "./out/picture10.svg" p1-  where-    p1 = vsepA VRight 5 s1 [s2,s3]-    s1 = uniformScale 1.5  $ mkFilledSquare plum 40-    s2 = uniformScale 1.75 $ mkFilledSquare peru 40-    s3 = scale 3 1.5       $ mkFilledSquare black 40- ----- Stroked ellipe problem under scaling...-demo11 :: IO ()-demo11 = do -    writeEPS_latin1 "./out/picture11.eps" pic-    writeSVG_latin1 "./out/picture11.svg" pic-  where-    pic :: Picture Double-    pic = p1 -//- p2-    p1 = scale 6 12 $ frame $ ellipse (plum, LineWidth 2) 4 6 zeroPt-    p2 = scale 6 12 $ frame $ ellipse (peru, LineWidth 2) 6 6 zeroPt----- Note the movement of the plum square won't be regarded by --- Firefox as it crops whitespace automatically.-demo12 :: IO ()-demo12 = do -    writeEPS_latin1 "./out/picture12.eps" pic-    writeSVG_latin1 "./out/picture12.svg" pic-  where-    pic :: Picture Double-    pic = p1 -//- p2 -//- p3 -//- p4-    p1 = small_black -@- large_plum     -- moves black-    p2 = large_plum  -@- small_black    -- moves plum-    p3 = small_black ->- large_plum     -- moves plum-    p4 = small_black -<- large_plum     -- moves black--    small_black = mkFilledSquare black 10 `at` P2 30 0-    large_plum  = mkFilledSquare plum  40 `at` P2 100 0---demo13 :: IO ()-demo13 = do -    writeEPS_latin1 "./out/picture13.eps" pic-    writeSVG_latin1 "./out/picture13.svg" pic-  where-    pic :: Picture Double-    pic = (p1 `at` P2 20 20) ->- (p2 `at` P2 60 20) --    p1 = small_black `below` small_peru   -- moves small black-    p2 = small_black `above` small_plum   -- moves small black--    small_black = mkFilledSquare black 10 `at` P2 50 0-    small_plum  = mkFilledSquare plum  10 `at` P2 50 0-    small_peru  = mkFilledSquare peru  10 `at` P2 50 0--demo14 :: IO ()-demo14 = do -    writeEPS_latin1 "./out/picture14.eps" pic-    writeSVG_latin1 "./out/picture14.svg" pic-  where-    pic :: Picture Double-    pic = hsep 40 p1 [p2,p3,p4,p5,p6]--    p1 = alignH HTop    small_black mid_peru-    p2 = alignH HBottom small_black mid_plum-    p3 = alignH HCenter small_black mid_peru--    p4 = alignV VLeft   mid_black small_peru-    p5 = alignV VRight  mid_black small_plum-    p6 = alignV VCenter mid_black small_peru--    small_black = mkFilledSquare black 10 `at` P2 10 0-    mid_plum    = mkFilledSquare plum  25 `at` P2 50 0-    mid_peru    = mkFilledSquare peru  25 `at` P2 50 0--    mid_black   = mkFilledSquare black 25 `at` P2 10 10-    small_plum  = mkFilledSquare plum  10 `at` P2 10 50-    small_peru  = mkFilledSquare peru  10 `at` P2 10 50--
doc-src/Guide.lhs view
@@ -103,7 +103,7 @@ 
 \item[\texttt{Wumpus.Core.TextEncoder.}]
 Types for handling non-ASCII character codes. This module is
-perhaps under-cooked thou it appears adequate for Latin-1...
+perhaps under-cooked although it appears adequate for Latin-1.
 
 \item[\texttt{Wumpus.Core.TextLatin1.}]
 A instance of the TextEncoder type for mapping Latin 1 characters
@@ -117,14 +117,6 @@ presents them as opaque types - i.e. their constructors are 
 hidden. 
 \end{description}
-
-The package also contains a deprecated module defining
-picture composition operators, 
-\texttt{Wumpus.Extra.PictureLanguage}. The operators are somewhat 
-analogue to the usual operators or pretty-printing libraries, 
-but work in 2D rather than largely horizontally with some 
-vertical concatenation. At some point in the future 
-\texttt{wumpus-basic} should supercede this module.
 
 %-----------------------------------------------------------------
 \section{Drawing model}
doc/Guide.pdf view

binary file changed (56739 → 56794 bytes)

src/Wumpus/Core.hs view
@@ -70,7 +70,7 @@ import Wumpus.Core.Colour hiding ( black, white, red, green, blue ) import Wumpus.Core.FontSize import Wumpus.Core.Geometry-import Wumpus.Core.GraphicsState+import Wumpus.Core.GraphicsState hiding ( CTM, ToCTM ) import Wumpus.Core.OutputPostScript import Wumpus.Core.OutputSVG import Wumpus.Core.Picture
src/Wumpus/Core/FontSize.hs view
@@ -17,7 +17,10 @@ -- calculated for other font families will usually have longer  -- width than is necessary for the printed text.  -- --- This is a deficiency of Wumpus, but alternatives would have+-- 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  -- significant implementation complexity. --  --------------------------------------------------------------------------------@@ -31,9 +34,11 @@    -- * Courier metrics at 48 point   , courier48_width-  , courier48_body_height   , courier48_height+  , courier48_numeral_height+  , courier48_xheight   , courier48_descender_depth+  , courier48_ascender_height   , courier48_spacer_width  @@ -41,7 +46,8 @@   , widthAt48pt   , textWidth   , textHeight-  , capHeight+  , numeralHeight+  , xcharHeight   , descenderDepth   , textBounds @@ -55,48 +61,84 @@ type CharCount = Int type FontSize = Int +-- NOTE - I\'ve largely tried to follow the terminoly from +-- Edward Tufte\'s /Visual Explantions/, page 99.+--++ -- | The width of a letter in Courier at 48 pt. -- -- The value is not entirely accurate but it is satisfactory. --+-- > width = 26.0 +-- courier48_width :: Num u => u courier48_width = 26 ---- | The height of a letter without accents, ascenders or --- descenders in Courier at 48 pt .+-- | The point size of a character in Courier at 48 pt. ----- The value is not entirely accurate but it is satisfactory - --- some letters are taller than others (e.g. numbers are taller --- then capitals).+-- \*\* Naturally the height is 48.0 \*\*. ---courier48_body_height :: Num u => u -courier48_body_height = 30+courier48_height :: Num u => u+courier48_height = 48  --- | The /common maximum/ height of a letter in Courier at 48pt.++-- | The height of a numeral without accents, ascenders or +-- descenders in Courier at 48 pt. ----- By common maximum the letter is allowed to have both an accent --- or ascender and a descender.+-- Note - the height of a numeral in Courier is slightly +-- larger than a upper-case letter. ----- Naturally the height is 48.0.+-- > numeral_height = 30.0  ---courier48_height :: Num u => u-courier48_height = 48+courier48_numeral_height :: Num u => u +courier48_numeral_height = 30 +-- | The height of the body of a lower-case letter +--  (typically the letter  \'x\') in Courier at 48 pt. +--+-- This is also known as the \"body height\".+--+-- > xheight = 20.0 +-- +courier48_xheight :: Num u => u +courier48_xheight = 20 + -- | The depth of a descender in Courier at 48 pt. -- --- Also the height of an ascender.+-- > descender_depth = 9.0+--  courier48_descender_depth :: Num u => u  courier48_descender_depth = 9 +-- | The depth of an ascender in Courier at 48 pt.+-- +-- > ascender_height = 10.0+-- +-- Note - for Courier point size is not the sum of+-- descender, ascender and xheight and lower-case letters with+-- ascenders are slightly taller than upper-case letters:+--+-- > descender_depth + xheight + ascender_height /= point_size+--+-- > xheight + ascender_height /= cap_height+--+-- > xheight + ascender_height == numeral_height+--+courier48_ascender_height :: Num u => u +courier48_ascender_height = 10   -- | The spacing between letters printed directly with  -- PostScript\'s show command for Courier at 48 pt. ----- The value is not entirely accurate but it is satisfactory.+-- The value is not entirely accurate but it is satisfactory+-- for bounding box calculations.+--+-- > spacer_width = 3.0+-- courier48_spacer_width :: Num u => u courier48_spacer_width = 3 @@ -117,21 +159,27 @@ textWidth sz n = (fromIntegral sz)/48 * widthAt48pt n  --- | Text height is just identity/double-coercion, i.e. --- @18 == 18.0@. The /size/ of a font is the maximum height:------ > body + descender max + ascender max+-- | Text height is just identity/double-coercion of the Point size.+-- i.e. @18 == 18.0@. The /size/ of a font is the maximum height: -- textHeight :: Num u =>  FontSize -> u textHeight = fromIntegral --- The height of an upper case letter (without ascender or --- descender).+-- | Approximate the height of a numeral using metrics derived +-- from the Courier monospaced font. ---capHeight :: Fractional u => FontSize -> u-capHeight sz = textHeight sz - (2 * descenderDepth sz)+numeralHeight :: Fractional u => FontSize -> u+numeralHeight sz = textHeight sz * (courier48_numeral_height / courier48_height) --- | Descender depth for font size @sz@.+-- | Approximate the height of the lower-case char \'x\' using +-- metrics derived from the Courier monospaced font.+--+xcharHeight :: Fractional u => FontSize -> u+xcharHeight sz = textHeight sz * (courier48_xheight / courier48_height)+++-- | Approximate the descender depth for font size @sz@ using+-- metrics derived from the Courier monospaced font. --  descenderDepth :: Fractional u => FontSize -> u descenderDepth sz =  (fromIntegral sz) / 48 * courier48_descender_depth
src/Wumpus/Core/Geometry.hs view
@@ -49,6 +49,7 @@   , MatrixMult(..)    -- * Vector operations+  , vec   , direction   , hvec   , vvec@@ -417,6 +418,20 @@ -------------------------------------------------------------------------------- -- Vectors +-- | A synonym for the constructor 'V2' with a Num constraint on +-- the arguments.+--+-- Essentially superfluous, but it can be slightly more +-- typographically pleasant when used in lists of vectors:+--+-- > [ vec 2 2, vvec 4, hvec 4, vec 2 2 ]+--+-- Versus:+--+-- > [ V2 2 2, vvec 4, hvec 4, V2 2 2 ]+--  +vec :: Num u => u -> u -> Vec2 u+vec = V2  -- | Direction of a vector - i.e. the counter-clockwise angle  -- from the x-axis.
src/Wumpus/Core/PictureInternal.hs view
@@ -203,7 +203,11 @@ type DPrimEllipse = PrimEllipse Double  -data PrimCTM u = PrimCTM { _xscale :: u, _yscale :: u, _rot :: Radian }+data PrimCTM u = PrimCTM +      { ctm_scale_x     :: u+      , ctm_scale_y     :: u+      , ctm_rotation    :: Radian +      }   deriving (Eq,Show)  @@ -511,13 +515,13 @@ -- Manipulating the Primitive CTM  identityCTM :: Num u => PrimCTM u-identityCTM = PrimCTM 1 1 0+identityCTM = PrimCTM { ctm_scale_x = 1, ctm_scale_y = 1, ctm_rotation = 0 }  scaleCTM :: Num u => u -> u -> PrimCTM u -> PrimCTM u scaleCTM x1 y1 (PrimCTM x y ang) = PrimCTM (x1*x) (y1*y) ang  rotateCTM :: Radian -> PrimCTM u -> PrimCTM u-rotateCTM ang1 (PrimCTM x y ang) = PrimCTM x y (ang1+ang)+rotateCTM ang1 (PrimCTM x y ang) = PrimCTM x y (circularModulo $ ang1+ang)  matrixRepCTM :: (Floating u, Real u) => PrimCTM u -> Matrix3'3 u matrixRepCTM (PrimCTM x y ang) = 
src/Wumpus/Core/VersionNumber.hs view
@@ -20,6 +20,9 @@    ) where -+-- | Version number+--+-- > (0,22,0)+-- wumpus_core_version :: (Int,Int,Int)-wumpus_core_version = (0,21,0)+wumpus_core_version = (0,22,0)
src/Wumpus/Core/WumpusTypes.hs view
@@ -51,8 +51,12 @@   , uniformScalePrimitive  +  -- * Printable unit for PostScript+  , PSUnit(..)+   ) where   import Wumpus.Core.PictureInternal+import Wumpus.Core.Utils () 
− src/Wumpus/Extra/PictureLanguage.hs
@@ -1,554 +0,0 @@-{-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# OPTIONS -Wall #-}------------------------------------------------------------------------------------- |--- Module      :  Wumpus.Extra.PictureLanguage--- Copyright   :  (c) Stephen Tetley 2009-2010--- License     :  BSD3------ Maintainer  :  stephen.tetley@gmail.com--- Stability   :  unstable--- Portability :  GHC with TypeFamilies and more------ Type classes and derived functions to compose 2D /pictures/.------ The operations are fairly standard - see Regions in Paul --- Hudak\'s \'The Haskell School of Expression' and the pretty--- printing libraries wl-pprint and Text.PrettyPrint.HughesPJ --- (pretty printing combinators are some ways in \'One and a --- half D\' as they have horizontal operations but only carriage --- return in the vertical.------ WARNING - this module may change in detail if not in spirit--- quite significantly in future.------ These drawing operations are pretty fundamental and a --- compentent functional drawing program should provide them in --- some formulation. However the implementation herein needs --- some more thought.--------------------------------------------------------------------------------------module Wumpus.Extra.PictureLanguage -  (-  -- * Data types for alignment -    HAlign(..)-  , VAlign(..)--  -- * Type family and classes-  , PUnit -  , Horizontal(..)-  , Vertical(..)-  , Composite(..)-  , Move(..)-  , Blank(..)--  -- * Bounds-  -- $boundsdoc-  , center-  , topleft-  , topright-  , bottomleft-  , bottomright--  -- * Composition-  , ( -@- )-  , ( ->- )-  , ( -<- )-  , ( -//- )-  , above-  , below-  , at-  , centeredAt-  , stackOnto-  , hcat -  , vcat-  , stackOntoCenter--  , hspace-  , vspace-  , hsep-  , vsep- -  -- * Compose with alignment-  , alignH-  , alignV-  , hcatA-  , vcatA-  , hsepA-  , vsepA--  -- * Special function for text-  , multilabel---  ) where--import Wumpus.Core--import Data.AffineSpace--import Data.List ( foldl' )-------------------------------------------------------------------------------------- Data types---- Alignment---- | Horizontal alignment - align to the top, center or bottom.-data HAlign = HTop | HCenter | HBottom-  deriving (Eq,Show)---- | Vertical alignment - align to the left, center or bottom.-data VAlign = VLeft | VCenter | VRight-  deriving (Eq,Show)---------------------------------------------------------------------------------------- Type family and classes----- | The type of /points/ within a Picture.-type family PUnit a----- | > a `over` b--- --- Place \'picture\' a over b. The idea of @over@ here is the same--- as z-ordering in 2D design programs. Implementations of this --- class should \'draw\' picture a over b but move neither.--- --- Similarly @beneath@ should \'draw\' the first picture behind --- the second but move neither.------ Beneath has a default definition:------ > beneath = flip over----class Composite a where-  over    :: a -> a -> a-  beneath :: a -> a -> a--  beneath = flip over----- | Create a /picture/ that has no content but occupies space --- (i.e. it has a bounding box).-class Blank a where-  blank :: PUnit a -> PUnit a -> a----- | Move horizontally.-class Horizontal a where-  moveH      :: PUnit a -> a -> a-  leftBound  :: a -> PUnit a-  rightBound :: a -> PUnit a---- | Move vertically.-class Vertical a where-  moveV       :: PUnit a -> a -> a-  topBound    :: a -> PUnit a-  bottomBound :: a -> PUnit a---  --- | Move in both the horizontal and vertical.-class Move a where-  move :: PUnit a -> PUnit a -> a -> a----------------------------------------------------------------------------------------- Operations on bounds---- $boundsdoc--- Corresponding operations are available on bounding boxes - the --- definitions here have different type class obligations.---- | The center of a picture.-center :: (Horizontal a, Vertical a, Fractional u, u ~ PUnit a) => a -> Point2 u-center a = P2 hcenter vcenter where  -    hcenter = leftBound a   + 0.5 * (rightBound a - leftBound a)-    vcenter = bottomBound a + 0.5 * (topBound a   - bottomBound a)---- | Extract the top-left corner.-topleft       :: (Horizontal a, Vertical a, u ~ PUnit a) => a -> Point2 u-topleft a     = P2 (leftBound a)  (topBound a)---- | Extract the top-right corner.-topright      :: (Horizontal a, Vertical a, u ~ PUnit a) => a -> Point2 u-topright a    = P2 (rightBound a) (topBound a)---- | Extract the bottom-left corner.-bottomleft    :: (Horizontal a, Vertical a, u ~ PUnit a) => a -> Point2 u-bottomleft a  = P2 (leftBound a)  (bottomBound a)---- | Extract the bottom-right corner.-bottomright   :: (Horizontal a, Vertical a, u ~ PUnit a) => a -> Point2 u-bottomright a = P2 (rightBound a) (bottomBound a)------------------------------------------------------------------------------------- Internal helpers--leftmid       :: (Fractional u, Horizontal a, Vertical a, u ~ PUnit a) -              => a -> Point2 u-leftmid a     = P2 (leftBound a) (midpt (bottomBound a) (topBound a))--rightmid      :: (Fractional u, Horizontal a, Vertical a, u ~ PUnit a) -              => a -> Point2 u-rightmid a    = P2 (rightBound a) (midpt (bottomBound a) (topBound a))---topmid        :: (Fractional u, Horizontal a, Vertical a, u ~ PUnit a) -              => a -> Point2 u-topmid a      = P2 (midpt (leftBound a) (rightBound a)) (topBound a)--bottommid     :: (Fractional u, Horizontal a, Vertical a, u ~ PUnit a) -              => a -> Point2 u-bottommid a   = P2 (midpt (leftBound a) (rightBound a)) (bottomBound a)---midpt :: Fractional a => a -> a -> a-midpt a b = a + 0.5*(b-a)------------------------------------------------------------------------------------- Composition--infixr 5 -//-, `above`, `below`-infixr 6 ->-, -@------ | > a -@- b--- --- Center @a@ on top of @b@, @a@ is potentially moved and drawn --- 'over' @b@.----(-@-) :: (Horizontal a, Vertical a, Composite a, Move a, Fractional u, -             u ~ PUnit a)-         => a -> a -> a-p1 -@- p2 = (move x y p1) `over` p2 where V2 x y = center p2 .-. center p1----- | > a ->- b--- --- Horizontal composition - move @b@, placing it to the right --- of @a@.--- -(->-) :: (Horizontal a, Composite a, Num u, u ~ PUnit a) => a -> a -> a-a ->- b = a `over` (moveH disp b) where disp = rightBound a - leftBound b ---- | > a -<- b--- --- Horizontal composition - move @a@, placing it to the left --- of @b@.----(-<-) :: (Horizontal a, Composite a, Num u, u ~ PUnit a) => a -> a -> a-a -<- b = (moveH disp a) `over` b where disp = leftBound b - rightBound a----- | > a -//- b------ Vertical composition - move @b@, placing it below @a@.----(-//-) :: (Vertical a, Composite a, Num u, u ~ PUnit a) => a -> a -> a-a -//- b = a `over` (moveV disp b) where disp = bottomBound a - topBound b ----- | > a `below` b--- --- Vertical composition - move @a@, placing it below @b@----below :: (Vertical a, Composite a, Num u, u ~ PUnit a) => a -> a -> a-a `below` b = (moveV disp a) `over` b where disp = bottomBound a - topBound b------ | > a `above` b--- --- Vertical composition - move @a@, placing it above @b@.----above :: (Vertical a, Composite a, Num u, u ~ PUnit a) => a -> a -> a-a `above` b = (moveV disp a) `over` b where disp = topBound b - bottomBound a ----- | Place the picture at the supplied point.--- -at :: (Move a, u ~ PUnit a) => a -> Point2 u  -> a-p `at` (P2 x y) = move x y p---- | Center the picture at the supplied point.----centeredAt :: (Horizontal a, Vertical a, Move a, Composite a, Blank a, -               Fractional u, u ~ PUnit a) -           => a -> Point2 u -> a-centeredAt p pt = p -@- (blank 0 0 `at` pt) ------ | > xs `stackOnto` a--- --- Stack the list of pictures @xs@ 'over' @a@.------ Note, the first picture in the list is drawn at the top, the--- last picture is draw 'over' @a@.----stackOnto :: (Composite a) => [a] -> a -> a-stackOnto = flip (foldr over)---- | > x ->- xs--- --- Concatenate the list pictures @xs@ horizontally with @(->-)@ --- starting at @x@.--- -hcat :: (Horizontal a, Composite a, Num u, u ~ PUnit a)-     => a -> [a] -> a-hcat = foldl' (->-)---- | > x -//- xs--- --- Concatenate the list of pictures @xs@ vertically with @(-\/\/-)@ --- starting at @x@.----vcat :: (Vertical a, Composite a, Num u, u ~ PUnit a)-     => a -> [a] -> a-vcat = foldl' (-//-)------ | Stack pictures centered ontop of each other - the first --- picture in the list is drawn at the top, last picture is on --- drawn at the bottom.-stackOntoCenter :: (Horizontal a, Vertical a, Composite a, -                Move a, Fractional u,-                u ~ PUnit a)-            => [a] -> a -> a-stackOntoCenter = flip $ foldr (-@-)---------------------------------------------------------------------------------------- Helpers-blankH  :: (Num u, Blank a, u ~ PUnit a) => u -> a-blankH = blank `flip` 0--blankV  :: (Num u, Blank a, u ~ PUnit a) => u -> a-blankV = blank 0----- NOTE--- The following simple definition of hspace is invalid:------ > hspace n a b = a ->- (moveH n b)--- --- The movement due to @moveH n@ is annulled by the @->-@ --- operator which moves relative to the bounding box.--- --- The almost as simple definition below, seems to justify --- including Blank as a Picture constructor.-------- | > hspace n a b------ Concatenate the pictures @a@ and @b@ with @(->-)@ - injecting --- a space of @n@ units to separate the pictures.----hspace :: (Num u, Composite a, Horizontal a, Blank a, u ~ PUnit a) -       => u -> a -> a -> a-hspace n a b = a ->- blankH n ->- b---- | > vspace n a b------ Concatenate the pictures @a@ and @b@ with @(-\/\/-)@ - injecting --- a space of @n@ units to separate the pictures.----vspace :: (Num u, Composite a, Vertical a, Blank a, u ~ PUnit a) -       => u -> a -> a -> a-vspace n a b = a -//- blankV n -//-  b------ | > hsep n x xs------ Concatenate the list of pictures @xs@ horizontally with --- @hspace@ starting at @x@. The pictures are interspersed with --- spaces of @n@ units.----hsep :: (Num u, Composite a, Horizontal a, Blank a, u ~ PUnit a) -       => u -> a -> [a] -> a-hsep n = foldl' (hspace n)------ | > vsep n x xs------ Concatenate the list of pictures @xs@ vertically with --- @vspace@ starting at @x@. The pictures are interspersed with --- spaces of @n@ units.----vsep :: (Num u, Composite a, Vertical a, Blank a, u ~ PUnit a) -       => u -> a -> [a] -> a-vsep n = foldl' (vspace n)-------------------------------------------------------------------------------------- Aligning pictures----- | > alignH z a b------ Move picture @b@ up or down to be horizontally aligned along a --- line from the top, center or bottom of picture @a@--- -alignH :: ( Fractional u, Composite a, Horizontal a, Vertical a, Move a-          , u ~ PUnit a ) -       => HAlign -> a -> a -> a-alignH HTop    p1 p2 = vecMove p1 p2 (vvec $ topBound p1 - topBound p2)-alignH HBottom p1 p2 = vecMove p1 p2 (vvec $ bottomBound p1 - bottomBound p2)-alignH HCenter p1 p2 = vecMove p1 p2 (vvec v)-  where V2 _ v = rightmid p1    .-. leftmid p2----- | > alignV z a b------ Move picture @b@ left or right to be vertically aligned along a --- line from the left side, center or right side of picture @a@--- -alignV :: ( Fractional u, Composite a, Horizontal a, Vertical a, Move a-          , u ~ PUnit a ) -       => VAlign -> a -> a -> a-alignV VLeft   p1 p2 = vecMove p1 p2 (hvec $ leftBound p1 - leftBound p2) -alignV VRight  p1 p2 = vecMove p1 p2 (hvec $ rightBound p1 - rightBound p2)-alignV VCenter p1 p2 = vecMove p1 p2 (hvec h) -  where V2 h _ = bottommid p1   .-. topmid p2----- Helpers--vecMove :: (Composite a, Move a, u ~ PUnit a) => a -> a -> (Vec2 u) -> a -vecMove a b (V2 x y) = a `over` (move x y) b ---- Unlike alignH this function \"moves and concatenates\".-moveAlignH :: ( Fractional u, Composite a, Horizontal a, Vertical a, Move a-          , u ~ PUnit a ) -       => HAlign -> a -> a -> a-moveAlignH HTop    p1 p2 = vecMove p1 p2 (topright p1    .-. topleft p2)-moveAlignH HCenter p1 p2 = vecMove p1 p2 (rightmid p1    .-. leftmid p2)-moveAlignH HBottom p1 p2 = vecMove p1 p2 (bottomright p1 .-. bottomleft p2)----- Unlike alignV this function \"moves and concatenates\".-moveAlignV :: ( Fractional u, Composite a, Horizontal a, Vertical a, Move a-          , u ~ PUnit a ) -       => VAlign -> a -> a -> a-moveAlignV VLeft   p1 p2 = vecMove p1 p2 (bottomleft p1  .-. topleft p2)-moveAlignV VCenter p1 p2 = vecMove p1 p2 (bottommid p1   .-. topmid p2)-moveAlignV VRight  p1 p2 = vecMove p1 p2 (bottomright p1 .-. topright p2)----- | Variant of 'hcat' that aligns the pictures as well as--- concatenating them.-hcatA :: ( Fractional u, Horizontal a, Vertical a-         , Composite a, Move a, u ~ PUnit a)-     => HAlign -> a -> [a] -> a-hcatA ha = foldl' (moveAlignH ha)---- | Variant of 'vcat' that aligns the pictures as well as--- concatenating them.-vcatA :: ( Fractional u, Horizontal a, Vertical a-         , Composite a, Move a, u ~ PUnit a)-     => VAlign -> a -> [a] -> a-vcatA va = foldl' (moveAlignV va)----- | Variant of @hsep@ that aligns the pictures as well as--- concatenating and spacing them.-hsepA :: ( Fractional u, Horizontal a, Vertical a-         , Composite a, Move a, Blank a, u ~ PUnit a)-     => HAlign -> u -> a -> [a] -> a-hsepA ha n = foldl' op where -   a `op` b = moveAlignH ha (moveAlignH ha a (blankH n)) b ---- | Variant of @vsep@ that aligns the pictures as well as--- concatenating and spacing them.-vsepA :: ( Fractional u, Horizontal a, Vertical a-         , Composite a, Move a, Blank a, u ~ PUnit a)-     => VAlign -> u -> a -> [a] -> a-vsepA va n = foldl' op where -   a `op` b = moveAlignV va (moveAlignV va a (blankV n)) b -------------------------------------------------------------------------------------- TO DETERMINE--- What should leftBound and rightBound be for an empty picture?--type instance PUnit (Picture u) = u--instance (Num u, Ord u) => Horizontal (Picture u) where-  moveH a p  = p `picMoveBy` (hvec a) -  leftBound  = leftPlane . boundary-  rightBound = rightPlane . boundary--instance (Num u, Ord u) => Vertical (Picture u) where-  moveV a p   = p `picMoveBy` (vvec a) -  topBound    = upperPlane . boundary-  bottomBound = lowerPlane . boundary---- Note - picture is a binary tree and drawing is depth-first,--- left-to-right so pictures in the right of the tree potentially--- are drawn on top of pictures on the left.------ So to print picture a _over_ picture b we form this node:------ >  locale --- >    /\--- >   /  \--- >  b    a------ Hence `over` flips b and a---instance (Num u, Ord u) => Composite (Picture u) where-  over = picOver       --instance (Num u, Ord u) => Move (Picture u) where-  move x y p = p `picMoveBy` (V2 x y)---instance (Num u, Ord u) => Blank (Picture u) where-  blank w h = blankPicture (bbox zeroPt (P2 w h))--------------------------------------------------------------------------------------- ----- | Create multiple lines of text.------ The dimension argument is the linespacing, measured as the--- distance between the upper lines descender and the lower --- lines ascender.------ An error is throw if the list of strings is empty--- -multilabel :: (Real u, Floating u, TextLabel t) -           => t -> u -> VAlign -> [String] -> Point2 u -> Picture u-multilabel _    _ _  []     _  = error $ -    "Wumpus.Core.PictureLanguage.multilabel - empty list."--multilabel attr n va (x:xs) pt = -    moveAll $ vsepA va n line1 (map mkPic xs)-  where-    line1     = mkPic x-    mkPic s   = frame $ textlabel attr s zeroPt-    vdelta p  = boundaryHeight (boundary p) - boundaryHeight (boundary line1)-    moveAll p = moveV (vdelta p) $ p `at` pt
wumpus-core.cabal view
@@ -1,5 +1,5 @@ name:             wumpus-core-version:          0.21.0+version:          0.22.0 license:          BSD3 license-file:     LICENSE copyright:        Stephen Tetley <stephen.tetley@gmail.com>@@ -21,8 +21,8 @@   Pictures in Wumpus are made from /paths/ and text /labels/.    Paths themselves are made from points. The usual affine    transformations (rotations, scaling, translations) can be-  applied to geometric objects. Unlike PostScript there -  is no notion of a current point, Wumpus builds pictures in a+  applied to geometric objects. Unlike PostScript there is no +  notion of a current point, Wumpus builds pictures in a   coordinate-free style.    .   GENERAL DRAWBACKS...@@ -61,13 +61,34 @@   .   Changelog:   .+  0.21.0 to 0.22.0:+  .+  * Moved the deprecated module @Wumpus.Extra.PictureLanguage@+    into the package Wumpus-Basic along with the example +    @Picture.hs@.+  .+  * Added vec as a synonym for the constructor V2.+  .+  * Changed some of the Core.FontSize to use better terminology. +    Thus some of the constants have changed. Added a new example+    @FontMetrics.hs@ to illustrate how FontSize works. +    Particularly, the function @capHeight@ has been replaced with+    the function @numeralHeight@ which has better semantics.+  .+  * The CTM data type and ToCTM class are now hidden in the+    top-level import module @Wumpus.Core@. They can be accessed+    by importing @Wumpus.Core.GraphicsState@ directly.+  .+  * Exposed the PSUnit type class. +  .   0.20.0 to 0.21.0:   .-  * Removed the instances of the Affine transformation. They have-    been replaced with special transformation functions: -    @rotatePrimitive@, @scalePrimitive@, @translatePrimitive@.-    As Primitives are not in an affine frame until they are lifted -    to Pictures the affine instances had ill-conceived semantics.+  * Removed the Primitive instances of the Affine transformation +    classes. They have been replaced with special transformation +    functions: @rotatePrimitive@, @scalePrimitive@, +    @translatePrimitive@. As Primitives are not in an affine +    frame until they are lifted to Pictures the affine instances +    had ill-conceived semantics.   .   * Due to changes to accommodate the new non-affine       transformations, many of the class obligations have changed @@ -100,9 +121,9 @@   demo/AffineTest02.hs,   demo/AffineTest03.hs,   demo/AffineTestBase.hs,+  demo/FontMetrics.hs   demo/LabelPic.hs,   demo/MultiPic.hs-  demo/Picture.hs,   demo/Rotated.hs   demo/Scaled.hs   demo/Translated.hs@@ -134,8 +155,7 @@     Wumpus.Core.TextEncoder,     Wumpus.Core.TextLatin1,     Wumpus.Core.VersionNumber,-    Wumpus.Core.WumpusTypes,-    Wumpus.Extra.PictureLanguage+    Wumpus.Core.WumpusTypes    other-modules:     Wumpus.Core.PictureInternal,