simple-pango-0.1.0.1: src/Graphics/Pango/Basic/GlyphStorage/Internal.hsc
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE BlockArguments, LambdaCase, TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
module Graphics.Pango.Basic.GlyphStorage.Internal (
-- * PANGO FIXED
PangoFixed, PU, fromCInt, toCInt,
-- * PANGO RECTANGLE AND EXTENTS
-- ** PangoRectangleFixed
PangoRectangleFixed(..),
pattern PangoRectangleFixed,
pangoRectangleFixedX, pangoRectangleFixedY,
pangoRectangleFixedWidth, pangoRectangleFixedHeight,
PangoRectangleFixedPrim(..), PangoRectangleFixedST, PangoRectangleFixedIO,
pangoRectangleFixedFreeze, pangoRectangleFixedThaw, pangoRectangleFixedCopy,
-- ** PangoRectanglePixel
PangoRectanglePixel(..),
pattern PangoRectanglePixel,
pangoRectanglePixelX, pangoRectanglePixelY,
pangoRectanglePixelWidth, pangoRectanglePixelHeight,
PangoRectanglePixelPrim(..),
PangoRectanglePixelST, PangoRectanglePixelIO,
pangoRectanglePixelFreeze, pangoRectanglePixelThaw,
pangoRectanglePixelCopy,
-- ** Extents and PixelExtents
Extents(..), PixelExtents(..),
pangoExtentsToPixelsInclusive, pangoExtentsToPixelsNearest,
-- * PANGO GLYPH ITEM
PangoGlyphItem(..), PangoLayoutRun,
mkPangoGlyphItemMaybe0
) where
import GHC.Stack
import Foreign.Ptr
import Foreign.Ptr.Misc
import Foreign.ForeignPtr hiding (newForeignPtr)
import Foreign.Concurrent
import Foreign.Marshal
import Foreign.Storable
import Foreign.C.Types
import Foreign.C.Struct
import Control.Monad.Primitive
import Control.Exception
import Data.Fixed
import System.IO.Unsafe
#include <pango/pango.h>
data PU
instance HasResolution PU where resolution _ = #{const PANGO_SCALE}
type PangoFixed = Fixed PU
minCInt, maxCInt :: Integer
minCInt = fromIntegral (minBound @CInt)
maxCInt = fromIntegral (maxBound @CInt)
fromCInt :: CInt -> PangoFixed
fromCInt = MkFixed . fromIntegral
toCInt :: HasCallStack => PangoFixed -> CInt
toCInt (MkFixed i)
| minCInt <= i && i <= maxCInt = fromIntegral i
| otherwise = unsafePerformIO do
putStrLn $ prettyCallStack callStack
throw Overflow
struct "PangoRectangleFixed" #{size PangoRectangle} #{alignment PangoRectangle}
[ ("x", ''PangoFixed, [| (fromCInt <$>) . #{peek PangoRectangle, x} |],
[| \p -> #{poke PangoRectangle, x} p . toCInt |]),
("y", ''PangoFixed, [| (fromCInt <$>) . #{peek PangoRectangle, y} |],
[| \p -> #{poke PangoRectangle, y} p . toCInt |]),
("width", ''PangoFixed, [| (fromCInt <$>) . #{peek PangoRectangle, width} |],
[| \p -> #{poke PangoRectangle, width} p . toCInt |]),
("height", ''PangoFixed, [| (fromCInt <$>) . #{peek PangoRectangle, height} |],
[| \p -> #{poke PangoRectangle, height} p . toCInt |]) ]
[''Show]
c_pango_rectangle_copy :: Ptr PangoRectangleFixed -> IO (Ptr PangoRectangleFixed)
c_pango_rectangle_copy s = mallocBytes #{size PangoRectangle} >>= \d ->
d <$ copyBytes d s #{size PangoRectangle}
c_pango_rectangle_free :: Ptr PangoRectangleFixed -> IO ()
c_pango_rectangle_free = free
structPrim "PangoRectangleFixed" 'c_pango_rectangle_copy 'c_pango_rectangle_free
[''Show]
{-
pattern PangoRectangleFixed ::
PangoFixed -> PangoFixed -> PangoFixed -> PangoFixed -> PangoRectangle
pattern PangoRectangleFixed {
pangoRectangleFixedX, pangoRectangleFixedY,
pangoRectangleFixedWidth, pangoRectangleFixedHeight } <- (pangoRectangleFixed -> (
pangoRectangleFixedX, pangoRectangleFixedY,
pangoRectangleFixedWidth, pangoRectangleFixedHeight )) where
PangoRectangleFixed x y w h =
PangoRectangle (toCInt x) (toCInt y) (toCInt w) (toCInt h)
pangoRectangleFixed ::
PangoRectangle -> (PangoFixed, PangoFixed, PangoFixed, PangoFixed)
pangoRectangleFixed (PangoRectangle
(fromCInt -> x) (fromCInt -> y)
(fromCInt -> w) (fromCInt -> h)) = (x, y, w, h)
-}
struct "PangoRectanglePixel" #{size PangoRectangle} #{alignment PangoRectangle}
[ ("x", ''CInt, [| #{peek PangoRectangle, x} |],
[| #{poke PangoRectangle, x} |]),
("y", ''CInt, [| #{peek PangoRectangle, y} |],
[| #{poke PangoRectangle, y} |]),
("width", ''CInt, [| #{peek PangoRectangle, width} |],
[| #{poke PangoRectangle, width} |]),
("height", ''CInt, [| #{peek PangoRectangle, height} |],
[| #{poke PangoRectangle, height} |]) ]
[''Show]
c_pango_rectangle_pixel_copy :: Ptr PangoRectanglePixel -> IO (Ptr PangoRectanglePixel)
c_pango_rectangle_pixel_copy s = castPtr <$> c_pango_rectangle_copy (castPtr s)
c_pango_rectangle_pixel_free :: Ptr PangoRectanglePixel -> IO ()
c_pango_rectangle_pixel_free = c_pango_rectangle_free . castPtr
structPrim "PangoRectanglePixel" 'c_pango_rectangle_pixel_copy
'c_pango_rectangle_pixel_free [''Show]
data Extents = Extents {
extentsInkRect :: PangoRectangleFixed,
extentsLogicalRect :: PangoRectangleFixed } deriving Show
data PixelExtents = PixelExtents {
pixelExtentsInkRect :: PangoRectanglePixel,
pixelExtentsLogicalRect :: PangoRectanglePixel } deriving Show
newtype PangoGlyphItem = PangoGlyphItem (ForeignPtr PangoGlyphItem) deriving Show
mkPangoGlyphItemMaybe0 :: Ptr PangoGlyphItem -> IO (Maybe PangoGlyphItem)
mkPangoGlyphItemMaybe0 = \case
NullPtr -> pure Nothing
p -> Just . PangoGlyphItem <$> do
p' <- c_pango_glyph_item_copy p
newForeignPtr p' $ c_pango_glyph_item_free p'
foreign import ccall "pango_glyph_item_free" c_pango_glyph_item_free ::
Ptr PangoGlyphItem -> IO ()
foreign import ccall "pango_glyph_item_copy" c_pango_glyph_item_copy ::
Ptr PangoGlyphItem -> IO (Ptr PangoGlyphItem)
type PangoLayoutRun = PangoGlyphItem
pangoExtentsToPixelsInclusive ::
PrimMonad m => PangoRectangleFixedPrim (PrimState m) -> m ()
pangoExtentsToPixelsInclusive (PangoRectangleFixedPrim fr) = unsafeIOToPrim
$ withForeignPtr fr (`c_pango_extents_to_pixels` nullPtr)
pangoExtentsToPixelsNearest ::
PrimMonad m => PangoRectangleFixedPrim (PrimState m) -> m ()
pangoExtentsToPixelsNearest (PangoRectangleFixedPrim fr) = unsafeIOToPrim
. withForeignPtr fr $ c_pango_extents_to_pixels nullPtr
foreign import ccall "pango_extents_to_pixels" c_pango_extents_to_pixels ::
Ptr PangoRectangleFixed -> Ptr PangoRectangleFixed -> IO ()