-------------------------------------------------------------------------------- -- | -- Module : Graphics.UI.GLUT.Fonts -- Copyright : (c) Sven Panne 2002-2018 -- License : BSD3 -- -- Maintainer : Sven Panne -- Stability : stable -- Portability : portable -- -- GLUT supports two types of font rendering: stroke fonts, meaning each -- character is rendered as a set of line segments; and bitmap fonts, where each -- character is a bitmap generated with -- 'Graphics.Rendering.OpenGL.GL.Bitmaps.bitmap'. Stroke fonts have the -- advantage that because they are geometry, they can be arbitrarily scale and -- rendered. Bitmap fonts are less flexible since they are rendered as bitmaps -- but are usually faster than stroke fonts. -- -------------------------------------------------------------------------------- module Graphics.UI.GLUT.Fonts ( Font(..), BitmapFont(..), StrokeFont(..), ) where import Control.Monad.IO.Class ( MonadIO(..) ) import Data.Char ( ord ) import Foreign.C.String ( withCString ) import Foreign.C.Types ( CInt ) import Foreign.Ptr ( castPtr ) import Graphics.Rendering.OpenGL ( GLint, GLfloat ) import Graphics.UI.GLUT.Raw -------------------------------------------------------------------------------- class Font a where -- | Render the string in the named font, without using any display lists. -- Rendering a nonexistent character has no effect. -- -- If the font is a bitmap font, 'renderString' automatically sets the OpenGL -- unpack pixel storage modes it needs appropriately and saves and restores -- the previous modes before returning. The generated call to -- 'Graphics.Rendering.OpenGL.GL.bitmap' will adjust the current raster -- position based on the width of the string. -- If the font is a stroke font, -- 'Graphics.Rendering.OpenGL.GL.CoordTrans.translate' is used to translate -- the current model view matrix to advance the width of the string. renderString :: MonadIO m => a -> String -> m () -- | For a bitmap font, return the width in pixels of a string. For a stroke -- font, return the width in units. While the width of characters in a font -- may vary (though fixed width fonts do not vary), the maximum height -- characteristics of a particular font are fixed. stringWidth :: MonadIO m => a -> String -> m GLint -- | (/freeglut only/) For a bitmap font, return the maximum height of the -- characters in the given font measured in pixels. For a stroke font, -- return the height in units. fontHeight :: MonadIO m => a -> m GLfloat instance Font BitmapFont where renderString = bitmapString stringWidth = bitmapLength fontHeight = bitmapHeight instance Font StrokeFont where renderString = strokeString stringWidth = strokeLength fontHeight = strokeHeight -------------------------------------------------------------------------------- bitmapString :: MonadIO m => BitmapFont -> String -> m () bitmapString f s = do i <- marshalBitmapFont f mapM_ (\c -> withChar c (glutBitmapCharacter i)) s withChar :: Char -> (CInt -> m a) -> m a withChar c f = f . fromIntegral . ord $ c -------------------------------------------------------------------------------- strokeString :: MonadIO m => StrokeFont -> String -> m () strokeString f s = do i <- marshalStrokeFont f mapM_ (\c -> withChar c (glutStrokeCharacter i)) s -------------------------------------------------------------------------------- bitmapLength :: MonadIO m => BitmapFont -- ^ Bitmap font to use. -> String -- ^ String to return width of (not confined to 8 -- bits). -> m GLint -- ^ Width in pixels. bitmapLength f s = liftIO $ do i <- marshalBitmapFont f fmap fromIntegral $ withCString s (glutBitmapLength i . castPtr) -------------------------------------------------------------------------------- strokeLength :: MonadIO m => StrokeFont -- ^ Stroke font to use. -> String -- ^ String to return width of (not confined to 8 -- bits). -> m GLint -- ^ Width in units. strokeLength f s = liftIO $ do i <- marshalStrokeFont f fmap fromIntegral $ withCString s (glutStrokeLength i . castPtr) -------------------------------------------------------------------------------- bitmapHeight :: MonadIO m => BitmapFont -- ^ Bitmap font to use. -> m GLfloat -- ^ Height in pixels. bitmapHeight f = liftIO $ do i <- marshalBitmapFont f fromIntegral `fmap` glutBitmapHeight i -------------------------------------------------------------------------------- strokeHeight :: MonadIO m => StrokeFont -- ^ Stroke font to use. -> m GLfloat -- ^ Height in units. strokeHeight f = glutStrokeHeight =<< marshalStrokeFont f