packages feed

balkon 1.2.0.0 → 1.3.0.0

raw patch · 64 files changed

+2805/−440 lines, 64 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Data.Text.ParagraphLayout.Rich: AlignBaseline :: Int32 -> VerticalAlignment
+ Data.Text.ParagraphLayout.Rich: AlignLineBottom :: VerticalAlignment
+ Data.Text.ParagraphLayout.Rich: AlignLineTop :: VerticalAlignment
+ Data.Text.ParagraphLayout.Rich: Line :: Int -> Rect Int32 -> Line
+ Data.Text.ParagraphLayout.Rich: [lineNumber] :: Line -> Int
+ Data.Text.ParagraphLayout.Rich: [lineRect] :: Line -> Rect Int32
+ Data.Text.ParagraphLayout.Rich: [paragraphLines] :: ParagraphLayout d -> [Line]
+ Data.Text.ParagraphLayout.Rich: boxVerticalAlignment :: BoxOptions -> VerticalAlignment
+ Data.Text.ParagraphLayout.Rich: data Line
+ Data.Text.ParagraphLayout.Rich: data VerticalAlignment
+ Data.Text.ParagraphLayout.Rich: textAscender :: TextOptions -> Maybe Int32
+ Data.Text.ParagraphLayout.Rich: textDescender :: TextOptions -> Maybe Int32
- Data.Text.ParagraphLayout.Rich: ParagraphLayout :: Rect Int32 -> [Fragment d] -> ParagraphLayout d
+ Data.Text.ParagraphLayout.Rich: ParagraphLayout :: Rect Int32 -> [Line] -> [Fragment d] -> ParagraphLayout d

Files

