simple-pango-0.1.0.1: src/Data/Font/VariationAxis/Internal.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE BlockArguments, LambdaCase, OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
module Data.Font.VariationAxis.Internal (
-- * AXIS CLASS
FontDescriptionAxis,
-- * ADD AXIS
fontDescriptionAddAxis,
-- * SET AND GET AXIS
Variations, variationsEmpty, variationsSetAxis, variationsGetAxis,
-- * SHOW AND READ VARIATIONS
showVariations, readVariations ) where
import Control.Arrow
import qualified Data.Map as M
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BSC
import Language.Haskell.TH
class FontDescriptionAxis a where
fontDescriptionAxisTag :: BS.ByteString
fontDescriptionAxisToDouble :: a -> Double
fontDescriptionAxisFromDouble :: Double -> a
newtype Variations = Variations { getVariations :: M.Map BS.ByteString Double }
deriving Show
variationsEmpty :: Variations
variationsEmpty = Variations M.empty
fontDescriptionAddAxis :: String -> String -> DecsQ
fontDescriptionAddAxis a t = (\n i -> [n, i])
<$> fontDescriptionAddAxisNewtype a
<*> fontDescriptionAddAxisInstance a t
fontDescriptionAddAxisNewtype :: String -> DecQ
fontDescriptionAddAxisNewtype a =
newtypeD (cxt [])
(mkName a) [] Nothing (recC (mkName a) [
varBangType (mkName $ "get" ++ a)
$ bangType (bang noSourceUnpackedness noSourceStrictness) (conT ''Double) ])
[derivClause Nothing [conT ''Show]]
fontDescriptionAddAxisInstance :: String -> String -> DecQ
fontDescriptionAddAxisInstance a t = instanceD (cxt []) (conT ''FontDescriptionAxis `appT` conT (mkName a)) [
valD (varP 'fontDescriptionAxisTag) (normalB . litE $ StringL t) [],
valD (varP 'fontDescriptionAxisToDouble) (normalB . varE . mkName $ "get" ++ a) [],
valD (varP 'fontDescriptionAxisFromDouble) (normalB . conE $ mkName a) []
]
showVariations :: Variations -> BS.ByteString
showVariations = BS.intercalate "," . ((\(a, v) -> a <> "=" <> v) . (id *** BSC.pack . show) <$>) . M.toList . getVariations
readVariations :: BS.ByteString -> Variations
readVariations = Variations . M.fromList . ((\[a, v] -> (a, read $ BSC.unpack v)) . BSC.split '=' <$>) . BSC.split ','
variationsSetAxis :: forall a . FontDescriptionAxis a => a -> Variations -> Variations
variationsSetAxis a = Variations . M.insert
(fontDescriptionAxisTag @a)
(fontDescriptionAxisToDouble a) . getVariations
variationsGetAxis ::
forall a . FontDescriptionAxis a => Variations -> Maybe a
variationsGetAxis (Variations as) = fontDescriptionAxisFromDouble
<$> M.lookup (fontDescriptionAxisTag @a) as