monomer-1.0.0.3: src/Monomer/Widgets/Util/Text.hs
{-|
Module : Monomer.Widgets.Util.Text
Copyright : (c) 2018 Francisco Vallarino
License : BSD-3-Clause (see the LICENSE file)
Maintainer : fjvallarino@gmail.com
Stability : experimental
Portability : non-portable
Helper functions to text related operations in widgets.
-}
{-# LANGUAGE Strict #-}
module Monomer.Widgets.Util.Text (
getTextMetrics,
getTextSize,
getTextSize_,
getSingleTextLineRect,
getTextGlyphs
) where
import Control.Lens ((&), (^.), (+~))
import Data.Default
import Data.Sequence (Seq(..), (<|), (|>))
import Data.Text (Text)
import Monomer.Core
import Monomer.Graphics
import qualified Monomer.Core.Lens as L
-- | Returns the text metrics of the active style.
getTextMetrics :: WidgetEnv s e -> StyleState -> TextMetrics
getTextMetrics wenv style = textMetrics where
fontMgr = wenv ^. L.fontManager
textMetrics = computeTextMetrics fontMgr font fontSize
font = styleFont style
fontSize = styleFontSize style
-- | Returns the size of the text using the active style and default options.
getTextSize :: WidgetEnv s e -> StyleState -> Text -> Size
getTextSize wenv style text = size where
fontMgr = wenv ^. L.fontManager
size = calcTextSize_ fontMgr style SingleLine KeepSpaces Nothing Nothing text
-- | Returns the size of the text using the active style.
getTextSize_
:: WidgetEnv s e -- ^ The widget environment.
-> StyleState -- ^ The active style.
-> TextMode -- ^ Whether to use single or multi line.
-> TextTrim -- ^ Whether to trim spacers or keep them.
-> Maybe Double -- ^ Maximum width (required for multi line).
-> Maybe Int -- ^ Max lines.
-> Text -- ^ Text to measure.
-> Size -- ^ The calculated size.
getTextSize_ wenv style mode trim mwidth mlines text = newSize where
fontMgr = wenv ^. L.fontManager
newSize = calcTextSize_ fontMgr style mode trim mwidth mlines text
-- | Returns the rect a single line of text needs to be displayed completely.
getSingleTextLineRect
:: WidgetEnv s e -- ^ The widget environment.
-> StyleState -- ^ The active style.
-> Rect -- ^ The bounding rect.
-> AlignTH -- ^ The horizontal alignment.
-> AlignTV -- ^ The vertical alignment.
-> Text -- ^ The text to measure.
-> Rect -- ^ The used rect. May be larger than the bounding rect.
getSingleTextLineRect wenv style rect alignH alignV text = textRect where
fontMgr = wenv ^. L.fontManager
font = styleFont style
fSize = styleFontSize style
fSpcH = styleFontSpaceH style
Rect x y w h = rect
Size tw _ = computeTextSize fontMgr font fSize fSpcH text
TextMetrics asc desc lineh lowerX = computeTextMetrics fontMgr font fSize
tx | alignH == ATLeft = x
| alignH == ATCenter = x + (w - tw) / 2
| otherwise = x + (w - tw)
ty | alignV == ATTop = y + asc
| alignV == ATMiddle = y + h + desc - (h - lineh) / 2
| alignV == ATAscender = y + h - (h - asc) / 2
| alignV == ATLowerX = y + h - (h - lowerX) / 2
| otherwise = y + h + desc
textRect = Rect {
_rX = tx,
_rY = ty - lineh,
_rW = tw,
_rH = lineh
}
-- | Returns the glyphs of a single line of text.
getTextGlyphs :: WidgetEnv s e -> StyleState -> Text -> Seq GlyphPos
getTextGlyphs wenv style text = glyphs where
fontMgr = wenv ^. L.fontManager
font = styleFont style
fSize = styleFontSize style
fSpcH = styleFontSpaceH style
glyphs = computeGlyphsPos fontMgr font fSize fSpcH text