{-# OPTIONS -Wall #-}
{-# LANGUAGE TemplateHaskell #-}

-- | Bindings to @rtext@
module Raylib.Core.Text
  ( -- * High level
    getFontDefault,
    loadFont,
    loadFontEx,
    loadFontFromImage,
    loadFontFromMemory,
    loadFontData,
    genImageFontAtlas,
    unloadFont,
    isFontReady,
    exportFontAsCode,
    drawFPS,
    drawText,
    drawTextEx,
    drawTextPro,
    drawTextCodepoint,
    drawTextCodepoints,
    setTextLineSpacing,
    measureText,
    measureTextEx,
    getGlyphIndex,
    getGlyphInfo,
    getGlyphAtlasRec,
    loadUTF8,
    loadCodepoints,
    getCodepointCount,
    getCodepointNext,
    getCodepointPrevious,
    codepointToUTF8,

    -- * Native
    c'getFontDefault,
    c'loadFont,
    c'loadFontEx,
    c'loadFontFromImage,
    c'loadFontFromMemory,
    c'loadFontData,
    c'genImageFontAtlas,
    c'unloadFontData,
    c'isFontReady,
    c'unloadFont,
    c'exportFontAsCode,
    c'drawFPS,
    c'drawText,
    c'drawTextEx,
    c'drawTextPro,
    c'drawTextCodepoint,
    c'drawTextCodepoints,
    c'setTextLineSpacing,
    c'measureText,
    c'measureTextEx,
    c'getGlyphIndex,
    c'getGlyphInfo,
    c'getGlyphAtlasRec,
    c'loadUTF8,
    c'loadCodepoints,
    c'getCodepointCount,
    c'getCodepointNext,
    c'getCodepointPrevious,
    c'codepointToUTF8
  )
where

import Foreign (Ptr, Storable (peek, sizeOf), toBool)
import Foreign.C
  ( CBool (..),
    CFloat (..),
    CInt (..),
    CString,
    CUChar,
    peekCString,
    withCString,
  )
import Raylib.Internal (WindowResources, addTextureId, unloadSingleTexture)
import Raylib.Internal.Foreign
  ( pop,
    popCArray,
    popCString,
    withFreeable,
    withFreeableArray,
    withFreeableArray2D,
    withFreeableArrayLen,
  )
import Raylib.Internal.TH (genNative)
import Raylib.Types
  ( Color,
    Font (font'texture),
    FontType,
    GlyphInfo,
    Image,
    Rectangle,
    Texture (texture'id),
    Vector2,
  )

$( genNative
     [ ("c'getFontDefault", "GetFontDefault_", "rl_bindings.h", [t|IO (Ptr Font)|], False),
       ("c'loadFont", "LoadFont_", "rl_bindings.h", [t|CString -> IO (Ptr Font)|], False),
       ("c'loadFontEx", "LoadFontEx_", "rl_bindings.h", [t|CString -> CInt -> Ptr CInt -> CInt -> IO (Ptr Font)|], False),
       ("c'loadFontFromImage", "LoadFontFromImage_", "rl_bindings.h", [t|Ptr Image -> Ptr Color -> CInt -> IO (Ptr Font)|], False),
       ("c'loadFontFromMemory", "LoadFontFromMemory_", "rl_bindings.h", [t|CString -> Ptr CUChar -> CInt -> CInt -> Ptr CInt -> CInt -> IO (Ptr Font)|], False),
       ("c'loadFontData", "LoadFontData_", "rl_bindings.h", [t|Ptr CUChar -> CInt -> CInt -> Ptr CInt -> CInt -> CInt -> IO (Ptr GlyphInfo)|], False),
       ("c'genImageFontAtlas", "GenImageFontAtlas_", "rl_bindings.h", [t|Ptr GlyphInfo -> Ptr (Ptr Rectangle) -> CInt -> CInt -> CInt -> CInt -> IO (Ptr Image)|], False),
       ("c'unloadFontData", "UnloadFontData_", "rl_bindings.h", [t|Ptr GlyphInfo -> CInt -> IO ()|], False),
       ("c'isFontReady", "IsFontReady_", "rl_bindings.h", [t|Ptr Font -> IO CBool|], False),
       ("c'unloadFont", "UnloadFont_", "rl_bindings.h", [t|Ptr Font -> IO ()|], False),
       ("c'exportFontAsCode", "ExportFontAsCode_", "rl_bindings.h", [t|Ptr Font -> CString -> IO CBool|], False),
       ("c'drawFPS", "DrawFPS_", "rl_bindings.h", [t|CInt -> CInt -> IO ()|], False),
       ("c'drawText", "DrawText_", "rl_bindings.h", [t|CString -> CInt -> CInt -> CInt -> Ptr Color -> IO ()|], False),
       ("c'drawTextEx", "DrawTextEx_", "rl_bindings.h", [t|Ptr Font -> CString -> Ptr Vector2 -> CFloat -> CFloat -> Ptr Color -> IO ()|], False),
       ("c'drawTextPro", "DrawTextPro_", "rl_bindings.h", [t|Ptr Font -> CString -> Ptr Vector2 -> Ptr Vector2 -> CFloat -> CFloat -> CFloat -> Ptr Color -> IO ()|], False),
       ("c'drawTextCodepoint", "DrawTextCodepoint_", "rl_bindings.h", [t|Ptr Font -> CInt -> Ptr Vector2 -> CFloat -> Ptr Color -> IO ()|], False),
       ("c'drawTextCodepoints", "DrawTextCodepoints_", "rl_bindings.h", [t|Ptr Font -> Ptr CInt -> CInt -> Ptr Vector2 -> CFloat -> CFloat -> Ptr Color -> IO ()|], False),
       ("c'setTextLineSpacing", "SetTextLineSpacing_", "rl_bindings.h", [t|CInt -> IO ()|], False),
       ("c'measureText", "MeasureText_", "rl_bindings.h", [t|CString -> CInt -> IO CInt|], False),
       ("c'measureTextEx", "MeasureTextEx_", "rl_bindings.h", [t|Ptr Font -> CString -> CFloat -> CFloat -> IO (Ptr Vector2)|], False),
       ("c'getGlyphIndex", "GetGlyphIndex_", "rl_bindings.h", [t|Ptr Font -> CInt -> IO CInt|], False),
       ("c'getGlyphInfo", "GetGlyphInfo_", "rl_bindings.h", [t|Ptr Font -> CInt -> IO (Ptr GlyphInfo)|], False),
       ("c'getGlyphAtlasRec", "GetGlyphAtlasRec_", "rl_bindings.h", [t|Ptr Font -> CInt -> IO (Ptr Rectangle)|], False),
       ("c'loadUTF8", "LoadUTF8_", "rl_bindings.h", [t|Ptr CInt -> CInt -> IO CString|], False),
       ("c'loadCodepoints", "LoadCodepoints_", "rl_bindings.h", [t|CString -> Ptr CInt -> IO (Ptr CInt)|], False),
       ("c'getCodepointCount", "GetCodepointCount_", "rl_bindings.h", [t|CString -> IO CInt|], False),
       ("c'getCodepointNext", "GetCodepointNext_", "rl_bindings.h", [t|CString -> Ptr CInt -> IO CInt|], False),
       ("c'getCodepointPrevious", "GetCodepointPrevious_", "rl_bindings.h", [t|CString -> Ptr CInt -> IO CInt|], False),
       ("c'codepointToUTF8", "CodepointToUTF8_", "rl_bindings.h", [t|CInt -> Ptr CInt -> IO CString|], False)
     ]
 )

getFontDefault :: IO Font
getFontDefault :: IO Font
getFontDefault = IO (Ptr Font)
c'getFontDefault IO (Ptr Font) -> (Ptr Font -> IO Font) -> IO Font
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr Font -> IO Font
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop

loadFont :: String -> WindowResources -> IO Font
loadFont :: String -> WindowResources -> IO Font
loadFont String
fileName WindowResources
wr = do
  Font
font <- String -> (CString -> IO (Ptr Font)) -> IO (Ptr Font)
forall a. String -> (CString -> IO a) -> IO a
withCString String
fileName CString -> IO (Ptr Font)
c'loadFont IO (Ptr Font) -> (Ptr Font -> IO Font) -> IO Font
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr Font -> IO Font
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop
  Integer -> WindowResources -> IO ()
forall a. Integral a => a -> WindowResources -> IO ()
addTextureId (Texture -> Integer
texture'id (Texture -> Integer) -> Texture -> Integer
forall a b. (a -> b) -> a -> b
$ Font -> Texture
font'texture Font
font) WindowResources
wr
  Font -> IO Font
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Font
font

loadFontEx :: String -> Int -> [Int] -> Int -> WindowResources -> IO Font
loadFontEx :: String -> Int -> [Int] -> Int -> WindowResources -> IO Font
loadFontEx String
fileName Int
fontSize [Int]
fontChars Int
glyphCount WindowResources
wr = do
  Font
font <- String -> (CString -> IO (Ptr Font)) -> IO (Ptr Font)
forall a. String -> (CString -> IO a) -> IO a
withCString String
fileName (\CString
f -> [CInt] -> (Ptr CInt -> IO (Ptr Font)) -> IO (Ptr Font)
forall a b.
(Freeable a, Storable a) =>
[a] -> (Ptr a -> IO b) -> IO b
withFreeableArray ((Int -> CInt) -> [Int] -> [CInt]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Int]
fontChars) (\Ptr CInt
c -> CString -> CInt -> Ptr CInt -> CInt -> IO (Ptr Font)
c'loadFontEx CString
f (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
fontSize) Ptr CInt
c (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
glyphCount))) IO (Ptr Font) -> (Ptr Font -> IO Font) -> IO Font
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr Font -> IO Font
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop
  Integer -> WindowResources -> IO ()
forall a. Integral a => a -> WindowResources -> IO ()
addTextureId (Texture -> Integer
texture'id (Texture -> Integer) -> Texture -> Integer
forall a b. (a -> b) -> a -> b
$ Font -> Texture
font'texture Font
font) WindowResources
wr
  Font -> IO Font
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Font
font

loadFontFromImage :: Image -> Color -> Int -> WindowResources -> IO Font
loadFontFromImage :: Image -> Color -> Int -> WindowResources -> IO Font
loadFontFromImage Image
image Color
key Int
firstChar WindowResources
wr = do
  Font
font <- Image -> (Ptr Image -> IO (Ptr Font)) -> IO (Ptr Font)
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Image
image (\Ptr Image
i -> Color -> (Ptr Color -> IO (Ptr Font)) -> IO (Ptr Font)
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Color
key (\Ptr Color
k -> Ptr Image -> Ptr Color -> CInt -> IO (Ptr Font)
c'loadFontFromImage Ptr Image
i Ptr Color
k (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
firstChar))) IO (Ptr Font) -> (Ptr Font -> IO Font) -> IO Font
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr Font -> IO Font
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop
  Integer -> WindowResources -> IO ()
forall a. Integral a => a -> WindowResources -> IO ()
addTextureId (Texture -> Integer
texture'id (Texture -> Integer) -> Texture -> Integer
forall a b. (a -> b) -> a -> b
$ Font -> Texture
font'texture Font
font) WindowResources
wr
  Font -> IO Font
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Font
font

loadFontFromMemory :: String -> [Integer] -> Int -> [Int] -> Int -> WindowResources -> IO Font
loadFontFromMemory :: String
-> [Integer] -> Int -> [Int] -> Int -> WindowResources -> IO Font
loadFontFromMemory String
fileType [Integer]
fileData Int
fontSize [Int]
fontChars Int
glyphCount WindowResources
wr = do
  Font
font <- String -> (CString -> IO (Ptr Font)) -> IO (Ptr Font)
forall a. String -> (CString -> IO a) -> IO a
withCString String
fileType (\CString
t -> [CUChar] -> (Int -> Ptr CUChar -> IO (Ptr Font)) -> IO (Ptr Font)
forall a b.
(Freeable a, Storable a) =>
[a] -> (Int -> Ptr a -> IO b) -> IO b
withFreeableArrayLen ((Integer -> CUChar) -> [Integer] -> [CUChar]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> CUChar
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Integer]
fileData) (\Int
size Ptr CUChar
d -> [CInt] -> (Ptr CInt -> IO (Ptr Font)) -> IO (Ptr Font)
forall a b.
(Freeable a, Storable a) =>
[a] -> (Ptr a -> IO b) -> IO b
withFreeableArray ((Int -> CInt) -> [Int] -> [CInt]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Int]
fontChars) (\Ptr CInt
c -> CString
-> Ptr CUChar -> CInt -> CInt -> Ptr CInt -> CInt -> IO (Ptr Font)
c'loadFontFromMemory CString
t Ptr CUChar
d (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt) -> Int -> CInt
forall a b. (a -> b) -> a -> b
$ Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
* CUChar -> Int
forall a. Storable a => a -> Int
sizeOf (CUChar
0 :: CUChar)) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
fontSize) Ptr CInt
c (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
glyphCount)))) IO (Ptr Font) -> (Ptr Font -> IO Font) -> IO Font
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr Font -> IO Font
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop
  Integer -> WindowResources -> IO ()
