packages feed

hp2pretty-0.4: src/Graphics.hs

module Graphics where

import Data.ByteString.Char8 (ByteString, foldl')
import Data.Char (ord)
import Data.Bits (shiftR)
import Data.Int (Int32, Int64)

type Point = (Double, Double)
type Size = (Double, Double)
type Angle = Double

type FontSize = Double
data Anchor = Start | Middle | End

type StrokeWidth = Double
type Opacity = Double
data RGB = RGB Double Double Double

data Graphics =
  Graphics
  { text     :: Maybe Angle -> Anchor -> FontSize -> Point -> [ByteString] -> [ByteString]
  , rect     :: Point -> Size -> [ByteString]
  , line     :: Point -> Point -> [ByteString]
  , polygon  :: [Point] -> [ByteString]
  , visual   :: Maybe RGB -> Maybe Opacity -> Maybe RGB -> Maybe StrokeWidth -> [ByteString] -> [ByteString]
  , document :: Size -> [ByteString] -> [ByteString]
  }

rescalePoint :: (Point,Point) -> (Point,Point) -> Point -> Point
rescalePoint ((inX0,inY0),(inX1,inY1)) ((outX0,outY0),(outX1,outY1)) (x,y) =
  let inW = inX1 - inX0
      inH = inY1 - inY0
      outW = outX1 - outX0
      outH = outY1 - outY0
  in  ((x - inX0) / inW * outW + outX0, (y - inY0) / inH * outH + outY0)

black, white :: RGB
black = RGB 0 0 0
white = RGB 1 1 1

colour :: ByteString -> RGB
colour s = hsvToRGB (c 0x12345) (c 0x6789a) (c 0xbcdef)
  where
    c m = fromIntegral (hashByteString m s) * 667 / fromIntegral (maxBound :: Int32)

hsvToRGB :: Double -> Double -> Double -> RGB
hsvToRGB h0 s0 v0 =
  let s = 0.5 + 0.5 * (s0 - (fromIntegral (floor s0 :: Int)))
      v = 0.5 + 0.5 * (v0 - (fromIntegral (floor v0 :: Int)))
      h = floor h0 :: Int
      i = h `mod` 6
      f = h0 - fromIntegral h
      p = v * (1 - s)
      q = v * (1 - s * f)
      t = v * (1 - s * (1 - f))
  in  case i of
        0 -> RGB v t p
        1 -> RGB q v p
        2 -> RGB p v t
        3 -> RGB p q v
        4 -> RGB t p v
        _ -> RGB v p q

-- hashing functions copied and modified from BSD-style LICENSE'd
-- base-4.3.1.0:Data.HashTable (c) The University of Glasgow 2003

hashByteString :: Int32 -> ByteString -> Int32
hashByteString magic = foldl' f golden
  where f m c = fromIntegral (ord c) * magic + hashInt32 m

hashInt32 :: Int32 -> Int32
hashInt32 x = mulHi x golden + x

mulHi :: Int32 -> Int32 -> Int32
mulHi a b = fromIntegral (r `shiftR` 32)
  where r :: Int64
        r = fromIntegral a * fromIntegral b

golden :: Int32
golden = 1013904242