~jaro/balkon

b89500d0ec4226e51326a27f37ac0aa903362ec7 — Jaro 1 year, 8 months ago f389fa5
Calculate fragment position continuously.

This merges the various "arrange" functions into the layout functions,
which will be used to detect overflows for line breaking.
1 files changed, 29 insertions(+), 31 deletions(-)

M src/Data/Text/ParagraphLayout/Plain.hs
M src/Data/Text/ParagraphLayout/Plain.hs => src/Data/Text/ParagraphLayout/Plain.hs +29 -31
@@ 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 }