~jaro/balkon

88a5b6c714c5543b01d63d836ad403b5755d8d76 — Jaro 11 months ago c072603
Test shaping across intra-word breaks.
A .golden/shapedRuns/intraWordBreak.fontInfo => .golden/shapedRuns/intraWordBreak.fontInfo +1 -0
@@ 0,0 1,1 @@
assets/fonts/plex/IBMPlexSansArabic-Regular.ttf 0 32,32 32,32

A .golden/shapedRuns/intraWordBreak.golden => .golden/shapedRuns/intraWordBreak.golden +19 -0
@@ 0,0 1,19 @@
[ (0, -35, 
    [ (GlyphInfo {codepoint = 373, cluster = 15, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 24, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 971, cluster = 13, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 14, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 407, cluster = 11, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 8, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 89, cluster = 10, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 1363, cluster = 6, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 31, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 373, cluster = 4, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 24, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 971, cluster = 2, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 14, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 407, cluster = 0, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 8, y_advance = 0, x_offset = 0, y_offset = 0})
    ])
, (0, -83, 
    [ (GlyphInfo {codepoint = 1363, cluster = 28, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 31, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 373, cluster = 26, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 24, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 971, cluster = 24, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 14, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 407, cluster = 22, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 8, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 89, cluster = 21, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 18, y_advance = 0, x_offset = 0, y_offset = 0})
    , (GlyphInfo {codepoint = 1363, cluster = 17, unsafeToBreak = False, unsafeToConcat = False, safeToInsertTatweel = False}, GlyphPos {x_advance = 31, y_advance = 0, x_offset = 0, y_offset = 0})
    ])
]
\ No newline at end of file

M test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs => test/Data/Text/ParagraphLayout/Rich/ParagraphData.hs +14 -0
@@ 1,6 1,7 @@
module Data.Text.ParagraphLayout.Rich.ParagraphData
    ( hardBoxBreakLTRParagraph
    , hardBoxBreakRTLParagraph
    , intraWordBreakParagraph
    , loremIpsumParagraph
    , mixedDirectionComplexParagraph
    , mixedDirectionSimpleParagraph


@@ 79,6 80,19 @@ hardBoxBreakRTLParagraph font = constructParagraph
        b2 = b_ { boxSpacing = BoxSpacingLeftRight 150 200 }
        t = tRTL { textFont = font, textLanguage = "zxx" }

-- | For testing that soft wrap preserves the form of Arabic characters.
-- Source: <https://www.w3.org/TR/css-text-3/#word-break-shaping>
intraWordBreakParagraph :: Font -> ParagraphOptions -> Paragraph String
intraWordBreakParagraph font = constructParagraph
    empty
    (rootBox t
        [ text "text" "نوشتن_نوشتن_نوشتن"
        ]
    )
    empty
    where
        t = tRTL { textFont = font, textLanguage = "fa" }

-- | Filler text using the Latin script.
-- Source: <https://www.lipsum.com/>
loremIpsumParagraph :: Font -> ParagraphOptions -> Paragraph String

M test/Data/Text/ParagraphLayout/RichSpec.hs => test/Data/Text/ParagraphLayout/RichSpec.hs +38 -8
@@ 1,7 1,8 @@
module Data.Text.ParagraphLayout.RichSpec (spec) where

import Data.Int (Int32)
import Data.Text.Glyphize (Direction (DirLTR, DirRTL))
import Data.Word (Word32)
import Data.Text.Glyphize (Direction (DirLTR, DirRTL), codepoint)

import Test.Hspec
import System.FilePath ((</>))


@@ 19,6 20,9 @@ fragmentRects :: ParagraphLayout d -> [(d, Rect Int32)]
fragmentRects p = map toItem $ paragraphFragments p
    where toItem (Fragment { fragmentUserData = d, fragmentRect = r }) = (d, r)

glyphRuns :: ParagraphLayout d -> [[Word32]]
glyphRuns = map (map (codepoint . fst) . fragmentGlyphs) . paragraphFragments

spec :: Spec
spec = do



@@ 158,6 162,27 @@ spec = do
                let result = layoutRich input
                result `shouldBeGolden` "mixedDirectionComplexLTR"

            it "preserves joining forms across soft breaks" $ do
                let opts = defaultParagraphOptions { paragraphMaxWidth = 4500 }
                let input = intraWordBreakParagraph font opts
                let glyphRunsVisual = glyphRuns $ layoutRich input
                let glyphRunsLogical = map reverse glyphRunsVisual
                -- Glyph indexes for the corresponding Arabic letters/ligatures:
                let n_initial = 407
                let v_final = 971
                let sh_initial = 373
                let tn_final = 1363
                -- Glyph index for the underscore used to break repetitions:
                let sp = 89
                -- Unconventional code formatting here shows that there should
                -- be three repetitions of the same glyph sequence, unaffected
                -- by the line break inserted after an initial form and before
                -- a final form.
                glyphRunsLogical `shouldBe`
                    [[n_initial, v_final, sh_initial, tn_final, sp,
                    n_initial, v_final, sh_initial], [tn_final, sp,
                    n_initial, v_final, sh_initial, tn_final]]

    describe "paginate" $ do
        let
            goldenDir = ".golden" </> "paginatedRichParagraphLayout"


@@ 195,13 220,18 @@ spec = do
            let fontPath = arabicFont
            font <- runIO $ loadFont fontPath 0 demoOptions

            let
                opts = defaultParagraphOptions
                input = mixedDirectionComplexParagraph DirRTL font opts
                result = layoutRich input
                shapedRunsSpec = shapedRunsSpecWithFont fontPath font
            let shapedRunsSpec = shapedRunsSpecWithFont fontPath font

            shapedRunsSpec
                "handles complex mixed direction in RTL paragraph"
                "mixedDirectionComplexRTL"
                result
                "mixedDirectionComplexRTL" $
                layoutRich $
                mixedDirectionComplexParagraph DirRTL font $
                defaultParagraphOptions

            shapedRunsSpec
                "preserves joining forms across soft breaks"
                "intraWordBreak" $
                layoutRich $
                intraWordBreakParagraph font $
                defaultParagraphOptions { paragraphMaxWidth = 144 }