module Opentype.Fileformat.Kern
where
import Opentype.Fileformat.Types
import Data.Word
import Data.Binary.Put
import Data.Binary.Get
import Data.Bits
import Control.Monad
import Data.Foldable
import Lens.Micro.TH
data KernPair = KernPair Word16 Word16 FWord
deriving Show
data KernTable = KernTable {
coverage :: Word8,
kernPairs :: [KernPair]}
deriving Show
makeLensesFor [("kernPairs", "_kernPairs")] ''KernTable
getKernTable :: Get KernTable
getKernTable = do
version <- getWord16be
when (version /= 0) $
fail "Unsupported kern table."
nTables <- getWord16be
if nTables == 0
then return $ KernTable 0 []
else do
skip 4
cov <- getWord16be
if cov .&. 0xff00 /= 0
then return $ KernTable 0 []
else do
nPairs <- getWord16be
skip 6
fmap (KernTable (fromIntegral $ cov .&. 0xff)) $
replicateM (fromIntegral nPairs) $
KernPair <$> getWord16be <*> getWord16be <*> getInt16be
putKernTable :: KernTable -> Put
putKernTable (KernTable _ pairs) = do
putWord16be 0
putWord16be 1
putWord16be 0
putWord16be $ fromIntegral $ 14+6 * length pairs
putWord16be $ fromIntegral 1
putWord16be $ fromIntegral len
putWord16be searchRange
putWord16be entrySelector
putWord16be $ len*6 searchRange
for_ pairs $ \(KernPair l r v) -> do
putWord16be l
putWord16be r
putInt16be v
where
len = fromIntegral $ length pairs
entrySelector = fromIntegral $ iLog2 len
searchRange = 6 * (1 `shift` fromIntegral entrySelector)