From d5807a8ebe4763c4fbdf157357e16eae70ff0f00 Mon Sep 17 00:00:00 2001 From: Jaro Date: Fri, 26 May 2023 11:14:25 +0200 Subject: [PATCH] Add tests for mixed text direction. --- .../mixedDirectionComplexLTR.golden | 137 ++++++++++++++++++ .../mixedDirectionComplexRTL.golden | 137 ++++++++++++++++++ .../mixedDirectionSimpleLTR.golden | 50 +++++++ .../mixedDirectionSimpleRTL.golden | 50 +++++++ .../Internal/BiDiLevelsSpec.hs | 6 + .../Text/ParagraphLayout/Internal/RunSpec.hs | 54 +++++++ .../ParagraphLayout/Rich/ParagraphData.hs | 46 +++++- test/Data/Text/ParagraphLayout/RichSpec.hs | 25 ++++ test/Data/Text/ParagraphLayout/TextData.hs | 13 ++ 9 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 .golden/richParagraphLayout/mixedDirectionComplexLTR.golden create mode 100644 .golden/richParagraphLayout/mixedDirectionComplexRTL.golden create mode 100644 .golden/richParagraphLayout/mixedDirectionSimpleLTR.golden create mode 100644 .golden/richParagraphLayout/mixedDirectionSimpleRTL.golden diff --git a/.golden/richParagraphLayout/mixedDirectionComplexLTR.golden b/.golden/richParagraphLayout/mixedDirectionComplexLTR.golden new file mode 100644 index 0000000..aa52708 --- /dev/null +++ b/.golden/richParagraphLayout/mixedDirectionComplexLTR.golden @@ -0,0 +1,137 @@ +ParagraphLayout + { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 20949, y_size = -1500} + , paragraphFragments = + [ Fragment + { fragmentUserData = "text1" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 5748, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 90, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 6, cluster = 12, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 580, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 6, cluster = 18, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 580, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 23, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text2" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [ AncestorBox {boxUserData = "box1", boxLeftEdge = SpacedEdge 0, boxRightEdge = NoEdge, boxStartEdge = SpacedEdge 0, boxEndEdge = NoEdge} + ] + , fragmentRect = Rect {x_origin = 5748, y_origin = 0, x_size = 1252, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 3, cluster = 25, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 27, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 28, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 29, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text2" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [ AncestorBox {boxUserData = "box1", boxLeftEdge = NoEdge, boxRightEdge = NoEdge, boxStartEdge = NoEdge, boxEndEdge = NoEdge} + ] + , fragmentRect = Rect {x_origin = 7000, y_origin = 0, x_size = 4090, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 3, cluster = 47, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 46, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 45, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 44, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 43, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 293, cluster = 41, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 389, cluster = 39, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 38, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 37, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 36, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 35, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 34, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 512, cluster = 32, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 839, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 286, cluster = 30, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 224, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text2" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [ AncestorBox {boxUserData = "box1", boxLeftEdge = NoEdge, boxRightEdge = SpacedEdge 0, boxStartEdge = NoEdge, boxEndEdge = SpacedEdge 0} + ] + , fragmentRect = Rect {x_origin = 11090, y_origin = 0, x_size = 4342, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 26, cluster = 48, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 351, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 27, cluster = 49, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 50, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 51, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 52, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 53, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 54, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 27, cluster = 55, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 26, cluster = 56, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 351, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 57, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 58, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 59, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 60, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 61, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text3" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 15432, y_origin = 0, x_size = 1252, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 3, cluster = 62, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 63, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 64, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 65, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 66, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text3" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 16684, y_origin = 0, x_size = 4265, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 90, cluster = 83, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 82, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 81, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 80, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 517, cluster = 78, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 839, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 955, cluster = 76, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 455, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 75, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 74, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 73, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 72, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 71, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 971, cluster = 69, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 450, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 394, cluster = 67, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + ] + } diff --git a/.golden/richParagraphLayout/mixedDirectionComplexRTL.golden b/.golden/richParagraphLayout/mixedDirectionComplexRTL.golden new file mode 100644 index 0000000..1041ae5 --- /dev/null +++ b/.golden/richParagraphLayout/mixedDirectionComplexRTL.golden @@ -0,0 +1,137 @@ +ParagraphLayout + { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 20949, y_size = -1500} + , paragraphFragments = + [ Fragment + { fragmentUserData = "text3" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 4265, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 90, cluster = 83, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 82, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 81, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 80, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 517, cluster = 78, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 839, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 955, cluster = 76, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 455, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 75, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 74, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 73, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 72, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 71, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 971, cluster = 69, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 450, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 394, cluster = 67, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text2" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [ AncestorBox {boxUserData = "box1", boxLeftEdge = SpacedEdge 0, boxRightEdge = NoEdge, boxStartEdge = NoEdge, boxEndEdge = SpacedEdge 0} + ] + , fragmentRect = Rect {x_origin = 4265, y_origin = 0, x_size = 4342, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 26, cluster = 48, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 351, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 27, cluster = 49, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 50, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 51, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 52, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 53, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 54, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 27, cluster = 55, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 26, cluster = 56, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 351, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 57, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 58, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 59, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 60, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 61, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text3" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 8607, y_origin = 0, x_size = 1252, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 3, cluster = 62, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 63, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 64, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 65, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 66, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text2" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [ AncestorBox {boxUserData = "box1", boxLeftEdge = NoEdge, boxRightEdge = NoEdge, boxStartEdge = NoEdge, boxEndEdge = NoEdge} + ] + , fragmentRect = Rect {x_origin = 9859, y_origin = 0, x_size = 4090, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 3, cluster = 47, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 46, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 45, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 44, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 43, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 293, cluster = 41, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 270, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 389, cluster = 39, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 253, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 38, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 37, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 36, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 35, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 34, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 512, cluster = 32, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 839, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 286, cluster = 30, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 224, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text1" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 13949, y_origin = 0, x_size = 5748, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 90, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 8, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 6, cluster = 12, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 580, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 6, cluster = 18, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 580, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 19, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 20, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 23, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text2" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [ AncestorBox {boxUserData = "box1", boxLeftEdge = NoEdge, boxRightEdge = SpacedEdge 0, boxStartEdge = SpacedEdge 0, boxEndEdge = NoEdge} + ] + , fragmentRect = Rect {x_origin = 19697, y_origin = 0, x_size = 1252, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 3, cluster = 25, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 27, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 90, cluster = 28, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 272, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 3, cluster = 29, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 236, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + ] + } diff --git a/.golden/richParagraphLayout/mixedDirectionSimpleLTR.golden b/.golden/richParagraphLayout/mixedDirectionSimpleLTR.golden new file mode 100644 index 0000000..abd2dae --- /dev/null +++ b/.golden/richParagraphLayout/mixedDirectionSimpleLTR.golden @@ -0,0 +1,50 @@ +ParagraphLayout + { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 7954, y_size = -1500} + , paragraphFragments = + [ Fragment + { fragmentUserData = "text" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 3397, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 6, cluster = 0, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 580, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 1, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 14, cluster = 2, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 24, cluster = 3, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 363, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 4, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 15, cluster = 5, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 250, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 20, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 3397, y_origin = 0, x_size = 1578, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 1143, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 1095, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 920, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 483, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 4975, y_origin = 0, x_size = 2979, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 17, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 517, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 27, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 29, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 759, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 15, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 250, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 26, cluster = 18, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 351, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + ] + } diff --git a/.golden/richParagraphLayout/mixedDirectionSimpleRTL.golden b/.golden/richParagraphLayout/mixedDirectionSimpleRTL.golden new file mode 100644 index 0000000..5c8ec4f --- /dev/null +++ b/.golden/richParagraphLayout/mixedDirectionSimpleRTL.golden @@ -0,0 +1,50 @@ +ParagraphLayout + { paragraphRect = Rect {x_origin = 0, y_origin = 0, x_size = 7954, y_size = -1500} + , paragraphFragments = + [ Fragment + { fragmentUserData = "text" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 0, y_origin = 0, x_size = 2979, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 17, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 517, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 27, cluster = 14, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 29, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 759, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 16, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 15, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 250, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 26, cluster = 18, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 351, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 2979, y_origin = 0, x_size = 1578, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 1143, cluster = 9, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 1095, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 920, cluster = 7, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 483, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + , Fragment + { fragmentUserData = "text" + , fragmentLine = 1 + , fragmentAncestorBoxes = + [] + , fragmentRect = Rect {x_origin = 4557, y_origin = 0, x_size = 3397, y_size = -1500} + , fragmentPen = (0, -1085) + , fragmentGlyphs = + [ (GlyphInfo {codepoint = 6, cluster = 0, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 580, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 1, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 14, cluster = 2, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 24, cluster = 3, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 363, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 4, cluster = 4, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 534, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 15, cluster = 5, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 250, y_advance = 0, x_offset = 0, y_offset = 0}) + , (GlyphInfo {codepoint = 20, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 568, y_advance = 0, x_offset = 0, y_offset = 0}) + ] + } + ] + } diff --git a/test/Data/Text/ParagraphLayout/Internal/BiDiLevelsSpec.hs b/test/Data/Text/ParagraphLayout/Internal/BiDiLevelsSpec.hs index 38f489a..71ea022 100644 --- a/test/Data/Text/ParagraphLayout/Internal/BiDiLevelsSpec.hs +++ b/test/Data/Text/ParagraphLayout/Internal/BiDiLevelsSpec.hs @@ -65,6 +65,12 @@ spec = do describe "on Serbian mixed script" $ serbianMixedScript `shouldHaveLevels` [0] + describe "on mixed direction with base LTR" $ + mixedDirectionSimple DirLTR `shouldHaveLevels` [0, 1, 0] + + describe "on mixed direction with base RTL" $ + mixedDirectionSimple DirRTL `shouldHaveLevels` [2, 1, 2] + describe "on Arabic around English" $ arabicAroundEnglish `shouldHaveLevels` [1, 2, 1, 2, 1] diff --git a/test/Data/Text/ParagraphLayout/Internal/RunSpec.hs b/test/Data/Text/ParagraphLayout/Internal/RunSpec.hs index 84bf2e3..b36cc73 100644 --- a/test/Data/Text/ParagraphLayout/Internal/RunSpec.hs +++ b/test/Data/Text/ParagraphLayout/Internal/RunSpec.hs @@ -94,6 +94,60 @@ spec = do , runScript = Just "Cyrl" } ] + it "handles mixed direction with base LTR" $ do + let levels = levelsRLE [(7, 0), (3, 1), (6, 0)] + let inputSpan = sampleSpan (mixedDirectionSimple DirLTR) levels + let runs = spanToRuns inputSpan + runs `shouldBe` + [ Run + { runOffsetInSpan = 0 + , runText = pack "bahrain" + , runLevel = 0 + , runDirection = Just DirLTR + , runScript = Just "Latn" + } + , Run + { runOffsetInSpan = 7 + , runText = pack "مصر" + , runLevel = 1 + , runDirection = Just DirRTL + , runScript = Just "Arab" + } + , Run + { runOffsetInSpan = 13 + , runText = pack "kuwait" + , runLevel = 0 + , runDirection = Just DirLTR + , runScript = Just "Latn" + } + ] + it "handles mixed direction with base RTL" $ do + let levels = levelsRLE [(7, 2), (3, 1), (6, 2)] + let inputSpan = sampleSpan (mixedDirectionSimple DirRTL) levels + let runs = spanToRuns inputSpan + runs `shouldBe` + [ Run + { runOffsetInSpan = 0 + , runText = pack "bahrain" + , runLevel = 2 + , runDirection = Just DirLTR + , runScript = Just "Latn" + } + , Run + { runOffsetInSpan = 7 + , runText = pack "مصر" + , runLevel = 1 + , runDirection = Just DirRTL + , runScript = Just "Arab" + } + , Run + { runOffsetInSpan = 13 + , runText = pack "kuwait" + , runLevel = 2 + , runDirection = Just DirLTR + , runScript = Just "Latn" + } + ] it "handles Arabic text with English inside" $ do let levels = levelsRLE [(3, 1), (9, 2), (36, 1), (3, 2), (1, 1)] let inputSpan = sampleSpan arabicAroundEnglish levels diff --git a/test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs b/test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs index 1d6a73a..90fe893 100644 --- a/test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs +++ b/test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs @@ -2,6 +2,8 @@ module Data.Text.ParagraphLayout.Rich.ParagraphData ( hardBoxBreakLTRParagraph , hardBoxBreakRTLParagraph , loremIpsumParagraph + , mixedDirectionComplexParagraph + , mixedDirectionSimpleParagraph , mixedScriptParagraph , mixedSizesParagraph , nestedBoxesParagraph @@ -10,7 +12,7 @@ module Data.Text.ParagraphLayout.Rich.ParagraphData where import Data.Int (Int32) -import Data.Text (Text, pack) +import Data.Text (Text, empty, pack) import Data.Text.Glyphize (Direction (DirLTR, DirRTL), Font) import Data.Text.ParagraphLayout.Internal.BoxOptions @@ -18,6 +20,7 @@ import Data.Text.ParagraphLayout.Internal.ParagraphOptions import Data.Text.ParagraphLayout.Internal.Rich.Paragraph import Data.Text.ParagraphLayout.Internal.TextOptions import Data.Text.ParagraphLayout.Internal.Tree +import Data.Text.ParagraphLayout.TextData tLTR :: TextOptions tLTR = defaultTextOptions DirLTR @@ -88,6 +91,47 @@ loremIpsumParagraph font = constructParagraph where t = tLTR { textFont = font, textLanguage = "zxx" } +-- | Edge case: +-- Directionally neutral characters between box boundary and direction boundary. +-- +-- In the case of a LTR paragraph, neutral characters should only be considered +-- RTL when surrounded by RTL characters on both sides, otherwise they should +-- be LTR. +-- +-- In the case of a RTL paragraph, neutral characters should only be considered +-- LTR when surrounded by LTR characters on both sides, otherwise they should +-- be RTL. +-- +-- Box boundaries should not, by default, affect the direction of neutral +-- characters. +mixedDirectionComplexParagraph :: Direction -> Font -> ParagraphOptions -> + Paragraph String +mixedDirectionComplexParagraph dir font = constructParagraph + (pack "prefix") + (rootBox t + [ text "text1" " . . ab . . ba . . " + , box "box1" b_ t + [ text "text2" " . . اب . . با . . tu . . ut . . " + ] + , text "text3" " . . تو . . وت . . " + ] + ) + (pack "suffix") + where + t = (defaultTextOptions dir) { textFont = font, textLanguage = "zxx" } + +-- | A paragraph that contains only strongly directional letters of mixed +-- directions, no spaces or other neutral characters, for basic BiDi tests. +mixedDirectionSimpleParagraph :: Direction -> Font -> ParagraphOptions -> + Paragraph String +mixedDirectionSimpleParagraph dir font = constructParagraph + empty + (rootBox t [TextSequence "text" textContents]) + empty + where + t = (defaultTextOptions dir) { textFont = font, textLanguage = lang } + (_, lang, textContents, _) = mixedDirectionSimple dir + mixedScriptParagraph :: Font -> ParagraphOptions -> Paragraph String mixedScriptParagraph font = constructParagraph (pack "prefix") diff --git a/test/Data/Text/ParagraphLayout/RichSpec.hs b/test/Data/Text/ParagraphLayout/RichSpec.hs index d73c617..3a198ce 100644 --- a/test/Data/Text/ParagraphLayout/RichSpec.hs +++ b/test/Data/Text/ParagraphLayout/RichSpec.hs @@ -1,6 +1,7 @@ module Data.Text.ParagraphLayout.RichSpec (spec) where import Data.Int (Int32) +import Data.Text.Glyphize (Direction (DirLTR, DirRTL)) import Test.Hspec import System.FilePath (()) @@ -120,6 +121,30 @@ spec = do let result = layoutRich input result `shouldBeGolden` "hardBoxBreakRTL" + it "handles simple mixed direction in RTL paragraph" $ do + let opts = defaultParagraphOptions + let input = mixedDirectionSimpleParagraph DirRTL font opts + let result = layoutRich input + result `shouldBeGolden` "mixedDirectionSimpleRTL" + + it "handles simple mixed direction in LTR paragraph" $ do + let opts = defaultParagraphOptions + let input = mixedDirectionSimpleParagraph DirLTR font opts + let result = layoutRich input + result `shouldBeGolden` "mixedDirectionSimpleLTR" + + it "handles complex mixed direction in RTL paragraph" $ do + let opts = defaultParagraphOptions + let input = mixedDirectionComplexParagraph DirRTL font opts + let result = layoutRich input + result `shouldBeGolden` "mixedDirectionComplexRTL" + + it "handles complex mixed direction in LTR paragraph" $ do + let opts = defaultParagraphOptions + let input = mixedDirectionComplexParagraph DirLTR font opts + let result = layoutRich input + result `shouldBeGolden` "mixedDirectionComplexLTR" + describe "paginate" $ do let goldenDir = ".golden" "paginatedRichParagraphLayout" diff --git a/test/Data/Text/ParagraphLayout/TextData.hs b/test/Data/Text/ParagraphLayout/TextData.hs index 793bcf5..16d86bd 100644 --- a/test/Data/Text/ParagraphLayout/TextData.hs +++ b/test/Data/Text/ParagraphLayout/TextData.hs @@ -5,6 +5,7 @@ module Data.Text.ParagraphLayout.TextData , arabicHello , czechHello , serbianMixedScript + , mixedDirectionSimple , arabicAroundEnglish , englishAroundArabic ) @@ -65,6 +66,18 @@ serbianMixedScript = , [23] ) +-- | Source: +-- +-- +-- Used to test the effect of base direction. +mixedDirectionSimple :: Direction -> Sample +mixedDirectionSimple dir = + ( dir + , "ar" + , pack "bahrainمصرkuwait" + , [7, 3, 6] + ) + -- | Source: -- arabicAroundEnglish :: Sample -- 2.30.2