module Main where
import FreeType
import Control.Monad
import Data.Char
import Data.Word
import Foreign.Marshal.Array
import Foreign.Marshal.Utils
import Foreign.Storable
import System.Environment
import System.Exit
-- | Takes a font filepath and a string as commanline arguments, printing to stdout
-- every character from the string provided at size 16 if the bitmap is scalable.
--
-- Arguments after the first two are discarded.
main :: IO ()
main = do
paths <- getArgs
(filepath, phrase) <- case paths of
(filepath:phrase:_) -> return (filepath, phrase)
_ -> die "Program accepts two arguments: first one is filepath, \
\second is a set of characters you wish to print"
forM_ phrase $ \charcode ->
ft_With_FreeType $ \lib ->
ft_With_Face lib filepath 0 $ \face -> do
isScalable <- FT_IS_SCALABLE face
when isScalable
$ ft_Set_Char_Size face 0 (16 * 64) 0 0
ft_Load_Char face (fromIntegral $ ord charcode) FT_LOAD_RENDER
slot <- peek . frGlyph =<< peek face
withBitmap lib (gsrBitmap slot) $ \bmap -> do
let bufferSize = fromIntegral $ (bRows bmap) * fromIntegral (bPitch bmap)
buffr <- peekArray bufferSize $ bBuffer bmap
drawBitmap (fromIntegral $ bPitch bmap) buffr
withBitmap :: FT_Library -> FT_Bitmap -> (FT_Bitmap -> IO a) -> IO a
withBitmap lib source f =
if any (== bPixel_mode source)
[ FT_PIXEL_MODE_MONO, FT_PIXEL_MODE_GRAY2
, FT_PIXEL_MODE_GRAY4, FT_PIXEL_MODE_BGRA
]
then ft_Bitmap_With lib $ \targetPtr -> do
with source $ \sourcePtr -> do
ft_Bitmap_Convert lib sourcePtr targetPtr . fromIntegral $ bPixel_mode source
f =<< peek targetPtr
else f source
drawBitmap :: Int -> [Word8] -> IO ()
drawBitmap n [] = return ()
drawBitmap n list = do
putStrLn $ color <$> take n list
drawBitmap n $ drop n list
where
color :: Word8 -> Char
color a =
case () of
() | a == 0 -> ' '
| a < 85 -> '░'
| a < 170 -> '▒'
| a < 255 -> '▓'
| otherwise -> '█'