~jaro/balkon

ref: ff1079899e99faf229e747c333f34b5be822877c balkon/src/Data/Text/ParagraphLayout.hs -rw-r--r-- 1.9 KiB
ff107989Jaro Add unit tests for spanToRuns. 1 year, 9 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
module Data.Text.ParagraphLayout (Span(..), layout)
where

import Data.Text.Glyphize
    (Buffer(..)
    ,ContentType(ContentTypeUnicode)
    ,GlyphInfo
    ,GlyphPos
    ,defaultBuffer
    ,shape
    )

import Data.Text.ParagraphLayout.Run
import Data.Text.ParagraphLayout.Span

data Position = Beginning | Middle | End | Only
    deriving (Eq)

-- TODO: Add maximum line length as input.
-- TODO: Compute and return bounding box for each provided span.
--       More if implementing the CSS Box Model.
-- TODO: Also compute and return overall bounding box, in addition to individual
--       ones.
-- TODO: Allow a run across multiple spans (e.g. if they only differ by colour).
layout :: [Span] -> [[(GlyphInfo, GlyphPos)]]
layout = layoutRuns . concat . map spanToRuns

layoutRuns :: [Run] -> [[(GlyphInfo, GlyphPos)]]
layoutRuns [] = []
layoutRuns [s] = [layoutOneRun Only s]
-- TODO: What if there are no visible characters in the edge runs?
layoutRuns (s1:s2:ss) = (layoutOneRun Beginning s1):(layoutRemainingRuns s2 ss)

layoutRemainingRuns :: Run -> [Run] -> [[(GlyphInfo, GlyphPos)]]
layoutRemainingRuns s [] = [layoutOneRun End s]
layoutRemainingRuns s1 (s2:ss) = (layoutOneRun Middle s1):(layoutRemainingRuns s2 ss)

layoutOneRun :: Position -> Run -> [(GlyphInfo, GlyphPos)]
layoutOneRun pos run = shape font buffer features
    where
        originalSpan = runOriginalSpan run
        font = spanFont originalSpan
        lang = spanLanguage originalSpan
        buffer = defaultBuffer { text = runText run
                        , contentType = Just ContentTypeUnicode
                        , direction = runDirection run
                        , script = runScript run
                        , language = lang
                        , beginsText = pos == Beginning || pos == Only
                        , endsText = pos == End || pos == Only
                        }
        features = []