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 = []