mirror of
				https://github.com/Drezil/dear-imgui.hs.git
				synced 2025-11-04 15:11:06 +01:00 
			
		
		
		
	Extended font & glyph support (#114)
* Separate font utils, add glyph support (#113) * Implement font glyph ranges builder * Implement raw font config binds * Implement font atlas module * Rewrite font altas rebuilder in Managed
This commit is contained in:
		
							
								
								
									
										150
									
								
								examples/fonts/Main.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								examples/fonts/Main.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
{-# language BlockArguments #-}
 | 
			
		||||
{-# language LambdaCase #-}
 | 
			
		||||
{-# language OverloadedStrings #-}
 | 
			
		||||
{-# language RecordWildCards #-}
 | 
			
		||||
{-# language NamedFieldPuns #-}
 | 
			
		||||
{-# language DeriveTraversable #-}
 | 
			
		||||
 | 
			
		||||
{- | Font usage example.
 | 
			
		||||
 | 
			
		||||
Loads two non-standard fonts
 | 
			
		||||
 | 
			
		||||
This example uses NotoSansJP-Regular.otf from Google Fonts
 | 
			
		||||
Licensed under the SIL Open Font License, Version 1.1
 | 
			
		||||
https://fonts.google.com/noto/specimen/Noto+Sans+JP
 | 
			
		||||
-}
 | 
			
		||||
 | 
			
		||||
module Main ( main ) where
 | 
			
		||||
 | 
			
		||||
import Control.Exception
 | 
			
		||||
import Control.Monad
 | 
			
		||||
import Control.Monad.IO.Class
 | 
			
		||||
import Control.Monad.Managed
 | 
			
		||||
import Data.IORef
 | 
			
		||||
import DearImGui
 | 
			
		||||
import qualified DearImGui.FontAtlas as FontAtlas
 | 
			
		||||
import DearImGui.OpenGL2
 | 
			
		||||
import DearImGui.SDL
 | 
			
		||||
import DearImGui.SDL.OpenGL
 | 
			
		||||
import Graphics.GL
 | 
			
		||||
import SDL
 | 
			
		||||
 | 
			
		||||
-- Rebuild syntax enables us to keep fonts in any
 | 
			
		||||
-- traversable type, so let's make our life a little easier.
 | 
			
		||||
-- But feel free to use lists or maps.
 | 
			
		||||
data FontSet a = FontSet
 | 
			
		||||
  { droidFont :: a
 | 
			
		||||
  , defaultFont :: a
 | 
			
		||||
  , notoFont :: a
 | 
			
		||||
  }
 | 
			
		||||
  deriving (Functor, Foldable, Traversable)
 | 
			
		||||
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = do
 | 
			
		||||
  -- Window initialization is similar to another examples.
 | 
			
		||||
  initializeAll
 | 
			
		||||
  runManaged do
 | 
			
		||||
    window <- do
 | 
			
		||||
      let title = "Hello, Dear ImGui!"
 | 
			
		||||
      let config = defaultWindow { windowGraphicsContext = OpenGLContext defaultOpenGL }
 | 
			
		||||
      managed $ bracket (createWindow title config) destroyWindow
 | 
			
		||||
    glContext <- managed $ bracket (glCreateContext window) glDeleteContext
 | 
			
		||||
    _ <- managed $ bracket createContext destroyContext
 | 
			
		||||
    _ <- managed_ $ bracket_ (sdl2InitForOpenGL window glContext) sdl2Shutdown
 | 
			
		||||
    _ <- managed_ $ bracket_ openGL2Init openGL2Shutdown
 | 
			
		||||
 | 
			
		||||
    -- We use high-level syntax to build font atlas and
 | 
			
		||||
    -- get handles to use in the main loop.
 | 
			
		||||
    fontSet <- FontAtlas.rebuild FontSet
 | 
			
		||||
      { -- The first mentioned font is loaded first
 | 
			
		||||
        -- and set as a global default.
 | 
			
		||||
        droidFont =
 | 
			
		||||
          FontAtlas.FromTTF
 | 
			
		||||
            "./imgui/misc/fonts/DroidSans.ttf"
 | 
			
		||||
            15
 | 
			
		||||
            Nothing
 | 
			
		||||
            FontAtlas.Cyrillic
 | 
			
		||||
 | 
			
		||||
        -- You also may use a default hardcoded font for
 | 
			
		||||
        -- some purposes (i.e. as fallback)
 | 
			
		||||
      , defaultFont =
 | 
			
		||||
          FontAtlas.DefaultFont
 | 
			
		||||
 | 
			
		||||
        -- To optimize atlas size, use ranges builder and
 | 
			
		||||
        -- provide source localization data.
 | 
			
		||||
      , notoFont =
 | 
			
		||||
          FontAtlas.FromTTF
 | 
			
		||||
            "./examples/fonts/NotoSansJP-Regular.otf"
 | 
			
		||||
            20
 | 
			
		||||
            Nothing
 | 
			
		||||
            ( FontAtlas.RangesBuilder $ mconcat
 | 
			
		||||
                [ FontAtlas.addRanges FontAtlas.Latin
 | 
			
		||||
                , FontAtlas.addText "私をクリックしてください"
 | 
			
		||||
                , FontAtlas.addText "こんにちは"
 | 
			
		||||
                ]
 | 
			
		||||
            )
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    liftIO $ do
 | 
			
		||||
      fontFlag <- newIORef False
 | 
			
		||||
      mainLoop window do
 | 
			
		||||
        let FontSet{..} = fontSet
 | 
			
		||||
        withWindowOpen "Hello, ImGui!" do
 | 
			
		||||
          -- To use a font for widget text, you may either put it
 | 
			
		||||
          -- into a 'withFont' block:
 | 
			
		||||
          withFont defaultFont do
 | 
			
		||||
            text "Hello, ImGui!"
 | 
			
		||||
 | 
			
		||||
          text "Привет, ImGui!"
 | 
			
		||||
 | 
			
		||||
          -- ...or you can explicitly push and pop a font.
 | 
			
		||||
          -- Though it's not recommended.
 | 
			
		||||
          toggled <- readIORef fontFlag
 | 
			
		||||
 | 
			
		||||
          when toggled $
 | 
			
		||||
            pushFont notoFont
 | 
			
		||||
 | 
			
		||||
          -- Some of those are only present in Noto font range
 | 
			
		||||
          -- and will render as `?`s.
 | 
			
		||||
          text "こんにちは, ImGui!"
 | 
			
		||||
 | 
			
		||||
          let buttonText = if toggled then "私をクリックしてください" else "Click Me!"
 | 
			
		||||
          button buttonText >>= \clicked ->
 | 
			
		||||
            when clicked $
 | 
			
		||||
              modifyIORef' fontFlag not
 | 
			
		||||
 | 
			
		||||
          when toggled
 | 
			
		||||
            popFont
 | 
			
		||||
 | 
			
		||||
        showDemoWindow
 | 
			
		||||
 | 
			
		||||
mainLoop :: Window -> IO () -> IO ()
 | 
			
		||||
mainLoop window frameAction = loop
 | 
			
		||||
  where
 | 
			
		||||
  loop = unlessQuit do
 | 
			
		||||
    openGL2NewFrame
 | 
			
		||||
    sdl2NewFrame
 | 
			
		||||
    newFrame
 | 
			
		||||
 | 
			
		||||
    frameAction
 | 
			
		||||
 | 
			
		||||
    glClear GL_COLOR_BUFFER_BIT
 | 
			
		||||
    render
 | 
			
		||||
    openGL2RenderDrawData =<< getDrawData
 | 
			
		||||
    glSwapWindow window
 | 
			
		||||
 | 
			
		||||
    loop
 | 
			
		||||
 | 
			
		||||
  unlessQuit action = do
 | 
			
		||||
    shouldQuit <- checkEvents
 | 
			
		||||
    if shouldQuit then pure () else action
 | 
			
		||||
 | 
			
		||||
  checkEvents = do
 | 
			
		||||
    pollEventWithImGui >>= \case
 | 
			
		||||
      Nothing ->
 | 
			
		||||
        return False
 | 
			
		||||
      Just event ->
 | 
			
		||||
        (isQuit event ||) <$> checkEvents
 | 
			
		||||
 | 
			
		||||
  isQuit event =
 | 
			
		||||
    SDL.eventPayload event == SDL.QuitEvent
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								examples/fonts/NotoSansJP-Regular.otf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								examples/fonts/NotoSansJP-Regular.otf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -134,12 +134,6 @@ app = do
 | 
			
		||||
    ImGui.createContext
 | 
			
		||||
    ImGui.destroyContext
 | 
			
		||||
 | 
			
		||||
  logDebug "Adding fonts"
 | 
			
		||||
  ImGui.clearFontAtlas
 | 
			
		||||
  _default <- ImGui.addFontDefault
 | 
			
		||||
  _custom <- ImGui.addFontFromFileTTF "imgui/misc/fonts/ProggyTiny.ttf" 10
 | 
			
		||||
  ImGui.buildFontAtlas
 | 
			
		||||
 | 
			
		||||
  let
 | 
			
		||||
    preferredFormat :: Vulkan.SurfaceFormatKHR
 | 
			
		||||
    preferredFormat =
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user