From ba1e5a040d130d35a16a7d9a0146cec41262cbff Mon Sep 17 00:00:00 2001 From: Jaro Date: Wed, 10 May 2023 15:24:17 +0200 Subject: [PATCH] Test line breaking in boxes. --- .../hardBoxBreakLTR.golden | 69 +++++++++++++++++++ .../hardBoxBreakRTL.golden | 69 +++++++++++++++++++ .../ParagraphLayout/Rich/ParagraphData.hs | 47 ++++++++++++- test/Data/Text/ParagraphLayout/RichSpec.hs | 15 ++++ 4 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 .golden/richParagraphLayout/hardBoxBreakLTR.golden create mode 100644 .golden/richParagraphLayout/hardBoxBreakRTL.golden diff --git a/.golden/richParagraphLayout/hardBoxBreakLTR.golden b/.golden/richParagraphLayout/hardBoxBreakLTR.golden new file mode 100644 index 0000000..43350ff --- /dev/null +++ b/.golden/richParagraphLayout/hardBoxBreakLTR.golden @@ -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}) + ] + } + ] + } diff --git a/.golden/richParagraphLayout/hardBoxBreakRTL.golden b/.golden/richParagraphLayout/hardBoxBreakRTL.golden new file mode 100644 index 0000000..7423738 --- /dev/null +++ b/.golden/richParagraphLayout/hardBoxBreakRTL.golden @@ -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}) + ] + } + ] + } diff --git a/test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs b/test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs index 9014d86..63e69c1 100644 --- a/test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs +++ b/test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs @@ -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: loremIpsumParagraph :: Font -> ParagraphOptions -> Paragraph String diff --git a/test/Data/Text/ParagraphLayout/RichSpec.hs b/test/Data/Text/ParagraphLayout/RichSpec.hs index 021c28a..9f8cfdc 100644 --- a/test/Data/Text/ParagraphLayout/RichSpec.hs +++ b/test/Data/Text/ParagraphLayout/RichSpec.hs @@ -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" -- 2.30.2