module Data.Text.ParagraphLayout.Internal.ParagraphLayout
(ParagraphLayout(..)
,paragraphLayout
,paragraphOriginX
,paragraphOriginY
,paragraphSpanBounds
,shapedRuns
)
where
import Data.Int (Int32)
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NonEmpty
import Data.Text.ParagraphLayout.Internal.Fragment
import Data.Text.ParagraphLayout.Internal.Paragraph
import Data.Text.ParagraphLayout.Internal.Rect
import Data.Text.ParagraphLayout.Internal.Span
-- | The resulting layout of the whole paragraph.
data ParagraphLayout = ParagraphLayout
{ paragraphRect :: Rect Int32
-- ^ The containing block (CSS3).
, spanLayouts :: [SpanLayout]
}
deriving (Eq, Read, Show)
-- | Calculate the offsets into the `Paragraph`'s underlying `Data.Text.Array`
-- where each span starts and ends, in ascending order. The resulting list
-- will be one larger than the list of input spans.
paragraphSpanBounds :: Paragraph -> NonEmpty Int
paragraphSpanBounds (Paragraph _ initialOffset spans _) =
NonEmpty.scanl (+) initialOffset (map spanLength spans)
paragraphOriginX :: (Num a) => a
paragraphOriginX = 0
paragraphOriginY :: (Num a) => a
paragraphOriginY = 0
empty :: (Num a) => Rect a
empty = Rect
{ x_origin = paragraphOriginX
, y_origin = paragraphOriginY
, x_size = 0
, y_size = 0
}
containRects :: (Ord a, Num a) => [Rect a] -> Rect a
containRects = foldr union empty
-- | Wrap the given `SpanLayout`s and compute their containing rectangle.
paragraphLayout :: [SpanLayout] -> ParagraphLayout
paragraphLayout sls = ParagraphLayout pRect sls
where pRect = containRects $ concat $ map spanRects sls
-- | Return all fragments of shaped text in one flat list,
-- discarding information about their associated spans.
paragraphFragments :: ParagraphLayout -> [Fragment]
paragraphFragments pl = concat $ map spanFragments $ spanLayouts pl
-- | Return all shaped runs in the paragraph.
shapedRuns :: ParagraphLayout -> [ShapedRun]
shapedRuns pl = map shapedRun $ paragraphFragments pl