~jaro/balkon

ba1e5a040d130d35a16a7d9a0146cec41262cbff — Jaro 11 months ago 35a5cc7
Test line breaking in boxes.
A .golden/richParagraphLayout/hardBoxBreakLTR.golden => .golden/richParagraphLayout/hardBoxBreakLTR.golden +69 -0
@@ 0,0 1,69 @@
ParagraphLayout
    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 5855, y_size = -2242}
    , paragraphFragments =
        [ Fragment
            { fragmentUserData = "text1"
            , fragmentLine = 1
            , fragmentAncestorBoxes =
                []
            , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 3333, y_size = -1121}
            , fragmentPen = (0, -932)
            , fragmentGlyphs =
                [ (GlyphInfo {codepoint = 68, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 68, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 68, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                ]
            }
        , Fragment
            { fragmentUserData = "text2"
            , fragmentLine = 1
            , fragmentAncestorBoxes =
                [ AncestorBox {boxUserData = "box2", boxLeftSpacing = Just 150, boxRightSpacing = Nothing, boxStartSpacing = Just 150, boxEndSpacing = Nothing}
                , AncestorBox {boxUserData = "box1", boxLeftSpacing = Just 50, boxRightSpacing = Nothing, boxStartSpacing = Just 50, boxEndSpacing = Nothing}
                ]
            , fragmentRect = Rect {x_origin = 3533, y_origin = 0, x_size = 2222, y_size = -1121}
            , fragmentPen = (0, -932)
            , fragmentGlyphs =
                [ (GlyphInfo {codepoint = 68, cluster = 12, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 68, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                ]
            }
        , Fragment
            { fragmentUserData = "text2"
            , fragmentLine = 2
            , fragmentAncestorBoxes =
                [ AncestorBox {boxUserData = "box2", boxLeftSpacing = Nothing, boxRightSpacing = Just 200, boxStartSpacing = Nothing, boxEndSpacing = Just 200}
                , AncestorBox {boxUserData = "box1", boxLeftSpacing = Nothing, boxRightSpacing = Just 100, boxStartSpacing = Nothing, boxEndSpacing = Just 100}
                ]
            , fragmentRect = Rect {x_origin = 0, y_origin = -1121, x_size = 2222, y_size = -1121}
            , fragmentPen = (0, -932)
            , fragmentGlyphs =
                [ (GlyphInfo {codepoint = 68, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 18, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 68, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                ]
            }
        , Fragment
            { fragmentUserData = "text3"
            , fragmentLine = 2
            , fragmentAncestorBoxes =
                []
            , fragmentRect = Rect {x_origin = 2522, y_origin = -1121, x_size = 3333, y_size = -1121}
            , fragmentPen = (0, -932)
            , fragmentGlyphs =
                [ (GlyphInfo {codepoint = 68, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 68, cluster = 23, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 68, cluster = 25, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 69, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})
                ]
            }
        ]
    }

A .golden/richParagraphLayout/hardBoxBreakRTL.golden => .golden/richParagraphLayout/hardBoxBreakRTL.golden +69 -0
@@ 0,0 1,69 @@
ParagraphLayout
    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 3455, y_size = -3000}
    , paragraphFragments =
        [ Fragment
            { fragmentUserData = "text2"
            , fragmentLine = 1
            , fragmentAncestorBoxes =
                [ AncestorBox {boxUserData = "box2", boxLeftSpacing = Nothing, boxRightSpacing = Just 200, boxStartSpacing = Just 200, boxEndSpacing = Nothing}
                , AncestorBox {boxUserData = "box1", boxLeftSpacing = Nothing, boxRightSpacing = Just 100, boxStartSpacing = Just 100, boxEndSpacing = Nothing}
                ]
            , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 1632, y_size = -1500}
            , fragmentPen = (0, -1085)
            , fragmentGlyphs =
                [ (GlyphInfo {codepoint = 512, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 839, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 293, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 389, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 293, cluster = 18, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0})
                ]
            }
        , Fragment
            { fragmentUserData = "text1"
            , fragmentLine = 1
            , fragmentAncestorBoxes =
                []
            , fragmentRect = Rect {x_origin = 1932, y_origin = 0, x_size = 1523, y_size = -1500}
            , fragmentPen = (0, -1085)
            , fragmentGlyphs =
                [ (GlyphInfo {codepoint = 389, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 293, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 389, cluster = 12, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 293, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 389, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 286, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 224, y_advance = 0, x_offset = 0, y_offset = 0})
                ]
            }
        , Fragment
            { fragmentUserData = "text3"
            , fragmentLine = 2
            , fragmentAncestorBoxes =
                []
            , fragmentRect = Rect {x_origin = 0, y_origin = -1500, x_size = 2155, y_size = -1500}
            , fragmentPen = (0, -1085)
            , fragmentGlyphs =
                [ (GlyphInfo {codepoint = 512, cluster = 45, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 839, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 293, cluster = 43, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 389, cluster = 41, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 293, cluster = 39, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 389, cluster = 37, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 293, cluster = 35, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0})
                ]
            }
        , Fragment
            { fragmentUserData = "text2"
            , fragmentLine = 2
            , fragmentAncestorBoxes =
                [ AncestorBox {boxUserData = "box2", boxLeftSpacing = Just 150, boxRightSpacing = Nothing, boxStartSpacing = Nothing, boxEndSpacing = Just 150}
                , AncestorBox {boxUserData = "box1", boxLeftSpacing = Just 50, boxRightSpacing = Nothing, boxStartSpacing = Nothing, boxEndSpacing = Just 50}
                ]
            , fragmentRect = Rect {x_origin = 2355, y_origin = -1500, x_size = 1000, y_size = -1500}
            , fragmentPen = (0, -1085)
            , fragmentGlyphs =
                [ (GlyphInfo {codepoint = 389, cluster = 33, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 293, cluster = 31, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 389, cluster = 29, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})
                , (GlyphInfo {codepoint = 286, cluster = 27, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 224, y_advance = 0, x_offset = 0, y_offset = 0})
                ]
            }
        ]
    }

M test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs => test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs +45 -2
@@ 1,12 1,14 @@
module Data.Text.ParagraphLayout.Rich.ParagraphData
    ( loremIpsumParagraph
    ( hardBoxBreakLTRParagraph
    , hardBoxBreakRTLParagraph
    , loremIpsumParagraph
    , mixedSizesParagraph
    , nestedBoxesParagraph
    )
where

import Data.Text (pack)
import Data.Text.Glyphize (Direction (DirLTR), Font)
import Data.Text.Glyphize (Direction (DirLTR, DirRTL), Font)

import Data.Text.ParagraphLayout.Internal.BoxOptions
import Data.Text.ParagraphLayout.Internal.ParagraphOptions


@@ 17,6 19,9 @@ import Data.Text.ParagraphLayout.Internal.TreeOfTexts
tLTR :: TextOptions
tLTR = defaultTextOptions DirLTR

tRTL :: TextOptions
tRTL = defaultTextOptions DirRTL

b_ :: BoxOptions
b_ = defaultBoxOptions



@@ 29,6 34,44 @@ box label boxOpts textOpts nodes = InlineBox label (Box nodes textOpts) boxOpts
text :: d -> String -> InnerNode d
text label contents = TextSequence label (pack contents)

hardBoxBreakLTRParagraph :: Font -> ParagraphOptions -> Paragraph String
hardBoxBreakLTRParagraph font = constructParagraph
    (pack "prefix")
    (rootBox t
        [ text "text1" "ababab"
        , box "box1" b1 t
            [ box "box2" b2 t
                [ text "text2" "abab\nabab"
                ]
            ]
        , text "text3" "ababab"
        ]
    )
    (pack "suffix")
    where
        b1 = b_ { boxSpacing = BoxSpacingLeftRight 50 100 }
        b2 = b_ { boxSpacing = BoxSpacingLeftRight 150 200 }
        t = tLTR { textFont = font, textLanguage = "zxx" }

hardBoxBreakRTLParagraph :: Font -> ParagraphOptions -> Paragraph String
hardBoxBreakRTLParagraph font = constructParagraph
    (pack "prefix")
    (rootBox t
        [ text "text1" "اباباب"
        , box "box1" b1 t
            [ box "box2" b2 t
                [ text "text2" "اباب\nاباب"
                ]
            ]
        , text "text3" "اباباب"
        ]
    )
    (pack "suffix")
    where
        b1 = b_ { boxSpacing = BoxSpacingLeftRight 50 100 }
        b2 = b_ { boxSpacing = BoxSpacingLeftRight 150 200 }
        t = tRTL { textFont = font, textLanguage = "zxx" }

-- | Filler text using the Latin script.
-- Source: <https://www.lipsum.com/>
loremIpsumParagraph :: Font -> ParagraphOptions -> Paragraph String

M test/Data/Text/ParagraphLayout/RichSpec.hs => test/Data/Text/ParagraphLayout/RichSpec.hs +15 -0
@@ 40,6 40,21 @@ spec = do
                let result = layoutRich input
                result `shouldBeGolden` "nestedBoxes"

            it "handles hard break in LTR boxes" $ do
                let opts = defaultParagraphOptions
                let input = hardBoxBreakLTRParagraph font opts
                let result = layoutRich input
                result `shouldBeGolden` "hardBoxBreakLTR"

        describe "with Arabic font" $ do
            font <- runIO $ loadFont arabicFont 0 testingOptions

            it "handles hard break in RTL boxes" $ do
                let opts = defaultParagraphOptions
                let input = hardBoxBreakRTLParagraph font opts
                let result = layoutRich input
                result `shouldBeGolden` "hardBoxBreakRTL"

    describe "paginate" $ do
        let
            goldenDir = ".golden" </> "paginatedRichParagraphLayout"