module Graphics.Rendering.Plot.Render.Plot.Glyph (
renderGlyph
) where
import qualified Graphics.Rendering.Cairo as C
import Graphics.Rendering.Plot.Types
glyphWidth :: Double
glyphWidth = 2*pi
renderGlyph :: Double -> Double -> LineWidth -> Glyph -> C.Render ()
renderGlyph xscale yscale pz g = do
C.save
C.scale (pz / xscale) (pz / yscale)
C.setLineWidth 1
renderGlyph' g
C.restore
where renderGlyph' Box = renderGlyphBox
renderGlyph' Cross = renderGlyphCross
renderGlyph' Diamond = renderGlyphDiamond
renderGlyph' Asterisk = renderGlyphAsterisk
renderGlyph' Triangle = renderGlyphTriangle
renderGlyph' Circle = renderGlyphCircle
renderGlyph' Bullet = renderGlyphBullet
renderGlyph' Top = renderGlyphTop
renderGlyph' Bot = renderGlyphBot
difference :: Num a => [a] -> [a]
difference [] = []
difference [_] = []
difference (x0:x1:xs) = (x1x0):(difference (x1:xs))
renderGlyphBox :: C.Render ()
renderGlyphBox = do
let x = glyphWidth
y = glyphWidth
C.relMoveTo (x/2) (y/2)
C.relLineTo 0 y
C.relLineTo x 0
C.relLineTo 0 (y)
C.closePath
C.stroke
renderGlyphCross :: C.Render ()
renderGlyphCross = do
let x = glyphWidth
y = glyphWidth
C.relMoveTo (x/2) 0
C.relLineTo x 0
C.relMoveTo (x/2) (y/2)
C.relLineTo 0 y
C.closePath
C.stroke
renderGlyphDiamond :: C.Render ()
renderGlyphDiamond = do
let x = glyphWidth
y = glyphWidth
C.relMoveTo (x/2) 0
C.relLineTo (x/2) y
C.relLineTo (x/2) (y)
C.relLineTo (x/2) (y)
C.closePath
C.stroke
renderGlyphAsterisk :: C.Render ()
renderGlyphAsterisk = do
let radius = glyphWidth/2
angles' = map ((+ 90) . (* (360 `div` 5))) [0..4]
angles = map ((* (2*pi/360)) . fromInteger . (`mod` 360)) angles'
xs = map ((* (radius)) . cos) angles
ys = map ((* (radius)) . sin) angles
mapM_ (\(x,y) -> do
C.relLineTo x y
C.relMoveTo (x) (y)) (zip xs ys)
C.stroke
renderGlyphTriangle :: C.Render ()
renderGlyphTriangle = do
let radius = glyphWidth/2
angles' = [90,210,330]
angles = map ((* (2*pi/360)) . fromInteger . (`mod` 360)) angles'
x@(sx:_) = map ((* (radius)) . cos) angles
y@(sy:_) = map ((* (radius)) . sin) angles
xs = difference x
ys = difference y
C.relMoveTo sx sy
mapM_ (uncurry C.relLineTo) (zip xs ys)
C.closePath
C.stroke
renderGlyphCircle :: C.Render ()
renderGlyphCircle = do
let radius = glyphWidth/2
angles = map (*(2*pi/36)) [0..35]
x@(sx:_) = map ((* (radius)) . cos) angles
y@(sy:_) = map ((* (radius)) . sin) angles
xs = difference x
ys = difference y
C.relMoveTo sx sy
mapM_ (uncurry C.relLineTo) (zip xs ys)
C.closePath
C.stroke
renderGlyphBullet :: C.Render ()
renderGlyphBullet = do
let radius = glyphWidth/2
angles = map (*(2*pi/36)) [0..35]
x@(sx:_) = map ((* (radius)) . cos) angles
y@(sy:_) = map ((* (radius)) . sin) angles
xs = difference x
ys = difference y
C.relMoveTo sx sy
mapM_ (uncurry C.relLineTo) (zip xs ys)
C.closePath
C.fill
C.stroke
renderGlyphTop :: C.Render ()
renderGlyphTop = do
let x = glyphWidth
y = glyphWidth
C.relMoveTo (x/2) 0
C.relLineTo x 0
C.relMoveTo (x/2) 0
C.relLineTo 0 (y)
C.stroke
renderGlyphBot :: C.Render ()
renderGlyphBot = do
let x = glyphWidth
y = glyphWidth
C.relMoveTo (x/2) 0
C.relLineTo x 0
C.relMoveTo (x/2) 0
C.relLineTo 0 (y)
C.stroke