X11-xft 0.3.3 → 0.3.4
raw patch · 3 files changed
+111/−3 lines, 3 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Graphics.X11.Xft: xftDrawStringFallback :: XftDraw -> XftColor -> [XftFont] -> Int -> Int -> String -> IO ()
+ Graphics.X11.Xft: xftTextAccumExtents :: Display -> [XftFont] -> String -> IO XGlyphInfo
+ Graphics.X11.Xft: xftfont_max_ascent :: NonEmpty XftFont -> IO Int
+ Graphics.X11.Xft: xftfont_max_descent :: NonEmpty XftFont -> IO Int
+ Graphics.X11.Xft: xftfont_max_height :: NonEmpty XftFont -> IO Int
Files
- CHANGES.md +15/−0
- Graphics/X11/Xft.hsc +93/−0
- X11-xft.cabal +3/−3
CHANGES.md view
@@ -1,5 +1,20 @@ # Change Log / Release Notes +## 0.3.4 (2021-12-11)++ * Dropped support for GHC 7.10.++ * Added `xftDrawStringFallback`, which works like `xftDrawString` but+ supports font fallback.++ * Added `xftTextAccumExtents`, which works like `xftTextExtents` but+ possibly uses different fonts for different parts of the string and+ returns the accumulative extents.++ * Added the functions `xftfont_max_ascent`, `xftfont_max_descent`, and+ `xftfont_max_height` to gain information about a non-empty list of+ `XftFont`s.+ ## 0.3.3 (2021-12-01) * Fixed flipped green/blue values in XRenderColor.
Graphics/X11/Xft.hsc view
@@ -26,8 +26,11 @@ , xftDrawDestroy , XftFont , xftfont_ascent+ , xftfont_max_ascent , xftfont_descent+ , xftfont_max_descent , xftfont_height+ , xftfont_max_height , xftfont_max_advance_width , xftFontOpen , xftFontOpenXlfd@@ -37,7 +40,9 @@ , xftFontClose , xftDrawGlyphs , xftDrawString+ , xftDrawStringFallback , xftTextExtents+ , xftTextAccumExtents , xftDrawRect , xftDrawSetClipRectangles , xftDrawSetSubwindowMode@@ -50,7 +55,12 @@ import Graphics.X11.Xrender import Codec.Binary.UTF8.String as UTF8+import Control.Arrow ((&&&)) import Control.Monad (void)+import Data.Char (ord)+import Data.Function (on)+import Data.List (groupBy, foldl')+import Data.List.NonEmpty (NonEmpty) import Foreign hiding (void) import Foreign.C.String import Foreign.C.Types@@ -182,12 +192,32 @@ foreign import ccall "XftFontClose" xftFontClose :: Display -> XftFont -> IO () +-- Support for multiple fonts --++xftfont_max_ascent :: NonEmpty XftFont -> IO Int+xftfont_max_ascent = fmap maximum . mapM xftfont_ascent++xftfont_max_descent :: NonEmpty XftFont -> IO Int+xftfont_max_descent = fmap maximum . mapM xftfont_descent++xftfont_max_height :: NonEmpty XftFont -> IO Int+xftfont_max_height = fmap maximum . mapM xftfont_height+ --------------------- -- Painting --------------------- -- Drawing strings or glyphs -- +foreign import ccall "XftCharExists"+ cXftCharExists :: Display -> XftFont -> (#type FcChar32) -> IO (#type FcBool)++xftCharExists :: Display -> XftFont -> Char -> IO Bool+xftCharExists d f c = bool <$> cXftCharExists d f (fi $ ord c)+ where+ bool 0 = False+ bool _ = True+ foreign import ccall "XftDrawGlyphs" cXftDrawGlyphs :: XftDraw -> XftColor -> XftFont -> CInt -> CInt -> Ptr (#type FT_UInt) -> CInt -> IO () @@ -218,6 +248,69 @@ \cglyph -> do cXftTextExtentsUtf8 d f str_ptr (fi len) cglyph peek cglyph++-- Support for multiple fonts --++-- | Like 'xftDrawString', but fall back to another font in the given+-- list if necessary (i.e., should a character not be drawable with the+-- currently selected font).+xftDrawStringFallback :: XftDraw -> XftColor -> [XftFont] -> Int -> Int -> String -> IO ()+xftDrawStringFallback d c fs x y string = do+ display <- xftDrawDisplay d+ chunks <- getChunks display fs x y string+ mapM_ (\(f, s, (XGlyphInfo _ _ x' y' _ _)) -> xftDrawString d c f x' y' s) chunks++-- | Like 'xftTextExtents' but for multiple fonts. Return+-- accumulative extents using appropriate fonts for each part of+-- string.+xftTextAccumExtents :: Display -> [XftFont] -> String -> IO XGlyphInfo+xftTextAccumExtents disp fts string = do+ chunks <- map (\ (_, _, gi) -> gi) <$> getChunks disp fts 0 0 string+ return $ foldl' calcExtents (XGlyphInfo 0 0 0 0 0 0) chunks+ where+ calcExtents :: XGlyphInfo -> XGlyphInfo -> XGlyphInfo+ calcExtents (XGlyphInfo _ _ x y xo yo) (XGlyphInfo w' h' _ _ xo' yo')+ = XGlyphInfo (xo + w') (yo + h') x y (xo + xo') (yo + yo')++-- | Split string and determine fonts/offsets for individual parts+getChunks :: Display+ -> [XftFont]+ -> Int+ -> Int+ -> String+ -> IO [(XftFont, String, XGlyphInfo)]+getChunks disp fts xInit yInit str = do+ chunks <- getFonts fts str+ getChunksExtents xInit yInit chunks+ where+ -- Split string and determine fonts for individual parts+ getFonts :: [XftFont] -> String -> IO [(XftFont, String)]+ getFonts [] _ = return []+ getFonts [ft] s = return [(ft, s)]+ getFonts fonts@(ft:_) s = do+ -- Determine which glyph can be rendered by current font+ glyphs <- mapM (xftCharExists disp ft) s+ -- Split string into parts that return "can/cannot be rendered"+ let splits = map (fst . head &&& map snd)+ . groupBy ((==) `on` fst)+ $ zip glyphs s+ -- Determine which font to render each chunk with+ concat <$> mapM (getFont fonts) splits++ -- Determine fonts for substrings+ getFont :: [XftFont] -> (Bool, String) -> IO [(XftFont, String)]+ getFont [] _ = return []+ getFont [ft] (_, s) = return [(ft, s)] -- Last font, use it+ getFont (ft:_) (True, s) = return [(ft, s)] -- Current font can render this substring+ getFont (_:fs) (False, s) = getFonts fs s -- Fallback to next font++ -- Determine coordinates for chunks using extents+ getChunksExtents :: Int -> Int -> [(XftFont, String)] -> IO [(XftFont, String, XGlyphInfo)]+ getChunksExtents _ _ [] = return []+ getChunksExtents x y ((f, s) : chunks) = do+ (XGlyphInfo w h _ _ xo yo) <- xftTextExtents disp f s+ rest <- getChunksExtents (x + xo) (y + yo) chunks+ return $ (f, s, XGlyphInfo w h x y xo yo) : rest -- Drawing auxilary --
X11-xft.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: X11-xft-version: 0.3.3+version: 0.3.4 license: BSD-3-Clause license-file: LICENSE author: Clemens Fruhwirth@@ -12,7 +12,7 @@ fonts with anti-aliasing and subpixel rendering. The bindings also provide minimal bindings to Xrender parts. build-type: Simple-tested-with: GHC == 7.10.3 || == 8.0.2 || == 8.2.2 || == 8.4.4 || == 8.6.5 || == 8.8.4 || == 8.10.4 || == 9.0.1 || == 9.2.1+tested-with: GHC == 8.0.2 || == 8.2.2 || == 8.4.4 || == 8.6.5 || == 8.8.4 || == 8.10.4 || == 9.0.1 || == 9.2.1 extra-source-files: CHANGES.md README.md @@ -22,7 +22,7 @@ manual: True library- build-depends: base < 5+ build-depends: base >= 4.9.0.0 && < 5 , X11 >= 1.2.1 , utf8-string >= 0.1 ghc-options: -funbox-strict-fields -Wall -fno-warn-unused-binds