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