Last active
September 24, 2024 08:33
-
-
Save Omustardo/b15eedaacabdf4d6a6579f762a8a05a0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
imgui "github.com/AllenDang/cimgui-go" | |
"os" | |
"time" | |
"unsafe" | |
_ "embed" | |
) | |
// Embed the full ttf file contents within the golang binary at compile-time. This requires importing the `embed` package. | |
// Note that any TTF file will work. I got this one from https://fonts.google.com/specimen/Merriweather | |
// If you have a different way of loading a ttf (e.g. hard-coding the TTF bytes as a base64 string), this can be replaced. | |
// | |
//go:embed Merriweather-Regular.ttf | |
var defaultFontTTF []byte | |
const ( | |
DefaultFontSize int32 = 20 | |
MinFontSize int32 = 10 | |
MaxFontSize int32 = 100 | |
) | |
var ( | |
selectedFontSize int32 = DefaultFontSize | |
// FontsBySize is populated by a single font, rendered from MinFontSize through MaxFontSize. This allows using | |
// different the font at different sizes without needing to scale them (i.e. `imgui.CurrentFont().SetScale(2)`). | |
// Scaling the font usually causes blurriness or other distortion. It's preferable to load the font at all | |
// of the sizes you plan to use, if you know those sizes in advance. | |
FontsBySize map[int]*imgui.Font | |
) | |
// InitFonts must be called in `backend.SetAfterCreateContextHook(hookFunc)`. Before rendering, imgui may not | |
// have a context. During the game loop, imgui doesn't allow loading fonts. | |
func InitFonts() { | |
fmt.Println("Loading fonts...") | |
start := time.Now() | |
FontsBySize = make(map[int]*imgui.Font) | |
for i := MinFontSize; i <= MaxFontSize; i++ { | |
FontsBySize[int(i)] = loadFont(float32(i)) | |
} | |
imgui.CurrentIO().Fonts().Build() | |
imgui.CurrentIO().SetFontDefault(FontsBySize[int(DefaultFontSize)]) | |
fmt.Printf("Finished loading fonts in %v\n", time.Now().Sub(start).Round(time.Millisecond)) | |
} | |
func loadFont(fontSize float32) *imgui.Font { | |
// NOTE: It takes an estimated 2ms per font, so for 100 sizes it's slightly noticeable to load these at startup. | |
// You may want to add a loading screen, or simply load less sizes fonts. Perhaps keep only a few different | |
// fonts, named based on their usage (e.g. Title, Heading1, etc) | |
cfg := imgui.NewFontConfig() | |
cfg.SetFontData(uintptr(unsafe.Pointer(imgui.SliceToPtr(defaultFontTTF)))) | |
cfg.SetFontDataSize(int32(len(defaultFontTTF))) | |
cfg.SetSizePixels(fontSize) | |
cfg.SetFontDataOwnedByAtlas(false) // Let golang manage this memory. Otherwise imgui crashes when trying to clean it up while exiting. The error is: `munmap_chunk(): invalid pointer`. | |
cfg.SetPixelSnapH(true) | |
return imgui.CurrentIO().Fonts().AddFont(cfg) | |
} | |
func loop() { | |
imgui.Begin("Window1") | |
{ | |
imgui.Text("Size: ") | |
imgui.SameLine() | |
imgui.SliderInt("##FontSizeSlider", &selectedFontSize, MinFontSize, MaxFontSize) | |
imgui.PushFont(FontsBySize[int(selectedFontSize)]) | |
imgui.Text(fmt.Sprintf("%d default default default", selectedFontSize)) | |
imgui.PopFont() | |
for i := MinFontSize; i <= MaxFontSize; i += 10 { | |
imgui.PushFont(FontsBySize[int(i)]) | |
imgui.Text(fmt.Sprintf("%d test test test test test test", i)) | |
imgui.PopFont() | |
} | |
} | |
imgui.End() | |
} | |
func main() { | |
backend, err := imgui.CreateBackend(imgui.NewGLFWBackend()) | |
if err != nil { | |
fmt.Printf("Error creating backend: %v\n", err) | |
os.Exit(1) | |
} | |
backend.SetAfterCreateContextHook(func() { | |
InitFonts() | |
}) | |
backend.CreateWindow("Resized font demo", 1500, 900) | |
backend.Run(loop) | |
} |
Author
Omustardo
commented
Sep 24, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment