~jaro/balkon

ref: 01cd9cc6548f5469ec6a252987cdb1d40d403d28 balkon/src/Data/Text/ParagraphLayout/Internal/ResolvedBox.hs -rw-r--r-- 2.1 KiB
01cd9cc6Jaro Implement set operations on [ResolvedBox]. 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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