forall a. Integral a => a -> WindowResources -> IO ()
addTextureId (Texture -> Integer
texture'id (Texture -> Integer) -> Texture -> Integer
forall a b. (a -> b) -> a -> b
$ Font -> Texture
font'texture Font
font) WindowResources
wr
  Font -> IO Font
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Font
font

loadFontData :: [Integer] -> Int -> [Int] -> Int -> FontType -> IO GlyphInfo
loadFontData :: [Integer] -> Int -> [Int] -> Int -> FontType -> IO GlyphInfo
loadFontData [Integer]
fileData Int
fontSize [Int]
fontChars Int
glyphCount FontType
fontType = [CUChar]
-> (Int -> Ptr CUChar -> IO (Ptr GlyphInfo)) -> IO (Ptr GlyphInfo)
forall a b.
(Freeable a, Storable a) =>
[a] -> (Int -> Ptr a -> IO b) -> IO b
withFreeableArrayLen ((Integer -> CUChar) -> [Integer] -> [CUChar]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> CUChar
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Integer]
fileData) (\Int
size Ptr CUChar
d -> [CInt] -> (Ptr CInt -> IO (Ptr GlyphInfo)) -> IO (Ptr GlyphInfo)
forall a b.
(Freeable a, Storable a) =>
[a] -> (Ptr a -> IO b) -> IO b
withFreeableArray ((Int -> CInt) -> [Int] -> [CInt]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Int]
fontChars) (\Ptr CInt
c -> Ptr CUChar
-> CInt -> CInt -> Ptr CInt -> CInt -> CInt -> IO (Ptr GlyphInfo)
c'loadFontData Ptr CUChar
d (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt) -> Int -> CInt
forall a b. (a -> b) -> a -> b
$ Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
* CUChar -> Int
forall a. Storable a => a -> Int
sizeOf (CUChar
0 :: CUChar)) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
fontSize) Ptr CInt
c (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
glyphCount) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt) -> Int -> CInt
forall a b. (a -> b) -> a -> b
$ FontType -> Int
forall a. Enum a => a -> Int
fromEnum FontType
fontType))) IO (Ptr GlyphInfo)
-> (Ptr GlyphInfo -> IO GlyphInfo) -> IO GlyphInfo
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr GlyphInfo -> IO GlyphInfo
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop

