M src/Data/Text/ParagraphLayout/Internal/Paginable.hs => src/Data/Text/ParagraphLayout/Internal/Paginable.hs +9 -0
@@ 12,6 12,8 @@ import Data.Text.ParagraphLayout.Internal.LinePagination
import Data.Text.ParagraphLayout.Internal.ParagraphLine
import qualified Data.Text.ParagraphLayout.Internal.Plain.ParagraphLayout
as Plain
+import qualified Data.Text.ParagraphLayout.Internal.Rich.ParagraphLayout
+ as Rich
-- | Defines options for breaking a layout into pages.
data PageOptions = PageOptions
@@ 81,6 83,13 @@ instance Paginable (Plain.ParagraphLayout d) where
(c, p, Nothing) -> (c, mergeLines p, Nothing)
(c, p, Just rest) -> (c, mergeLines p, Just (mergeLines rest))
+-- | Implementation of paginating a rich text paragraph layout.
+-- Breaks the layout on page boundaries and automatically adjusts coordinates.
+instance Paginable (Rich.ParagraphLayout d) where
+ paginate opts pl = case paginate opts (cutLines pl) of
+ (c, p, Nothing) -> (c, mergeLines p, Nothing)
+ (c, p, Just rest) -> (c, mergeLines p, Just (mergeLines rest))
+
-- | Perform page breaking on the entire input, returning a list of pages.
paginateAll :: Paginable a => PageOptions -> a -> [(PageContinuity, a)]
paginateAll opts pl = case paginate opts pl of
M src/Data/Text/ParagraphLayout/Internal/ParagraphLine.hs => src/Data/Text/ParagraphLayout/Internal/ParagraphLine.hs +10 -0
@@ 10,6 10,7 @@ import qualified Data.List.NonEmpty as NonEmpty
import Data.Text.ParagraphLayout.Internal.Fragment
import qualified Data.Text.ParagraphLayout.Internal.Plain.ParagraphLayout as P
+import qualified Data.Text.ParagraphLayout.Internal.Rich.ParagraphLayout as R
import Data.Text.ParagraphLayout.Internal.Rect
class GenericLayout pl where
@@ 45,6 46,15 @@ instance GenericLayout (P.ParagraphLayout d) where
shiftFragments dy = P.mapFragments (shiftFragment dy)
appendFragments = P.appendFragments
+instance GenericLayout (R.ParagraphLayout d) where
+ empty = R.emptyParagraphLayout
+ rect = R.paragraphRect
+ topDistance pl = topFragmentOrigin $ R.paragraphFragments pl
+ lineNumbers pl = uniqueFragmentLines $ R.paragraphFragments pl
+ limitFragments n = R.filterFragments (fragmentIsOnLine n)
+ shiftFragments dy = R.mapFragments (shiftFragment dy)
+ appendFragments = R.appendFragments
+
-- | Split the given `ParagraphLayout` into single-line layouts.
cutLines :: GenericLayout pl => pl -> [pl]
cutLines pl = map (\ n -> cutLine n pl) (lineNumbers pl)
M src/Data/Text/ParagraphLayout/Internal/Rich/ParagraphLayout.hs => src/Data/Text/ParagraphLayout/Internal/Rich/ParagraphLayout.hs +4 -0
@@ 14,6 14,7 @@ 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
@@ 28,6 29,9 @@ data ParagraphLayout d = ParagraphLayout
}
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