~jaro/balkon

ref: segfault-debug balkon/src/Data/Text/ParagraphLayout/Internal/Rich/ParagraphLayout.hs -rw-r--r-- 2.4 KiB
f72b5805Jaro Add stress test for Heisenbug hunting. 1 year, 5 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
module Data.Text.ParagraphLayout.Internal.Rich.ParagraphLayout
    ( ParagraphLayout (..)
    , appendFragments
    , emptyParagraphLayout
    , filterFragments
    , mapFragments
    , paragraphLayout
    , paragraphOriginX
    , paragraphOriginY
    , shapedRuns
    )
where

import Data.Int (Int32)

import Data.Text.ParagraphLayout.Internal.Fragment
import Data.Text.ParagraphLayout.Internal.LinePagination
import Data.Text.ParagraphLayout.Internal.ParagraphExtents
import Data.Text.ParagraphLayout.Internal.Rect

-- | The resulting layout of the whole paragraph.
data ParagraphLayout d = ParagraphLayout
    { paragraphRect :: Rect Int32
    -- ^ The containing block (CSS3).
    , paragraphFragments :: [Fragment d]
    -- ^ The resulting layout of all input text, divided into fragments as
    -- required by the input structure, line breaking, text writing direction,
    -- and changes of script.
    }
    deriving (Eq, Read, Show)

instance Line (ParagraphLayout d) where
    lineHeight pl = height $ paragraphRect pl

-- | Wrap the given `Fragment`s and compute their containing rectangle.
paragraphLayout :: [Fragment d] -> ParagraphLayout d
paragraphLayout frags = ParagraphLayout pRect frags
    where pRect = containRects $ map fragmentSpacedRect frags

-- | A `ParagraphLayout` with no fragments.
-- Useful as an identity element for `appendFragments`.
emptyParagraphLayout :: ParagraphLayout a
emptyParagraphLayout = ParagraphLayout emptyRect []

-- | Remove fragments that do not match the given predicate.
--
-- The containing rectangle will be recalculated.
filterFragments :: (Fragment d -> Bool) -> ParagraphLayout d ->
    ParagraphLayout d
filterFragments predicate (ParagraphLayout _ frags) =
    paragraphLayout $ filter predicate frags

-- | Run a mapping function over each fragment inside a `ParagraphLayout`.
--
-- The containing rectangle will be recalculated.
mapFragments :: (Fragment d -> Fragment d) -> ParagraphLayout d ->
    ParagraphLayout d
mapFragments mapFunc (ParagraphLayout _ frags) =
    paragraphLayout $ map mapFunc frags

-- | Combine fragments from two `ParagraphLayout`s.
--
-- The containing rectangle will be recalculated.
appendFragments :: ParagraphLayout d -> ParagraphLayout d -> ParagraphLayout d
appendFragments (ParagraphLayout _ a) (ParagraphLayout _ b) =
    paragraphLayout $ a ++ b

-- | Return all shaped runs in the paragraph.
shapedRuns :: ParagraphLayout d -> [ShapedRun]
shapedRuns pl = map shapedRun $ paragraphFragments pl