From b89500d0ec4226e51326a27f37ac0aa903362ec7 Mon Sep 17 00:00:00 2001 From: Jaro Date: Fri, 24 Feb 2023 22:00:41 +0100 Subject: [PATCH] Calculate fragment position continuously. This merges the various "arrange" functions into the layout functions, which will be used to detect overflows for line breaking. --- src/Data/Text/ParagraphLayout/Plain.hs | 60 +++++++++++++------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/Data/Text/ParagraphLayout/Plain.hs b/src/Data/Text/ParagraphLayout/Plain.hs index a50a6fe..72d422b 100644 --- a/src/Data/Text/ParagraphLayout/Plain.hs +++ b/src/Data/Text/ParagraphLayout/Plain.hs @@ -110,19 +110,42 @@ containGlyphsH lineHeight ps = Rect -- will be shaped using a single font, aligned to the left for LTR text or to -- the right for RTL text. layoutPlain :: Paragraph -> ParagraphLayout -layoutPlain paragraph = ParagraphLayout pRect arrangedLayouts +layoutPlain paragraph = ParagraphLayout pRect layouts where pRect = containRects allRects - allRects = concat $ map spanRects arrangedLayouts - arrangedLayouts = snd $ arrangeSpansH 0 $ layouts - layouts = map layoutSpan spans + allRects = concat $ map spanRects layouts + layouts = snd $ addSpansH 0 spans spans = resolveSpans paragraph +-- | Calculate layout for all given spans, +-- arrange them in one horizontal direction starting from the given x_offset, +-- and return the final x_offset for continuation. +addSpansH :: Int32 -> [RS.ResolvedSpan] -> (Int32, [SpanLayout]) +addSpansH currentX rss = mapAccumL addSpanH currentX rss + -- TODO: Break lines. -- TODO: Allow a run across multiple spans (e.g. if they only differ by colour). -layoutSpan :: RS.ResolvedSpan -> SpanLayout -layoutSpan rs = SpanLayout (map layoutRun $ spanToRuns rs) +-- | Calculate layout for the given span, arrange each of its fragments +-- in one horizontal direction starting from the given x_offset, +-- and return the final x_offset for continuation. +addSpanH :: Int32 -> RS.ResolvedSpan -> (Int32, SpanLayout) +addSpanH currentX rs = (nextX, SpanLayout frags) + where (nextX, frags) = mapAccumL addRunH currentX $ spanToRuns rs + +-- | Calculate layout for the given run, +-- place the generated fragment horizontally at the given x_offset, +-- and return the final x_offset for continuation. +addRunH :: Int32 -> Run -> (Int32, Fragment) +addRunH currentX run = (nextX, nextFrag) + where + frag = layoutRun run + rect = fragmentRect frag + nextX = currentX + x_size rect + nextFrag = frag { fragmentRect = nextRect } + nextRect = rect { x_origin = currentX } + +-- | Calculate layout for the given run independently of its position. layoutRun :: Run -> Fragment layoutRun run = Fragment rect (penX, penY) glyphs where @@ -183,28 +206,3 @@ cut arr off s = (end, t) len = spanLength s end = off + len t = Text arr (fromIntegral off) (fromIntegral len) - --- | Arrange all fragments in multiple spans in one horizontal direction --- and return the final x_offset for continuation. -arrangeSpansH :: Int32 -> [SpanLayout] -> (Int32, [SpanLayout]) -arrangeSpansH currentX sls = mapAccumL arrangeSpanH currentX sls - --- | Arrange all fragments in one span in one horizontal direction --- and return the final x_offset for continuation. -arrangeSpanH :: Int32 -> SpanLayout -> (Int32, SpanLayout) -arrangeSpanH currentX (SpanLayout frags) = (nextX, SpanLayout newFragments) - where (nextX, newFragments) = arrangeFragmentsH currentX frags - --- | Arrange fragments in one horizontal direction --- and return the final x_offset for continuation. -arrangeFragmentsH :: Int32 -> [Fragment] -> (Int32, [Fragment]) -arrangeFragmentsH currentX frags = mapAccumL arrangeFragmentH currentX frags - --- | Set the horizontal offset of the given box --- and return the x coordinate of its other side for continuation. -arrangeFragmentH :: Int32 -> Fragment -> (Int32, Fragment) -arrangeFragmentH currentX frag = (nextX, frag { fragmentRect = newRect }) - where - rect = fragmentRect frag - nextX = currentX + x_size rect - newRect = rect { x_origin = currentX } -- 2.30.2