module Data.Text.ParagraphLayout.Rich.ParagraphData ( emptyBoxParagraph , hardBoxBreakLTRParagraph , hardBoxBreakRTLParagraph , intraWordBreakParagraph , loremIpsumParagraph , mixedDirectionComplexParagraph , mixedDirectionSimpleParagraph , mixedLineHeightParagraph , mixedScriptParagraph , mixedSizesParagraph , mixedVerticalAlignmentParagraph , nestedBoxesParagraph , neutralDirectionParagraph , newline1Paragraph , newline1TextParagraph , newline2Paragraph , newline2TextParagraph , offsetMiddleInnerTextParagraph , offsetMiddleOuterTextParagraph , offsetTextlessBoxParagraph , softBreakParagraph , spaceBoxParagraph ) where import Data.Int (Int32) import Data.Text (Text, empty, pack) import Data.Text.Glyphize (Direction (DirLTR, DirRTL), Font) import Data.Text.ParagraphLayout.Internal.BoxOptions import Data.Text.ParagraphLayout.Internal.ParagraphOptions import Data.Text.ParagraphLayout.Internal.Rich.Paragraph import Data.Text.ParagraphLayout.Internal.TextOptions import Data.Text.ParagraphLayout.Internal.Tree import Data.Text.ParagraphLayout.Rich import Data.Text.ParagraphLayout.TextData tLTR :: TextOptions tLTR = defaultTextOptions DirLTR tRTL :: TextOptions tRTL = defaultTextOptions DirRTL b_ :: BoxOptions b_ = defaultBoxOptions rootBox :: TextOptions -> [InnerNode Text d] -> RootNode Text d rootBox opts nodes = RootBox (Box nodes opts) box :: d -> BoxOptions -> TextOptions -> [InnerNode Text d] -> InnerNode Text d box label boxOpts textOpts nodes = InlineBox label (Box nodes textOpts) boxOpts text :: d -> String -> InnerNode Text d text label contents = TextSequence label (pack contents) emptyBoxParagraph :: Font -> ParagraphOptions -> Paragraph String emptyBoxParagraph font = constructParagraph (pack "prefix") (rootBox t [ text "text1" "empty " , box "box1" b t [ text "emptyText" "" ] , text "text2" " box" ] ) (pack "suffix") where b = b_ { boxSpacing = BoxSpacingLeftRight 50 100 } t = tLTR { textFont = font, textLanguage = "en" } 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" } -- | For testing that soft wrap preserves the form of Arabic characters. -- Source: intraWordBreakParagraph :: Font -> ParagraphOptions -> Paragraph String intraWordBreakParagraph font = constructParagraph empty (rootBox t [ text "text" "نوشتن_نوشتن_نوشتن" ] ) empty where t = tRTL { textFont = font, textLanguage = "fa" } -- | Filler text using the Latin script. -- Source: loremIpsumParagraph :: Font -> ParagraphOptions -> Paragraph String loremIpsumParagraph font = constructParagraph (pack "xxxx") (rootBox t [ text "text" "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." ] ) (pack "z") where t = tLTR { textFont = font, textLanguage = "zxx" } -- | Edge case: -- Directionally neutral characters between box boundary and direction boundary. -- -- In the case of a LTR paragraph, neutral characters should only be considered -- RTL when surrounded by RTL characters on both sides, otherwise they should -- be LTR. -- -- In the case of a RTL paragraph, neutral characters should only be considered -- LTR when surrounded by LTR characters on both sides, otherwise they should -- be RTL. -- -- Box boundaries should not, by default, affect the direction of neutral -- characters. mixedDirectionComplexParagraph :: Direction -> Font -> ParagraphOptions -> Paragraph String mixedDirectionComplexParagraph dir font = constructParagraph (pack "prefix") (rootBox t [ text "text1" " . > ab . > ba . > " , box "box1" b_ t [ text "text2" " . > اب . > با . > tu . > ut . > " ] , text "text3" " . > تو . > وت . > " ] ) (pack "suffix") where t = (defaultTextOptions dir) { textFont = font, textLanguage = "zxx" } -- | A paragraph that contains only strongly directional letters of mixed -- directions, no spaces or other neutral characters, for basic BiDi tests. mixedDirectionSimpleParagraph :: Direction -> Font -> ParagraphOptions -> Paragraph String mixedDirectionSimpleParagraph dir font = constructParagraph empty (rootBox t [TextSequence "text" textContents]) empty where t = (defaultTextOptions dir) { textFont = font, textLanguage = lang } (_, lang, textContents, _) = mixedDirectionSimple dir mixedLineHeightParagraph :: (Int32, Int32, Int32) -> VerticalAlignment -> Font -> ParagraphOptions -> Paragraph String mixedLineHeightParagraph lhs va font = constructParagraph (pack "prefix") (rootBox tMedium -- Line 1: all 3 heights, with medium height prevailing. [ text "mediumText" "medium " , box "smallBox" b tSmall [text "smallText" "small "] , text "mediumText" "medium " , box "largeBox" b tLarge [text "largeText" "large "] , text "mediumText" "medium " , text "lineBreak" "\n" -- Line 2: all 3 line heights, with medium only in the middle. , box "smallBox" b tSmall [text "smallText" "small "] , text "mediumText" "medium " , box "largeBox" b tLarge [text "largeText" "large "] , text "lineBreak" "\n" -- Line 3: asymmetric, medium changing into small. , text "mediumText" "medium " , box "smallBox" b tSmall [text "smallText" "small "] , text "lineBreak" "\n" -- Line 4: asymmetric, large changing into medium. , box "largeBox" b tLarge [text "largeText" "large "] , text "mediumText" "medium " , text "lineBreak" "\n" -- Line 5: small only. , box "smallBox" b tSmall [text "smallText" "small "] , text "lineBreak" "\n" -- Line 6: large only. , box "largeBox" b tLarge [text "largeText" "large "] ] ) (pack "suffix") where tLarge = t { textLineHeight = Absolute lhLarge } tMedium = t { textLineHeight = Absolute lhMedium } tSmall = t { textLineHeight = Absolute lhSmall } (lhSmall, lhMedium, lhLarge) = lhs t = tLTR { textFont = font, textLanguage = "en" } b = b_ { boxVerticalAlignment = va } mixedScriptParagraph :: Font -> ParagraphOptions -> Paragraph String mixedScriptParagraph font = constructParagraph (pack "prefix") (rootBox t [ text "text1" "jjjжжж" -- Box starting on script boundary: , box "box1" b1 t -- Box continuing over script boundary: [ text "text2" "jjjжжж" ] -- Box ending outside script boundary: , text "text3" "жжж" -- Box starting outside script boundary: , box "box2" b2 t -- Box continuing over two script boundaries: [ text "text4" "жжжjjjжжж" ] -- Box ending on script boundary: , text "text5" "jjj" ] ) (pack "suffix") where b1 = b_ { boxSpacing = BoxSpacingLeftRight 50 100 } b2 = b_ { boxSpacing = BoxSpacingLeftRight 150 200 } t = tLTR { textFont = font, textLanguage = "zxx" } mixedSizesParagraph :: (Font, Font) -> ParagraphOptions -> Paragraph String mixedSizesParagraph (bigFont, smallFont) = constructParagraph (pack "prefix") (rootBox tBig [ text "bigText1" "big " , box "smallBox1" b_ tSmall [ text "smallText1" "small " ] , text "bigText2" "big " , box "smallBox2" b_ tSmall [ text "smallText2" "small " ] , text "bigText3" "big" ] ) (pack "suffix") where tBig = tLTR { textFont = bigFont, textLanguage = "en" } tSmall = tLTR { textFont = smallFont, textLanguage = "en" } mixedVerticalAlignmentParagraph :: Font -> ParagraphOptions -> Paragraph String mixedVerticalAlignmentParagraph font = constructParagraph (pack "prefix") (rootBox t -- Testing raised baselines. [ text "base" "up " , box "+9" (bRaise 9) t [ text "base+9" "high " , box "+6" (bRaise 6) t [ text "base+9+6" "and " , box "+2" (bRaise 2) t [ text "base+9+6+2" "higher " ] ] ] -- Testing lowered baselines. , text "base" "down " , box "-9" (bLower 9) t [ text "base-9" "low " , box "-6" (bLower 6) t [ text "base-9-6" "and " , box "-2" (bLower 2) t [ text "base-9-6-2" "lower " ] ] ] -- Line-aligned boxes should ignore their baseline-aligned parent. -- -- Setting line height to zero should make approximately half -- of the glyph (at the midpoint between ascender and descender) -- overflow the line. -- -- The parent should not affect layout unless it happens to be tall -- enough to stretch the line. , box "redundant" bBaseline (t { textLineHeight = Absolute 70 }) [ box "(h0)top" bTop (t { textLineHeight = Absolute 0 }) [ text "(h0)top" "X " ] , box "(h0)bottom" bBottom (t { textLineHeight = Absolute 0 }) [ text "(h0)bottom" "X " ] ] -- Stretch the line more upwards than downwards, so that -- top-aligned boxes will be placed higher than any other boxes. , text "base" "stretching " , box "(h72)+9" (bRaise 9) (t { textLineHeight = Absolute 72 }) [ text "(h72)base+9" "tall " ] -- Test line-top alignment with a subtree. , box "top" bTop t [ box "+12" (bRaise 12) t [ text "top+12" "climax " ] , text "top" "preceding " ] -- Test line-bottom alignment, which should exclude other line-relative -- aligned boxes from its subtree. , box "bottom" bBottom t [ box "top" bTop t [ text "bottom+top" "the " ] , text "bottom" "crash " ] ] ) (pack "suffix") where bTop = b_ { boxVerticalAlignment = AlignLineTop } bRaise x = b_ { boxVerticalAlignment = AlignBaseline x } bBaseline = b_ { boxVerticalAlignment = AlignBaseline 0 } bLower x = b_ { boxVerticalAlignment = AlignBaseline (-x) } bBottom = b_ { boxVerticalAlignment = AlignLineBottom } t = tLTR { textFont = font, textLanguage = "en" } nestedBoxesParagraph :: Font -> ParagraphOptions -> Paragraph String nestedBoxesParagraph font = constructParagraph (pack "prefix") (rootBox t [ text "text1" "this paragraph has " , box "box2" b_ t [ box "box3" b_ t [ text "text2" "nested " ] , text "text3" "boxes" ] ] ) (pack "suffix") where t = tLTR { textFont = font, textLanguage = "en" } -- | A paragraph that contains only characters in the BiDi class -- /Other neutrals (ON)/. This includes characters that can be mirrored. neutralDirectionParagraph :: Direction -> Font -> ParagraphOptions -> Paragraph String neutralDirectionParagraph dir font = constructParagraph (pack "_»") (rootBox t [text "text" "…―>"]) (pack "*†") where t = (defaultTextOptions dir) { textFont = font, textLanguage = "zxx" } newline1Paragraph :: Font -> ParagraphOptions -> Paragraph String newline1Paragraph font = constructParagraph (pack "prefix") (rootBox t [ text "text" "\n" ]) (pack "suffix") where t = tRTL { textFont = font, textLanguage = "zxx" } newline1TextParagraph :: Font -> ParagraphOptions -> Paragraph String newline1TextParagraph font = constructParagraph (pack "prefix") (rootBox t [ text "text" "\nt" ]) (pack "suffix") where t = tRTL { textFont = font, textLanguage = "zxx" } newline2Paragraph :: Font -> ParagraphOptions -> Paragraph String newline2Paragraph font = constructParagraph (pack "prefix") (rootBox t [ text "text" "\n\n" ]) (pack "suffix") where t = tRTL { textFont = font, textLanguage = "zxx" } newline2TextParagraph :: Font -> ParagraphOptions -> Paragraph String newline2TextParagraph font = constructParagraph (pack "prefix") (rootBox t [ text "text" "\n\nt" ]) (pack "suffix") where t = tRTL { textFont = font, textLanguage = "zxx" } offsetMiddleInnerTextParagraph :: Int32 -> Font -> ParagraphOptions -> Paragraph String offsetMiddleInnerTextParagraph offset font = constructParagraph (pack "zero ") (rootBox t [ box "box" b t [ text "inner" "three" ] ] ) (pack " six") where b = b_ { boxVerticalAlignment = AlignBaseline offset } t = tLTR { textFont = font, textLanguage = "en" } offsetMiddleOuterTextParagraph :: Int32 -> Font -> ParagraphOptions -> Paragraph String offsetMiddleOuterTextParagraph offset font = constructParagraph (pack "zero ") (rootBox t [ text "outer start" "one two " , box "box" b t -- API requires empty text to preserve the inner box. [ text "inner" "" ] , text "outer end" " four five" ] ) (pack " six") where b = b_ { boxVerticalAlignment = AlignBaseline offset } t = tLTR { textFont = font, textLanguage = "en" } offsetTextlessBoxParagraph :: Int32 -> Font -> ParagraphOptions -> Paragraph String offsetTextlessBoxParagraph offset font = constructParagraph (pack "prefix") (rootBox t [ text "outer" "out " , box "textless box" b1 t [ box "text box" b2 t [ text "inner" "in" ] ] ] ) (pack "suffix") where b1 = b_ { boxVerticalAlignment = AlignBaseline offset } b2 = b_ { boxVerticalAlignment = AlignLineBottom } t = tLTR { textFont = font, textLanguage = "en" } softBreakParagraph :: Int32 -> Font -> ParagraphOptions -> Paragraph String softBreakParagraph spacing font = constructParagraph (pack "prefix") (rootBox t [ text "text1" "Lorem " , text "text2" "ipsum " , box "box2" b t [ text "text3" "dolor " , text "text4" "sit " , text "text5" "amet," ] ] ) (pack "suffix") where b = b_ { boxSpacing = BoxSpacingLeftRight spacing spacing } t = tLTR { textFont = font, textLanguage = "en" } spaceBoxParagraph :: BoxCollapse -> Font -> ParagraphOptions -> Paragraph String spaceBoxParagraph collapse font = constructParagraph (pack "prefix") (rootBox t [ text "text1" "space" , box "box1" b t [ text "text2" " " ] , text "text3" "box" ] ) (pack "suffix") where b = b_ { boxCollapse = collapse , boxSpacing = BoxSpacingLeftRight 50 100 } t = tLTR { textFont = font, textLanguage = "en" }