M src/Data/Text/ParagraphLayout/Internal/ParagraphLine.hs => src/Data/Text/ParagraphLayout/Internal/ParagraphLine.hs +15 -14
@@ 21,19 21,20 @@ instance Line ParagraphLine where
-- | Split the given `ParagraphLayout` into individual lines.
cutLines :: ParagraphLayout -> [ParagraphLine]
-cutLines pl = map (\ y -> cutLine y pl) (lineOrigins pl)
+cutLines pl = map (\ n -> cutLine n pl) (lineNumbers pl)
--- | Reduce the given `ParagraphLayout` to fragments with the given `y_origin`.
---
--- This assumes that each line consists of fragments of equal height and that
--- there is no space between lines.
---
--- TODO: Use line numbers to support rich text.
-cutLine :: Int32 -> ParagraphLayout -> ParagraphLine
-cutLine y pl = ParagraphLine $ shiftFragments (-y) $ limitFragments y pl
+-- | Reduce the given `ParagraphLayout` to fragments with the given line number.
+cutLine :: Int -> ParagraphLayout -> ParagraphLine
+cutLine n pl = ParagraphLine $ trimTop $ limitFragments n pl
-lineOrigins :: ParagraphLayout -> [Int32]
-lineOrigins pl = dedupe $ map (y_origin . fragmentRect) $ paragraphFragments pl
+-- | Add a constant to each fragment's `y_origin` so that their maximum is zero.
+trimTop :: ParagraphLayout -> ParagraphLayout
+trimTop pl = shiftFragments (-top) pl
+ where
+ top = maximum $ map (y_origin . fragmentRect) $ paragraphFragments pl
+
+lineNumbers :: ParagraphLayout -> [Int]
+lineNumbers pl = dedupe $ map fragmentLine $ paragraphFragments pl
-- | Remove duplicates from a sorted list.
dedupe :: Eq a => [a] -> [a]
@@ 62,6 63,6 @@ shiftFragment dy f = f'
r' = r { y_origin = y_origin r + dy }
r = fragmentRect f
--- | Keep only fragments with the given `y_origin` value.
-limitFragments :: Int32 -> ParagraphLayout -> ParagraphLayout
-limitFragments y = filterFragments ((== y) . y_origin . fragmentRect)
+-- | Keep only fragments with the given line number.
+limitFragments :: Int -> ParagraphLayout -> ParagraphLayout
+limitFragments n = filterFragments ((== n) . fragmentLine)