chalkboard-0.1: Graphics/Chalkboard/Ascii.hs
-- |
-- Module: Graphics.Chalkboard.Array
-- Copyright: (c) 2009 Andy Gill
-- License: BSD3
--
-- Maintainer: Andy Gill <andygill@ku.edu>
-- Stability: unstable
-- Portability: ghc
--
-- This module supports basic ascii drawing of 'Board's.
--
module Graphics.Chalkboard.Ascii
( toAscii, toCount )
where
import Data.Array
import Graphics.Chalkboard.Board
import Graphics.Chalkboard.Array
import Graphics.Chalkboard.Types
import Graphics.Chalkboard.Color
-- | 'toAscii' generates a board of ascii characters, where each char is two pixels, one wide and two high.
toAscii :: (Int,Int) -> Board Gray -> [String]
toAscii = toAsciiWithPen $ \ v v' -> case (sampleInk v,sampleInk v') of
(NoInk,NoInk) -> ' '
(NoInk,SomeInk) -> '.'
(NoInk,MostInk) -> '_'
(SomeInk,NoInk) -> head "'"
(SomeInk,SomeInk) -> ':'
(SomeInk,MostInk) -> ';'
(MostInk,NoInk) -> '"'
(MostInk,SomeInk) -> '?'
(MostInk,MostInk) -> '%'
-- | 'toCount' generates a board of ascii characters, where each char is two pixels, one wide and two high.
-- we uses digits 1 .. 9, then 0 (highest) to represent intensity, adding the two pixels for each char.
toCount :: (Int,Int) -> Board Gray -> [String]
toCount = toAsciiWithPen $ \ v v' ->
case show (ceiling ((v + v') * 5) :: Int) of
"0" -> ' '
[c] -> c
"10" -> '0'
_ -> '?'
toAsciiWithPen :: (Gray -> Gray -> Char) -> (Int,Int) -> Board Gray -> [String]
toAsciiWithPen pen (x_dim,y_dim) board = [
[ let v = arr' ! (x,y)
v' = arr' ! (x,y')
in pen v v'
| x <- [0..x_dim]
]
| (y,y') <- join [y_dim', y_dim'-2 ..]
]
where arr = boardToArray (x_dim,y_dim') 2 board
arr' = floydSteinberg sampleT arr
y_dim' = if even y_dim then succ y_dim else y_dim
join (x:xs) | x < 0 = []
| otherwise = (x,x-1) : join xs
join _ = error "fatal error"
data Ink = NoInk | SomeInk | MostInk
sampleT :: UI -> UI
sampleT n
| n <= 0.33 = 0.15
| n <= 0.67 = 0.60
| otherwise = 1
sampleInk :: UI -> Ink
sampleInk n
| n <= 0.33 = MostInk
| n <= 0.67 = SomeInk
| otherwise = NoInk