genImageFontAtlas :: [GlyphInfo] -> [[Rectangle]] -> Int -> Int -> Int -> Int -> IO Image
genImageFontAtlas :: [GlyphInfo]
-> [[Rectangle]] -> Int -> Int -> Int -> Int -> IO Image
genImageFontAtlas [GlyphInfo]
chars [[Rectangle]]
recs Int
glyphCount Int
fontSize Int
padding Int
packMethod = [GlyphInfo] -> (Ptr GlyphInfo -> IO (Ptr Image)) -> IO (Ptr Image)
forall a b.
(Freeable a, Storable a) =>
[a] -> (Ptr a -> IO b) -> IO b
withFreeableArray [GlyphInfo]
chars (\Ptr GlyphInfo
c -> [[Rectangle]]
-> (Ptr (Ptr Rectangle) -> IO (Ptr Image)) -> IO (Ptr Image)
forall a b.
(Freeable a, Storable a) =>
[[a]] -> (Ptr (Ptr a) -> IO b) -> IO b
withFreeableArray2D [[Rectangle]]
recs (\Ptr (Ptr Rectangle)
r -> Ptr GlyphInfo
-> Ptr (Ptr Rectangle)
-> CInt
-> CInt
-> CInt
-> CInt
-> IO (Ptr Image)
c'genImageFontAtlas Ptr GlyphInfo
c Ptr (Ptr Rectangle)
r (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
glyphCount) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
fontSize) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
padding) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
packMethod))) IO (Ptr Image) -> (Ptr Image -> IO Image) -> IO Image
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr Image -> IO Image
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop

