module Data.Text.ParagraphLayout.Internal.ResolvedBox
( ResolvedBox (..)
, boxEndSpacing
, boxLeftSpacing
, boxRightSpacing
, boxStartSpacing
, diff
, union
)
where
import Data.Int (Int32)
import Data.Text.Glyphize (Direction (DirLTR, DirRTL))
import Data.Text.ParagraphLayout.Internal.BoxOptions
-- | Internal structure describing an inline box.
-- May be shared by multiple fragments.
data ResolvedBox d = ResolvedBox
{ boxUserData :: d
, boxIndex :: Int
, boxOptions :: BoxOptions
, boxDirection :: Direction
}
instance Eq (ResolvedBox d) where
a == b = boxIndex a == boxIndex b
instance Ord (ResolvedBox d) where
a `compare` b = boxIndex a `compare` boxIndex b
-- | Calculate the union of two lists of boxes that are ordered
-- from highest index to lowest and do not contain duplicates.
union :: Ord a => [a] -> [a] -> [a]
union xs [] = xs
union [] ys = ys
union (x : xs) (y : ys) = case x `compare` y of
EQ -> x : union xs ys
GT -> x : union xs (y : ys)
LT -> y : union (x : xs) ys
-- | Calculate the difference of two lists of boxes that are ordered
-- from highest index to lowest and do not contain duplicates.
diff :: Ord a => [a] -> [a] -> [a]
diff xs [] = xs
diff [] _ = []
diff (x : xs) (y : ys) = case x `compare` y of
EQ -> diff xs ys
GT -> x : diff xs (y : ys)
LT -> diff (x : xs) ys
boxLeftSpacing :: ResolvedBox d -> Int32
boxLeftSpacing rb = case boxSpacing $ boxOptions rb of
BoxSpacingLeftRight s _ -> s
boxRightSpacing :: ResolvedBox d -> Int32
boxRightSpacing rb = case boxSpacing $ boxOptions rb of
BoxSpacingLeftRight _ s -> s
-- | Spacing at the start of the given box.
boxStartSpacing :: ResolvedBox d -> Int32
boxStartSpacing rb = case (boxDirection rb, boxSpacing $ boxOptions rb) of
(DirLTR, BoxSpacingLeftRight s _) -> s
(DirRTL, BoxSpacingLeftRight _ s) -> s
(_, _) -> 0
-- | Spacing at the end of the given box.
boxEndSpacing :: ResolvedBox d -> Int32
boxEndSpacing rb = case (boxDirection rb, boxSpacing $ boxOptions rb) of
(DirLTR, BoxSpacingLeftRight _ s) -> s
(DirRTL, BoxSpacingLeftRight s _) -> s
(_, _) -> 0