module Data.Text.ParagraphLayout.Internal.Span
( Span (..)
, SpanLayout (..)
, SpanOptions (..)
, defaultSpanOptions
, spanFragments
, spanRects
)
where
import Data.Int (Int32)
import Data.Text.ParagraphLayout.Internal.Fragment
import Data.Text.ParagraphLayout.Internal.Rect
-- | A paragraph is broken into spans by the caller.
--
-- Each span could have a different font family, size, style, text decoration,
-- colour, language, etc.
data Span = Span
{ spanLength :: Int
-- ^ Byte offset to the next span or the end of the paragraph text.
, spanOptions :: SpanOptions
-- ^ Options applying to this specific span.
}
deriving (Eq)
-- | Defines options relevant to the layout of a single span of text.
--
-- This record type is likely to be extended in the future.
-- Use `defaultSpanOptions` and update it with specific record selectors
-- instead of constructing `SpanOptions` directly.
data SpanOptions = SpanOptions
{ spanLanguage :: String
-- ^ IETF BCP 47 language tag, such as the value expected to be found in
-- the HTML @lang@ attribute, specifying the primary language for the
-- span's text content. An empty string explicitly means "language unknown".
--
-- Used for selecting the appropriate glyphs and line breaking rules,
-- primarily in East Asian languages.
-- TODO: Add all relevant attributes.
}
deriving (Eq)
-- | `SpanOptions` with default values.
defaultSpanOptions :: SpanOptions
defaultSpanOptions = SpanOptions
{ spanLanguage = ""
}
-- | The resulting layout of each span, which may include multiple fragments
-- as required by line breaking, text writing direction, and changes of script.
data SpanLayout = SpanLayout [Fragment]
-- TODO: Consider merging fragments created by script changes.
deriving (Eq, Read, Show)
-- | Return all fragments of shaped text from the given span.
spanFragments :: SpanLayout -> [Fragment]
spanFragments (SpanLayout frags) = frags
spanRects :: SpanLayout -> [Rect Int32]
spanRects sl = map fragmentRect $ spanFragments sl