From e5196add6c88a4034109c516d6c338becfea7c6c Mon Sep 17 00:00:00 2001 From: Jaro Date: Thu, 29 Jun 2023 20:03:50 +0200 Subject: [PATCH] Add options for vertical alignment. --- lib/Data/Text/ParagraphLayout/Rich.hs | 6 ++ .../ParagraphLayout/Internal/BoxOptions.hs | 58 ++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/lib/Data/Text/ParagraphLayout/Rich.hs b/lib/Data/Text/ParagraphLayout/Rich.hs index c0456b1..d00a64c 100644 --- a/lib/Data/Text/ParagraphLayout/Rich.hs +++ b/lib/Data/Text/ParagraphLayout/Rich.hs @@ -14,6 +14,11 @@ module Data.Text.ParagraphLayout.Rich ) , BoxCollapse (AllowBoxCollapse, AvoidBoxCollapse) , BoxSpacing (BoxSpacingLeftRight) + , VerticalAlignment + ( AlignLineTop + , AlignLineBottom + , AlignBaseline + ) , LineHeight (Absolute, Normal) , ParagraphOptions , defaultParagraphOptions @@ -39,6 +44,7 @@ module Data.Text.ParagraphLayout.Rich -- as well as updating specific option fields. , boxSpacing , boxCollapse + , boxVerticalAlignment , activateBoxSpacing -- ** Text options -- | These are record selectors that can be used for reading diff --git a/src/Data/Text/ParagraphLayout/Internal/BoxOptions.hs b/src/Data/Text/ParagraphLayout/Internal/BoxOptions.hs index 0057086..397044b 100644 --- a/src/Data/Text/ParagraphLayout/Internal/BoxOptions.hs +++ b/src/Data/Text/ParagraphLayout/Internal/BoxOptions.hs @@ -2,6 +2,7 @@ module Data.Text.ParagraphLayout.Internal.BoxOptions ( BoxCollapse (..) , BoxOptions (..) , BoxSpacing (..) + , VerticalAlignment (..) , activateBoxSpacing , defaultBoxOptions ) @@ -14,6 +15,10 @@ import Data.Int (Int32) -- 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 @@ data BoxOptions = BoxOptions -- ^ 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 @@ data BoxCollapse 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: \@ 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` -- 2.30.2