wumpus-core 0.32.0 → 0.33.0
raw patch · 23 files changed
+933/−502 lines, 23 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Wumpus.Core.TextLatin1: latin1All :: [(Latin1Name, Latin1ISOCode)]
- Wumpus.Core.TextLatin1: latin1Encoder :: TextEncoder
- Wumpus.Core.TextLatin1: type Latin1ISOCode = Int
- Wumpus.Core.TextLatin1: type Latin1Name = String
+ Wumpus.Core.FontSize: spacerWidth :: FontSize -> PtSize
+ Wumpus.Core.GraphicsState: font_enc_name :: FontFace -> FontEncoderName
+ Wumpus.Core.TextDefaultEncoder: defaultEncoder :: TextEncoder
+ Wumpus.Core.TextEncoder: FontEncoder :: PostScriptLookup -> SVGLookup -> GlyphName -> CharCode -> FontEncoder
+ Wumpus.Core.TextEncoder: FontEncoderName :: Word16 -> FontEncoderName
+ Wumpus.Core.TextEncoder: data FontEncoder
+ Wumpus.Core.TextEncoder: font_encoder_map :: TextEncoder -> Map FontEncoderName FontEncoder
+ Wumpus.Core.TextEncoder: getFontEncoderName :: FontEncoderName -> Word16
+ Wumpus.Core.TextEncoder: instance Eq FontEncoderName
+ Wumpus.Core.TextEncoder: instance Ord FontEncoderName
+ Wumpus.Core.TextEncoder: instance Show FontEncoderName
+ Wumpus.Core.TextEncoder: newtype FontEncoderName
+ Wumpus.Core.TextLatin1: latin1FontAll :: [(GlyphName, CharCode)]
+ Wumpus.Core.TextLatin1: latin1FontEncoder :: FontEncoder
+ Wumpus.Core.TextLatin1: latin1_font_encoder :: FontEncoderName
+ Wumpus.Core.TextSymbolFont: symbolFontAll :: [(GlyphName, CharCode)]
+ Wumpus.Core.TextSymbolFont: symbolFontEncoder :: FontEncoder
+ Wumpus.Core.TextSymbolFont: symbol_font_encoder :: FontEncoderName
- Wumpus.Core.GraphicsState: FontFace :: String -> String -> SVGFontStyle -> FontFace
+ Wumpus.Core.GraphicsState: FontFace :: String -> String -> SVGFontStyle -> FontEncoderName -> FontFace
- Wumpus.Core.TextEncoder: TextEncoder :: PostScriptLookup -> SVGLookup -> String -> GlyphName -> CharCode -> TextEncoder
+ Wumpus.Core.TextEncoder: TextEncoder :: String -> Map FontEncoderName FontEncoder -> TextEncoder
- Wumpus.Core.TextEncoder: ps_fallback :: TextEncoder -> GlyphName
+ Wumpus.Core.TextEncoder: ps_fallback :: FontEncoder -> GlyphName
- Wumpus.Core.TextEncoder: ps_lookup :: TextEncoder -> PostScriptLookup
+ Wumpus.Core.TextEncoder: ps_lookup :: FontEncoder -> PostScriptLookup
- Wumpus.Core.TextEncoder: svg_fallback :: TextEncoder -> CharCode
+ Wumpus.Core.TextEncoder: svg_fallback :: FontEncoder -> CharCode
- Wumpus.Core.TextEncoder: svg_lookup :: TextEncoder -> SVGLookup
+ Wumpus.Core.TextEncoder: svg_lookup :: FontEncoder -> SVGLookup
Files
- CHANGES +53/−0
- demo/DeltaPic.hs +1/−1
- demo/FontMetrics.hs +2/−1
- demo/KernPic.hs +25/−4
- demo/LabelPic.hs +4/−2
- demo/Latin1Pic.hs +2/−1
- demo/ZOrderPic.hs +13/−2
- doc-src/Guide.lhs +34/−26
- doc-src/WorldFrame.hs +2/−1
- doc/Guide.pdf binary
- src/Wumpus/Core.hs +11/−1
- src/Wumpus/Core/FontSize.hs +10/−0
- src/Wumpus/Core/GraphicsState.hs +6/−3
- src/Wumpus/Core/OutputPostScript.hs +76/−70
- src/Wumpus/Core/OutputSVG.hs +45/−38
- src/Wumpus/Core/Picture.hs +11/−4
- src/Wumpus/Core/TextDefaultEncoder.hs +44/−0
- src/Wumpus/Core/TextEncoder.hs +65/−13
- src/Wumpus/Core/TextInternal.hs +22/−5
- src/Wumpus/Core/TextLatin1.hs +226/−222
- src/Wumpus/Core/TextSymbolFont.hs +249/−0
- src/Wumpus/Core/VersionNumber.hs +2/−2
- wumpus-core.cabal +30/−106
CHANGES view
@@ -1,4 +1,57 @@ +0.32.0 to 0.33.0:++ * Major change - reworked support for text encoding. Encoding + maps are now linked with fonts - it was spotted that the + Symbol font does not use the Latin1 names. The @TextEncoder@ + data type has been changed and there is a new @FontEncoder@ + data type. There are also new modules for the Symbol Font + encoder table and for the /Default Encoder/ which + accommodates both Latin1 and the Symbol font. This has also + mandated changes to the @FontFace@ data type.+ + * Major change - the printing order has been changed. The first + element in a @frame@ of Prims is draw first. This means it + appears first in the output file (this makes sense) - it also + means it is at the back in the Z-Order. This latter point + might not be so intuitive, but changing the printing order at + least makes Wumpus-Core match SVG and PostScript.++ * Changed the visiblity of the new colours (yellow, cyan, + magenta) to be hidden at the top level. They can be exposed+ by importing @Wumpus.Core.Colour@. ++ * @Wumpus.Core.FontSize@ - added @spacerWidth@ function.++0.31.0 to 0.32.0:++ * Major API changes to @Core.Picture@ for XML hyperlinks.+ Hyperlinks now group one-or-more Primitives (path or label), + instead of being attached to a single Primitive. This better+ corresponds with XML but it has made the Picture type more + complicated, and has mandated significant changes to the + Picture API. All the hyperlink variants of the Primitive + constructors have been removed (xcstroke, xfill, xtextlabel, + ...), and hyperlinks are now created with @xlinkGroup@. ++ * The type signatures for the /primitive/ constructors (fill, + cstroke, textlabel, ...) in the Picture API have changed and + are now more complicated as there is an extra layer of + indirection in the type hierarchy.++ * The primitive constructors for filled and stroked paths and + ellipses have been renamed: @bordered@ is now @fillStroke@,+ @borderedEllipse@ is now @fillStrokeEllipse@.++ * @Core.FontSize@ - the arguments to the function @textBounds@+ have been changed to take the String in question, rather than + its precomputed length. The size of the string is then + calculated with the new function @charCount@ which takes into + account escaped characters.++ * Added @yellow@, @cyan@ and @magenta@ to the predefined + colours in @Core.Colour@.+ 0.30.0 to 0.31.0: * Extended the label type to optionally handle horizontal
demo/DeltaPic.hs view
@@ -35,7 +35,7 @@ common_ff :: FontFace-common_ff = FontFace "Helvetica" "Helvetica" SVG_REGULAR+common_ff = FontFace "Helvetica" "Helvetica" SVG_REGULAR latin1_font_encoder -- Note - each label is fully attributed with the font style.
demo/FontMetrics.hs view
@@ -27,7 +27,8 @@ black = RGBi 0 0 0 courier_attr :: FontAttr-courier_attr = FontAttr 48 (FontFace "Courier" "Courier New" SVG_REGULAR)+courier_attr = FontAttr 48 (FontFace "Courier" "Courier New" + SVG_REGULAR latin1_font_encoder) metrics_pic :: DPicture metrics_pic = char_pic `picOver` lines_pic
demo/KernPic.hs view
@@ -17,17 +17,19 @@ kern_pic :: DPicture-kern_pic = pic1 `picOver` pic2+kern_pic = pic1 `picOver` pic2 `picOver` pic3 pic1 :: DPicture-pic1 = frame [ helveticaLabelH mystere (P2 0 40)- , helveticaLabelH mystere (P2 0 20)+pic1 = frame [ helveticaLabelH mystere (P2 0 50)+ , helveticaLabelH mystere (P2 0 25) ] pic2 :: DPicture pic2 = illustrateBoundsPrim blue_violet $ helveticaLabelV mystere (P2 100 140) +pic3 :: DPicture+pic3 = frame [ symbolLabelH uUpsilon (P2 0 0) ] mystere ::[DKerningChar] mystere = [ kernchar 0 'm'@@ -39,15 +41,34 @@ , kernchar 6 'e' ] +-- Note - to assert that this is working check both the +-- PostScript and the SVG.+--+uUpsilon :: [ DKerningChar ]+uUpsilon = [ kernEscInt 6 0o241, kernchar 12 'a', kernchar 12 'b' ] + helveticaLabelH :: [KerningChar Double] -> DPoint2 -> DPrimElement helveticaLabelH xs pt = hkernlabel black helvetica18 xs pt helveticaLabelV :: [KerningChar Double] -> DPoint2 -> DPrimElement helveticaLabelV xs pt = vkernlabel black helvetica18 xs pt +symbolLabelH :: [KerningChar Double] -> DPoint2 -> DPrimElement+symbolLabelH xs pt = hkernlabel black symbol18 xs pt + helvetica18 :: FontAttr-helvetica18 = FontAttr 18 (FontFace "Helvetica" "Helvetica" SVG_REGULAR)+helvetica18 = FontAttr 18 (FontFace "Helvetica" + "Helvetica" + SVG_REGULAR + latin1_font_encoder)+++symbol18 :: FontAttr+symbol18 = FontAttr 18 (FontFace "Symbol" + "Symbol" + SVG_REGULAR+ symbol_font_encoder) blue_violet :: RGBi blue_violet = RGBi 0x8a 0x2b 0xe2
demo/LabelPic.hs view
@@ -43,7 +43,8 @@ lbl1 = line1 `picBeside` line2 where line1 = frame [textlabel peru attrs "Hello" zeroPt] line2 = frame [textlabel peru attrs "World" zeroPt]- attrs = FontAttr 12 (FontFace "Helvetica" "Helvetica" SVG_REGULAR)+ attrs = FontAttr 12 (FontFace "Helvetica" "Helvetica" + SVG_REGULAR latin1_font_encoder) demo01 :: IO ()@@ -92,7 +93,8 @@ bigLetter :: RGBi -> Char -> Picture Double bigLetter rgb ch = uniformScale 5 $ frame [textlabel rgb attrs [ch] zeroPt] where- attrs = FontAttr 12 (FontFace "Helvetica" "Helvetica" SVG_REGULAR)+ attrs = FontAttr 12 (FontFace "Helvetica" "Helvetica" + SVG_REGULAR latin1_font_encoder) -- | A should be above B, above T
demo/Latin1Pic.hs view
@@ -31,4 +31,5 @@ helveticaLabel ss pt = textlabel black helvetica18 ss pt helvetica18 :: FontAttr-helvetica18 = FontAttr 18 (FontFace "Helvetica" "Helvetica" SVG_REGULAR)+helvetica18 = FontAttr 18 (FontFace "Helvetica" "Helvetica" + SVG_REGULAR latin1_font_encoder)
demo/ZOrderPic.hs view
@@ -12,9 +12,22 @@ main :: IO () main = do createDirectoryIfMissing True "./out/"+ putStrLn zorder_msg writeEPS_latin1 "./out/zorder01.eps" combined_pic writeSVG_latin1 "./out/zorder01.svg" combined_pic +zorder_msg :: String+zorder_msg = unlines $ + [ ""+ , "Wumpus-core draws lists of 'PrimElement' left-to-right."+ , "The head of the list will be drawn first - it will appear"+ , "at the top of the output file. It will also be drawn at"+ , "the back of the Z-Order."+ , ""+ , "In the generated file, you should see:"+ , " red `under` green, green `under` blue"+ , ""+ ] combined_pic :: DPicture combined_pic = multi [pic1,pic2]@@ -24,8 +37,6 @@ pic2 :: DPicture pic2 = multi $ map (\a -> frame [a]) $ prim_list (P2 200 0)-- prim_list :: DPoint2 -> [DPrimElement] prim_list = sequence [ fillEllipse red 20 20
doc-src/Guide.lhs view
@@ -31,7 +31,7 @@ \wumpuscore is rather primitive, the basic drawing objects are paths and text labels. A second library \texttt{wumpus-basic} contains code for higher level drawing but it is still missing -main functionalities e.g. shapes, arrowheads. +main functionalities e.g. connectors, arrowheads. Although \wumpuscore is heavily inspired by PostScript it avoids PostScript's notion of an (implicit) current point and the @@ -47,10 +47,12 @@ \begin{description} \item[\texttt{Wumpus.Core.}] -Top-level import module, re-exports the exposed modules. Exports -as opaque some of the internal data types, where the export is -necessary for writing type signatures to user functions but access -to the objects themselves is hidden by \emph{smart} constructors. +Top-level \emph{shim} module to import all the exposed modules. +Some internal data types are also exported as opaque - the +implementation is hidden, but the type name is exposed so it can +be used in the type signatures of \emph{userland} functions. +Typically, where these data types need to be \emph{instantiated}, +smart constructors are provided. \item[\texttt{Wumpus.Core.AffineTrans.}] The standard affine transformations (scaling, rotation, @@ -60,15 +62,16 @@ \item[\texttt{Wumpus.Core.BoundingBox.}] Data type representing bounding boxes and operations on them. -This module is potentially important for defining higher-level -graphics objects (arrowheads and the like). +Bounding boxes are important for Pictures and they support the +definition of \emph{Picture composition operators}. \item[\texttt{Wumpus.Core.Colour.}] -Colour types (RGB, grayscale and HSB) and conversion between -them. Some named colours, which should be hidden or import -qualified if a more extensive package of colours (e.g. the named -SVG colours) is used. RGB is the default format, where black is -\texttt{(0.0, 0.0, 0.0)}, and white is \texttt{(1.0, 1.0, 1.0)}. +A single colour type \texttt{RGBi} is supported. This type defines +colour as a triple of integers (Word8) - black is 0, 0, 0; white +is 255, 255, 255. Some named colours are defined, although they +are hidden by the top level shim module to avoid name clashes. +\texttt{Wumpus.Core.Colour} can be imported directly if the named +colours are required. \item[\texttt{Wumpus.Core.FontSize.}] Various calculations for font size metrics. Generally not useful @@ -97,8 +100,8 @@ Operations to build \emph{pictures} - paths and labels within an affine frame. Generally the functions here are convenience constructors for types from the hidden module -\texttt{Wumpus.Core.PictureInternal}. The types from this -module are exported as opaque signatures by +\texttt{Wumpus.Core.PictureInternal}. The types from +\texttt{PictureInternal} are exported as opaque signatures by \texttt{Wumpus.Core.WumpusTypes}. \item[\texttt{Wumpus.Core.PtSize.}] @@ -112,8 +115,13 @@ \item[\texttt{Wumpus.Core.TextLatin1.}] A instance of the TextEncoder type for mapping Latin 1 characters -to the PostScript and SVG escape characters. +to the PostScript and SVG escape characters. Typically this +encoder is associated with the fonts - Helvetica, Courier and +Times-Roman. +\item[\texttt{Wumpus.Core.TextSymbol.}] +A instance of the TextEncoder type for the Symbol font. + \item[\texttt{Wumpus.Core.VersionNumber.}] Current version number of \wumpuscore. @@ -138,14 +146,15 @@ multiple labels. Primitives are attributed with drawing styles - font name and -size for labels; line width, colour, etc. for paths - and -place within a picture. The function \texttt{frame} lifts a -primitive to a picture within the standard affine frame (the -standard frame has origin at (0,0) and unit bases for the X and -Y axes). The function \texttt{frameMulti} places one or more -primitives in a frame - this will produce more efficient -PostScript and should be preferred for creating scatter-plots -and the like. +size for labels; line width, colour, etc. for paths. Drawing +Primitives is unfortunately complicated due to the need to +support hyperlinks in SVG output. Primitives have to be lifted +to a \texttt{PrimElement} before they can be placed within a +\texttt{Picture} - using the shorthand constructors in +\texttt{Wumpus.Core.Picture} does this lifting automatically. +The function \texttt{frame} assembles a list of primitives +into a \texttt{Picture} with a standard affine frame where the +origin is at (0,0) and the X and Y axes have the unit bases. \begin{figure} \centering @@ -153,7 +162,7 @@ \caption{The world frame, with origin at the bottom left.} \end{figure} -\wumpuscore uses the same picture frame as PostScript with +\wumpuscore uses the same picture frame as PostScript where the origin at the bottom left, see Figure 1. This contrasts to SVG where the origin at the top-left. When \wumpuscore generates SVG, the whole picture is produced within a matrix transformation @@ -271,8 +280,7 @@ The following table lists PostScript fonts and their SVG -equivalents. As of revision 0.20.0, the package -\texttt{wumpus-basic} includes a module +equivalents, the package \texttt{wumpus-basic} includes a module \texttt{Wumpus.Basic.SafeFonts} encoding the fonts in this list to avoid typographical slips.
doc-src/WorldFrame.hs view
@@ -29,7 +29,8 @@ makeLabelPrim :: String -> DPoint2 -> DPrimElement makeLabelPrim = textlabel black attrs where- attrs = FontAttr 10 (FontFace "Helvetica" "Helvetica" SVG_REGULAR)+ attrs = FontAttr 10 (FontFace "Helvetica" "Helvetica" + SVG_REGULAR latin1_font_encoder) makeLinePrim :: Double -> DPoint2 -> DPoint2 -> DPrimElement makeLinePrim lw a b = ostroke black attrs $ path a [lineTo b]
doc/Guide.pdf view
binary file changed (56526 → 57051 bytes)
src/Wumpus/Core.hs view
@@ -38,6 +38,10 @@ -- -- * "Wumpus.Core.TextEncoder" --+-- * "Wumpus.Core.TextLatin1"+--+-- * "Wumpus.Core.TextSymbolFont"+-- -- * "Wumpus.Core.VersionNumber" -- -- * "Wumpus.Core.WumpusTypes"@@ -65,14 +69,18 @@ , module Wumpus.Core.Picture , module Wumpus.Core.PtSize , module Wumpus.Core.TextEncoder+ , module Wumpus.Core.TextLatin1+ , module Wumpus.Core.TextSymbolFont , module Wumpus.Core.VersionNumber , module Wumpus.Core.WumpusTypes + ) where import Wumpus.Core.AffineTrans import Wumpus.Core.BoundingBox-import Wumpus.Core.Colour hiding ( black, white, red, green, blue )+import Wumpus.Core.Colour hiding ( black, white, red, green, blue, yellow, + cyan, magenta ) import Wumpus.Core.FontSize hiding ( textBoundsEnc ) import Wumpus.Core.Geometry import Wumpus.Core.GraphicsState hiding ( GraphicsState )@@ -81,6 +89,8 @@ import Wumpus.Core.Picture import Wumpus.Core.PtSize import Wumpus.Core.TextEncoder+import Wumpus.Core.TextLatin1+import Wumpus.Core.TextSymbolFont import Wumpus.Core.VersionNumber import Wumpus.Core.WumpusTypes
src/Wumpus/Core/FontSize.hs view
@@ -45,6 +45,7 @@ -- * Metrics calculation , widthAt48pt , charWidth+ , spacerWidth , textWidth , textHeight , numeralHeight@@ -165,6 +166,15 @@ -- charWidth :: FontSize -> PtSize charWidth sz = (fromIntegral sz)/48 * courier48_width+++-- | Approximate the width of a spacer between monospace +-- characters using metrics derived from the Courier font.+--+spacerWidth :: FontSize -> PtSize+spacerWidth sz = (fromIntegral sz)/48 * courier48_spacer_width++ -- | Text width at @sz@ point size of the string @s@. All -- characters are counted literally - special chars may cause
src/Wumpus/Core/GraphicsState.hs view
@@ -63,6 +63,8 @@ ) where import Wumpus.Core.Colour+import Wumpus.Core.TextEncoder+import Wumpus.Core.TextLatin1 -- Graphics state datatypes @@ -124,8 +126,8 @@ -- See the PostScript Language Reference Manual. -- data FontAttr = FontAttr - { font_size :: Int - , font_face :: FontFace+ { font_size :: Int + , font_face :: FontFace } deriving (Eq,Ord,Show) @@ -135,6 +137,7 @@ { font_name :: String -- for PostScript , svg_font_family :: String -- for SVG , svg_font_style :: SVGFontStyle+ , font_enc_name :: FontEncoderName } deriving (Eq,Ord,Show) @@ -157,7 +160,7 @@ , gs_stroke_attr = default_stroke_attr } where- unmatchable_face = FontFace "DONT_MATCH" "" SVG_BOLD_OBLIQUE+ unmatchable_face = FontFace "DONT_MATCH" "" SVG_BOLD_OBLIQUE latin1_font_encoder -- | Default stroke attributes.
src/Wumpus/Core/OutputPostScript.hs view
@@ -35,9 +35,9 @@ import Wumpus.Core.OneList import Wumpus.Core.PictureInternal import Wumpus.Core.PostScriptDoc+import Wumpus.Core.TextDefaultEncoder import Wumpus.Core.TextEncoder import Wumpus.Core.TextInternal-import Wumpus.Core.TextLatin1 import Wumpus.Core.Utils import Control.Applicative hiding ( empty, some )@@ -58,6 +58,8 @@ -- are no /savings/ by diffing from an outer environment, instead -- the diff is with the last drawn object. --++ newtype PsMonad a = PsMonad { getPsMonad :: TextEncoder -> GraphicsState -> (a,GraphicsState) } @@ -80,79 +82,74 @@ runPsMonad :: TextEncoder -> PsMonad a -> a runPsMonad enc mf = fst $ getPsMonad mf enc zeroGS -askCharCode :: Int -> PsMonad (Either GlyphName GlyphName)-askCharCode i = PsMonad $ \r s -> case lookupByCharCode i r of- Just n -> (Right n,s)- Nothing -> (Left $ ps_fallback r,s)+askCharCode :: FontEncoderName -> Int -> PsMonad (Either GlyphName GlyphName)+askCharCode fen i = PsMonad $ \r s -> + case lookupByCharCode fen i r of+ Just n -> (Right n, s)+ Nothing -> (Left $ getPsFallback fen r, s) -- runLocalGS :: GSUpdate -> PsMonad a -> PsMonad a -- runLocalGS upd mf = -- PsMonad $ \r s -> let (a,_) = getPsMonad mf r (getGSU upd s) in (a,s) +getsGS :: (GraphicsState -> a) -> PsMonad a+getsGS fn = PsMonad $ \_ s -> (fn s,s)++setsGS :: (GraphicsState -> GraphicsState) -> PsMonad ()+setsGS fn = PsMonad $ \_ s -> ((),fn s)+++setsSA :: (StrokeAttr -> StrokeAttr) -> PsMonad ()+setsSA fn = getsGS gs_stroke_attr >>= \sa -> + setsGS (\s -> s { gs_stroke_attr = fn sa })+ getDrawColour :: PsMonad RGBi-getDrawColour = PsMonad $ \_ s -> (gs_draw_colour s, s)+getDrawColour = getsGS gs_draw_colour setDrawColour :: RGBi -> PsMonad ()-setDrawColour a = PsMonad $ \_ s -> ((), s {gs_draw_colour=a})+setDrawColour a = setsGS (\s -> s { gs_draw_colour=a}) getFontAttr :: PsMonad FontAttr-getFontAttr = PsMonad $ \_ s -> let sz = gs_font_size s - ff = gs_font_face s- in (FontAttr sz ff, s)+getFontAttr = getsGS (\s -> FontAttr (gs_font_size s) (gs_font_face s)) setFontAttr :: FontAttr -> PsMonad () setFontAttr (FontAttr sz ff) = - PsMonad $ \_ s -> ((), s { gs_font_size=sz,gs_font_face=ff })+ setsGS (\s -> s { gs_font_size=sz, gs_font_face=ff }) getLineWidth :: PsMonad Double-getLineWidth = PsMonad $ \_ s -> (line_width $ gs_stroke_attr s, s)+getLineWidth = getsGS (line_width . gs_stroke_attr) setLineWidth :: Double -> PsMonad ()-setLineWidth a = PsMonad $ \_ s -> - ((), s { gs_stroke_attr = fn $ gs_stroke_attr s })- where- fn sa = sa { line_width = a }+setLineWidth a = setsSA (\s -> s { line_width = a } ) getMiterLimit :: PsMonad Double-getMiterLimit = PsMonad $ \_ s -> (miter_limit $ gs_stroke_attr s,s)+getMiterLimit = getsGS (miter_limit . gs_stroke_attr) setMiterLimit :: Double -> PsMonad ()-setMiterLimit a = PsMonad $ \_ s -> - ((), s { gs_stroke_attr = fn $ gs_stroke_attr s })- where- fn sa = sa { miter_limit = a }+setMiterLimit a = setsSA (\s -> s { miter_limit = a } ) getLineCap :: PsMonad LineCap-getLineCap = PsMonad $ \_ s -> (line_cap $ gs_stroke_attr s,s)+getLineCap = getsGS (line_cap . gs_stroke_attr) setLineCap :: LineCap -> PsMonad ()-setLineCap a = PsMonad $ \_ s ->- ((), s { gs_stroke_attr = fn $ gs_stroke_attr s })- where- fn sa = sa { line_cap = a }+setLineCap a = setsSA (\s -> s { line_cap = a }) getLineJoin :: PsMonad LineJoin-getLineJoin = PsMonad $ \_ s -> (line_join $ gs_stroke_attr s,s)+getLineJoin = getsGS (line_join . gs_stroke_attr) setLineJoin :: LineJoin -> PsMonad ()-setLineJoin a = PsMonad $ \_ s ->- ((), s { gs_stroke_attr = fn $ gs_stroke_attr s })- where- fn sa = sa { line_join = a }+setLineJoin a = setsSA (\s -> s { line_join = a }) getDashPattern :: PsMonad DashPattern-getDashPattern = PsMonad $ \_ s -> (dash_pattern $ gs_stroke_attr s,s)+getDashPattern = getsGS (dash_pattern . gs_stroke_attr) setDashPattern :: DashPattern -> PsMonad ()-setDashPattern a = PsMonad $ \_ s -> - ((), s { gs_stroke_attr = fn $ gs_stroke_attr s })- where- fn sa = sa { dash_pattern = a }+setDashPattern a = setsSA (\s -> s { dash_pattern = a }) --------------------------------------------------------------------------------@@ -180,13 +177,13 @@ -- writePS_latin1 :: (Real u, Floating u, PSUnit u) => FilePath -> [Picture u] -> IO ()-writePS_latin1 filepath = writePS filepath latin1Encoder+writePS_latin1 filepath = writePS filepath defaultEncoder -- | Version of 'writeEPS' - using Latin1 encoding. -- writeEPS_latin1 :: (Real u, Floating u, PSUnit u) => FilePath -> Picture u -> IO ()-writeEPS_latin1 filepath = writeEPS filepath latin1Encoder+writeEPS_latin1 filepath = writeEPS filepath defaultEncoder -------------------------------------------------------------------------------- -- Internals@@ -255,26 +252,28 @@ -- constructor. -- picture :: (Real u, Floating u, PSUnit u) => Picture u -> PsMonad Doc-picture (Leaf (_,xs) ones) = bracketTrafos xs $ revConcat primElement ones-picture (Picture (_,xs) ones) = bracketTrafos xs $ revConcat picture ones+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) -revConcat :: (a -> PsMonad Doc) -> OneList a -> PsMonad Doc-revConcat fn ones = some empty <$> F.foldrM step None ones+oneConcat :: (a -> PsMonad Doc) -> OneList a -> PsMonad Doc+oneConcat fn ones = outstep (viewl ones) where- step e ac = (\d -> d `conc` ac) <$> fn e- conc d None = Some d- conc d (Some ac) = Some $ ac `vconcat` d+ outstep (e :< rest) = fn e >>= \a -> instep a (viewl rest)+ outstep (OneL e) = fn e+ + instep ac (OneL e) = fn e >>= \a -> return (ac `vconcat` a)+ instep ac (e :< rest) = fn e >>= \a -> instep (ac `vconcat` a) (viewl rest) -- No action is taken for hyperlinks in PostScript. -- primElement :: (Real u, Floating u, PSUnit u) => PrimElement u -> PsMonad Doc primElement (Atom prim) = primitive prim-primElement (XLinkGroup _ ones) = revConcat primElement ones+primElement (XLinkGroup _ ones) = oneConcat primElement ones primitive :: (Real u, Floating u, PSUnit u) => Primitive u -> PsMonad Doc primitive (PPath props pp) = primPath props pp@@ -367,52 +366,59 @@ -- primLabel :: (Real u, Floating u, PSUnit u) => LabelProps -> PrimLabel u -> PsMonad Doc-primLabel (LabelProps rgb font) (PrimLabel basept body ctm) = +primLabel (LabelProps rgb attrs) (PrimLabel basept body ctm) = bracketPrimCTM basept ctm mf where mf pt = (\rgbd fontd showd -> vcat [ rgbd, fontd, showd ]) - <$> deltaDrawColour rgb <*> deltaFontAttrs font - <*> labelBody pt body+ <$> deltaDrawColour rgb <*> deltaFontAttrs attrs+ <*> labelBody fen pt body+ + fen = font_enc_name $ font_face attrs -labelBody :: PSUnit u => Point2 u -> LabelBody u -> PsMonad Doc-labelBody pt (StdLayout txt) = (\d1 -> ps_moveto pt `vconcat` d1) - <$> encodedText txt-labelBody pt (KernTextH xs) = kernTextH pt xs-labelBody pt (KernTextV xs) = kernTextV pt xs -encodedText :: EncodedText -> PsMonad Doc -encodedText etext = vcat <$> (mapM textChunk $ getEncodedText etext)+labelBody :: PSUnit u + => FontEncoderName -> Point2 u -> LabelBody u -> PsMonad Doc+labelBody nm pt (StdLayout txt) = (\d1 -> ps_moveto pt `vconcat` d1) + <$> encodedText nm txt+labelBody nm pt (KernTextH xs) = kernTextH nm pt xs+labelBody nm pt (KernTextV xs) = kernTextV nm pt xs -textChunk :: TextChunk -> PsMonad Doc-textChunk (TextSpan s) = pure (ps_show $ escapeSpecial s)-textChunk (TextEscName s) = pure (ps_glyphshow s)-textChunk (TextEscInt i) = (either failk ps_glyphshow) <$> askCharCode i +encodedText :: FontEncoderName -> EncodedText -> PsMonad Doc +encodedText nm etext = vcat <$> (mapM (textChunk nm) $ getEncodedText etext)+++textChunk :: FontEncoderName -> TextChunk -> PsMonad Doc+textChunk _ (TextSpan s) = pure (ps_show $ escapeSpecial s)+textChunk _ (TextEscName s) = pure (ps_glyphshow s)+textChunk nm (TextEscInt i) = (either failk ps_glyphshow) <$> askCharCode nm i where failk gly_name = missingCharCode i gly_name -kernTextH :: PSUnit u => Point2 u -> [KerningChar u] -> PsMonad Doc-kernTextH pt0 xs = snd <$> F.foldlM fn (pt0,empty) xs+kernTextH :: PSUnit u + => FontEncoderName -> Point2 u -> [KerningChar u] -> PsMonad Doc+kernTextH nm pt0 xs = snd <$> F.foldlM fn (pt0,empty) xs where fn (P2 x y,acc) (dx,ch) = (\doc1 -> let pt = P2 (x+dx) y in (pt, vcat [acc, ps_moveto pt, doc1]))- <$> encodedChar ch+ <$> encodedChar nm ch -- Note - vertical labels grow downwards... ---kernTextV :: PSUnit u => Point2 u -> [KerningChar u] -> PsMonad Doc-kernTextV pt0 xs = snd <$> F.foldlM fn (pt0,empty) xs+kernTextV :: PSUnit u + => FontEncoderName -> Point2 u -> [KerningChar u] -> PsMonad Doc+kernTextV nm pt0 xs = snd <$> F.foldlM fn (pt0,empty) xs where fn (P2 x y,acc) (dy,ch) = (\doc1 -> let pt = P2 x (y-dy) in (pt, vcat [acc, ps_moveto pt, doc1]))- <$> encodedChar ch+ <$> encodedChar nm ch -encodedChar :: EncodedChar -> PsMonad Doc-encodedChar (CharLiteral c) = pure (ps_show $ escapeSpecialChar c)-encodedChar (CharEscName s) = pure (ps_glyphshow s)-encodedChar (CharEscInt i) = (either failk ps_glyphshow) <$> askCharCode i +encodedChar :: FontEncoderName -> EncodedChar -> PsMonad Doc+encodedChar _ (CharLiteral c) = pure (ps_show $ escapeSpecialChar c)+encodedChar _ (CharEscName s) = pure (ps_glyphshow s)+encodedChar nm (CharEscInt i) = (either failk ps_glyphshow) <$> askCharCode nm i where failk gly_name = missingCharCode i gly_name
src/Wumpus/Core/OutputSVG.hs view
@@ -49,19 +49,20 @@ import Wumpus.Core.PageTranslation import Wumpus.Core.PictureInternal import Wumpus.Core.SVGDoc+import Wumpus.Core.TextDefaultEncoder import Wumpus.Core.TextEncoder import Wumpus.Core.TextInternal-import Wumpus.Core.TextLatin1 import Wumpus.Core.Utils import Control.Applicative hiding ( empty, some )-import qualified Data.Foldable as F import Data.Maybe -- SvgMonad is two Readers plus Int state for clip paths... --++ newtype SvgMonad a = SvgMonad { - getSvgMonad :: TextEncoder -> GraphicsState -> Int -> (a,Int) }+ getSvgMonad :: TextEncoder -> GraphicsState -> Int -> (a,Int) } @@ -88,11 +89,13 @@ newClipLabel :: SvgMonad String newClipLabel = SvgMonad $ \_ _ s -> ('c':'l':'i':'p':show s, s+1) -askGlyphName :: String -> SvgMonad (Either GlyphName GlyphName)-askGlyphName nm = SvgMonad $ \r1 _ s -> case lookupByGlyphName nm r1 of- Just a -> (Right $ escapeSpecial a, s)- Nothing -> (Left $ escapeSpecial $ svg_fallback r1, s) +getGlyphName :: FontEncoderName -> String -> SvgMonad (Either GlyphName GlyphName)+getGlyphName fen glyname = SvgMonad $ \r1 _ s -> + case lookupByGlyphName fen glyname r1 of+ Just a -> (Right $ escapeSpecial a, s)+ Nothing -> (Left $ escapeSpecial $ getSvgFallback fen r1, s)+ -- This is different to the PsMonad version, as SVG is nested -- (and /graphics state/ is via a Reader), so it is the same as -- local with a Reader monad.@@ -109,8 +112,8 @@ asksGraphicsState fn = SvgMonad $ \_ r2 s -> (fn r2,s) askFontAttr :: SvgMonad FontAttr-askFontAttr = - asksGraphicsState $ \r -> FontAttr (gs_font_size r) (gs_font_face r)+askFontAttr = asksGraphicsState $ \r -> + FontAttr (gs_font_size r) (gs_font_face r) askLineWidth :: SvgMonad Double askLineWidth = asksGraphicsState (line_width . gs_stroke_attr)@@ -127,6 +130,8 @@ askDashPattern :: SvgMonad DashPattern askDashPattern = asksGraphicsState (dash_pattern . gs_stroke_attr) ++ -------------------------------------------------------------------------------- -- | Output a picture to a SVG file. @@ -136,11 +141,11 @@ writeSVG filepath enc pic = writeFile filepath $ show $ svgDraw enc pic --- | Version of 'writeSVG' - using Latin1 encoding. +-- | Version of 'writeSVG' - using Latin1 and Symbol font encodings. -- writeSVG_latin1 :: (Real u, Floating u, PSUnit u) => FilePath -> Picture u -> IO ()-writeSVG_latin1 filepath = writeSVG filepath latin1Encoder+writeSVG_latin1 filepath = writeSVG filepath defaultEncoder svgDraw :: (Real u, Floating u, PSUnit u) => TextEncoder -> Picture u -> Doc@@ -169,8 +174,8 @@ picture :: (Real u, Floating u, PSUnit u) => Picture u -> SvgMonad Doc-picture (Leaf (_,xs) ones) = bracketTrafos xs $ revConcat primElement ones-picture (Picture (_,xs) ones) = bracketTrafos xs $ revConcat picture ones+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 $ do { lbl <- newClipLabel ; d1 <- clipPath lbl cp@@ -181,20 +186,20 @@ --- This starts with an empty line...--- -revConcat :: (a -> SvgMonad Doc) -> OneList a -> SvgMonad Doc-revConcat fn ones = some empty <$> F.foldrM step None ones+oneConcat :: (a -> SvgMonad Doc) -> OneList a -> SvgMonad Doc+oneConcat fn ones = outstep (viewl ones) where- step e ac = (\d -> d `conc` ac) <$> fn e- conc d None = Some d- conc d (Some ac) = Some $ ac `vconcat` d+ outstep (e :< rest) = fn e >>= \a -> instep a (viewl rest)+ outstep (OneL e) = fn e+ + instep ac (OneL e) = fn e >>= \a -> return (ac `vconcat` a)+ instep ac (e :< rest) = fn e >>= \a -> instep (ac `vconcat` a) (viewl rest) primElement :: (Real u, Floating u, PSUnit u) => PrimElement u -> SvgMonad Doc primElement (Atom prim) = primitive prim-primElement (XLinkGroup xl ones) = drawXLink xl <$> revConcat primElement ones+primElement (XLinkGroup xl ones) = drawXLink xl <$> oneConcat primElement ones primitive :: (Real u, Floating u, PSUnit u) => Primitive u -> SvgMonad Doc primitive (PPath props pp) = primPath props pp@@ -287,8 +292,9 @@ primLabel (LabelProps rgb attrs) (PrimLabel pt body ctm) = (\fa ca dtxt -> elem_text (fa <+> ca) (makeTspan rgb dtxt)) <$> deltaFontAttrs attrs <*> bracketPrimCTM pt ctm (labelBodyCoords body)- <*> labelBodyText body- + <*> labelBodyText fen body+ where+ fen = font_enc_name $ font_face attrs labelBodyCoords :: PSUnit u => LabelBody u -> Point2 u -> SvgMonad Doc@@ -296,24 +302,24 @@ labelBodyCoords (KernTextH xs) pt = pure $ makeXsY pt xs labelBodyCoords (KernTextV xs) pt = pure $ makeXYs pt xs -labelBodyText :: LabelBody u -> SvgMonad Doc-labelBodyText (StdLayout enctext) = encodedText enctext-labelBodyText (KernTextH xs) = hcat <$> mapM kerningChar xs-labelBodyText (KernTextV xs) = hcat <$> mapM kerningChar xs+labelBodyText :: FontEncoderName -> LabelBody u -> SvgMonad Doc+labelBodyText nm (StdLayout enctext) = encodedText nm enctext+labelBodyText nm (KernTextH xs) = hcat <$> mapM (kerningChar nm) xs+labelBodyText nm (KernTextV xs) = hcat <$> mapM (kerningChar nm) xs -encodedText :: EncodedText -> SvgMonad Doc-encodedText enctext = hcat <$> mapM textChunk (getEncodedText enctext)+encodedText :: FontEncoderName -> EncodedText -> SvgMonad Doc+encodedText nm enctext = hcat <$> mapM (textChunk nm) (getEncodedText enctext) -textChunk :: TextChunk -> SvgMonad Doc-textChunk (TextSpan s) = pure $ text s-textChunk (TextEscInt i) = pure $ text $ escapeSpecial i-textChunk (TextEscName s) = either text text <$> askGlyphName s +textChunk :: FontEncoderName -> TextChunk -> SvgMonad Doc+textChunk _ (TextSpan s) = pure $ text s+textChunk _ (TextEscInt i) = pure $ text $ escapeSpecial i+textChunk nm (TextEscName s) = either text text <$> getGlyphName nm s -kerningChar :: KerningChar u -> SvgMonad Doc-kerningChar (_, CharLiteral c) = pure $ char c-kerningChar (_, CharEscInt i) = pure $ text $ escapeSpecial i-kerningChar (_, CharEscName s) = either text text <$> askGlyphName s +kerningChar :: FontEncoderName -> KerningChar u -> SvgMonad Doc+kerningChar _ (_, CharLiteral c) = pure $ char c+kerningChar _ (_, CharEscInt i) = pure $ text $ escapeSpecial i+kerningChar nm (_, CharEscName s) = either text text <$> getGlyphName nm s makeTspan :: RGBi -> Doc -> Doc@@ -393,7 +399,7 @@ deltaFontAttrs :: FontAttr -> SvgMonad Doc deltaFontAttrs fa = - (\inh -> if fa ==inh then empty else makeFontAttrs fa) <$> askFontAttr+ (\inh -> if fa == inh then empty else makeFontAttrs fa) <$> askFontAttr makeFontAttrs :: FontAttr -> Doc makeFontAttrs (FontAttr sz face) = @@ -465,3 +471,4 @@ zeroPt' = zeroPt mtrx = val_matrix $ translMatrixRepCTM x y ctm+
src/Wumpus/Core/Picture.hs view
@@ -87,6 +87,7 @@ import Wumpus.Core.PictureInternal import Wumpus.Core.PtSize import Wumpus.Core.TextInternal+import Wumpus.Core.TextLatin1 import Wumpus.Core.Utils import Data.AffineSpace -- package: vector-space@@ -101,8 +102,10 @@ -- | Lift a list of primitives to a composite picture. ----- The order of the list maps to the zorder - the front of the--- list is drawn at the top.+-- The order of the list maps to the order of printing - the +-- front of the list is drawn first in the file. This also means+-- that the front of the list is drawn /at the back/ in the +-- Z-Order. -- -- This function throws an error when supplied the empty list. --@@ -287,12 +290,15 @@ -- Labels to primitive -- | Create a text label. The string should not contain newline--- or tab characters.+-- or tab characters. Also double-spaces should not be used - a +-- rendering agent for SVG will coalesce double-spaces into a +-- single space. For precise control of spacing and kerning use+-- 'hkernlabel'. -- -- The supplied point is the left baseline. -- textlabel :: Num u - => RGBi -> FontAttr -> String -> Point2 u -> PrimElement u+ => RGBi -> FontAttr -> String -> Point2 u -> PrimElement u textlabel rgb attr txt pt = Atom $ PLabel (LabelProps rgb attr) lbl where lbl = PrimLabel pt (StdLayout $ lexLabel txt) identityCTM@@ -315,6 +321,7 @@ face = FontFace { font_name = "Courier" , svg_font_family = "Courier New" , svg_font_style = SVG_REGULAR+ , font_enc_name = latin1_font_encoder } --------------------------------------------------------------------------------
+ src/Wumpus/Core/TextDefaultEncoder.hs view
@@ -0,0 +1,44 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module : Wumpus.Core.TextDefaultEncoder+-- Copyright : (c) Stephen Tetley 2010+-- License : BSD3+--+-- Maintainer : stephen.tetley@gmail.com+-- Stability : unstable+-- Portability : GHC+--+-- This is the default Text encoder with lookups for both Latin1+-- and Symbol font.+--+--------------------------------------------------------------------------------++module Wumpus.Core.TextDefaultEncoder+ ( + defaultEncoder++ ) where++import Wumpus.Core.TextEncoder+import Wumpus.Core.TextLatin1+import Wumpus.Core.TextSymbolFont++import Data.Map+++-- | This is the default encoder supporting names and codes for +-- both Latin1 and the Symbol font.+--+defaultEncoder :: TextEncoder+defaultEncoder = TextEncoder+ { svg_encoding_name = "ISO-8859-1"+ , font_encoder_map = fem+ }+ where+ fem = insert symbol_font_encoder symbolFontEncoder + $ insert latin1_font_encoder latin1FontEncoder+ $ empty ++
src/Wumpus/Core/TextEncoder.hs view
@@ -44,11 +44,15 @@ , CharCode , PostScriptLookup , SVGLookup++ , FontEncoderName(..) , TextEncoder(..)+ , FontEncoder(..) ) where -+import Data.Map+import Data.Word type GlyphName = String type CharCode = Int @@ -57,28 +61,76 @@ type SVGLookup = GlyphName -> Maybe CharCode --- | A TextEncoder++-- | Font encoder name - a newtype wrapped /number/.+-- +-- Ideally this would be an enumerated type, but it has to be +-- open - new encoders need to be added, so an enum is out of the+-- question. ----- An /instance/ needs: +-- A String would be good, but would have slow lookup when used +-- as a key. Dealing with multiple encoders was added late to +-- Wumpus-Core - it is necessary, but taking a performace hit +-- because of it is chagrin. So instead /uniquely/ asssigned+-- numbers are used. ----- * The functions for looking up codes by glyph-name and --- glyph-name by code. +-- Numbers below 10000 are reserved for Wumpus, though it is +-- unlikely to need more than a handful. Numbers above are free +-- to use (clearly clashes are possible, but probably unlikely). -- +-- Wumpus-Core assigns the following, other Wumpus libraries may +-- assign more:+--+-- > 0 - Latin1 (for Helvetica, Times Roman, Courier...)+--+-- > 1 - Symbol Font+-- +newtype FontEncoderName = FontEncoderName { getFontEncoderName :: Word16 }+ deriving (Eq,Ord)++instance Show FontEncoderName where+ show = step . getFontEncoderName+ where+ step 0 = "Latin1"+ step 1 = "Symbol-Font"+ step n = show n++-- | 'TextEncoder'+--+-- An /instance/ needs: +--+-- * A map of FontEncoderNames to FontEncoders.+-- -- * The name of the encoding - this is printed in the xml -- prologue of the SVG file as the @encoding@ attribute. Latin --- 1\'s official name is \"ISO-8859-1\". +-- 1\'s official name is seemingly \"ISO-8859-1\". -- +-- * The name of the default encoder - this should naturally be +-- in the Font Encoder map.+-- +-- +data TextEncoder = TextEncoder+ { svg_encoding_name :: String+ , font_encoder_map :: Map FontEncoderName FontEncoder+ }++-- | 'FontEncoder'.+--+-- * The functions for looking up codes by glyph-name and +-- glyph-name by code. +-- -- * Fallback glyph-names and char codes in case lookup fails. -- -- "Wumpus.Core.TextLatin1" defines an implementation for Latin 1. ---data TextEncoder = TextEncoder {- ps_lookup :: PostScriptLookup,- svg_lookup :: SVGLookup,- svg_encoding_name :: String,- ps_fallback :: GlyphName,- svg_fallback :: CharCode- }+data FontEncoder = FontEncoder + { ps_lookup :: PostScriptLookup+ , svg_lookup :: SVGLookup+ , ps_fallback :: GlyphName+ , svg_fallback :: CharCode+ } -- no show instance as a TextEncoder contains functions.++
src/Wumpus/Core/TextInternal.hs view
@@ -24,7 +24,9 @@ , textLength , lookupByCharCode , lookupByGlyphName-+ , getSvgFallback+ , getPsFallback+ , lexLabel ) where@@ -33,6 +35,7 @@ import Wumpus.Core.TextEncoder import Data.Char+import qualified Data.Map as Map newtype EncodedText = EncodedText { getEncodedText :: [TextChunk] } deriving (Eq,Show)@@ -72,17 +75,31 @@ -------------------------------------------------------------------------------- + textLength :: EncodedText -> Int textLength = foldr add 0 . getEncodedText where add (TextSpan s) n = n + length s add _ n = n + 1 -lookupByCharCode :: CharCode -> TextEncoder -> Maybe GlyphName-lookupByCharCode i enc = (ps_lookup enc) i+lookupByCharCode :: FontEncoderName -> CharCode -> TextEncoder -> Maybe GlyphName+lookupByCharCode name i enc = + Map.lookup name (font_encoder_map enc) >>= \a -> (ps_lookup a) i -lookupByGlyphName :: GlyphName -> TextEncoder -> Maybe CharCode-lookupByGlyphName i enc = (svg_lookup enc) i+lookupByGlyphName :: FontEncoderName -> GlyphName -> TextEncoder -> Maybe CharCode+lookupByGlyphName name i enc = + Map.lookup name (font_encoder_map enc) >>= \a -> (svg_lookup a) i+++getSvgFallback :: FontEncoderName -> TextEncoder -> CharCode+getSvgFallback name enc = case Map.lookup name (font_encoder_map enc) of+ Just fe -> svg_fallback fe + Nothing -> 0o040 -- wild guess++getPsFallback :: FontEncoderName -> TextEncoder -> GlyphName+getPsFallback name enc = case Map.lookup name (font_encoder_map enc) of+ Just fe -> ps_fallback fe + Nothing -> "space" -- wild guess -- | 'lexLabel' input is regular text and escaped glyph names or
src/Wumpus/Core/TextLatin1.hs view
@@ -16,12 +16,10 @@ module Wumpus.Core.TextLatin1 ( - Latin1Name- , Latin1ISOCode - , latin1Encoder-- , latin1All+ latin1_font_encoder+ , latin1FontEncoder+ , latin1FontAll ) where @@ -29,225 +27,231 @@ import qualified Data.Map as Map -type Latin1Name = String-type Latin1ISOCode = Int --- | Latin1 TextEncoder instance.-latin1Encoder :: TextEncoder-latin1Encoder = TextEncoder {- ps_lookup = Map.lookup `flip` codeToName,- svg_lookup = Map.lookup `flip` nameToCode,- svg_encoding_name = "ISO-8859-1",- ps_fallback = "space",- svg_fallback = 0o040- }-nameToCode :: Map.Map String Int-nameToCode = Map.fromList latin1All+-- | Latin1 Font Encoder name +-- +-- (Number 0) +--+latin1_font_encoder :: FontEncoderName+latin1_font_encoder = FontEncoderName 0 -codeToName :: Map.Map Int String-codeToName = foldr fn Map.empty latin1All where+-- | Latin1 FontEncoder instance.+latin1FontEncoder :: FontEncoder+latin1FontEncoder = FontEncoder + { ps_lookup = Map.lookup `flip` codeToName+ , svg_lookup = Map.lookup `flip` nameToCode+ , ps_fallback = "space"+ , svg_fallback = 0o040+ }++nameToCode :: Map.Map GlyphName CharCode+nameToCode = Map.fromList latin1FontAll++codeToName :: Map.Map CharCode GlyphName+codeToName = foldr fn Map.empty latin1FontAll where fn (s,i) a = Map.insert i s a -- | A lookup list of Latin 1 names to their octal code.-latin1All :: [(Latin1Name, Latin1ISOCode)]-latin1All = [ ("A", 0o101)- , ("AE", 0o306)- , ("Aacute", 0o301)- , ("Acircumflex", 0o302)- , ("Adieresis", 0o304)- , ("Agrave", 0o300)- , ("Aring", 0o305)- , ("Atilde", 0o303)- , ("B", 0o102)- , ("C", 0o103)- , ("Ccedilla", 0o307)- , ("D", 0o104)- , ("E", 0o105)- , ("Eacute", 0o311)- , ("Ecircumflex", 0o312)- , ("Edieresis", 0o313)- , ("Egrave", 0o310)- , ("Eth", 0o320)- , ("F", 0o106)- , ("G", 0o107)- , ("H", 0o110)- , ("I", 0o111)- , ("Iacute", 0o315)- , ("Icircumflex", 0o316)- , ("Idieresis", 0o317)- , ("Igrave", 0o314)- , ("J", 0o112)- , ("K", 0o113)- , ("L", 0o114)- , ("M", 0o115)- , ("N", 0o116)- , ("Ntilde", 0o321)- , ("O", 0o117)- , ("Oacute", 0o323)- , ("Ocircumflex", 0o324)- , ("Odieresis", 0o326)- , ("Ograve", 0o322)- , ("Oslash", 0o351)- , ("Otilde", 0o325)- , ("P", 0o120)- , ("Q", 0o121)- , ("R", 0o122)- , ("S", 0o123)- , ("T", 0o124)- , ("Thorn", 0o336)- , ("U", 0o125)- , ("Uacute", 0o332)- , ("Ucircumflex", 0o333)- , ("Udieresis", 0o334)- , ("Ugrave", 0o331)- , ("V", 0o126)- , ("W", 0o127)- , ("X", 0o130)- , ("Y", 0o131)- , ("Yacute", 0o335)- , ("Z", 0o132)- , ("a", 0o141)- , ("aacute", 0o341)- , ("acircumflex", 0o342)- , ("acute2", 0o264)- , ("adieresis", 0o344)- , ("ae", 0o346)- , ("agrave", 0o340)- , ("ampersand", 0o046)- , ("aring", 0o345)- , ("asciicircum", 0o136)- , ("asciitilde", 0o176)- , ("asterisk", 0o052)- , ("at", 0o100)- , ("atilde", 0o343)- , ("b", 0o142)- , ("backslash", 0o134)- , ("bar", 0o174)- , ("braceleft", 0o173)- , ("braceright", 0o175)- , ("bracketleft", 0o133)- , ("bracketright", 0o135)- , ("breve", 0o226)- , ("brokenbar", 0o246)- , ("c", 0o143)- , ("caron", 0o237)- , ("ccedilla", 0o347)- , ("cedilla", 0o270)- , ("cent", 0o242)- , ("circumflex", 0o223)- , ("colon", 0o072)- , ("comma", 0o054)- , ("copyright", 0o251)- , ("currency", 0o244)- , ("d", 0o144)- , ("degree", 0o260)- , ("dieresis", 0o250)- , ("divide", 0o367)- , ("dollar", 0o044)- , ("dotaccent", 0o227)- , ("dotlessi", 0o220)- , ("e", 0o145)- , ("eacute", 0o351)- , ("ecircumflex", 0o352)- , ("edieresis", 0o353)- , ("egrave", 0o350)- , ("eight", 0o070)- , ("equal", 0o075)- , ("eth", 0o360)- , ("exclam", 0o041)- , ("exclamdown", 0o241)- , ("f", 0o146)- , ("five", 0o065)- , ("four", 0o064)- , ("g", 0o147)- , ("germandbls", 0o337)- , ("grave", 0o221)- , ("greater", 0o076)- , ("guillemotleft", 0o253)- , ("guillemotright", 0o273)- , ("h", 0o150)- , ("hungarumlaut", 0o235)- , ("hyphen", 0o255)- , ("i", 0o151)- , ("iacute", 0o355)- , ("icircumflex", 0o356)- , ("idieresis", 0o357)- , ("igrave", 0o354)- , ("j", 0o152)- , ("k", 0o153)- , ("l", 0o154)- , ("less", 0o074)- , ("logicalnot", 0o254)- , ("m", 0o155)- , ("macron", 0o257)- , ("minus", 0o055)- , ("mu", 0o265)- , ("multiply", 0o327)- , ("n", 0o156)- , ("nine", 0o071)- , ("ntilde", 0o361)- , ("numbersign", 0o043)- , ("o", 0o157)- , ("oacute", 0o363)- , ("ocircumflex", 0o364)- , ("odieresis", 0o366)- , ("ogonek", 0o236)- , ("ograve", 0o362)- , ("one", 0o061)- , ("onehalf", 0o275)- , ("onequarter", 0o274)- , ("onesuperior", 0o271)- , ("ordfeminine", 0o252)- , ("ordmasculine", 0o272)- , ("oslash", 0o370)- , ("otilde", 0o365)- , ("p", 0o160)- , ("paragraph", 0o266)- , ("parenleft", 0o050)- , ("parenright", 0o051)- , ("percent", 0o045)- , ("period", 0o056)- , ("periodcentered", 0o267)- , ("plus", 0o053)- , ("plusminus", 0o261)- , ("q", 0o161)- , ("question", 0o077)- , ("questiondown", 0o277)- , ("quotedbl", 0o042)- , ("quoteleft", 0o140)- , ("quoteright", 0o047)- , ("r", 0o162)- , ("registered", 0o256)- , ("ring", 0o232)- , ("s", 0o163)- , ("section", 0o247)- , ("semicolon", 0o073)- , ("seven", 0o067)- , ("six", 0o066)- , ("slash", 0o057)- , ("space", 0o040)- , ("sterling", 0o243)- , ("t", 0o164)- , ("thorn", 0o376)- , ("three", 0o063)- , ("threequarters", 0o276)- , ("threesuperior", 0o263)- , ("tilde", 0o224)- , ("two", 0o062)- , ("twosuperior", 0o262)- , ("u", 0o165)- , ("uacute", 0o372)- , ("ucircumflex", 0o373)- , ("udieresis", 0o374)- , ("ugrave", 0o371)- , ("underscore", 0o137)- , ("v", 0o166)- , ("w", 0o167)- , ("x", 0o170)- , ("y", 0o171)- , ("yacute", 0o375)- , ("ydieresis", 0o377)- , ("yen", 0o245)- , ("z", 0o172)- , ("zero", 0o060)- ]+latin1FontAll :: [(GlyphName, CharCode)]+latin1FontAll = + [ ("A", 0o101)+ , ("AE", 0o306)+ , ("Aacute", 0o301)+ , ("Acircumflex", 0o302)+ , ("Adieresis", 0o304)+ , ("Agrave", 0o300)+ , ("Aring", 0o305)+ , ("Atilde", 0o303)+ , ("B", 0o102)+ , ("C", 0o103)+ , ("Ccedilla", 0o307)+ , ("D", 0o104)+ , ("E", 0o105)+ , ("Eacute", 0o311)+ , ("Ecircumflex", 0o312)+ , ("Edieresis", 0o313)+ , ("Egrave", 0o310)+ , ("Eth", 0o320)+ , ("F", 0o106)+ , ("G", 0o107)+ , ("H", 0o110)+ , ("I", 0o111)+ , ("Iacute", 0o315)+ , ("Icircumflex", 0o316)+ , ("Idieresis", 0o317)+ , ("Igrave", 0o314)+ , ("J", 0o112)+ , ("K", 0o113)+ , ("L", 0o114)+ , ("M", 0o115)+ , ("N", 0o116)+ , ("Ntilde", 0o321)+ , ("O", 0o117)+ , ("Oacute", 0o323)+ , ("Ocircumflex", 0o324)+ , ("Odieresis", 0o326)+ , ("Ograve", 0o322)+ , ("Oslash", 0o351)+ , ("Otilde", 0o325)+ , ("P", 0o120)+ , ("Q", 0o121)+ , ("R", 0o122)+ , ("S", 0o123)+ , ("T", 0o124)+ , ("Thorn", 0o336)+ , ("U", 0o125)+ , ("Uacute", 0o332)+ , ("Ucircumflex", 0o333)+ , ("Udieresis", 0o334)+ , ("Ugrave", 0o331)+ , ("V", 0o126)+ , ("W", 0o127)+ , ("X", 0o130)+ , ("Y", 0o131)+ , ("Yacute", 0o335)+ , ("Z", 0o132)+ , ("a", 0o141)+ , ("aacute", 0o341)+ , ("acircumflex", 0o342)+ , ("acute2", 0o264)+ , ("adieresis", 0o344)+ , ("ae", 0o346)+ , ("agrave", 0o340)+ , ("ampersand", 0o046)+ , ("aring", 0o345)+ , ("asciicircum", 0o136)+ , ("asciitilde", 0o176)+ , ("asterisk", 0o052)+ , ("at", 0o100)+ , ("atilde", 0o343)+ , ("b", 0o142)+ , ("backslash", 0o134)+ , ("bar", 0o174)+ , ("braceleft", 0o173)+ , ("braceright", 0o175)+ , ("bracketleft", 0o133)+ , ("bracketright", 0o135)+ , ("breve", 0o226)+ , ("brokenbar", 0o246)+ , ("c", 0o143)+ , ("caron", 0o237)+ , ("ccedilla", 0o347)+ , ("cedilla", 0o270)+ , ("cent", 0o242)+ , ("circumflex", 0o223)+ , ("colon", 0o072)+ , ("comma", 0o054)+ , ("copyright", 0o251)+ , ("currency", 0o244)+ , ("d", 0o144)+ , ("degree", 0o260)+ , ("dieresis", 0o250)+ , ("divide", 0o367)+ , ("dollar", 0o044)+ , ("dotaccent", 0o227)+ , ("dotlessi", 0o220)+ , ("e", 0o145)+ , ("eacute", 0o351)+ , ("ecircumflex", 0o352)+ , ("edieresis", 0o353)+ , ("egrave", 0o350)+ , ("eight", 0o070)+ , ("equal", 0o075)+ , ("eth", 0o360)+ , ("exclam", 0o041)+ , ("exclamdown", 0o241)+ , ("f", 0o146)+ , ("five", 0o065)+ , ("four", 0o064)+ , ("g", 0o147)+ , ("germandbls", 0o337)+ , ("grave", 0o221)+ , ("greater", 0o076)+ , ("guillemotleft", 0o253)+ , ("guillemotright", 0o273)+ , ("h", 0o150)+ , ("hungarumlaut", 0o235)+ , ("hyphen", 0o255)+ , ("i", 0o151)+ , ("iacute", 0o355)+ , ("icircumflex", 0o356)+ , ("idieresis", 0o357)+ , ("igrave", 0o354)+ , ("j", 0o152)+ , ("k", 0o153)+ , ("l", 0o154)+ , ("less", 0o074)+ , ("logicalnot", 0o254)+ , ("m", 0o155)+ , ("macron", 0o257)+ , ("minus", 0o055)+ , ("mu", 0o265)+ , ("multiply", 0o327)+ , ("n", 0o156)+ , ("nine", 0o071)+ , ("ntilde", 0o361)+ , ("numbersign", 0o043)+ , ("o", 0o157)+ , ("oacute", 0o363)+ , ("ocircumflex", 0o364)+ , ("odieresis", 0o366)+ , ("ogonek", 0o236)+ , ("ograve", 0o362)+ , ("one", 0o061)+ , ("onehalf", 0o275)+ , ("onequarter", 0o274)+ , ("onesuperior", 0o271)+ , ("ordfeminine", 0o252)+ , ("ordmasculine", 0o272)+ , ("oslash", 0o370)+ , ("otilde", 0o365)+ , ("p", 0o160)+ , ("paragraph", 0o266)+ , ("parenleft", 0o050)+ , ("parenright", 0o051)+ , ("percent", 0o045)+ , ("period", 0o056)+ , ("periodcentered", 0o267)+ , ("plus", 0o053)+ , ("plusminus", 0o261)+ , ("q", 0o161)+ , ("question", 0o077)+ , ("questiondown", 0o277)+ , ("quotedbl", 0o042)+ , ("quoteleft", 0o140)+ , ("quoteright", 0o047)+ , ("r", 0o162)+ , ("registered", 0o256)+ , ("ring", 0o232)+ , ("s", 0o163)+ , ("section", 0o247)+ , ("semicolon", 0o073)+ , ("seven", 0o067)+ , ("six", 0o066)+ , ("slash", 0o057)+ , ("space", 0o040)+ , ("sterling", 0o243)+ , ("t", 0o164)+ , ("thorn", 0o376)+ , ("three", 0o063)+ , ("threequarters", 0o276)+ , ("threesuperior", 0o263)+ , ("tilde", 0o224)+ , ("two", 0o062)+ , ("twosuperior", 0o262)+ , ("u", 0o165)+ , ("uacute", 0o372)+ , ("ucircumflex", 0o373)+ , ("udieresis", 0o374)+ , ("ugrave", 0o371)+ , ("underscore", 0o137)+ , ("v", 0o166)+ , ("w", 0o167)+ , ("x", 0o170)+ , ("y", 0o171)+ , ("yacute", 0o375)+ , ("ydieresis", 0o377)+ , ("yen", 0o245)+ , ("z", 0o172)+ , ("zero", 0o060)+ ]
+ src/Wumpus/Core/TextSymbolFont.hs view
@@ -0,0 +1,249 @@+{-# OPTIONS -Wall #-}++--------------------------------------------------------------------------------+-- |+-- Module : Wumpus.Core.TextSymbolFont+-- Copyright : (c) Stephen Tetley 2010+-- License : BSD3+--+-- Maintainer : stephen.tetley@gmail.com+-- Stability : unstable+-- Portability : GHC+--+-- A TextEncoder record instance for Symbol font characters.+-- +--------------------------------------------------------------------------------++module Wumpus.Core.TextSymbolFont+ ( + + symbol_font_encoder+ , symbolFontEncoder+ , symbolFontAll++ ) where++import Wumpus.Core.TextEncoder++import qualified Data.Map as Map++++-- | Symbol Font Encoder name +--+-- (Number 1)+-- +symbol_font_encoder :: FontEncoderName+symbol_font_encoder = FontEncoderName 1++++-- | Latin1 TextEncoder instance.+symbolFontEncoder :: FontEncoder+symbolFontEncoder = FontEncoder + { ps_lookup = Map.lookup `flip` codeToName+ , svg_lookup = Map.lookup `flip` nameToCode+ , ps_fallback = "space"+ , svg_fallback = 0o040+ }++nameToCode :: Map.Map GlyphName CharCode+nameToCode = Map.fromList symbolFontAll++codeToName :: Map.Map CharCode GlyphName+codeToName = foldr fn Map.empty symbolFontAll where+ fn (s,i) a = Map.insert i s a ++-- | A lookup list of Latin 1 names to their octal code.+symbolFontAll :: [(GlyphName, CharCode)]+symbolFontAll = + [ ("Alpha", 0o101)+ , ("Beta", 0o102)+ , ("Chi", 0o103)+ , ("Delta", 0o104)+ , ("Epsilon", 0o105)+ , ("Eta", 0o110)+ , ("Euro", 0o240)+ , ("Gamma", 0o107)+ , ("Ifraktur", 0o301)+ , ("Iota", 0o111)+ , ("Kappa", 0o113)+ , ("Lambda", 0o114)+ , ("Mu", 0o115)+ , ("Nu", 0o116)+ , ("Omega", 0o127)+ , ("Omicron", 0o117)+ , ("Phi", 0o106)+ , ("Pi", 0o120)+ , ("Psi", 0o131)+ , ("Rfraktur", 0o302)+ , ("Rho", 0o122)+ , ("Sigma", 0o123)+ , ("Tau", 0o124)+ , ("Theta", 0o121)+ , ("Upsilon", 0o125)+ , ("Upsilon1", 0o241)+ , ("Xi", 0o130)+ , ("Zeta", 0o132)+ , ("aleph", 0o300)+ , ("alpha", 0o141)+ , ("ampersand", 0o046)+ , ("angle", 0o320)+ , ("angleleft", 0o341)+ , ("angleright", 0o361)+ , ("approxequal", 0o273)+ , ("arrowboth", 0o253)+ , ("arrowdblboth", 0o333)+ , ("arrowdbldown", 0o337)+ , ("arrowdblleft", 0o334)+ , ("arrowdblright", 0o336)+ , ("arrowdblup", 0o335)+ , ("arrowdown", 0o257)+ , ("arrowhorizex", 0o276)+ , ("arrowleft", 0o254)+ , ("arrowright", 0o256)+ , ("arrowup", 0o255)+ , ("arrowvertex", 0o275)+ , ("asteriskmath", 0o052)+ , ("bar", 0o174)+ , ("beta", 0o142)+ , ("braceleft", 0o173)+ , ("braceright", 0o175)+ , ("bracelefttp", 0o354)+ , ("braceleftmid", 0o355)+ , ("braceleftbt", 0o356)+ , ("bracerighttp", 0o374)+ , ("bracerightmid", 0o375)+ , ("bracerightbt", 0o376)+ , ("braceex", 0o357)+ , ("bracketleft", 0o133)+ , ("bracketright", 0o135)+ , ("bracketlefttp", 0o351)+ , ("bracketleftex", 0o352)+ , ("bracketleftbt", 0o353)+ , ("bracketrighttp", 0o371)+ , ("bracketrightex", 0o372)+ , ("bracketrightbt", 0o373)+ , ("bullet", 0o267)+ , ("carriagereturn", 0o277)+ , ("chi", 0o143)+ , ("circlemultiply", 0o304)+ , ("circleplus", 0o305)+ , ("club", 0o247)+ , ("colon", 0o072)+ , ("comma", 0o054)+ , ("congruent", 0o100)+ , ("copyrightsans", 0o343)+ , ("copyrightserif", 0o323)+ , ("degree", 0o260)+ , ("delta", 0o144)+ , ("diamond", 0o250)+ , ("divide", 0o270)+ , ("dotmath", 0o327)+ , ("eight", 0o070)+ , ("element", 0o316)+ , ("ellipsis", 0o274)+ , ("emptyset", 0o306)+ , ("epsilon", 0o145)+ , ("equal", 0o075)+ , ("equivalence", 0o272)+ , ("eta", 0o150)+ , ("exclam", 0o041)+ , ("existential", 0o044)+ , ("five", 0o065)+ , ("florin", 0o246)+ , ("four", 0o064)+ , ("fraction", 0o244)+ , ("gamma", 0o147)+ , ("gradient", 0o321)+ , ("greater", 0o076)+ , ("greaterequal", 0o263)+ , ("heart", 0o251)+ , ("infinity", 0o245)+ , ("integral", 0o362)+ , ("integraltp", 0o363)+ , ("integralex", 0o364)+ , ("integralbt", 0o365)+ , ("intersection", 0o307)+ , ("iota", 0o151)+ , ("kappa", 0o153)+ , ("lambda", 0o154)+ , ("less", 0o074)+ , ("lessequal", 0o243)+ , ("logicaland", 0o331)+ , ("logicalnot", 0o330)+ , ("logicalor", 0o332)+ , ("lozenge", 0o340)+ , ("minus", 0o055)+ , ("minute", 0o242)+ , ("mu", 0o155)+ , ("multiply", 0o264)+ , ("nine", 0o071)+ , ("notelement", 0o317)+ , ("notequal", 0o271)+ , ("notsubset", 0o313)+ , ("nu", 0o156)+ , ("numbersign", 0o043)+ , ("omega", 0o167)+ , ("omega1", 0o166)+ , ("omicron", 0o157)+ , ("one", 0o061)+ , ("parenleft", 0o050)+ , ("parenright", 0o051)+ , ("parenlefttp", 0o346)+ , ("parenleftex", 0o347)+ , ("parenleftbt", 0o350)+ , ("parenrighttp", 0o366)+ , ("parenrightex", 0o367)+ , ("parenrightbt", 0o370)+ , ("partialdiff", 0o266)+ , ("percent", 0o045)+ , ("period", 0o056)+ , ("perpendicular", 0o136)+ , ("phi", 0o146)+ , ("phi1", 0o152)+ , ("pi", 0o160)+ , ("plus", 0o053)+ , ("plusminus", 0o261)+ , ("product", 0o325)+ , ("propersubset", 0o314)+ , ("propersuperset", 0o311)+ , ("proportional", 0o265)+ , ("psi", 0o171)+ , ("question", 0o077)+ , ("radical", 0o326)+ , ("radicalex", 0o140)+ , ("reflexsubset", 0o315)+ , ("reflexsuperset", 0o312)+ , ("registersans", 0o342)+ , ("registerserif", 0o322)+ , ("rho", 0o162)+ , ("second", 0o262)+ , ("semicolon", 0o073)+ , ("seven", 0o067)+ , ("sigma", 0o163)+ , ("sigma1", 0o126)+ , ("similar", 0o176)+ , ("six", 0o066)+ , ("slash", 0o057)+ , ("space", 0o040)+ , ("spade", 0o252)+ , ("suchthat", 0o047)+ , ("summation", 0o345)+ , ("tau", 0o164)+ , ("therefore", 0o134)+ , ("theta", 0o161)+ , ("theta1", 0o112)+ , ("three", 0o063)+ , ("trademarksans", 0o344)+ , ("trademarkserif", 0o324)+ , ("two", 0o062)+ , ("underscore", 0o137)+ , ("union", 0o310)+ , ("universal", 0o042)+ , ("upsilon", 0o165)+ , ("weierstrass", 0o303)+ , ("xi", 0o170)+ , ("zero", 0o060)+ , ("zeta", 0o172)+ ]
src/Wumpus/Core/VersionNumber.hs view
@@ -22,7 +22,7 @@ -- | Version number. ----- > (0,32,0)+-- > (0,33,0) -- wumpus_core_version :: (Int,Int,Int)-wumpus_core_version = (0,32,0)+wumpus_core_version = (0,33,0)
wumpus-core.cabal view
@@ -1,5 +1,5 @@ name: wumpus-core-version: 0.32.0+version: 0.33.0 license: BSD3 license-file: LICENSE copyright: Stephen Tetley <stephen.tetley@gmail.com>@@ -9,10 +9,10 @@ synopsis: Pure Haskell PostScript and SVG generation. description: .- Wumpus is a kernel library for generating 2D vector pictures, - its salient feature is portability due to no FFI dependencies. - It can generate PostScript (EPS) files and SVG files. The - generated PostScript code is plain [1] and reasonably + Wumpus is a low-level library for generating static 2D vector + pictures, its salient feature is portability due to no FFI + dependencies. It can generate PostScript (EPS) files and SVG + files. The generated PostScript code is plain [1] and reasonably efficient as the use of stack operations, i.e @gsave@ and @grestore@, is minimized. .@@ -28,125 +28,47 @@ For actually drawing pictures, diagrams, etc. Wumpus is very low level. There is a supplemantary package @wumpus-basic@ available that helps create certain types of diagram, but it is- experimental - functionality is added an dropped between + experimental - functionality is added and dropped between releases. .- Some of the design decisions made for wumpus-core are not + Some of the design decisions made for Wumpus-core are not sophisticated (e.g. how attributes like colour are handled, and how the bounding boxes of text labels are calculated), so 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 - to convert Wumpus'\s EPS files to many other formats + to convert EPS files generated by Wumpus to many other formats (bitmaps). . Changelog: .- 0.31.0 to 0.32.0:- .- * Major API changes to @Core.Picture@ for XML hyperlinks.- Hyperlinks now group one-or-more Primitives (path or label), - instead of being attached to a single Primitive. This better- corresponds with XML but it has made the Picture type more - complicated, and has mandated significant changes to the - Picture API. All the hyperlink variants of the Primitive - constructors have been removed (xcstroke, xfill, xtextlabel, - ...), and hyperlinks are now created with @xlinkGroup@. - .- * The type signatures for the /primitive/ constructors (fill, - cstroke, textlabel, ...) in the Picture API have changed and - are now more complicated as there is an extra layer of - indirection in the type hierarchy.- .- * The primitive constructors for filled and stroked paths and - ellipses have been renamed: @bordered@ is now @fillStroke@,- @borderedEllipse@ is now @fillStrokeEllipse@.- .- * @Core.FontSize@ - the arguments to the function @textBounds@- have been changed to take the String in question, rather than - its precomputed length. The size of the string is then - calculated with the new function @charCount@ which takes into - account escaped characters.- .- * Added @yellow@, @cyan@ and @magenta@ to the predefined - colours in @Core.Colour@.- .- 0.30.0 to 0.31.0:- .- * Extended the label type to optionally handle horizontal- or vertical \"kerning\". This can be efficiently implemented - in SVG.- .- * Major API change - the Primitive constructors defined in - @Core.PictureLanguage@ are no longer overloaded (@cstroke@, - @ostroke@, @fill@, @textlabel@, @ellipse@). The respective - classes (@Stroke@, @TextLabel@, @Ellipse@) have been removed- and the constructors now have monomorphic types. This is - because Wumpus-Core now only has one colour type and stroke- attributes are now a single type, so polymorphism became- less useful (and the simplicity of monomorphic types became- more favourable). @ellipse@ is no longer a constructor - instead there variants @fillEllipse@ and @strokeEllipse@.- .- * Added support for /bordered/ closed paths - i.e. paths that- are both stroked and filled. These can be efficiently drawn - in SVG with a single @path@ element.- .- * Changed StrokeAttr representation to be a regular data type- rather than a list of /deltas/ - i.e. differences to the - graphics state.- .- * Added SVG font attribute /delta optimizations/ to help reduce - SVG code size - via the @fontDeltaContext@ function in - @Core.Picture@. This functionality was partially inplemented - in the last release using the @GSUpdate@ datatype - this - datatype it is now called @FontCtx@.- .- * Some internal work documenting text encoding.- .- 0.23.0 to 0.30.0:- .- * Substantial changes - the output machinery has been heavily - modified, the intention was to reduce the use of matrix - transformations in SVG output. Though this goal has not been - achieved, some code-size improvements in the SVG output have - been made. - .- * The code generation monads have been changed - Wumpus no - longer uses a writer monad for code generation, but it will- keep the Wumpus name.- .- * Added support for hyperlinks in the SVG output.- .- * Improved internal pretty printing and added the function - @printPicture@ for debugging.- .- * The @Core.Colour@ module has been simplified to support just - one (new) type - RGBi, and the conversion type class - @PSColour@ has been eliminated.+ 0.32.0 to 0.33.0: .- * @Core.Picture@ - the type of the @frame@ function has been - changed to take a list of Primitives rather than a single - Primitive. The function @frameMulti@ which previously - provided this functionality has been removed. SVG hyperlinks- are now supported for Primitives. + * Major change - reworked support for text encoding. Encoding + maps are now linked with fonts - it was spotted that the + Symbol font does not use the Latin1 names. The @TextEncoder@ + data type has been changed and there is a new @FontEncoder@ + data type. There are also new modules for the Symbol Font + encoder table and for the /Default Encoder/ which + accommodates both Latin1 and the Symbol font. This has also + mandated changes to the @FontFace@ data type. . - * The default font size has been changed to 14 pt. - .- * The Path datatype has been renamed PrimPath, likewise Ellipse - is now PrimEllispe and Label becomes PrimLabel.+ * Major change - the printing order has been changed. The first + element in a @frame@ of Prims is draw first. This means it + appears first in the output file (this makes sense) - it also + means it is at the back in the Z-Order. This latter point + might not be so intuitive, but changing the printing order at + least makes Wumpus-Core match SVG and PostScript. .- * @Core.Geometry@ now longer defines an affine frame datatype.+ * Changed the visiblity of the new colours (yellow, cyan, + magenta) to be hidden at the top level. They can be exposed+ by importing @Wumpus.Core.Colour@. .- * @Core.BoundingBox@ module changed significantly. The corner - functions (@boundaryBottomLeft@, etc.) have been removed, - along with the plane functions (@leftPlane@, etc.). Some - functions have been given more verbose names - @corners@ is - now @boundaryCorners@, @within@ is now @withinBoundary@ and - @union@ is now @boundaryUnion@. + * @Wumpus.Core.FontSize@ - added @spacerWidth@ function. . . .@@ -198,8 +120,10 @@ Wumpus.Core.OutputSVG, Wumpus.Core.Picture, Wumpus.Core.PtSize,+ Wumpus.Core.TextDefaultEncoder, Wumpus.Core.TextEncoder, Wumpus.Core.TextLatin1,+ Wumpus.Core.TextSymbolFont, Wumpus.Core.VersionNumber, Wumpus.Core.WumpusTypes