From 1e8de66a311429538c26baf8e8a6fac212270e42 Mon Sep 17 00:00:00 2001 From: Jaro Date: Sat, 1 Jul 2023 12:30:04 +0200 Subject: [PATCH] Allow overriding font ascender and descender. Provides an easy option for influencing vertical metrics, which may be useful for implementing replaced and inline-block elements. --- CHANGELOG.md | 2 ++ lib/Data/Text/ParagraphLayout/Rich.hs | 2 ++ .../Text/ParagraphLayout/Internal/Layout.hs | 4 +-- .../ParagraphLayout/Internal/LineHeight.hs | 11 +++++--- .../ParagraphLayout/Internal/TextOptions.hs | 26 +++++++++++++++++++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b88acd..c533a95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ 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: diff --git a/lib/Data/Text/ParagraphLayout/Rich.hs b/lib/Data/Text/ParagraphLayout/Rich.hs index d00a64c..b7a13a2 100644 --- a/lib/Data/Text/ParagraphLayout/Rich.hs +++ b/lib/Data/Text/ParagraphLayout/Rich.hs @@ -50,6 +50,8 @@ module Data.Text.ParagraphLayout.Rich -- | These are record selectors that can be used for reading -- as well as updating specific option fields. , textFont + , textAscender + , textDescender , textLineHeight , textLanguage , textDirection diff --git a/src/Data/Text/ParagraphLayout/Internal/Layout.hs b/src/Data/Text/ParagraphLayout/Internal/Layout.hs index 926835b..ccd9b05 100644 --- a/src/Data/Text/ParagraphLayout/Internal/Layout.hs +++ b/src/Data/Text/ParagraphLayout/Internal/Layout.hs @@ -438,9 +438,9 @@ verticalOffsets dir opts = VO.VerticalOffsets -- `normalLineHeight` > 0 for horizontal fonts normalLineHeight = ascent + descent -- `ascent` >= 0 for horizontal fonts - ascent = ascender extents + ascent = ascender extents `fromMaybe` textAscender opts -- `descent` >= 0 for horizontal fonts - descent = - descender extents + descent = - (descender extents `fromMaybe` textDescender opts) extents = fontExtentsForDir (textFont opts) (Just dir) lineHeight = case textLineHeight opts of Normal -> normalLineHeight diff --git a/src/Data/Text/ParagraphLayout/Internal/LineHeight.hs b/src/Data/Text/ParagraphLayout/Internal/LineHeight.hs index a27ad01..7d237c1 100644 --- a/src/Data/Text/ParagraphLayout/Internal/LineHeight.hs +++ b/src/Data/Text/ParagraphLayout/Internal/LineHeight.hs @@ -7,10 +7,15 @@ import Data.Int (Int32) 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) diff --git a/src/Data/Text/ParagraphLayout/Internal/TextOptions.hs b/src/Data/Text/ParagraphLayout/Internal/TextOptions.hs index 8bd69e3..5a3bc80 100644 --- a/src/Data/Text/ParagraphLayout/Internal/TextOptions.hs +++ b/src/Data/Text/ParagraphLayout/Internal/TextOptions.hs @@ -4,6 +4,7 @@ module Data.Text.ParagraphLayout.Internal.TextOptions ) where +import Data.Int (Int32) import Data.Text.Glyphize (Direction, Font, emptyFont) import Data.Text.ParagraphLayout.Internal.LineHeight @@ -20,6 +21,29 @@ data TextOptions = TextOptions -- 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 @@ defaultTextOptions -> TextOptions defaultTextOptions dir = TextOptions { textFont = emptyFont + , textAscender = Nothing + , textDescender = Nothing , textLineHeight = Normal , textLanguage = "" , textDirection = dir -- 2.30.2