-- | Unloads a font from GPU memory (VRAM). Fonts are automatically unloaded
-- when `Raylib.Core.closeWindow` is called, so manually unloading fonts is not required.
-- In larger projects, you may want to manually unload fonts to avoid having
-- them in VRAM for too long.
unloadFont :: Font -> WindowResources -> IO ()
unloadFont :: Font -> WindowResources -> IO ()
unloadFont Font
font = Integer -> WindowResources -> IO ()
forall a. Integral a => a -> WindowResources -> IO ()
unloadSingleTexture (Texture -> Integer
texture'id (Texture -> Integer) -> Texture -> Integer
forall a b. (a -> b) -> a -> b
$ Font -> Texture
font'texture Font
font)

isFontReady :: Font -> IO Bool
isFontReady :: Font -> IO Bool
isFontReady Font
font = CBool -> Bool
forall a. (Eq a, Num a) => a -> Bool
toBool (CBool -> Bool) -> IO CBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Font -> (Ptr Font -> IO CBool) -> IO CBool
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font Ptr Font -> IO CBool
c'isFontReady

exportFontAsCode :: Font -> String -> IO Bool
exportFontAsCode :: Font -> String -> IO Bool
exportFontAsCode Font
font String
fileName = CBool -> Bool
forall a. (Eq a, Num a) => a -> Bool
toBool (CBool -> Bool) -> IO CBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Font -> (Ptr Font -> IO CBool) -> IO CBool
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font (String -> (CString -> IO CBool) -> IO CBool
forall a. String -> (CString -> IO a) -> IO a
withCString String
fileName ((CString -> IO CBool) -> IO CBool)
-> (Ptr Font -> CString -> IO CBool) -> Ptr Font -> IO CBool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Font -> CString -> IO CBool
c'exportFontAsCode)

drawFPS :: Int -> Int -> IO ()
drawFPS :: Int -> Int -> IO ()
drawFPS Int
x Int
y = CInt -> CInt -> IO ()
c'drawFPS (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y)

drawText :: String -> Int -> Int -> Int -> Color -> IO ()
drawText :: String -> Int -> Int -> Int -> Color -> IO ()
drawText String
text Int
x Int
y Int
fontSize Color
color = String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withCString String
text (\CString
t -> Color -> (Ptr Color -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Color
color (CString -> CInt -> CInt -> CInt -> Ptr Color -> IO ()
c'drawText CString
t (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
fontSize)))

drawTextEx :: Font -> String -> Vector2 -> Float -> Float -> Color -> IO ()
drawTextEx :: Font -> String -> Vector2 -> Float -> Float -> Color -> IO ()
drawTextEx Font
font String
text Vector2
position Float
fontSize Float
spacing Color
tint = Font -> (Ptr Font -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font (\Ptr Font
f -> String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withCString String
text (\CString
t -> Vector2 -> (Ptr Vector2 -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Vector2
position (\Ptr Vector2
p -> Color -> (Ptr Color -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Color
tint (Ptr Font
-> CString -> Ptr Vector2 -> CFloat -> CFloat -> Ptr Color -> IO ()
c'drawTextEx Ptr Font
f CString
t Ptr Vector2
p (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
fontSize) (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
spacing)))))

drawTextPro :: Font -> String -> Vector2 -> Vector2 -> Float -> Float -> Float -> Color -> IO ()
drawTextPro :: Font
-> String
-> Vector2
-> Vector2
-> Float
-> Float
-> Float
-> Color
-> IO ()
drawTextPro Font
font String
text Vector2
position Vector2
origin Float
rotation Float
fontSize Float
spacing Color
tint = Font -> (Ptr Font -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font (\Ptr Font
f -> String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withCString String
text (\CString
t -> Vector2 -> (Ptr Vector2 -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Vector2
position (\Ptr Vector2
p -> Vector2 -> (Ptr Vector2 -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Vector2
origin (\Ptr Vector2
o -> Color -> (Ptr Color -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Color
tint (Ptr Font
-> CString
-> Ptr Vector2
-> Ptr Vector2
-> CFloat
-> CFloat
-> CFloat
-> Ptr Color
-> IO ()
c'drawTextPro Ptr Font
f CString
t Ptr Vector2
p Ptr Vector2
o (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
rotation) (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
fontSize) (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
spacing))))))

drawTextCodepoint :: Font -> Int -> Vector2 -> Float -> Color -> IO ()
drawTextCodepoint :: Font -> Int -> Vector2 -> Float -> Color -> IO ()
drawTextCodepoint Font
font Int
codepoint Vector2
position Float
fontSize Color
tint = Font -> (Ptr Font -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font (\Ptr Font
f -> Vector2 -> (Ptr Vector2 -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Vector2
position (\Ptr Vector2
p -> Color -> (Ptr Color -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Color
tint (Ptr Font -> CInt -> Ptr Vector2 -> CFloat -> Ptr Color -> IO ()
c'drawTextCodepoint Ptr Font
f (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
codepoint) Ptr Vector2
p (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
fontSize))))

drawTextCodepoints :: Font -> [Int] -> Vector2 -> Float -> Float -> Color -> IO ()
drawTextCodepoints :: Font -> [Int] -> Vector2 -> Float -> Float -> Color -> IO ()
drawTextCodepoints Font
font [Int]
codepoints Vector2
position Float
fontSize Float
spacing Color
tint = Font -> (Ptr Font -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font (\Ptr Font
f -> [CInt] -> (Int -> Ptr CInt -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
[a] -> (Int -> Ptr a -> IO b) -> IO b
withFreeableArrayLen ((Int -> CInt) -> [Int] -> [CInt]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Int]
codepoints) (\Int
count Ptr CInt
cp -> Vector2 -> (Ptr Vector2 -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Vector2
position (\Ptr Vector2
p -> Color -> (Ptr Color -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Color
tint (Ptr Font
-> Ptr CInt
-> CInt
-> Ptr Vector2
-> CFloat
-> CFloat
-> Ptr Color
-> IO ()
c'drawTextCodepoints Ptr Font
f Ptr CInt
cp (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
count) Ptr Vector2
p (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
fontSize) (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
spacing)))))

setTextLineSpacing :: Int -> IO ()
setTextLineSpacing :: Int -> IO ()
setTextLineSpacing = CInt -> IO ()
c'setTextLineSpacing (CInt -> IO ()) -> (Int -> CInt) -> Int -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral

measureText :: String -> Int -> IO Int
measureText :: String -> Int -> IO Int
measureText String
text Int
fontSize = CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> (CString -> IO CInt) -> IO CInt
forall a. String -> (CString -> IO a) -> IO a
withCString String
text (\CString
t -> CString -> CInt -> IO CInt
c'measureText CString
t (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
fontSize))

measureTextEx :: Font -> String -> Float -> Float -> IO Vector2
measureTextEx :: Font -> String -> Float -> Float -> IO Vector2
measureTextEx Font
font String
text Float
fontSize Float
spacing = Font -> (Ptr Font -> IO (Ptr Vector2)) -> IO (Ptr Vector2)
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font (\Ptr Font
f -> String -> (CString -> IO (Ptr Vector2)) -> IO (Ptr Vector2)
forall a. String -> (CString -> IO a) -> IO a
withCString String
text (\CString
t -> Ptr Font -> CString -> CFloat -> CFloat -> IO (Ptr Vector2)
c'measureTextEx Ptr Font
f CString
t (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
fontSize) (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
spacing))) IO (Ptr Vector2) -> (Ptr Vector2 -> IO Vector2) -> IO Vector2
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr Vector2 -> IO Vector2
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop

getGlyphIndex :: Font -> Int -> IO Int
getGlyphIndex :: Font -> Int -> IO Int
getGlyphIndex Font
font Int
codepoint = CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Font -> (Ptr Font -> IO CInt) -> IO CInt
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font (\Ptr Font
f -> Ptr Font -> CInt -> IO CInt
c'getGlyphIndex Ptr Font
f (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
codepoint))

getGlyphInfo :: Font -> Int -> IO GlyphInfo
getGlyphInfo :: Font -> Int -> IO GlyphInfo
getGlyphInfo Font
font Int
codepoint = Font -> (Ptr Font -> IO (Ptr GlyphInfo)) -> IO (Ptr GlyphInfo)
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font (\Ptr Font
f -> Ptr Font -> CInt -> IO (Ptr GlyphInfo)
c'getGlyphInfo Ptr Font
f (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
codepoint)) IO (Ptr GlyphInfo)
-> (Ptr GlyphInfo -> IO GlyphInfo) -> IO GlyphInfo
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr GlyphInfo -> IO GlyphInfo
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop

getGlyphAtlasRec :: Font -> Int -> IO Rectangle
getGlyphAtlasRec :: Font -> Int -> IO Rectangle
getGlyphAtlasRec Font
font Int
codepoint = Font -> (Ptr Font -> IO (Ptr Rectangle)) -> IO (Ptr Rectangle)
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Font
font (\Ptr Font
f -> Ptr Font -> CInt -> IO (Ptr Rectangle)
c'getGlyphAtlasRec Ptr Font
f (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
codepoint)) IO (Ptr Rectangle)
-> (Ptr Rectangle -> IO Rectangle) -> IO Rectangle
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr Rectangle -> IO Rectangle
forall a. (Freeable a, Storable a) => Ptr a -> IO a
pop

loadUTF8 :: [Integer] -> IO String
loadUTF8 :: [Integer] -> IO String
loadUTF8 [Integer]
codepoints =
  [CInt] -> (Int -> Ptr CInt -> IO CString) -> IO CString
forall a b.
(Freeable a, Storable a) =>
[a] -> (Int -> Ptr a -> IO b) -> IO b
withFreeableArrayLen
    ((Integer -> CInt) -> [Integer] -> [CInt]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Integer]
codepoints)
    ( \Int
size Ptr CInt
c ->
        Ptr CInt -> CInt -> IO CString
c'loadUTF8 Ptr CInt
c (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size)
    )
    IO CString -> (CString -> IO String) -> IO String
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CString -> IO String
popCString

loadCodepoints :: String -> IO [Int]
loadCodepoints :: String -> IO [Int]
loadCodepoints String
text =
  String -> (CString -> IO [Int]) -> IO [Int]
forall a. String -> (CString -> IO a) -> IO a
withCString
    String
text
    ( \CString
t ->
        CInt -> (Ptr CInt -> IO [Int]) -> IO [Int]
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable
          CInt
0
          ( \Ptr CInt
n -> do
              Ptr CInt
res <- CString -> Ptr CInt -> IO (Ptr CInt)
c'loadCodepoints CString
t Ptr CInt
n
              CInt
num <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
n
              (CInt -> Int) -> [CInt] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([CInt] -> [Int]) -> IO [CInt] -> IO [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Ptr CInt -> IO [CInt]
forall a. (Freeable a, Storable a) => Int -> Ptr a -> IO [a]
popCArray (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
num) Ptr CInt
res
          )
    )

getCodepointCount :: String -> IO Int
getCodepointCount :: String -> IO Int
getCodepointCount String
text = CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> (CString -> IO CInt) -> IO CInt
forall a. String -> (CString -> IO a) -> IO a
withCString String
text CString -> IO CInt
c'getCodepointCount

getCodepointNext :: String -> IO (Int, Int)
getCodepointNext :: String -> IO (Int, Int)
getCodepointNext String
text =
  String -> (CString -> IO (Int, Int)) -> IO (Int, Int)
forall a. String -> (CString -> IO a) -> IO a
withCString
    String
text
    ( \CString
t ->
        CInt -> (Ptr CInt -> IO (Int, Int)) -> IO (Int, Int)
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable
          CInt
0
          ( \Ptr CInt
n ->
              do
                CInt
res <- CString -> Ptr CInt -> IO CInt
c'getCodepointNext CString
t Ptr CInt
n
                CInt
num <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
n
                (Int, Int) -> IO (Int, Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
res, CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
num)
          )
    )

getCodepointPrevious :: String -> IO (Int, Int)
getCodepointPrevious :: String -> IO (Int, Int)
getCodepointPrevious String
text =
  String -> (CString -> IO (Int, Int)) -> IO (Int, Int)
forall a. String -> (CString -> IO a) -> IO a
withCString
    String
text
    ( \CString
t ->
        CInt -> (Ptr CInt -> IO (Int, Int)) -> IO (Int, Int)
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable
          CInt
0
          ( \Ptr CInt
n ->
              do
                CInt
res <- CString -> Ptr CInt -> IO CInt
c'getCodepointPrevious CString
t Ptr CInt
n
                CInt
num <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
n
                (Int, Int) -> IO (Int, Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
res, CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
num)
          )
    )

codepointToUTF8 :: Int -> IO String
codepointToUTF8 :: Int -> IO String
codepointToUTF8 Int
codepoint = CInt -> (Ptr CInt -> IO CString) -> IO CString
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable CInt
0 (CInt -> Ptr CInt -> IO CString
c'codepointToUTF8 (CInt -> Ptr CInt -> IO CString) -> CInt -> Ptr CInt -> IO CString
forall a b. (a -> b) -> a -> b
$ Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
codepoint) IO CString -> (CString -> IO String) -> IO String
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CString -> IO String
peekCString