A .golden/richParagraphLayout/offsetMiddleDownInnerText.golden => .golden/richParagraphLayout/offsetMiddleDownInnerText.golden +25 -0
@@ 0,0 1,25 @@
+ParagraphLayout
+ { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 2477, y_size = -1621}
+ , paragraphLines =
+ [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 2477, y_size = -1621}}
+ ]
+ , paragraphFragments =
+ [ Fragment
+ { fragmentUserData = "inner"
+ , fragmentLine = 1
+ , fragmentAncestorBoxes =
+ [ AncestorBox {boxUserData = "box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}
+ ]
+ , fragmentContentRect = Rect {x_origin = 0, y_origin = -500, x_size = 2477, y_size = -1121}
+ , fragmentRect = Rect {x_origin = 0, y_origin = -500, x_size = 2477, y_size = -1121}
+ , fragmentPen = (0, -932)
+ , fragmentGlyphs =
+ [ (GlyphInfo {codepoint = 87, cluster = 5, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 402, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 75, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 571, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 85, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 72, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 72, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})
+ ]
+ }
+ ]
+ }
A .golden/richParagraphLayout/offsetMiddleDownOuterText.golden => .golden/richParagraphLayout/offsetMiddleDownOuterText.golden +59 -0
@@ 0,0 1,59 @@
+ParagraphLayout
+ { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 8030, y_size = -1621}
+ , paragraphLines =
+ [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 8030, y_size = -1621}}
+ ]
+ , paragraphFragments =
+ [ Fragment
+ { fragmentUserData = "outer start"
+ , fragmentLine = 1
+ , fragmentAncestorBoxes =
+ []
+ , fragmentContentRect = Rect {x_origin = 0, y_origin = 0, x_size = 3942, y_size = -1121}
+ , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 3942, y_size = -1121}
+ , fragmentPen = (0, -932)
+ , fragmentGlyphs =
+ [ (GlyphInfo {codepoint = 82, cluster = 5, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 590, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 81, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 72, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 3, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 87, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 402, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 90, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 765, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 82, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 590, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 3, cluster = 12, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})
+ ]
+ }
+ , Fragment
+ { fragmentUserData = "inner"
+ , fragmentLine = 1
+ , fragmentAncestorBoxes =
+ [ AncestorBox {boxUserData = "box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}
+ ]
+ , fragmentContentRect = Rect {x_origin = 3942, y_origin = -500, x_size = 0, y_size = -1121}
+ , fragmentRect = Rect {x_origin = 3942, y_origin = -500, x_size = 0, y_size = -1121}
+ , fragmentPen = (0, -932)
+ , fragmentGlyphs =
+ []
+ }
+ , Fragment
+ { fragmentUserData = "outer end"
+ , fragmentLine = 1
+ , fragmentAncestorBoxes =
+ []
+ , fragmentContentRect = Rect {x_origin = 3942, y_origin = 0, x_size = 4088, y_size = -1121}
+ , fragmentRect = Rect {x_origin = 3942, y_origin = 0, x_size = 4088, y_size = -1121}
+ , fragmentPen = (0, -932)
+ , fragmentGlyphs =
+ [ (GlyphInfo {codepoint = 3, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 73, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 82, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 590, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 88, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 85, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 3, cluster = 18, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 428, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 643, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 89, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 488, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 72, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})
+ ]
+ }
+ ]
+ }
A .golden/richParagraphLayout/offsetMiddleUpInnerText.golden => .golden/richParagraphLayout/offsetMiddleUpInnerText.golden +25 -0
@@ 0,0 1,25 @@
+ParagraphLayout
+ { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 2477, y_size = -1621}
+ , paragraphLines =
+ [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 2477, y_size = -1621}}
+ ]
+ , paragraphFragments =
+ [ Fragment
+ { fragmentUserData = "inner"
+ , fragmentLine = 1
+ , fragmentAncestorBoxes =
+ [ AncestorBox {boxUserData = "box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}
+ ]
+ , fragmentContentRect = Rect {x_origin = 0, y_origin = 0, x_size = 2477, y_size = -1121}
+ , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 2477, y_size = -1121}
+ , fragmentPen = (0, -932)
+ , fragmentGlyphs =
+ [ (GlyphInfo {codepoint = 87, cluster = 5, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 402, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 75, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 571, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 85, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 72, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 72, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})
+ ]
+ }
+ ]
+ }
A .golden/richParagraphLayout/offsetMiddleUpOuterText.golden => .golden/richParagraphLayout/offsetMiddleUpOuterText.golden +59 -0
@@ 0,0 1,59 @@
+ParagraphLayout
+ { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 8030, y_size = -1621}
+ , paragraphLines =
+ [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 8030, y_size = -1621}}
+ ]
+ , paragraphFragments =
+ [ Fragment
+ { fragmentUserData = "outer start"
+ , fragmentLine = 1
+ , fragmentAncestorBoxes =
+ []
+ , fragmentContentRect = Rect {x_origin = 0, y_origin = -500, x_size = 3942, y_size = -1121}
+ , fragmentRect = Rect {x_origin = 0, y_origin = -500, x_size = 3942, y_size = -1121}
+ , fragmentPen = (0, -932)
+ , fragmentGlyphs =
+ [ (GlyphInfo {codepoint = 82, cluster = 5, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 590, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 81, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 72, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 3, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 87, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 402, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 90, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 765, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 82, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 590, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 3, cluster = 12, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})
+ ]
+ }
+ , Fragment
+ { fragmentUserData = "inner"
+ , fragmentLine = 1
+ , fragmentAncestorBoxes =
+ [ AncestorBox {boxUserData = "box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}
+ ]
+ , fragmentContentRect = Rect {x_origin = 3942, y_origin = 0, x_size = 0, y_size = -1121}
+ , fragmentRect = Rect {x_origin = 3942, y_origin = 0, x_size = 0, y_size = -1121}
+ , fragmentPen = (0, -932)
+ , fragmentGlyphs =
+ []
+ }
+ , Fragment
+ { fragmentUserData = "outer end"
+ , fragmentLine = 1
+ , fragmentAncestorBoxes =
+ []
+ , fragmentContentRect = Rect {x_origin = 3942, y_origin = -500, x_size = 4088, y_size = -1121}
+ , fragmentRect = Rect {x_origin = 3942, y_origin = -500, x_size = 4088, y_size = -1121}
+ , fragmentPen = (0, -932)
+ , fragmentGlyphs =
+ [ (GlyphInfo {codepoint = 3, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 73, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 82, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 590, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 88, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 85, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 3, cluster = 18, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 428, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 643, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 89, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 488, y_advance = 0, x_offset = 0, y_offset = 0})
+ , (GlyphInfo {codepoint = 72, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})
+ ]
+ }
+ ]
+ }
M test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs => test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs +35 -0
@@ 16,6 16,8 @@ module Data.Text.ParagraphLayout.Rich.ParagraphData
, newline1TextParagraph
, newline2Paragraph
, newline2TextParagraph
+ , offsetMiddleInnerTextParagraph
+ , offsetMiddleOuterTextParagraph
, softBreakParagraph
, spaceBoxParagraph
)
@@ 396,6 398,39 @@ newline2TextParagraph font = constructParagraph
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" }
+
softBreakParagraph :: Int32 -> Font -> ParagraphOptions -> Paragraph String
softBreakParagraph spacing font = constructParagraph
(pack "prefix")
M test/Data/Text/ParagraphLayout/RichSpec.hs => test/Data/Text/ParagraphLayout/RichSpec.hs +29 -0
@@ 173,6 173,35 @@ spec = do
let result = layoutRich input
result `shouldBeGolden` "mixedLineHeightBaseline3"
+ describe "offset middle baseline" $ do
+ -- TODO: also test interaction with line wrapping
+ -- TODO: also test struts for inline boxes with children
+ -- FIXME: prevent vertical trimming of paragraphs
+ let opts = defaultParagraphOptions
+ { paragraphAlignment = AlignStart
+ , paragraphMaxWidth = largeWidth
+ }
+
+ it "root strut extends line downwards" $ do
+ let input = offsetMiddleInnerTextParagraph 500 font opts
+ let result = layoutRich input
+ result `shouldBeGolden` "offsetMiddleUpInnerText"
+
+ it "root strut extends line upwards" $ do
+ let input = offsetMiddleInnerTextParagraph (-500) font opts
+ let result = layoutRich input
+ result `shouldBeGolden` "offsetMiddleDownInnerText"
+
+ it "inline box strut extends line upwards" $ do
+ let input = offsetMiddleOuterTextParagraph 500 font opts
+ let result = layoutRich input
+ result `shouldBeGolden` "offsetMiddleUpOuterText"
+
+ it "inline box strut extends line downwards" $ do
+ let input = offsetMiddleOuterTextParagraph (-500) font opts
+ let result = layoutRich input
+ result `shouldBeGolden` "offsetMiddleDownOuterText"
+
it "handles mixed sizes" $ do
let opts = defaultParagraphOptions
{ paragraphAlignment = AlignStart