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: <https://www.w3.org/TR/css-text-3/#word-break-shaping>
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: <https://www.lipsum.com/>
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" }