-- | -- Module: Graphics.Chalkboard.Array -- Copyright: (c) 2009 Andy Gill -- License: BSD3 -- -- Maintainer: Andy Gill -- 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