.golden/paginatedRichParagraphLayout/loremIpsum20em.golden view
@@ -1,5 +1,9 @@ [ (Continue, ParagraphLayout-    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 18310, y_size = -2242}+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 19791, y_size = -2242}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 19791, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"@@ -105,6 +109,14 @@ ) , (Continue, ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 19791, y_size = -6726}+    , paragraphLines =+        [ Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 0, y_origin = -2242, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 0, y_origin = -3363, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 7, lineRect = Rect {x_origin = 0, y_origin = -4484, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 8, lineRect = Rect {x_origin = 0, y_origin = -5605, x_size = 19791, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"@@ -426,7 +438,12 @@     } ) , (Continue, ParagraphLayout-    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 19199, y_size = -3363}+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 19791, y_size = -3363}+    , paragraphLines =+        [ Line {lineNumber = 9, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 10, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 11, lineRect = Rect {x_origin = 0, y_origin = -2242, x_size = 19791, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/emptyBoxMiddle.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 5193, y_size = -1121}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 5193, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text1"
.golden/richParagraphLayout/hardBoxBreakLTR.golden view
@@ -1,5 +1,9 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 5855, y_size = -2242}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 5855, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 5855, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text1"
.golden/richParagraphLayout/hardBoxBreakRTL.golden view
@@ -1,5 +1,9 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 999996545, y_origin = 0, x_size = 3455, y_size = -3000}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 999996545, y_origin = 0, x_size = 3455, y_size = -1500}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 999996545, y_origin = -1500, x_size = 3455, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text2"
.golden/richParagraphLayout/loremIpsum20em.golden view
@@ -1,5 +1,18 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 19791, y_size = -12331}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -2242, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -3363, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 0, y_origin = -4484, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 0, y_origin = -5605, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 7, lineRect = Rect {x_origin = 0, y_origin = -6726, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 8, lineRect = Rect {x_origin = 0, y_origin = -7847, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 9, lineRect = Rect {x_origin = 0, y_origin = -8968, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 10, lineRect = Rect {x_origin = 0, y_origin = -10089, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 11, lineRect = Rect {x_origin = 0, y_origin = -11210, x_size = 19791, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/loremIpsum20emCentre.golden view
@@ -1,5 +1,18 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 104, y_origin = 0, x_size = 19791, y_size = -12331}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 104, y_origin = 0, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 104, y_origin = -1121, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 104, y_origin = -2242, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 104, y_origin = -3363, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 104, y_origin = -4484, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 104, y_origin = -5605, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 7, lineRect = Rect {x_origin = 104, y_origin = -6726, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 8, lineRect = Rect {x_origin = 104, y_origin = -7847, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 9, lineRect = Rect {x_origin = 104, y_origin = -8968, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 10, lineRect = Rect {x_origin = 104, y_origin = -10089, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 11, lineRect = Rect {x_origin = 104, y_origin = -11210, x_size = 19791, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/loremIpsum20emRight.golden view
@@ -1,5 +1,18 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 209, y_origin = 0, x_size = 19791, y_size = -12331}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 209, y_origin = 0, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 209, y_origin = -1121, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 209, y_origin = -2242, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 209, y_origin = -3363, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 209, y_origin = -4484, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 209, y_origin = -5605, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 7, lineRect = Rect {x_origin = 209, y_origin = -6726, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 8, lineRect = Rect {x_origin = 209, y_origin = -7847, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 9, lineRect = Rect {x_origin = 209, y_origin = -8968, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 10, lineRect = Rect {x_origin = 209, y_origin = -10089, x_size = 19791, y_size = -1121}}+        , Line {lineNumber = 11, lineRect = Rect {x_origin = 209, y_origin = -11210, x_size = 19791, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/mixedDirectionComplexLTR.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 24557, y_size = -1500}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 24557, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text1"
.golden/richParagraphLayout/mixedDirectionComplexRTL.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 999975443, y_origin = 0, x_size = 24557, y_size = -1500}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 999975443, y_origin = 0, x_size = 24557, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text3"
.golden/richParagraphLayout/mixedDirectionSimpleLTR.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 7954, y_size = -1500}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 7954, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/mixedDirectionSimpleRTL.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 999992046, y_origin = 0, x_size = 7954, y_size = -1500}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 999992046, y_origin = 0, x_size = 7954, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
− .golden/richParagraphLayout/mixedLineHeight.golden
@@ -1,306 +0,0 @@-ParagraphLayout-    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 16708, y_size = -9400}-    , paragraphFragments =-        [ Fragment-            { fragmentUserData = "mediumText"-            , fragmentLine = 1-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 0, y_origin = -90, x_size = 3928, y_size = -1121}-            , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 3928, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 80, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = 71, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 76, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 88, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = "smallText"-            , fragmentLine = 1-            , fragmentAncestorBoxes =-                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}-                ]-            , fragmentContentRect = Rect {x_origin = 3928, y_origin = 160, x_size = 2606, y_size = -1121}-            , fragmentRect = Rect {x_origin = 3928, y_origin = 0, x_size = 2606, y_size = -800}-            , fragmentPen = (0, -772)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 86, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 68, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 79, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 79, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, 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})-                ]-            }-        , Fragment-            { fragmentUserData = "mediumText"-            , fragmentLine = 1-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -90, x_size = 3928, y_size = -1121}-            , fragmentRect = Rect {x_origin = 6534, y_origin = 0, x_size = 3928, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 80, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 72, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 71, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 76, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 88, cluster = 23, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 3, cluster = 25, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "largeText"-            , fragmentLine = 1-            , fragmentAncestorBoxes =-                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}-                ]-            , fragmentContentRect = Rect {x_origin = 10462, y_origin = -290, x_size = 2549, y_size = -1121}-            , fragmentRect = Rect {x_origin = 10462, y_origin = 0, x_size = 2549, y_size = -1700}-            , fragmentPen = (0, -1222)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 79, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 68, cluster = 27, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 85, cluster = 28, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 74, cluster = 29, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 72, cluster = 30, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 3, cluster = 31, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "mediumText"-            , fragmentLine = 1-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 13011, y_origin = -90, x_size = 3697, y_size = -1121}-            , fragmentRect = Rect {x_origin = 13011, y_origin = 0, x_size = 3697, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 80, cluster = 32, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 72, cluster = 33, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 71, cluster = 34, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 76, cluster = 35, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 88, cluster = 36, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 37, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "lineBreak"-            , fragmentLine = 1-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 16708, y_origin = -90, x_size = 0, y_size = -1121}-            , fragmentRect = Rect {x_origin = 16708, y_origin = 0, x_size = 0, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                []-            }-        , Fragment-            { fragmentUserData = "smallText"-            , fragmentLine = 2-            , fragmentAncestorBoxes =-                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}-                ]-            , fragmentContentRect = Rect {x_origin = 0, y_origin = -1540, x_size = 2606, y_size = -1121}-            , fragmentRect = Rect {x_origin = 0, y_origin = -1700, x_size = 2606, y_size = -800}-            , fragmentPen = (0, -772)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 86, cluster = 40, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 41, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 68, cluster = 42, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 79, cluster = 43, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 79, cluster = 44, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 3, cluster = 45, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "mediumText"-            , fragmentLine = 2-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 2606, y_origin = -1790, x_size = 3928, y_size = -1121}-            , fragmentRect = Rect {x_origin = 2606, y_origin = -1700, x_size = 3928, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 80, cluster = 46, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 72, cluster = 47, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 71, cluster = 48, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 76, cluster = 49, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 88, cluster = 50, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 51, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 3, cluster = 52, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "largeText"-            , fragmentLine = 2-            , fragmentAncestorBoxes =-                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}-                ]-            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -1990, x_size = 2318, y_size = -1121}-            , fragmentRect = Rect {x_origin = 6534, y_origin = -1700, x_size = 2318, y_size = -1700}-            , fragmentPen = (0, -1222)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 79, cluster = 53, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 68, cluster = 54, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 85, cluster = 55, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 74, cluster = 56, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 72, cluster = 57, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "lineBreak"-            , fragmentLine = 2-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 8852, y_origin = -1790, x_size = 0, y_size = -1121}-            , fragmentRect = Rect {x_origin = 8852, y_origin = -1700, x_size = 0, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                []-            }-        , Fragment-            { fragmentUserData = "mediumText"-            , fragmentLine = 3-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 0, y_origin = -3490, x_size = 3928, y_size = -1121}-            , fragmentRect = Rect {x_origin = 0, y_origin = -3400, x_size = 3928, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 80, cluster = 60, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 72, cluster = 61, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 71, cluster = 62, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 76, cluster = 63, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 88, cluster = 64, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 65, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 3, cluster = 66, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "smallText"-            , fragmentLine = 3-            , fragmentAncestorBoxes =-                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}-                ]-            , fragmentContentRect = Rect {x_origin = 3928, y_origin = -3240, x_size = 2375, y_size = -1121}-            , fragmentRect = Rect {x_origin = 3928, y_origin = -3400, x_size = 2375, y_size = -800}-            , fragmentPen = (0, -772)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 86, cluster = 67, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 68, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 68, cluster = 69, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 79, cluster = 70, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 79, cluster = 71, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "lineBreak"-            , fragmentLine = 3-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 6303, y_origin = -3490, x_size = 0, y_size = -1121}-            , fragmentRect = Rect {x_origin = 6303, y_origin = -3400, x_size = 0, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                []-            }-        , Fragment-            { fragmentUserData = "largeText"-            , fragmentLine = 4-            , fragmentAncestorBoxes =-                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}-                ]-            , fragmentContentRect = Rect {x_origin = 0, y_origin = -4990, x_size = 2549, y_size = -1121}-            , fragmentRect = Rect {x_origin = 0, y_origin = -4700, x_size = 2549, y_size = -1700}-            , fragmentPen = (0, -1222)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 79, cluster = 74, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 68, cluster = 75, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 85, cluster = 76, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 74, cluster = 77, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 72, cluster = 78, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 3, cluster = 79, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "mediumText"-            , fragmentLine = 4-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 2549, y_origin = -4790, x_size = 3697, y_size = -1121}-            , fragmentRect = Rect {x_origin = 2549, y_origin = -4700, x_size = 3697, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 80, cluster = 80, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 72, cluster = 81, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 71, cluster = 82, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 76, cluster = 83, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 88, cluster = 84, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 85, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "lineBreak"-            , fragmentLine = 4-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 6246, y_origin = -4790, x_size = 0, y_size = -1121}-            , fragmentRect = Rect {x_origin = 6246, y_origin = -4700, x_size = 0, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                []-            }-        , Fragment-            { fragmentUserData = "smallText"-            , fragmentLine = 5-            , fragmentAncestorBoxes =-                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}-                ]-            , fragmentContentRect = Rect {x_origin = 0, y_origin = -6240, x_size = 2375, y_size = -1121}-            , fragmentRect = Rect {x_origin = 0, y_origin = -6400, x_size = 2375, y_size = -800}-            , fragmentPen = (0, -772)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 86, cluster = 88, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 80, cluster = 89, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 68, cluster = 90, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 79, cluster = 91, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 79, cluster = 92, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        , Fragment-            { fragmentUserData = "lineBreak"-            , fragmentLine = 5-            , fragmentAncestorBoxes =-                []-            , fragmentContentRect = Rect {x_origin = 2375, y_origin = -6490, x_size = 0, y_size = -1121}-            , fragmentRect = Rect {x_origin = 2375, y_origin = -6400, x_size = 0, y_size = -1300}-            , fragmentPen = (0, -1022)-            , fragmentGlyphs =-                []-            }-        , Fragment-            { fragmentUserData = "largeText"-            , fragmentLine = 6-            , fragmentAncestorBoxes =-                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}-                ]-            , fragmentContentRect = Rect {x_origin = 0, y_origin = -7990, x_size = 2318, y_size = -1121}-            , fragmentRect = Rect {x_origin = 0, y_origin = -7700, x_size = 2318, y_size = -1700}-            , fragmentPen = (0, -1222)-            , fragmentGlyphs =-                [ (GlyphInfo {codepoint = 79, cluster = 95, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 68, cluster = 96, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 85, cluster = 97, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 74, cluster = 98, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})-                , (GlyphInfo {codepoint = 72, cluster = 99, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})-                ]-            }-        ]-    }
+ .golden/richParagraphLayout/mixedLineHeightBaseline.golden view
@@ -0,0 +1,314 @@+ParagraphLayout+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 16708, y_size = -9400}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1700, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -3400, x_size = 16708, y_size = -1300}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -4700, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 0, y_origin = -6400, x_size = 16708, y_size = -1300}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 0, y_origin = -7700, x_size = 16708, y_size = -1700}}+        ]+    , paragraphFragments =+        [ Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -290, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -200, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = 71, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = "smallText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 3928, y_origin = -290, x_size = 2606, y_size = -1121}+            , fragmentRect = Rect {x_origin = 3928, y_origin = -450, x_size = 2606, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, 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})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -290, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6534, y_origin = -200, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 23, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 25, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 10462, y_origin = -290, x_size = 2549, y_size = -1121}+            , fragmentRect = Rect {x_origin = 10462, y_origin = 0, x_size = 2549, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 27, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 28, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 29, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 30, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 31, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 13011, y_origin = -290, x_size = 3697, y_size = -1121}+            , fragmentRect = Rect {x_origin = 13011, y_origin = -200, x_size = 3697, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 32, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 33, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 34, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 35, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 36, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 37, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 16708, y_origin = -290, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 16708, y_origin = -200, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -1990, x_size = 2606, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -2150, x_size = 2606, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 40, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 41, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 42, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 43, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 44, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 45, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2606, y_origin = -1990, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2606, y_origin = -1900, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 46, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 47, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 48, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 49, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 50, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 51, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 52, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -1990, x_size = 2318, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6534, y_origin = -1700, x_size = 2318, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 53, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 54, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 55, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 56, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 57, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 8852, y_origin = -1990, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 8852, y_origin = -1900, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -3490, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -3400, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 60, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 61, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 62, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 63, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 64, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 65, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 66, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 3928, y_origin = -3490, x_size = 2375, y_size = -1121}+            , fragmentRect = Rect {x_origin = 3928, y_origin = -3650, x_size = 2375, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 67, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 68, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 69, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 70, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 71, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6303, y_origin = -3490, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6303, y_origin = -3400, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -4990, x_size = 2549, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -4700, x_size = 2549, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 74, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 75, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 76, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 77, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 78, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 79, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2549, y_origin = -4990, x_size = 3697, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2549, y_origin = -4900, x_size = 3697, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 80, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 81, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 82, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 83, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 84, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 85, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6246, y_origin = -4990, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6246, y_origin = -4900, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 5+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -6490, x_size = 2375, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -6650, x_size = 2375, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 88, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 89, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 90, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 91, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 92, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 5+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2375, y_origin = -6490, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2375, y_origin = -6400, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 6+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -7990, x_size = 2318, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -7700, x_size = 2318, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 95, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 96, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 97, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 98, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 99, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/mixedLineHeightBaseline3.golden view
@@ -0,0 +1,314 @@+ParagraphLayout+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 16708, y_size = -9400}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1700, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -3400, x_size = 16708, y_size = -1300}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -4700, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 0, y_origin = -6400, x_size = 16708, y_size = -1300}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 0, y_origin = -7700, x_size = 16708, y_size = -1700}}+        ]+    , paragraphFragments =+        [ Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -293, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -203, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = 71, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = "smallText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 3928, y_origin = -290, x_size = 2606, y_size = -1121}+            , fragmentRect = Rect {x_origin = 3928, y_origin = -450, x_size = 2606, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, 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})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -293, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6534, y_origin = -203, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 23, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 25, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 10462, y_origin = -290, x_size = 2549, y_size = -1121}+            , fragmentRect = Rect {x_origin = 10462, y_origin = 0, x_size = 2549, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 27, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 28, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 29, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 30, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 31, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 13011, y_origin = -293, x_size = 3697, y_size = -1121}+            , fragmentRect = Rect {x_origin = 13011, y_origin = -203, x_size = 3697, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 32, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 33, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 34, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 35, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 36, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 37, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 16708, y_origin = -293, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 16708, y_origin = -203, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -1990, x_size = 2606, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -2150, x_size = 2606, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 40, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 41, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 42, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 43, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 44, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 45, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2606, y_origin = -1993, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2606, y_origin = -1903, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 46, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 47, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 48, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 49, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 50, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 51, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 52, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -1990, x_size = 2318, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6534, y_origin = -1700, x_size = 2318, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 53, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 54, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 55, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 56, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 57, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 8852, y_origin = -1993, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 8852, y_origin = -1903, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -3490, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -3400, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 60, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 61, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 62, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 63, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 64, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 65, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 66, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 3928, y_origin = -3487, x_size = 2375, y_size = -1121}+            , fragmentRect = Rect {x_origin = 3928, y_origin = -3647, x_size = 2375, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 67, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 68, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 69, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 70, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 71, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6303, y_origin = -3490, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6303, y_origin = -3400, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -4990, x_size = 2549, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -4700, x_size = 2549, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 74, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 75, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 76, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 77, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 78, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 79, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2549, y_origin = -4993, x_size = 3697, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2549, y_origin = -4903, x_size = 3697, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 80, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 81, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 82, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 83, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 84, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 85, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6246, y_origin = -4993, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6246, y_origin = -4903, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 5+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -6487, x_size = 2375, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -6647, x_size = 2375, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 88, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 89, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 90, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 91, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 92, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 5+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2375, y_origin = -6490, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2375, y_origin = -6400, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 6+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -7990, x_size = 2318, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -7700, x_size = 2318, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 95, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 96, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 97, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 98, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 99, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/mixedLineHeightBottom.golden view
@@ -0,0 +1,314 @@+ParagraphLayout+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 16708, y_size = -9400}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1700, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -3400, x_size = 16708, y_size = -1300}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -4700, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 0, y_origin = -6400, x_size = 16708, y_size = -1300}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 0, y_origin = -7700, x_size = 16708, y_size = -1700}}+        ]+    , paragraphFragments =+        [ Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -490, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -400, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = 71, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = "smallText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 3928, y_origin = -740, x_size = 2606, y_size = -1121}+            , fragmentRect = Rect {x_origin = 3928, y_origin = -900, x_size = 2606, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, 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})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -490, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6534, y_origin = -400, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 23, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 25, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 10462, y_origin = -290, x_size = 2549, y_size = -1121}+            , fragmentRect = Rect {x_origin = 10462, y_origin = 0, x_size = 2549, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 27, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 28, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 29, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 30, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 31, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 13011, y_origin = -490, x_size = 3697, y_size = -1121}+            , fragmentRect = Rect {x_origin = 13011, y_origin = -400, x_size = 3697, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 32, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 33, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 34, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 35, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 36, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 37, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 16708, y_origin = -490, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 16708, y_origin = -400, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -2440, x_size = 2606, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -2600, x_size = 2606, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 40, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 41, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 42, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 43, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 44, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 45, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2606, y_origin = -2190, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2606, y_origin = -2100, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 46, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 47, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 48, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 49, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 50, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 51, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 52, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -1990, x_size = 2318, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6534, y_origin = -1700, x_size = 2318, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 53, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 54, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 55, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 56, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 57, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 8852, y_origin = -2190, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 8852, y_origin = -2100, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -3490, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -3400, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 60, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 61, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 62, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 63, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 64, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 65, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 66, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 3928, y_origin = -3740, x_size = 2375, y_size = -1121}+            , fragmentRect = Rect {x_origin = 3928, y_origin = -3900, x_size = 2375, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 67, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 68, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 69, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 70, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 71, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6303, y_origin = -3490, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6303, y_origin = -3400, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -4990, x_size = 2549, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -4700, x_size = 2549, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 74, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 75, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 76, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 77, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 78, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 79, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2549, y_origin = -5190, x_size = 3697, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2549, y_origin = -5100, x_size = 3697, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 80, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 81, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 82, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 83, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 84, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 85, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6246, y_origin = -5190, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6246, y_origin = -5100, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 5+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -6740, x_size = 2375, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -6900, x_size = 2375, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 88, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 89, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 90, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 91, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 92, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 5+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2375, y_origin = -6490, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2375, y_origin = -6400, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 6+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -7990, x_size = 2318, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -7700, x_size = 2318, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 95, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 96, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 97, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 98, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 99, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/mixedLineHeightTop.golden view
@@ -0,0 +1,314 @@+ParagraphLayout+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 16708, y_size = -9400}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1700, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -3400, x_size = 16708, y_size = -1300}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -4700, x_size = 16708, y_size = -1700}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 0, y_origin = -6400, x_size = 16708, y_size = -1300}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 0, y_origin = -7700, x_size = 16708, y_size = -1700}}+        ]+    , paragraphFragments =+        [ Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -90, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = 71, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, 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 = "smallText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 3928, y_origin = 160, x_size = 2606, y_size = -1121}+            , fragmentRect = Rect {x_origin = 3928, y_origin = 0, x_size = 2606, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, 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})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -90, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6534, y_origin = 0, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 23, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 25, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 10462, y_origin = -290, x_size = 2549, y_size = -1121}+            , fragmentRect = Rect {x_origin = 10462, y_origin = 0, x_size = 2549, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 27, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 28, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 29, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 30, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 31, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 13011, y_origin = -90, x_size = 3697, y_size = -1121}+            , fragmentRect = Rect {x_origin = 13011, y_origin = 0, x_size = 3697, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 32, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 33, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 34, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 35, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 36, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 37, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 16708, y_origin = -90, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 16708, y_origin = 0, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -1540, x_size = 2606, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -1700, x_size = 2606, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 40, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 41, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 42, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 43, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 44, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 45, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2606, y_origin = -1790, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2606, y_origin = -1700, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 46, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 47, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 48, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 49, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 50, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 51, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 52, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 6534, y_origin = -1990, x_size = 2318, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6534, y_origin = -1700, x_size = 2318, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 53, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 54, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 55, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 56, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 57, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 8852, y_origin = -1790, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 8852, y_origin = -1700, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -3490, x_size = 3928, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -3400, x_size = 3928, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 60, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 61, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 62, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 63, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 64, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 65, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 66, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 3928, y_origin = -3240, x_size = 2375, y_size = -1121}+            , fragmentRect = Rect {x_origin = 3928, y_origin = -3400, x_size = 2375, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 67, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 68, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 69, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 70, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 71, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6303, y_origin = -3490, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6303, y_origin = -3400, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -4990, x_size = 2549, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -4700, x_size = 2549, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 74, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 75, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 76, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 77, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 78, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 79, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 231, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "mediumText"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2549, y_origin = -4790, x_size = 3697, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2549, y_origin = -4700, x_size = 3697, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 80, cluster = 80, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 81, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 71, cluster = 82, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 589, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 76, cluster = 83, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 84, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 85, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 6246, y_origin = -4790, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 6246, y_origin = -4700, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "smallText"+            , fragmentLine = 5+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "smallBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -6240, x_size = 2375, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -6400, x_size = 2375, y_size = -800}+            , fragmentPen = (0, -772)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 86, cluster = 88, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 446, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 80, cluster = 89, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 861, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 90, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 91, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 79, cluster = 92, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        , Fragment+            { fragmentUserData = "lineBreak"+            , fragmentLine = 5+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 2375, y_origin = -6490, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 2375, y_origin = -6400, x_size = 0, y_size = -1300}+            , fragmentPen = (0, -1022)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "largeText"+            , fragmentLine = 6+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "largeBox", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -7990, x_size = 2318, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -7700, x_size = 2318, y_size = -1700}+            , fragmentPen = (0, -1222)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 79, cluster = 95, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 273, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 68, cluster = 96, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 522, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 85, cluster = 97, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 386, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 74, cluster = 98, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 578, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 72, cluster = 99, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 559, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        ]+    }
.golden/richParagraphLayout/mixedScript.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 15283, y_size = -1121}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 15283, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text1"
.golden/richParagraphLayout/mixedScriptWrap.golden view
@@ -1,5 +1,11 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 4897, y_size = -4484}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 4897, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 4897, y_size = -1121}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -2242, x_size = 4897, y_size = -1121}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -3363, x_size = 4897, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text1"
.golden/richParagraphLayout/mixedSizes.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 8634, y_size = -1121}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 8634, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "bigText1"
.golden/richParagraphLayout/nestedBoxes.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 14576, y_size = -1121}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 14576, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text1"
.golden/richParagraphLayout/neutralDirectionLTR.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 2003, y_size = -1500}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 2003, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/neutralDirectionRTL.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 999997997, y_origin = 0, x_size = 2003, y_size = -1500}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 999997997, y_origin = 0, x_size = 2003, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/newline1Paragraph.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 1000000000, y_origin = 0, x_size = 0, y_size = -1500}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 1000000000, y_origin = 0, x_size = 0, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/newline1TextParagraph.golden view
@@ -1,5 +1,9 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 999999649, y_origin = 0, x_size = 351, y_size = -3000}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 999999649, y_origin = 0, x_size = 351, y_size = -1500}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 999999649, y_origin = -1500, x_size = 351, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/newline2Paragraph.golden view
@@ -1,5 +1,9 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 1000000000, y_origin = 0, x_size = 0, y_size = -3000}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 1000000000, y_origin = 0, x_size = 0, y_size = -1500}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 1000000000, y_origin = -1500, x_size = 0, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
.golden/richParagraphLayout/newline2TextParagraph.golden view
@@ -1,5 +1,10 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 999999649, y_origin = 0, x_size = 351, y_size = -4500}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 999999649, y_origin = 0, x_size = 351, y_size = -1500}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 999999649, y_origin = -1500, x_size = 351, y_size = -1500}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 999999649, y_origin = -3000, x_size = 351, y_size = -1500}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text"
+ .golden/richParagraphLayout/offsetMiddleDownInnerText.golden view
@@ -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})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/offsetMiddleDownOuterText.golden view
@@ -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})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/offsetMiddleDownOuterTextWrap.golden view
@@ -0,0 +1,91 @@+ParagraphLayout+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 1936, y_size = -4984}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 1936, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 1936, y_size = -1621}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -2742, x_size = 1936, y_size = -1121}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -3863, x_size = 1936, y_size = -1121}}+        ]+    , paragraphFragments =+        [ Fragment+            { fragmentUserData = "outer start"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = 0, x_size = 1723, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 1723, 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})+                ]+            }+        , Fragment+            { fragmentUserData = "outer start"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -1121, x_size = 1757, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -1121, x_size = 1757, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (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})+                ]+            }+        , Fragment+            { fragmentUserData = "inner"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 1757, y_origin = -1621, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 1757, y_origin = -1621, x_size = 0, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "outer end"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 1757, y_origin = -1121, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 1757, y_origin = -1121, x_size = 0, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "outer end"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -2742, x_size = 1936, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -2742, x_size = 1936, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (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})+                ]+            }+        , Fragment+            { fragmentUserData = "outer end"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -3863, x_size = 1690, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -3863, x_size = 1690, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (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})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/offsetMiddleUpInnerText.golden view
@@ -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})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/offsetMiddleUpOuterText.golden view
@@ -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})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/offsetMiddleUpOuterTextWrap.golden view
@@ -0,0 +1,91 @@+ParagraphLayout+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 1936, y_size = -4984}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 1936, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 1936, y_size = -1621}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -2742, x_size = 1936, y_size = -1121}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -3863, x_size = 1936, y_size = -1121}}+        ]+    , paragraphFragments =+        [ Fragment+            { fragmentUserData = "outer start"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = 0, x_size = 1723, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 1723, 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})+                ]+            }+        , Fragment+            { fragmentUserData = "outer start"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -1621, x_size = 1757, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -1621, x_size = 1757, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (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})+                ]+            }+        , Fragment+            { fragmentUserData = "inner"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                [ AncestorBox {boxUserData = "box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 1757, y_origin = -1121, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 1757, y_origin = -1121, x_size = 0, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "outer end"+            , fragmentLine = 2+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 1757, y_origin = -1621, x_size = 0, y_size = -1121}+            , fragmentRect = Rect {x_origin = 1757, y_origin = -1621, x_size = 0, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                []+            }+        , Fragment+            { fragmentUserData = "outer end"+            , fragmentLine = 3+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -2742, x_size = 1936, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -2742, x_size = 1936, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (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})+                ]+            }+        , Fragment+            { fragmentUserData = "outer end"+            , fragmentLine = 4+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -3863, x_size = 1690, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -3863, x_size = 1690, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (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})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/offsetTextlessBoxDown.golden view
@@ -0,0 +1,38 @@+ParagraphLayout+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 2624, y_size = -1621}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 2624, y_size = -1621}}+        ]+    , paragraphFragments =+        [ Fragment+            { fragmentUserData = "outer"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = 0, x_size = 1797, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 1797, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 82, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 590, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 87, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 402, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 9, 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 = "text box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                , AncestorBox {boxUserData = "textless box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 1797, y_origin = -500, x_size = 827, y_size = -1121}+            , fragmentRect = Rect {x_origin = 1797, y_origin = -500, x_size = 827, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 76, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 81, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        ]+    }
+ .golden/richParagraphLayout/offsetTextlessBoxUp.golden view
@@ -0,0 +1,38 @@+ParagraphLayout+    { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 2624, y_size = -1621}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 2624, y_size = -1621}}+        ]+    , paragraphFragments =+        [ Fragment+            { fragmentUserData = "outer"+            , fragmentLine = 1+            , fragmentAncestorBoxes =+                []+            , fragmentContentRect = Rect {x_origin = 0, y_origin = -500, x_size = 1797, y_size = -1121}+            , fragmentRect = Rect {x_origin = 0, y_origin = -500, x_size = 1797, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 82, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 590, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 88, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 87, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 402, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 3, cluster = 9, 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 = "text box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                , AncestorBox {boxUserData = "textless box", boxLeftEdge = SpacedEdge 0, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = SpacedEdge 0}+                ]+            , fragmentContentRect = Rect {x_origin = 1797, y_origin = -500, x_size = 827, y_size = -1121}+            , fragmentRect = Rect {x_origin = 1797, y_origin = -500, x_size = 827, y_size = -1121}+            , fragmentPen = (0, -932)+            , fragmentGlyphs =+                [ (GlyphInfo {codepoint = 76, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0})+                , (GlyphInfo {codepoint = 81, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 574, y_advance = 0, x_offset = 0, y_offset = 0})+                ]+            }+        ]+    }
.golden/richParagraphLayout/spaceBoxCollapsed.golden view
@@ -1,5 +1,15 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 590, y_size = -8968}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -2242, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -3363, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 0, y_origin = -4484, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 0, y_origin = -5605, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 7, lineRect = Rect {x_origin = 0, y_origin = -6726, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 8, lineRect = Rect {x_origin = 0, y_origin = -7847, x_size = 590, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text1"
.golden/richParagraphLayout/spaceBoxMiddle.golden view
@@ -1,5 +1,8 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 4635, y_size = -1121}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 4635, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text1"
.golden/richParagraphLayout/spaceBoxPreserved.golden view
@@ -1,5 +1,16 @@ ParagraphLayout     { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 590, y_size = -10089}+    , paragraphLines =+        [ Line {lineNumber = 1, lineRect = Rect {x_origin = 0, y_origin = 0, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 2, lineRect = Rect {x_origin = 0, y_origin = -1121, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 3, lineRect = Rect {x_origin = 0, y_origin = -2242, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 4, lineRect = Rect {x_origin = 0, y_origin = -3363, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 5, lineRect = Rect {x_origin = 0, y_origin = -4484, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 6, lineRect = Rect {x_origin = 0, y_origin = -5605, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 7, lineRect = Rect {x_origin = 0, y_origin = -6726, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 8, lineRect = Rect {x_origin = 0, y_origin = -7847, x_size = 590, y_size = -1121}}+        , Line {lineNumber = 9, lineRect = Rect {x_origin = 0, y_origin = -8968, x_size = 590, y_size = -1121}}+        ]     , paragraphFragments =         [ Fragment             { fragmentUserData = "text1"
+ .golden/shapedRuns/mixedVerticalAlignment.fontInfo view
@@ -0,0 +1,1 @@+assets/fonts/ubuntu/Ubuntu-R.ttf 0 32,32 32,32
+ .golden/shapedRuns/mixedVerticalAlignment.golden view
@@ -0,0 +1,117 @@+[ (0, -57, +    [ (GlyphInfo {codepoint = 88, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 83, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 19, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (44, -48, +    [ (GlyphInfo {codepoint = 75, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 76, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 8, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 74, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 75, cluster = 12, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (113, -42, +    [ (GlyphInfo {codepoint = 68, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 17, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 81, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 71, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 19, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (174, -40, +    [ (GlyphInfo {codepoint = 75, cluster = 18, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 76, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 8, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 74, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 75, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 72, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 85, cluster = 23, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 12, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (273, -57, +    [ (GlyphInfo {codepoint = 71, cluster = 25, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 19, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 82, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 19, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 90, cluster = 27, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 25, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 81, cluster = 28, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 29, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (361, -66, +    [ (GlyphInfo {codepoint = 79, cluster = 30, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 9, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 82, cluster = 31, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 19, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 90, cluster = 32, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 25, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 33, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (421, -72, +    [ (GlyphInfo {codepoint = 68, cluster = 34, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 17, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 81, cluster = 35, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 71, cluster = 36, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 19, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 37, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (482, -74, +    [ (GlyphInfo {codepoint = 79, cluster = 38, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 9, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 82, cluster = 39, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 19, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 90, cluster = 40, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 25, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 72, cluster = 41, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 85, cluster = 42, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 12, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 43, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (572, -12, +    [ (GlyphInfo {codepoint = 59, cluster = 44, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 20, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 45, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (599, -92, +    [ (GlyphInfo {codepoint = 59, cluster = 46, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 20, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 47, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (626, -57, +    [ (GlyphInfo {codepoint = 86, cluster = 48, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 14, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 87, cluster = 49, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 13, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 85, cluster = 50, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 12, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 72, cluster = 51, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 87, cluster = 52, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 13, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 70, cluster = 53, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 15, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 75, cluster = 54, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 76, cluster = 55, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 8, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 81, cluster = 56, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 74, cluster = 57, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 58, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (780, -48, +    [ (GlyphInfo {codepoint = 87, cluster = 59, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 13, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 68, cluster = 60, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 17, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 79, cluster = 61, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 9, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 79, cluster = 62, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 9, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 63, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (835, -30, +    [ (GlyphInfo {codepoint = 70, cluster = 64, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 15, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 79, cluster = 65, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 9, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 76, cluster = 66, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 8, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 80, cluster = 67, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 28, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 68, cluster = 68, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 17, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 91, cluster = 69, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 16, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 70, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (935, -42, +    [ (GlyphInfo {codepoint = 83, cluster = 71, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 19, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 85, cluster = 72, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 12, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 72, cluster = 73, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 70, cluster = 74, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 15, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 72, cluster = 75, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 71, cluster = 76, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 19, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 76, cluster = 77, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 8, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 81, cluster = 78, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 74, cluster = 79, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 80, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (1087, -30, +    [ (GlyphInfo {codepoint = 87, cluster = 81, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 13, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 75, cluster = 82, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 72, cluster = 83, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 3, cluster = 84, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 7, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+, (1143, -74, +    [ (GlyphInfo {codepoint = 70, cluster = 85, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 15, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 85, cluster = 86, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 12, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 68, cluster = 87, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 17, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 86, cluster = 88, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 14, y_advance = 0, x_offset = 0, y_offset = 0})+    , (GlyphInfo {codepoint = 75, cluster = 89, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})+    ])+]
CHANGELOG.md view
@@ -1,5 +1,29 @@ # Revision history for Balkón +## 1.3.0.0 -- 2023-07-03++* Added options for vertical box alignment:+  line top, line bottom, baseline with optional offset.++    * For backwards compatibility, line top alignment remains the default.+      Consider updating your code to use baseline alignment instead.++* Added `paragraphLines` to the rich text `ParagraphLayout`.+  This describes the dimensions of each line of wrapped text,+  including situations when the line contains more space than+  what is necessary to contain its fragments.+  This new field must be passed to pagination.++* The width of a rich text `ParagraphLayout` will now remain unchanged+  after pagination.++* Lines will now be sized to fit all ancestor boxes of all fragments+  on the line, as well as the root box, even if some of those boxes+  do not directly contain any text.+  Each box effectively contains an invisible "strut", which is required by CSS.++* Added options to override text ascender and descender metrics.+ ## 1.2.0.0 -- 2023-06-28  * Added options for horizontal paragraph alignment:
TESTING.md view
@@ -150,3 +150,71 @@          of blank space below the top of the window that is not large enough to          insert another line of text. +## Script 4: Verify visual output for vertical alignment++Goals:++  - To verify the correct effect of vertical alignment of inline boxes.++Prerequisites:++  - Access to files from the Git repository of Balkón.++  - Successfully built Typograffiti.+    See previous script.++  - Successfully verified visual output for a whole paragraph.+    See previous script.++  - A horizontal on-screen ruler to check baseline alignment.+    In a stacking window manager, the edge of another window can+    fulfil this role.++Steps:++  1. Run Typograffiti with the font path, face index, pixel size,+     and scale set according to the contents of the file+     `.golden/shapedRuns/mixedVerticalAlignment.fontInfo` from Balkón,+     and with input set to be read from the file+     `.golden/shapedRuns/mixedVerticalAlignment.golden` from Balkón.++  2. Verify that text is displayed in the output window.++  3. If necessary, resize the window so that the whole line can be seen.+     Note that there will be one instance of a letter "X" partially overflowing+     the top edge of the window, which is intentional.++  4. Verify all of the following:++      a. There is a line of text displayed, whose (vertically displaced) words+         read, left to right: "up high and higher down low and lower X X+         stretching tall climax preceding the crash"++      b. The baselines of the words "up", "down", and "stretching" are aligned+         to each other.++      c. The baselines of the words "lower" and "crash" are aligned+         to each other.++      d. The baselines of the words "climax" and "the" are aligned+         to each other.++      e. In the sequence of words "up high and higher", each word is placed+         higher than its preceding word.++      f. In the sequence of words "down low and lower", each word is placed+         lower than its preceding word.++      g. The words "climax" and "the" are placed at the top of the window,+         with only a small amount of blank space below the top of the window.++      h. The word "higher" is placed lower than the words "climax" and "the".++      i. The first letter "X" is placed higher than any of the words,+         and the centre of the letter's shape approximately intersects the top+         edge of the window, making only approximately half of it visible.++      j. The second letter "X" is placed lower than any of the words,+         and the letter's shape intersects the baseline of the words+         "lower" and "crash".+
balkon.cabal view
@@ -14,7 +14,7 @@ -- PVP summary:     +-+------- breaking API changes --                  | | +----- non-breaking API additions --                  | | | +--- code changes with no API change-version:            1.2.0.0+version:            1.3.0.0  stability:          experimental @@ -111,6 +111,7 @@         Data.Text.ParagraphLayout.Internal.BoxOptions,         Data.Text.ParagraphLayout.Internal.Break,         Data.Text.ParagraphLayout.Internal.Fragment,+        Data.Text.ParagraphLayout.Internal.Line,         Data.Text.ParagraphLayout.Internal.LineHeight,         Data.Text.ParagraphLayout.Internal.LinePagination,         Data.Text.ParagraphLayout.Internal.Paginable,@@ -144,7 +145,8 @@         Data.Text.ParagraphLayout.Internal.ProtoLine,         Data.Text.ParagraphLayout.Internal.ProtoRun,         Data.Text.ParagraphLayout.Internal.Script,-        Data.Text.ParagraphLayout.Internal.SplitList+        Data.Text.ParagraphLayout.Internal.SplitList,+        Data.Text.ParagraphLayout.Internal.VerticalOffsets      build-depends:         base >=4.12 && < 4.16,
lib/Data/Text/ParagraphLayout/Rich.hs view
@@ -14,6 +14,11 @@         )     , BoxCollapse (AllowBoxCollapse, AvoidBoxCollapse)     , BoxSpacing (BoxSpacingLeftRight)+    , VerticalAlignment+        ( AlignLineTop+        , AlignLineBottom+        , AlignBaseline+        )     , LineHeight (Absolute, Normal)     , ParagraphOptions     , defaultParagraphOptions@@ -39,11 +44,14 @@     -- as well as updating specific option fields.     , boxSpacing     , boxCollapse+    , boxVerticalAlignment     , activateBoxSpacing     -- ** Text options     -- | These are record selectors that can be used for reading     -- as well as updating specific option fields.     , textFont+    , textAscender+    , textDescender     , textLineHeight     , textLanguage     , textDirection@@ -53,8 +61,18 @@     , paragraphText     -- * Output layout     , layoutRich-    , ParagraphLayout (ParagraphLayout, paragraphRect, paragraphFragments)+    , ParagraphLayout+        ( ParagraphLayout+        , paragraphRect+        , paragraphLines+        , paragraphFragments+        )     , paragraphSafeWidth+    , Line+        ( Line+        , lineNumber+        , lineRect+        )     , Fragment         ( Fragment         , fragmentUserData@@ -81,6 +99,7 @@ import Data.Text.ParagraphLayout.Internal.AncestorBox import Data.Text.ParagraphLayout.Internal.BoxOptions import Data.Text.ParagraphLayout.Internal.Fragment+import Data.Text.ParagraphLayout.Internal.Line import Data.Text.ParagraphLayout.Internal.LineHeight import Data.Text.ParagraphLayout.Internal.ParagraphAlignment import Data.Text.ParagraphLayout.Internal.ParagraphOptions
src/Data/Text/ParagraphLayout/Internal/BoxOptions.hs view
@@ -2,6 +2,7 @@     ( BoxCollapse (..)     , BoxOptions (..)     , BoxSpacing (..)+    , VerticalAlignment (..)     , activateBoxSpacing     , defaultBoxOptions     )@@ -14,6 +15,10 @@ -- This record type is likely to be extended in the future. -- Use `defaultBoxOptions` and update it with specific record selectors -- instead of constructing `BoxOptions` directly.+--+-- In order to get CSS defaults, use:+--+-- > defaultBoxOptions { boxVerticalAlignment = AlignBaseline 0 } data BoxOptions = BoxOptions      { boxSpacing :: BoxSpacing@@ -30,7 +35,8 @@     -- ^ Determines how this box affects the height of a line that would     -- otherwise be empty. -    -- TODO: textVerticalAlign+    , boxVerticalAlignment :: VerticalAlignment+    -- ^ Determines how fragments are aligned vertically within a line.      }     deriving (Eq)@@ -92,11 +98,59 @@      deriving (Eq, Read, Show) --- | `BoxOptions` with default values.+-- | Determines how the contents of a line should be aligned vertically,+-- that is, how fragments should fill (and possibly extend) the vertical space+-- inside a line.+--+-- Vertical alignment takes place after line breaking.+data VerticalAlignment++    = AlignLineTop+    -- ^ Align the top of this box with the top of the line.+    --+    -- The /top of this box/ is the topmost coordinate of any fragment+    -- descended from this box, except for fragments that are descended from+    -- another box with `AlignLineTop` or `AlignLineBottom` closer to them.+    --+    -- t`Data.Text.ParagraphLayout.Rich.LineHeight` is included+    -- when considering the /top/ coordinates of descended fragments,+    -- and thus, leading is included.+    --+    -- This behaviour is equivalent to @vertical-align: top@ in CSS.++    | AlignLineBottom+    -- ^ Align the bottom of this box with the bottom of the line.+    --+    -- The /bottom of this box/ is the bottommost coordinate of any fragment+    -- descended from this box, except for fragments that are descended from+    -- another box with `AlignLineTop` or `AlignLineBottom` closer to them.+    --+    -- t`Data.Text.ParagraphLayout.Rich.LineHeight` is included+    -- when considering the /bottom/ coordinates of descended fragments,+    -- and thus, leading is included.+    --+    -- This behaviour is equivalent to @vertical-align: bottom@ in CSS.++    | AlignBaseline Int32+    -- ^ Align the baseline of this box with the baseline of its parent box,+    -- optionally shifting it by a specified amount upwards.+    --+    -- @`AlignBaseline` 0@ is equivalent to @vertical-align: baseline@ in CSS.+    --+    -- @`AlignBaseline` x@ is equivalent to @vertical-align: \<length\>@ in CSS,+    -- after an appropriate unit conversion.++    deriving (Eq, Read, Show)++-- | `BoxOptions` with backwards-compatible values.+--+-- Note that this sets `boxVerticalAlignment` to `AlignLineTop`,+-- whereas the CSS default should be `AlignBaseline 0`. defaultBoxOptions :: BoxOptions defaultBoxOptions = BoxOptions     { boxSpacing = BoxSpacingLeftRight 0 0     , boxCollapse = AllowBoxCollapse+    , boxVerticalAlignment = AlignLineTop     }  -- | Shorthand for updating `boxSpacing` and setting `boxCollapse`
src/Data/Text/ParagraphLayout/Internal/Layout.hs view
@@ -11,16 +11,15 @@ import Data.List.NonEmpty (NonEmpty ((:|)), nonEmpty, (<|)) import qualified Data.List.NonEmpty as NonEmpty import Data.Maybe (fromMaybe)+import Data.Semigroup (sconcat) import Data.Text.Foreign (lengthWord8) import Data.Text.Glyphize     ( Buffer (..)     , ContentType (ContentTypeUnicode)     , Direction (DirLTR, DirRTL, DirTTB, DirBTT)-    , FontExtents (..)     , GlyphInfo     , GlyphPos     , defaultBuffer-    , fontExtentsForDir     , shape     ) import qualified Data.Text.ICU as BreakStatus (Line (Hard))@@ -29,9 +28,10 @@ import Data.Text.ParagraphLayout.Internal.AncestorBox import Data.Text.ParagraphLayout.Internal.ApplyBoxes import Data.Text.ParagraphLayout.Internal.BiDiReorder+import Data.Text.ParagraphLayout.Internal.BoxOptions import Data.Text.ParagraphLayout.Internal.Break import Data.Text.ParagraphLayout.Internal.Fragment-import Data.Text.ParagraphLayout.Internal.LineHeight+import Data.Text.ParagraphLayout.Internal.Line import Data.Text.ParagraphLayout.Internal.ParagraphAlignment import Data.Text.ParagraphLayout.Internal.ParagraphExtents import qualified Data.Text.ParagraphLayout.Internal.ProtoFragment as PF@@ -43,6 +43,7 @@ import Data.Text.ParagraphLayout.Internal.SplitList import Data.Text.ParagraphLayout.Internal.TextContainer import Data.Text.ParagraphLayout.Internal.TextOptions+import qualified Data.Text.ParagraphLayout.Internal.VerticalOffsets as VO import Data.Text.ParagraphLayout.Internal.WithSpan  -- This is redundant.@@ -55,17 +56,22 @@ -- | Create a multi-line layout from the given runs, splitting them as -- necessary to fit within the requested line width. ----- The output is a flat list of fragments positioned in both dimensions.+-- The first output component is a flat list of fragments positioned+-- in both dimensions.+--+-- The second output component is a list of lines containing the+-- positioned content. layoutAndAlignLines     :: Direction     -> ParagraphAlignment     -> Int32     -> NonEmpty (WithSpan d Run)-    -> [FragmentWithSpan d]-layoutAndAlignLines dir align maxWidth runs = frags+    -> ([FragmentWithSpan d], [Line])+layoutAndAlignLines dir align maxWidth runs = (frags, ls)     where         frags = concatMap toList fragsInLines-        (_, fragsInLines) = mapAccumL positionLine originY numberedLines+        (fragsInLines, ls) = unzip fragsAndLines+        (_, fragsAndLines) = mapAccumL positionLine originY numberedLines         positionLine = positionLineH dir align maxWidth         numberedLines = zip [1 ..] canonicalLines         canonicalLines = fmap reorderProtoFragments visibleLines@@ -98,28 +104,86 @@ -- | Position all the given horizontal fragments on the same line, -- using @originY@ as its top edge, and return the bottom edge for continuation. ----- Glyphs will be aligned by their ascent line, similar to the behaviour of--- @vertical-align: top@ in CSS.------ TODO: For rich text, allow other types of vertical alignment.+-- Also return a `Line` structure with a defined vertical dimensions+-- but undefined horizontal dimensions. positionLineH     :: Direction     -> ParagraphAlignment     -> Int32     -> Int32     -> (Int, PL.ProtoLine NonEmpty d)-    -> (Int32, NonEmpty (FragmentWithSpan d))-positionLineH dir align maxWidth originY (num, pl) = (nextY, frags)+    -> (Int32, (NonEmpty (FragmentWithSpan d), Line))+positionLineH dir align maxWidth originY (num, pl) =+    (nextY, (frags, line))     where-        nextY = minimum $ fmap y_min rects-        rects = fmap (\ (WithSpan _ r) -> fragmentRect r) frags-        (_, frags) = mapAccumL (positionFragmentH num originY) originX wpfs-        wpfs = PL.applyBoxes pl+        line = Line { lineNumber = num, lineRect = Rect 0 originY 0 sizeY }+        sizeY = nextY - originY+        (_, frags) = mapAccumL (positionFragmentH num) originX wpfs+        wpfs = PL.applyBoxes alignedLine+        (nextY, alignedLine) = verticalAlignment originY pl         originX = paragraphOriginX + if lineWidth > maxWidth             then overflowingLineOffset dir (lineWidth - maxWidth)             else fittingLineOffset align dir (maxWidth - lineWidth)         lineWidth = PL.width pl +-- | Update vertical positions of all fragments on the line so that they+-- respect vertical alignment settings and fit on a line whose top coordinate+-- is @originY@. Also returns the bottom coordinate of the line.+verticalAlignment :: Int32 -> PL.ProtoLine NonEmpty d ->+    (Int32, PL.ProtoLine NonEmpty d)+verticalAlignment originY pl = (bottomY, PL.mapFragments setOrigin pl)+    where+        setOrigin rs pf =+            PF.mapVerticalOffsets (VO.alignBaseline (fragOffset rs)) pf++        fragOffset rs = case spanVO rs of+            (Nothing, vo) -> rootOffset + VO.baseline vo+            (Just b, vo) -> case boxVerticalAlignment $ RB.boxOptions b of+                AlignLineTop -> boxTopOffset b + VO.baseline vo+                AlignLineBottom -> boxBottomOffset b + VO.baseline vo+                _ -> error "verticalAlignment: wrong box used as anchor"++        bottomY = originY - finalLineHeight+        finalLineHeight = fittingTop - fittingBottom++        -- Firefox-like behaviour:+        -- First extend the line upwards to fit bottom-aligned boxes,+        -- then extend the line downwards to fit top-aligned boxes.+        fittingTop = maximum $ (:) rootTop $+            map ((rootBottom +) . boxHeight) bottomAlignedBoxes+        fittingBottom = minimum $ (:) rootBottom $+            map ((fittingTop -) . boxHeight) topAlignedBoxes++        rootTop = maximum $ fmap (VO.layoutTop . snd) rootVOs+        rootBottom = minimum $ fmap (VO.layoutBottom . snd) rootVOs+        rootVOs = filter VO.underRoot $ toList allVOs+        rootOffset = originY - fittingTop++        boxHeight b = boxTop b - boxBottom b+        boxTop b = maximum $ map (VO.layoutTop . snd) $ boxVOs b+        boxBottom b = minimum $ map (VO.layoutBottom . snd) $ boxVOs b+        boxVOs b = filter (VO.underBox b) $ toList allVOs+        -- How much to shift from baseline 0 so that layoutTop = originY?+        boxTopOffset b = originY - boxTop b+        -- How much to shift from baseline 0 so that layoutBottom = bottomY?+        boxBottomOffset b = bottomY - boxBottom b++        boxesOnLine = foldr RB.union [] $ fmap fragBoxes $ PL.protoFragments pl+        topAlignedBoxes = filter topAligned boxesOnLine+        bottomAlignedBoxes = filter bottomAligned boxesOnLine+        topAligned rb =+            boxVerticalAlignment (RB.boxOptions rb) == AlignLineTop+        bottomAligned rb =+            boxVerticalAlignment (RB.boxOptions rb) == AlignLineBottom+        fragBoxes (WithSpan rs _) = RS.spanBoxes rs+        -- Struts may get duplicated in `allVOs`.+        -- This should not be a problem since we are using idempotent functions.+        allVOs = sconcat $ fmap fragStruttedVOs $ PL.protoFragments pl+        fragStruttedVOs (WithSpan rs _) = spanStruttedVOs rs+        spanVO rs = NonEmpty.head $ spanStruttedVOs rs+        spanStruttedVOs rs =+            VO.strutted (RS.spanTextOptions rs) (RS.spanBoxes rs)+ -- | Inline offset of the first fragment on a line that overflows. overflowingLineOffset :: Direction -> Int32 -> Int32 overflowingLineOffset DirLTR _ = 0@@ -154,12 +218,11 @@ centreAlignOffset :: Int32 -> Int32 centreAlignOffset slack = slack `div` 2 --- | Position the given horizontal fragment on a line,--- using @originY@ as its top edge and @originX@ as its left edge,--- returning the X coordinate of its right edge for continuation.-positionFragmentH :: Int -> Int32 -> Int32 -> ProtoFragmentWithBoxes d ->+-- | Position the given horizontal fragment on a line, using @originX@ as its+-- left edge, returning the X coordinate of its right edge for continuation.+positionFragmentH :: Int -> Int32 -> ProtoFragmentWithBoxes d ->     (Int32, FragmentWithSpan d)-positionFragmentH line originY originX (WithBoxes lbs (WithSpan rs pf) rbs) =+positionFragmentH line originX (WithBoxes lbs (WithSpan rs pf) rbs) =     (nextX, WithSpan rs frag)     where         nextX = contentX + contentWidth + rightSpacing@@ -178,20 +241,17 @@             }         userData = RS.spanUserData rs         bs = ancestorBoxes lbs rbs rs-        contentRect = Rect contentX contentY contentWidth (-normalLineHeight)-        contentY = originY + penY + ascent-        rect = Rect contentX originY contentWidth (-lineHeight)+        contentRect = Rect contentX fontTop contentWidth (fontBottom - fontTop)+        rect = Rect contentX layoutTop contentWidth (layoutBottom - layoutTop)         penX = 0-        penY = descent + leading `div` 2 - lineHeight-        lineHeight = case textLineHeight opts of-            Normal -> normalLineHeight-            Absolute h -> h-        leading = lineHeight - normalLineHeight-        normalLineHeight = ascent + descent-        ascent = ascender extents-        descent = - descender extents-        extents = fontExtentsForDir (textFont opts) (Just $ PF.direction pf)-        opts = RS.spanTextOptions rs+        penY = baseline - layoutTop+        VO.VerticalOffsets+            { VO.layoutTop = layoutTop+            , VO.fontTop = fontTop+            , VO.baseline = baseline+            , VO.fontBottom = fontBottom+            , VO.layoutBottom = layoutBottom+            } = PF.verticalOffsets pf  ancestorBoxes     :: [RB.ResolvedBox d]@@ -361,10 +421,11 @@ layoutRunH :: WithSpan d Run -> ProtoFragmentWithSpan d layoutRunH (WithSpan rs run) = WithSpan rs pf     where-        pf = PF.protoFragmentH dir lvl glyphs hard+        pf = PF.protoFragmentH dir lvl vo glyphs hard         glyphs = shapeRun (WithSpan rs run)         dir = runDirection run         lvl = runLevel run+        vo = VO.fromText (RS.spanTextOptions rs)         hard = runHardBreak run  -- | Calculate layout for the given run independently of its position.
+ src/Data/Text/ParagraphLayout/Internal/Line.hs view
@@ -0,0 +1,25 @@+module Data.Text.ParagraphLayout.Internal.Line (Line (..), shiftLine)+where++import Data.Int (Int32)++import Data.Text.ParagraphLayout.Internal.Rect++-- | Information about a line in a laid out paragraph.+data Line = Line+    { lineNumber :: Int+    -- ^ Logical number of the line box, starting at 1 for a given paragraph.+    , lineRect :: Rect Int32+    -- ^ Dimensions of the line box (CSS), containing all fragments on a given+    -- line, and matching the width of the whole paragraph.+    }+    deriving (Eq, Read, Show)++-- | Add @dx@ and @dy@ to the line's `x_origin` and `y_origin`,+-- respectively.+shiftLine :: Int32 -> Int32 -> Line -> Line+shiftLine dx dy l = l'+    where+        l' = l { lineRect = r' }+        r' = r { x_origin = x_origin r + dx, y_origin = y_origin r + dy }+        r = lineRect l
src/Data/Text/ParagraphLayout/Internal/LineHeight.hs view
@@ -7,10 +7,15 @@ data LineHeight      = Normal-    -- ^ Determine the preferred line height automatically using its ascent and-    -- descent metrics.+    -- ^ The amount of vertical space taken up by the text in the layout+    -- will be exactly the distance between its font's ascender and descender+    -- line, with no further adjustment.      | Absolute Int32-    -- ^ Set the preferred line height independently of the font.+    -- ^ The amount of vertical space taken up by the text in the layout+    -- will be exactly the provided value. If this value is different from+    -- the distance between the font's ascender and descender line, the+    -- difference will be split in two equal parts (within a rounding error)+    -- and applied as /half-leading/ both above and below the glyphs.      deriving (Eq, Read, Show)
src/Data/Text/ParagraphLayout/Internal/LinePagination.hs view
@@ -12,7 +12,7 @@ --   (Preceding context may limit the space available on the given page, but it --   is assumed that the space on every following page can be used in full.) module Data.Text.ParagraphLayout.Internal.LinePagination-    ( Line+    ( LineHeight     , lineHeight     , PageContinuity (Break, Continue)     , bestSplit@@ -30,13 +30,13 @@ -- Lines are assumed to be tightly packed without overlaps, -- so that the vertical space taken up by multiple lines -- is equal to the sum of the height of each line.-class Line a where+class LineHeight a where     lineHeight :: a -> Int32 --- | A trivial instance of `Line` that is just a height.+-- | A trivial instance of `LineHeight` that is just a height. -- -- For testing purposes.-instance Line Int32 where+instance LineHeight Int32 where     lineHeight = id  -- | Represents the best place to place a chunk of paginated content.@@ -72,7 +72,7 @@ -- -- The third component of the output contains all remaining lines. If non-empty, -- these can be passed to this function again to produce more pages.-paginateLines :: Line a+paginateLines :: LineHeight a     => Word     -- ^ Minimum number of lines to keep before a page break ("orphans"),     -- if possible.@@ -136,7 +136,7 @@ -- as possible while satisfying the given constraints. -- -- This is a low-level function that makes no compromises.-bestSplit :: Line a+bestSplit :: LineHeight a     => Word     -- ^ Number of lines at the beginning ("orphans") to keep together.     -> Word@@ -156,7 +156,7 @@ -- not exceed @h@, the first @o@ lines ("orphans") are kept together, -- and the last @w@ lines ("widows") are kept together. constrainedSplits-    :: Line a => Word -> Word -> Int32 -> [a] -> NonEmpty ([a], [a])+    :: LineHeight a => Word -> Word -> Int32 -> [a] -> NonEmpty ([a], [a]) constrainedSplits o w h ls = zeroSplit :| dropWhileEnd violating splits     where         zeroSplit :| splits = fittingSplits h ls@@ -168,7 +168,7 @@ -- | Split a list of lines in every possible way, from shortest prefix -- to longest, as long as the total of line heights in the prefix does -- not exceed @h@.-fittingSplits :: Line a => Int32 -> [a] -> NonEmpty ([a], [a])+fittingSplits :: LineHeight a => Int32 -> [a] -> NonEmpty ([a], [a]) fittingSplits h ls = fmap snd $ zeroSplit :| takeWhile fitting splits     where         zeroSplit :| splits = splitsWithTotal ls@@ -176,7 +176,7 @@  -- | Split a list of lines in every possible way, from shortest prefix -- to longest, and keep a running total of line heights in the prefix.-splitsWithTotal :: Line a => [a] -> NonEmpty (Int32, ([a], [a]))+splitsWithTotal :: LineHeight a => [a] -> NonEmpty (Int32, ([a], [a])) splitsWithTotal ls = zeroSplit :| splits     where         zeroSplit = (zeroTotal, (zeroClosed, ls))@@ -184,7 +184,7 @@         zeroClosed = []         zeroTotal = 0 -splitsWithTotal' :: Line a => Int32 -> [a] -> [a] -> [(Int32, ([a], [a]))]+splitsWithTotal' :: LineHeight a => Int32 -> [a] -> [a] -> [(Int32, ([a], [a]))] splitsWithTotal' _ _ [] = [] splitsWithTotal' total closed (x : xs) = split : splits     where
src/Data/Text/ParagraphLayout/Internal/Paginable.hs view
@@ -67,7 +67,7 @@     paginate :: PageOptions -> pl -> (PageContinuity, pl, Maybe pl)  -- | Internal implementation of paginating a simple list of generic lines.-instance Line a => Paginable [a] where+instance LineHeight a => Paginable [a] where     paginate opts ls = case paginateLines o w h1 h2 ls of         (c, p, []) -> (c, p, Nothing)         (c, p, rest) -> (c, p, Just rest)@@ -87,7 +87,7 @@ instance Paginable (Rich.ParagraphLayout d) where     paginate = paginateLayout -paginateLayout :: (Line a, LineNumbers a, GenericLayout a) =>+paginateLayout :: (LineHeight a, LineNumbers a, GenericLayout a) =>    PageOptions -> a -> (PageContinuity, a, Maybe a) paginateLayout opts pl =     case paginate opts (cutLines pl) of
src/Data/Text/ParagraphLayout/Internal/ParagraphLine.hs view
@@ -34,13 +34,12 @@     -- | Keep only fragments with the given line number.     limitFragments :: Int -> pl -> pl -    -- | Add @dx@ and @dy@ to each fragment's `x_origin` and `y_origin`,-    -- respectively.-    shiftFragments :: Int32 -> Int32 -> pl -> pl+    -- | Shift all contents of the paragraph by @dx, dy@.+    shiftContents :: Int32 -> Int32 -> pl -> pl -    -- | Combine fragments from two layouts into one,+    -- | Combine contents from two layouts into one,     -- without any adjustment of coordinates.-    appendFragments :: pl -> pl -> pl+    appendContents :: pl -> pl -> pl  instance GenericLayout (P.ParagraphLayout d) where     empty = P.emptyParagraphLayout@@ -48,17 +47,17 @@     topDistance pl = topFragmentOrigin $ P.paragraphFragments pl     leftDistance pl = leftmostFragmentOrigin $ P.paragraphFragments pl     limitFragments n = P.filterFragments (fragmentIsOnLine n)-    shiftFragments dx dy = P.mapFragments (shiftFragment dx dy)-    appendFragments = P.appendFragments+    shiftContents dx dy = P.mapFragments (shiftFragment dx dy)+    appendContents = P.appendFragments  instance GenericLayout (R.ParagraphLayout d) where     empty = R.emptyParagraphLayout     rect = R.paragraphRect-    topDistance pl = topFragmentOrigin $ R.paragraphFragments pl+    topDistance = R.topDistance     leftDistance pl = leftmostFragmentOrigin $ R.paragraphFragments pl-    limitFragments n = R.filterFragments (fragmentIsOnLine n)-    shiftFragments dx dy = R.mapFragments (shiftFragment dx dy)-    appendFragments = R.appendFragments+    limitFragments n = R.filterLine n+    shiftContents dx dy = R.shiftContents dx dy+    appendContents = R.appendContents  -- | Split the given paragraph layout into single-line layouts. cutLines :: (GenericLayout pl, LineNumbers pl) => pl -> [pl]@@ -70,11 +69,11 @@  -- | Add a constant to each fragment's `y_origin` so that their maximum is zero. trimTop :: GenericLayout pl => pl -> pl-trimTop pl = shiftFragments 0 (-topDistance pl) pl+trimTop pl = shiftContents 0 (-topDistance pl) pl  -- | Add a constant to each fragment's `x_origin` so that their minimum is zero. trimLeft :: GenericLayout pl => pl -> pl-trimLeft pl = shiftFragments (-leftDistance pl) 0 pl+trimLeft pl = shiftContents (-leftDistance pl) 0 pl  topFragmentOrigin :: [Fragment d] -> Int32 topFragmentOrigin frags = maximum $ map (y_origin . fragmentRect) frags@@ -91,7 +90,7 @@ mergeLine pl nextLine = pl'     where         -- Quadratic time complexity. TODO: Consider optimising.-        pl' = appendFragments pl $ shiftFragments 0 y nextLine+        pl' = appendContents pl $ shiftContents 0 y nextLine         y = y_terminus $ rect pl  fragmentIsOnLine :: Int -> Fragment d -> Bool
src/Data/Text/ParagraphLayout/Internal/Plain/ParagraphLayout.hs view
@@ -30,7 +30,7 @@ instance LineNumbers (ParagraphLayout d) where     lineNumbersWithDuplication pl = map fragmentLine $ paragraphFragments pl -instance Line (ParagraphLayout d) where+instance LineHeight (ParagraphLayout d) where     lineHeight pl = height $ paragraphRect pl  -- | Wrap the given `SpanLayout`s and compute their containing rectangle.
src/Data/Text/ParagraphLayout/Internal/ProtoFragment.hs view
@@ -1,6 +1,7 @@ module Data.Text.ParagraphLayout.Internal.ProtoFragment-    ( ProtoFragment (direction, advance, glyphs, hardBreak)+    ( ProtoFragment (direction, verticalOffsets, advance, glyphs, hardBreak)     , protoFragmentH+    , mapVerticalOffsets     ) where @@ -8,6 +9,7 @@ import Data.Text.Glyphize (Direction (..), GlyphInfo, GlyphPos (x_advance))  import qualified Data.Text.ParagraphLayout.Internal.BiDiLevels as BiDi+import qualified Data.Text.ParagraphLayout.Internal.VerticalOffsets as VO  -- | A box fragment which has not been positioned yet. data ProtoFragment = ProtoFragment@@ -16,6 +18,8 @@     , level :: BiDi.Level     -- ^ BiDi embedding level.     -- Should be even for LTR fragments and odd for RTL fragments.+    , verticalOffsets :: VO.VerticalOffsets+    -- ^ Vertical offsets used for aligning the fragment within its line.     , advance :: Int32     -- ^ Total advance of glyphs in this fragment,     -- depending on the text direction.@@ -26,11 +30,24 @@  -- | Construct a `ProtoFragment`, automatically calculating the total advance -- for a horizontal text direction.-protoFragmentH :: Direction -> BiDi.Level -> [(GlyphInfo, GlyphPos)] -> Bool ->-    ProtoFragment-protoFragmentH dir lvl gs hard = ProtoFragment dir lvl adv gs hard+protoFragmentH+    :: Direction+    -> BiDi.Level+    -> VO.VerticalOffsets+    -> [(GlyphInfo, GlyphPos)]+    -> Bool+    -> ProtoFragment+protoFragmentH dir lvl vo gs hard = ProtoFragment dir lvl vo adv gs hard     where         adv = sum $ map (x_advance . snd) gs++-- | Apply the given function to the `verticalOffsets` in the given fragment.+mapVerticalOffsets+    :: (VO.VerticalOffsets -> VO.VerticalOffsets)+    -> ProtoFragment+    -> ProtoFragment+mapVerticalOffsets mapFunc pf =+    pf { verticalOffsets = mapFunc $ verticalOffsets pf }  instance BiDi.WithLevel ProtoFragment where     level = level -- BiDi.level = ProtoFragment.level
src/Data/Text/ParagraphLayout/Internal/ProtoLine.hs view
@@ -4,6 +4,7 @@     , visible     , width     , applyBoxes+    , mapFragments     ) where @@ -93,3 +94,17 @@ -- | Boxes that end on the given line. boxesEnd :: (Foldable f, Functor f) => ProtoLine f d -> [ResolvedBox d] boxesEnd pl = allBoxes (protoFragments pl) `diff` nextOpenBoxes pl++-- | Apply a function to every fragment on the line.+--+-- Note that `ResolvedSpan` cannot be changed in this manner and is+-- only provided on the input of the mapping function.+mapFragments+    :: Functor f+    => (ResolvedSpan d -> ProtoFragment -> ProtoFragment)+    -> ProtoLine f d+    -> ProtoLine f d+mapFragments mapFunc pl =+    pl { protoFragments = fmap mapFunc' $ protoFragments pl }+    where+        mapFunc' (WithSpan rs pf) = WithSpan rs $ mapFunc rs pf
src/Data/Text/ParagraphLayout/Internal/ResolvedBox.hs view
@@ -13,12 +13,14 @@ import Data.Text.Glyphize (Direction (DirLTR, DirRTL))  import Data.Text.ParagraphLayout.Internal.BoxOptions+import Data.Text.ParagraphLayout.Internal.TextOptions  -- | Internal structure describing an inline box. -- May be shared by multiple fragments. data ResolvedBox d = ResolvedBox     { boxUserData :: d     , boxIndex :: Int+    , boxParentTextOptions :: TextOptions     , boxOptions :: BoxOptions     , boxDirection :: Direction     }
src/Data/Text/ParagraphLayout/Internal/Rich.hs view
@@ -12,7 +12,10 @@ import Data.Text.ParagraphLayout.Internal.Break import Data.Text.ParagraphLayout.Internal.Fragment import Data.Text.ParagraphLayout.Internal.Layout+import Data.Text.ParagraphLayout.Internal.Line+import Data.Text.ParagraphLayout.Internal.ParagraphExtents import Data.Text.ParagraphLayout.Internal.ParagraphOptions+import Data.Text.ParagraphLayout.Internal.Rect import qualified Data.Text.ParagraphLayout.Internal.ResolvedSpan as RS import Data.Text.ParagraphLayout.Internal.Rich.Paragraph import Data.Text.ParagraphLayout.Internal.Rich.ParagraphLayout@@ -23,15 +26,24 @@  -- | Lay out a rich text paragraph. layoutRich :: Paragraph d -> ParagraphLayout d-layoutRich p = paragraphLayout $ map unwrap frags+layoutRich p = ParagraphLayout pRect stretchedLines unwrappedFrags     where         Paragraph _ _ root opts = p         RootBox (Box _ rootTextOpts) = root+        pRect = containRects $ map lineRect stretchedLines+        stretchedLines = map stretchLine ls+        stretchLine l = l { lineRect = stretchRect (lineRect l) }+        stretchRect r = r+            { x_origin = x_origin containingRect+            , x_size = x_size containingRect+            }+        containingRect = containRects $ map fragmentSpacedRect unwrappedFrags+        unwrappedFrags = map unwrap frags         unwrap (WithSpan rs frag) =             frag { fragmentUserData = RS.spanUserData rs }-        frags = case nonEmpty wrappedRuns of+        (frags, ls) = case nonEmpty wrappedRuns of             Just xs -> layoutAndAlignLines dir align maxWidth xs-            Nothing -> []+            Nothing -> ([], [])         wrappedRuns = spansToRunsWrapped spans         -- TODO: To support @unicode-bidi: plaintext@ as in CSS, allow ignoring         --       the text direction of the root box, and instead use the BiDi
src/Data/Text/ParagraphLayout/Internal/Rich/ParagraphLayout.hs view
@@ -1,20 +1,21 @@ module Data.Text.ParagraphLayout.Internal.Rich.ParagraphLayout     ( ParagraphLayout (..)-    , appendFragments+    , appendContents     , emptyParagraphLayout-    , filterFragments-    , mapFragments-    , paragraphLayout+    , filterLine     , paragraphOriginX     , paragraphOriginY     , paragraphSafeWidth     , shapedRuns+    , shiftContents+    , topDistance     ) where  import Data.Int (Int32)  import Data.Text.ParagraphLayout.Internal.Fragment+import Data.Text.ParagraphLayout.Internal.Line import Data.Text.ParagraphLayout.Internal.LineNumbers import Data.Text.ParagraphLayout.Internal.LinePagination import Data.Text.ParagraphLayout.Internal.ParagraphExtents@@ -24,6 +25,9 @@ data ParagraphLayout d = ParagraphLayout     { paragraphRect :: Rect Int32     -- ^ The containing block (CSS3).+    , paragraphLines :: [Line]+    -- ^ Information about line boxes (CSS).+    -- May describe additional empty space around text fragments.     , paragraphFragments :: [Fragment d]     -- ^ The resulting layout of all input text, divided into fragments as     -- required by the input structure, line breaking, text writing direction,@@ -34,41 +38,48 @@ instance LineNumbers (ParagraphLayout d) where     lineNumbersWithDuplication pl = map fragmentLine $ paragraphFragments pl -instance Line (ParagraphLayout d) where+instance LineHeight (ParagraphLayout d) where     lineHeight pl = height $ paragraphRect pl --- | Wrap the given `Fragment`s and compute their containing rectangle.-paragraphLayout :: [Fragment d] -> ParagraphLayout d-paragraphLayout frags = ParagraphLayout pRect frags-    where pRect = containRects $ map fragmentSpacedRect frags---- | A `ParagraphLayout` with no fragments.--- Useful as an identity element for `appendFragments`.+-- | A `ParagraphLayout` with no fragments and no lines.+-- Useful as an identity element for `appendContents`. emptyParagraphLayout :: ParagraphLayout a-emptyParagraphLayout = ParagraphLayout emptyRect []+emptyParagraphLayout = ParagraphLayout emptyRect [] [] --- | Remove fragments that do not match the given predicate.------ The containing rectangle will be recalculated.-filterFragments :: (Fragment d -> Bool) -> ParagraphLayout d ->-    ParagraphLayout d-filterFragments predicate (ParagraphLayout _ frags) =-    paragraphLayout $ filter predicate frags+-- | Distance from the paragraph origin to its topmost line.+topDistance :: ParagraphLayout d -> Int32+topDistance pl = case paragraphLines pl of+    [] -> 0+    ls -> maximum $ map (y_origin . lineRect) ls --- | Run a mapping function over each fragment inside a `ParagraphLayout`.------ The containing rectangle will be recalculated.-mapFragments :: (Fragment d -> Fragment d) -> ParagraphLayout d ->-    ParagraphLayout d-mapFragments mapFunc (ParagraphLayout _ frags) =-    paragraphLayout $ map mapFunc frags+-- | Keep the line with the given number and its fragments,+-- and remove everything else.+filterLine :: Int -> ParagraphLayout d -> ParagraphLayout d+filterLine num (ParagraphLayout _ ls frags) =+    ParagraphLayout pRect' ls' frags'+    where+        pRect' = containRects $ map lineRect ls+        ls' = filter ((== num) . lineNumber) ls+        frags' = filter ((== num) . fragmentLine) frags +-- | Add @dx@ and @dy@ to the origins of each line and fragment,+-- effectively shifting the whole paragraph by the given amount.+shiftContents :: Int32 -> Int32 -> ParagraphLayout d -> ParagraphLayout d+shiftContents dx dy (ParagraphLayout _ ls frags) =+    ParagraphLayout pRect' ls' frags'+    where+        pRect' = containRects $ map lineRect ls+        ls' = map (shiftLine dx dy) ls+        frags' = map (shiftFragment dx dy) frags+ -- | Combine fragments from two `ParagraphLayout`s.------ The containing rectangle will be recalculated.-appendFragments :: ParagraphLayout d -> ParagraphLayout d -> ParagraphLayout d-appendFragments (ParagraphLayout _ a) (ParagraphLayout _ b) =-    paragraphLayout $ a ++ b+appendContents :: ParagraphLayout d -> ParagraphLayout d -> ParagraphLayout d+appendContents (ParagraphLayout _ ls1 frags1) (ParagraphLayout _ ls2 frags2) =+    ParagraphLayout pRect ls frags+    where+        pRect = containRects $ map lineRect ls+        ls = ls1 ++ ls2+        frags = frags1 ++ frags2  -- | Return all shaped runs in the paragraph. shapedRuns :: ParagraphLayout d -> [ShapedRun]
src/Data/Text/ParagraphLayout/Internal/TextOptions.hs view
@@ -4,6 +4,7 @@     ) where +import Data.Int (Int32) import Data.Text.Glyphize (Direction, Font, emptyFont)  import Data.Text.ParagraphLayout.Internal.LineHeight@@ -20,6 +21,29 @@     -- Make sure to set its scale (see `Data.Text.Glyphize.optionScale`) using     -- the same units that you want in the output. +    , textAscender :: Maybe Int32+    -- ^ How much to add to the text's baseline coordinate to reach its+    -- ascender line. This is usually a positive value.+    --+    -- If set to `Nothing`, the font's own `Data.Text.Glyphize.ascender`+    -- metric will be used.+    --+    -- Setting an explicit value with @`Just` x@ is intended as an override+    -- for situations where the text is intended to be replaced by an object+    -- with differently calculated dimensions.++    , textDescender :: Maybe Int32+    -- ^ How much to add to the text's baseline coordinate to reach its+    -- descender line. Note that this is usually a negative value because+    -- the descender is usually below the baseline.+    --+    -- If set to `Nothing`, the font's own `Data.Text.Glyphize.descender`+    -- metric will be used.+    --+    -- Setting an explicit value with @`Just` x@ is intended as an override+    -- for situations where the text is intended to be replaced by an object+    -- with differently calculated dimensions.+     , textLineHeight :: LineHeight     -- ^ Preferred line height of the resulting fragments. @@ -55,6 +79,8 @@     -> TextOptions defaultTextOptions dir = TextOptions     { textFont = emptyFont+    , textAscender = Nothing+    , textDescender = Nothing     , textLineHeight = Normal     , textLanguage = ""     , textDirection = dir
src/Data/Text/ParagraphLayout/Internal/Tree.hs view
@@ -102,7 +102,7 @@     -- ^ Inline boxes found on the path from this text sequence to the root     -- of the original tree. --- | Data types that can represent an empty text sequence in a `Tree`.+-- | Data types that can represent an empty text sequence in a tree. class EmptyText t where     empty :: t @@ -142,9 +142,10 @@     (Int, [Leaf t d]) flattenNode idx path textOpts (TextSequence d t) =     (idx, [TextLeaf d t textOpts path])-flattenNode idx path _ (InlineBox d (Box ns textOpts) boxOpts) =-    flattenNodes (idx + 1) (ResolvedBox d idx boxOpts dir : path) textOpts ns+flattenNode idx path parentTextOpts (InlineBox d (Box ns textOpts) boxOpts) =+    flattenNodes (idx + 1) box textOpts ns     where+        box = ResolvedBox d idx parentTextOpts boxOpts dir : path         dir = textDirection textOpts  -- | Concatenate all pieces of text from a `Text` tree, plus an optional prefix
+ src/Data/Text/ParagraphLayout/Internal/VerticalOffsets.hs view
@@ -0,0 +1,148 @@+module Data.Text.ParagraphLayout.Internal.VerticalOffsets+    ( VerticalOffsets (..)+    , alignBaseline+    , fromText+    , strutted+    , underBox+    , underRoot+    )+where++import Data.Int (Int32)+import Data.List.NonEmpty (NonEmpty ((:|)), (<|))+import Data.Maybe (fromMaybe)+import Data.Text.Glyphize (ascender, descender, fontExtentsForDir)++import Data.Text.ParagraphLayout.Internal.BoxOptions+import Data.Text.ParagraphLayout.Internal.LineHeight+import Data.Text.ParagraphLayout.Internal.ResolvedBox+import Data.Text.ParagraphLayout.Internal.TextOptions++-- | Metrics used for vertical alignment of text fragments.+data VerticalOffsets = VerticalOffsets++    { layoutTop :: Int32+    -- ^ Y coordinate of the top edge of the fragment,+    -- including half-leading.++    , fontTop :: Int32+    -- ^ Y coordinate of the font's ascender.++    , baseline :: Int32+    -- ^ Y coordinate of the font's baseline.++    , fontBottom :: Int32+    -- ^ Y coordinate of the font's descender.++    , layoutBottom :: Int32+    -- ^ Y coordinate of the bottom edge of the fragment,+    -- including half-leading.++    }+    deriving (Eq, Show)++-- | Add a constant to each of the coordinates, effectively moving them+-- up by the given amount while preserving distances between them.+shift :: Int32 -> VerticalOffsets -> VerticalOffsets+shift d vo = vo+    { layoutTop = layoutTop vo + d+    , fontTop = fontTop vo + d+    , baseline = baseline vo + d+    , fontBottom = fontBottom vo + d+    , layoutBottom = layoutBottom vo + d+    }++-- | Set `baseline` to the given value and update all other coordinates+-- so that distances are preserved.+alignBaseline :: Int32 -> VerticalOffsets -> VerticalOffsets+alignBaseline x vo = shift (x - baseline vo) vo++-- | Metrics calculated for a single text box, as if it existed alone+-- with its baseline at @0@.+fromText :: TextOptions -> VerticalOffsets+fromText opts = VerticalOffsets+    { layoutTop = ascent + topHalfLeading+    , fontTop = ascent+    , baseline = 0+    , fontBottom = - descent+    , layoutBottom = - descent - bottomHalfLeading+    }+    where+        -- non-negative leading values iff `lineHeight` > `normalLineHeight`+        leading = lineHeight - normalLineHeight+        topHalfLeading = -((-leading) `div` 2)+        bottomHalfLeading = leading `div` 2+        -- `normalLineHeight` > 0 for horizontal fonts+        normalLineHeight = ascent + descent+        -- `ascent` >= 0 for horizontal fonts+        ascent = ascender extents `fromMaybe` textAscender opts+        -- `descent` >= 0 for horizontal fonts+        descent = - (descender extents `fromMaybe` textDescender opts)+        extents = fontExtentsForDir (textFont opts) (Just dir)+        -- Actual shaped text direction may differ from the direction set in+        -- `TextOptions` (for example RTL characters in a LTR box), but+        -- HarfBuzz only distinguished horizontal and vertical extents,+        -- so this should make no difference.+        dir = textDirection opts+        lineHeight = case textLineHeight opts of+            Normal -> normalLineHeight+            Absolute h -> h++-- | Metrics for a nested text fragment, with a defined relation either to+-- the root box or to a box with line-relative alignment.+type NestedVerticalOffsets d = (Maybe (ResolvedBox d), VerticalOffsets)++-- | Test whether the given `NestedVerticalOffsets` are defined relative to+-- the root box.+underRoot :: NestedVerticalOffsets d -> Bool+underRoot (Nothing, _) = True+underRoot (Just _, _) = False++-- | Test whether the given `NestedVerticalOffsets` are defined relative to+-- the given box.+--+-- (Note that boxes are compared internally using `boxIndex`, and should+-- therefore only be compared with boxes created from the same input.)+underBox :: ResolvedBox d -> NestedVerticalOffsets d -> Bool+underBox _ (Nothing, _) = False+underBox b (Just x, _) = b == x++-- | Metrics calculated for a text box nested within zero or more boxes.+--+-- Vertical offsets will be recursively adjusted using the ancestor boxes'+-- properties, stopping once a box with line-relative alignment is reached,+-- if there is one.+--+-- If recursion ends at the root, this function returns @(`Nothing`, vo)@,+-- where @vo@ is calculated such that the root baseline is at @0@.+--+-- If recursion ends at a box with line-relative alignment, this function+-- returns @(`Just` b, vo)@, where @b@ is the box where recursion stopped+-- (root of the /aligned subtree/ in CSS terminology), and @vo@ is calculated+-- such that the baseline of @b@ is at @0@.+--+-- Note: The font extents are calculated using the same direction for the whole+--       ancestry path regardless of the actual direction of these boxes, but+--       this should not matter for text that is only horizontal.+fromNestedText :: TextOptions -> [ResolvedBox d] -> NestedVerticalOffsets d+fromNestedText opts boxes = case boxes of+    [] -> -- Inline content directly in the root box.+        (Nothing, vo)+    (b : bs) -> case boxVerticalAlignment $ boxOptions b of+        AlignLineTop -> (Just b, vo)+        AlignLineBottom -> (Just b, vo)+        AlignBaseline offset ->+            let parentOpts = boxParentTextOptions b+                (anchor, parentVO) = fromNestedText parentOpts bs+            in (anchor, alignBaseline (baseline parentVO + offset) vo)+    where+        vo = fromText opts++-- | Metrics calculated for a text box nested within zero or more boxes,+-- plus metrics for each of its ancestor boxes, which can be used as struts+-- on lines where these boxes do not directly contain any text.+strutted :: TextOptions -> [ResolvedBox d] -> NonEmpty (NestedVerticalOffsets d)+strutted opts [] =+    fromNestedText opts [] :| []+strutted opts boxes@(b : bs) =+    fromNestedText opts boxes <| strutted (boxParentTextOptions b) bs
test/Data/Text/ParagraphLayout/Internal/ApplyBoxesSpec.hs view
@@ -14,7 +14,8 @@ import Data.Text.ParagraphLayout.Internal.WithSpan  trivialBox :: d -> Int -> Direction -> ResolvedBox d-trivialBox d i dir = ResolvedBox d i defaultBoxOptions dir+trivialBox d i dir =+    ResolvedBox d i (defaultTextOptions dir) defaultBoxOptions dir  trivialSpan :: d -> Int -> Direction -> [ResolvedBox d] -> ResolvedSpan d trivialSpan d i dir bs = ResolvedSpan
test/Data/Text/ParagraphLayout/Internal/RunSpec.hs view
@@ -15,7 +15,8 @@ import Data.Text.ParagraphLayout.TextData  defaultBox :: Direction -> ResolvedBox ()-defaultBox dir = ResolvedBox () 0 defaultBoxOptions dir+defaultBox dir =+    ResolvedBox () 0 (defaultTextOptions dir) defaultBoxOptions dir  sampleSpan :: (Direction, String, Text, a) -> TextLevels -> ResolvedSpan () sampleSpan (dir, lang, text, _) levels = ResolvedSpan
test/Data/Text/ParagraphLayout/PrettyShow.hs view
@@ -147,12 +147,17 @@         ]  instance Show d => PrettyShow (Rich.ParagraphLayout d) where-    prettyShow (Rich.ParagraphLayout pr frags) = concat+    prettyShow (Rich.ParagraphLayout pr ls frags) = concat         [ "ParagraphLayout"         , newline         , indent1         , "{ paragraphRect = "         , show pr+        , newline+        , indent1+        , ", paragraphLines ="+        , newline+        , concat $ commaFirstList indent2 $ map show ls         , newline         , indent1         , ", paragraphFragments ="
test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs view
@@ -9,12 +9,16 @@     , mixedLineHeightParagraph     , mixedScriptParagraph     , mixedSizesParagraph+    , mixedVerticalAlignmentParagraph     , nestedBoxesParagraph     , neutralDirectionParagraph     , newline1Paragraph     , newline1TextParagraph     , newline2Paragraph     , newline2TextParagraph+    , offsetMiddleInnerTextParagraph+    , offsetMiddleOuterTextParagraph+    , offsetTextlessBoxParagraph     , softBreakParagraph     , spaceBoxParagraph     )@@ -171,36 +175,40 @@         t = (defaultTextOptions dir) { textFont = font, textLanguage = lang }         (_, lang, textContents, _) = mixedDirectionSimple dir -mixedLineHeightParagraph :: (Int32, Int32, Int32) -> Font -> ParagraphOptions ->-    Paragraph String-mixedLineHeightParagraph (lhSmall, lhMedium, lhLarge) font = constructParagraph+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 "]+        , box "smallBox" b tSmall [text "smallText" "small "]         , text "mediumText" "medium "-        , box "largeBox" b_ tLarge [text "largeText" "large "]+        , 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 "]+        , box "smallBox" b tSmall [text "smallText" "small "]         , text "mediumText" "medium "-        , box "largeBox" b_ tLarge [text "largeText" "large "]+        , 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 "]+        , box "smallBox" b tSmall [text "smallText" "small "]         , text "lineBreak" "\n"         -- Line 4: asymmetric, large changing into medium.-        , box "largeBox" b_ tLarge [text "largeText" "large "]+        , box "largeBox" b tLarge [text "largeText" "large "]         , text "mediumText" "medium "         , text "lineBreak" "\n"         -- Line 5: small only.-        , box "smallBox" b_ tSmall [text "smallText" "small "]+        , box "smallBox" b tSmall [text "smallText" "small "]         , text "lineBreak" "\n"         -- Line 6: large only.-        , box "largeBox" b_ tLarge [text "largeText" "large "]+        , box "largeBox" b tLarge [text "largeText" "large "]         ]     )     (pack "suffix")@@ -208,7 +216,9 @@         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@@ -255,6 +265,80 @@         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")@@ -314,6 +398,58 @@     (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
test/Data/Text/ParagraphLayout/RichSpec.hs view
@@ -109,7 +109,8 @@                 let input w = loremIpsumParagraph font $                         opts { paragraphMaxWidth = w }                 let result20em = layoutRich $ input commonWrapWidth-                let resultSafe = layoutRich $ input expectedSafeWidth+                -- Adding + 1 to work around rounding errors.+                let resultSafe = layoutRich $ input (expectedSafeWidth + 1)                 let resultUnsafe = layoutRich $ input (expectedSafeWidth - 1)                 let resultUnsafe2 = layoutRich $ input (expectedSafeWidth - 2) @@ -129,16 +130,98 @@                 it "does not wrap the same at 2 units smaller width" $                     resultUnsafe2 `shouldNotBeWrappedLike` result20em -            it "handles mixed line height" $ do+            describe "mixed line height" $ do                 let opts = defaultParagraphOptions                         { paragraphAlignment = AlignStart                         , paragraphMaxWidth = largeWidth                         }                 let lineHeights = (800, 1300, 1700)-                let input = mixedLineHeightParagraph lineHeights font opts-                let result = layoutRich input-                result `shouldBeGolden` "mixedLineHeight" +                it "aligns to top of line" $ do+                    let input = mixedLineHeightParagraph+                            lineHeights+                            AlignLineTop+                            font+                            opts+                    let result = layoutRich input+                    result `shouldBeGolden` "mixedLineHeightTop"++                it "aligns to bottom of line" $ do+                    let input = mixedLineHeightParagraph+                            lineHeights+                            AlignLineBottom+                            font+                            opts+                    let result = layoutRich input+                    result `shouldBeGolden` "mixedLineHeightBottom"++                it "aligns to baseline" $ do+                    let input = mixedLineHeightParagraph+                            lineHeights+                            (AlignBaseline 0)+                            font+                            opts+                    let result = layoutRich input+                    result `shouldBeGolden` "mixedLineHeightBaseline"++                it "aligns to baseline plus 3 units" $ do+                    let input = mixedLineHeightParagraph+                            lineHeights+                            (AlignBaseline 3)+                            font+                            opts+                    let result = layoutRich input+                    result `shouldBeGolden` "mixedLineHeightBaseline3"++            describe "offset middle baseline" $ do+                let opts = defaultParagraphOptions+                        { paragraphAlignment = AlignStart+                        , paragraphMaxWidth = largeWidth+                        }+                let wrap = opts+                        { paragraphMaxWidth = 3000+                        }++                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 "inline box strut extends one wrapped line upwards" $ do+                    let input = offsetMiddleOuterTextParagraph 500 font wrap+                    let result = layoutRich input+                    result `shouldBeGolden` "offsetMiddleUpOuterTextWrap"++                it "inline box strut extends one wrapped line downwards" $ do+                    let input = offsetMiddleOuterTextParagraph (-500) font wrap+                    let result = layoutRich input+                    result `shouldBeGolden` "offsetMiddleDownOuterTextWrap"++                it "textless inline box strut extends line upwards" $ do+                    let input = offsetTextlessBoxParagraph 500 font opts+                    let result = layoutRich input+                    result `shouldBeGolden` "offsetTextlessBoxUp"++                it "textless inline box strut extends line downwards" $ do+                    let input = offsetTextlessBoxParagraph (-500) font opts+                    let result = layoutRich input+                    result `shouldBeGolden` "offsetTextlessBoxDown"+             it "handles mixed sizes" $ do                 let opts = defaultParagraphOptions                         { paragraphAlignment = AlignStart@@ -455,4 +538,20 @@                 defaultParagraphOptions                     { paragraphAlignment = AlignStart                     , paragraphMaxWidth = 144+                    }++        describe "with Latin font" $ do+            let fontPath = latinFont+            font <- runIO $ loadFont latinFont 0 demoOptions++            let shapedRunsSpec = shapedRunsSpecWithFont fontPath font++            shapedRunsSpec+                "handles complex vertical alignment"+                "mixedVerticalAlignment" $+                layoutRich $+                mixedVerticalAlignmentParagraph font $+                defaultParagraphOptions+                    { paragraphAlignment = AlignStart+                    , paragraphMaxWidth = largeWidth                     }