mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2025-04-02 11:02:17 -04:00
if pixel perfect is disabled and using bevel is enabled, then the curve and rounded corners amount are fixed values specific to the selected bevel. currently only the 'solid state' bevel is allowed set new default values for crt preferences increased perlin noise value for CRT screen
272 lines
8.4 KiB
Go
272 lines
8.4 KiB
Go
// This file is part of Gopher2600.
|
|
//
|
|
// Gopher2600 is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Gopher2600 is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package sdlimgui
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
|
|
"github.com/inkyblackness/imgui-go/v4"
|
|
"github.com/jetsetilly/gopher2600/gui/fonts"
|
|
)
|
|
|
|
type fontDisplay interface {
|
|
displayDPI() (float32, error)
|
|
}
|
|
|
|
type fontAtlas struct {
|
|
display fontDisplay
|
|
|
|
// gui font
|
|
gui imgui.Font
|
|
guiSize float32
|
|
|
|
smallGui imgui.Font
|
|
smallGuiSize float32
|
|
|
|
// used for notifications (eg. network access, etc.)
|
|
largeFontAwesome imgui.Font
|
|
largeFontAwesomeSize float32
|
|
|
|
// used for rewind/fast-forward state
|
|
veryLargeFontAwesome imgui.Font
|
|
veryLargeFontAwesomeSize float32
|
|
|
|
// custom icons for controllers and other peripherals
|
|
gopher2600Icons imgui.Font
|
|
gopher2600IconsSize float32
|
|
|
|
// annotation of diagrams
|
|
diagram imgui.Font
|
|
diagramSize float32
|
|
|
|
// terminal
|
|
terminal imgui.Font
|
|
terminalSize float32
|
|
|
|
// source code
|
|
code imgui.Font
|
|
codeSize float32
|
|
}
|
|
|
|
func scaleFontForDPI(pt float32, dpi float32) float32 {
|
|
return float32(math.Round(float64(pt * (dpi / 72))))
|
|
}
|
|
|
|
func (atlas *fontAtlas) initialise(display fontDisplay, renderer renderer, prefs *preferences) error {
|
|
setFontBuilderFlags(imgui.CurrentIO().Fonts())
|
|
dpi, err := display.displayDPI()
|
|
if err != nil {
|
|
return fmt.Errorf("font: %w", err)
|
|
}
|
|
|
|
err = atlas.setDefaultFont(prefs, dpi)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// load small gui font
|
|
if atlas.smallGui == 0 {
|
|
smallGuiConfig := imgui.NewFontConfig()
|
|
defer smallGuiConfig.Delete()
|
|
smallGuiConfig.SetPixelSnapH(true)
|
|
|
|
var smallGuiBuilder imgui.GlyphRangesBuilder
|
|
smallGuiBuilder.Add(fonts.JetBrainsMonoMin, fonts.JetBrainsMonoMax)
|
|
|
|
atlas.smallGuiSize = float32(prefs.guiFontSize.Get().(int)) * 0.85
|
|
atlas.smallGuiSize = scaleFontForDPI(atlas.smallGuiSize, dpi)
|
|
atlas.smallGui = imgui.CurrentIO().Fonts().AddFontFromMemoryTTFV(fonts.JetBrainsMono, atlas.smallGuiSize, smallGuiConfig, smallGuiBuilder.Build().GlyphRanges)
|
|
if atlas.smallGui == 0 {
|
|
return fmt.Errorf("font: error loading JetBrainsMono font from memory")
|
|
}
|
|
}
|
|
|
|
// load large font awesome
|
|
if atlas.largeFontAwesome == 0 {
|
|
largeFontAwesomeConfig := imgui.NewFontConfig()
|
|
defer largeFontAwesomeConfig.Delete()
|
|
largeFontAwesomeConfig.SetPixelSnapH(true)
|
|
|
|
var largeFontAwesomeBuilder imgui.GlyphRangesBuilder
|
|
largeFontAwesomeBuilder.Add(fonts.FontAwesomeMin, fonts.FontAwesomeMax)
|
|
|
|
atlas.largeFontAwesomeSize = 22.0
|
|
atlas.largeFontAwesome = imgui.CurrentIO().Fonts().AddFontFromMemoryTTFV(fonts.FontAwesome, atlas.largeFontAwesomeSize, largeFontAwesomeConfig, largeFontAwesomeBuilder.Build().GlyphRanges)
|
|
if atlas.largeFontAwesome == 0 {
|
|
return fmt.Errorf("font: error loading font-awesome from memory")
|
|
}
|
|
}
|
|
|
|
// load very-large font awesome
|
|
if atlas.veryLargeFontAwesome == 0 {
|
|
veryLargeFontAwesomeConfig := imgui.NewFontConfig()
|
|
defer veryLargeFontAwesomeConfig.Delete()
|
|
veryLargeFontAwesomeConfig.SetPixelSnapH(true)
|
|
|
|
var veryLargeFontAwesomeBuilder imgui.GlyphRangesBuilder
|
|
veryLargeFontAwesomeBuilder.Add(fonts.FontAwesomeMin, fonts.FontAwesomeMax)
|
|
|
|
atlas.veryLargeFontAwesomeSize = 44.0
|
|
atlas.veryLargeFontAwesome = imgui.CurrentIO().Fonts().AddFontFromMemoryTTFV(fonts.FontAwesome, atlas.veryLargeFontAwesomeSize, veryLargeFontAwesomeConfig, veryLargeFontAwesomeBuilder.Build().GlyphRanges)
|
|
if atlas.veryLargeFontAwesome == 0 {
|
|
return fmt.Errorf("font: error loading font-awesome from memory")
|
|
}
|
|
}
|
|
|
|
// load gopher icons
|
|
if atlas.gopher2600Icons == 0 {
|
|
gopher2600IconConfig := imgui.NewFontConfig()
|
|
defer gopher2600IconConfig.Delete()
|
|
gopher2600IconConfig.SetPixelSnapH(true)
|
|
gopher2600IconConfig.SetGlyphOffsetY(1.0)
|
|
|
|
var gopher2600IconBuilder imgui.GlyphRangesBuilder
|
|
gopher2600IconBuilder.Add(fonts.Gopher2600IconMin, fonts.Gopher2600IconMax)
|
|
|
|
atlas.gopher2600IconsSize = 60.0
|
|
atlas.gopher2600Icons = imgui.CurrentIO().Fonts().AddFontFromMemoryTTFV(fonts.Gopher2600Icons, atlas.gopher2600IconsSize, gopher2600IconConfig, gopher2600IconBuilder.Build().GlyphRanges)
|
|
if atlas.gopher2600Icons == 0 {
|
|
return fmt.Errorf("font: error loading Gopher2600 font from memory")
|
|
}
|
|
}
|
|
|
|
// load diagram font
|
|
if atlas.diagram == 0 {
|
|
diagramConfig := imgui.NewFontConfig()
|
|
defer diagramConfig.Delete()
|
|
diagramConfig.SetPixelSnapH(true)
|
|
|
|
var diagramBuilder imgui.GlyphRangesBuilder
|
|
diagramBuilder.Add(fonts.HackMin, fonts.HackMax)
|
|
|
|
atlas.diagramSize = scaleFontForDPI(10.0, dpi)
|
|
atlas.diagram = imgui.CurrentIO().Fonts().AddFontFromMemoryTTFV(fonts.Hack, atlas.diagramSize, diagramConfig, diagramBuilder.Build().GlyphRanges)
|
|
if atlas.diagram == 0 {
|
|
return fmt.Errorf("font: error loading hack font from memory")
|
|
}
|
|
}
|
|
|
|
// load terminal font
|
|
err = atlas.terminalFont(prefs, dpi)
|
|
if err != nil {
|
|
return fmt.Errorf("font: %w", err)
|
|
}
|
|
|
|
// load source code font
|
|
err = atlas.sourceCodeFont(prefs, dpi)
|
|
if err != nil {
|
|
return fmt.Errorf("font: %w", err)
|
|
}
|
|
|
|
// create textures and register with imgui
|
|
tex := renderer.addFontTexture(imgui.CurrentIO().Fonts())
|
|
imgui.CurrentIO().Fonts().SetTextureID(imgui.TextureID(tex.getID()))
|
|
|
|
return nil
|
|
}
|
|
|
|
func (atlas *fontAtlas) setDefaultFont(prefs *preferences, dpi float32) error {
|
|
guiFontSize := float32(prefs.guiFontSize.Get().(int))
|
|
if atlas.guiSize != 0 && guiFontSize == atlas.guiSize {
|
|
return nil
|
|
}
|
|
atlas.guiSize = guiFontSize
|
|
|
|
// load gui font
|
|
cfg := imgui.NewFontConfig()
|
|
defer cfg.Delete()
|
|
|
|
var builder imgui.GlyphRangesBuilder
|
|
builder.Add(fonts.JetBrainsMonoMin, fonts.JetBrainsMonoMax)
|
|
|
|
guiFontSize = scaleFontForDPI(guiFontSize, dpi)
|
|
atlas.gui = imgui.CurrentIO().Fonts().AddFontFromMemoryTTFV(fonts.JetBrainsMono, guiFontSize, cfg, builder.Build().GlyphRanges)
|
|
if atlas.gui == 0 {
|
|
return fmt.Errorf("font: error loading JetBrainsMono font from memory")
|
|
}
|
|
|
|
atlas.mergeFontAwesome(guiFontSize, 1.0)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (atlas *fontAtlas) sourceCodeFont(prefs *preferences, dpi float32) error {
|
|
codeSize := float32(prefs.codeFontSize.Get().(int))
|
|
if atlas.codeSize != 0 && codeSize == atlas.codeSize {
|
|
return nil
|
|
}
|
|
atlas.codeSize = codeSize
|
|
|
|
cfg := imgui.NewFontConfig()
|
|
defer cfg.Delete()
|
|
|
|
var builder imgui.GlyphRangesBuilder
|
|
builder.Add(fonts.JetBrainsMonoMin, fonts.JetBrainsMonoMax)
|
|
|
|
codeSize = scaleFontForDPI(codeSize, dpi)
|
|
atlas.code = imgui.CurrentIO().Fonts().AddFontFromMemoryTTFV(fonts.JetBrainsMono, codeSize, cfg, builder.Build().GlyphRanges)
|
|
if atlas.code == 0 {
|
|
return fmt.Errorf("font: error loading JetBrainsMono font from memory")
|
|
}
|
|
|
|
atlas.mergeFontAwesome(codeSize, 0.0)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (atlas *fontAtlas) terminalFont(prefs *preferences, dpi float32) error {
|
|
terminalSize := float32(prefs.terminalFontSize.Get().(int))
|
|
if atlas.terminalSize != 0 && terminalSize == atlas.terminalSize {
|
|
return nil
|
|
}
|
|
atlas.terminalSize = terminalSize
|
|
|
|
cfg := imgui.NewFontConfig()
|
|
defer cfg.Delete()
|
|
|
|
var builder imgui.GlyphRangesBuilder
|
|
builder.Add(fonts.JetBrainsMonoMin, fonts.JetBrainsMonoMax)
|
|
|
|
terminalSize = scaleFontForDPI(terminalSize, dpi)
|
|
atlas.terminal = imgui.CurrentIO().Fonts().AddFontFromMemoryTTFV(fonts.JetBrainsMono, terminalSize, cfg, builder.Build().GlyphRanges)
|
|
if atlas.terminal == 0 {
|
|
return fmt.Errorf("font: error loading JetBrainsMono font from memory")
|
|
}
|
|
|
|
atlas.mergeFontAwesome(terminalSize, 0.0)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (atlas *fontAtlas) mergeFontAwesome(size float32, adjust float32) error {
|
|
mergeConfig := imgui.NewFontConfig()
|
|
defer mergeConfig.Delete()
|
|
mergeConfig.SetMergeMode(true)
|
|
mergeConfig.SetGlyphOffsetY(adjust)
|
|
|
|
// limit what glyphs we load
|
|
var glyphBuilder imgui.GlyphRangesBuilder
|
|
glyphBuilder.Add(fonts.FontAwesomeMin, fonts.FontAwesomeMax)
|
|
|
|
// merge font awesome
|
|
merge := imgui.CurrentIO().Fonts().AddFontFromMemoryTTFV(fonts.FontAwesome, size, mergeConfig, glyphBuilder.Build().GlyphRanges)
|
|
if merge == 0 {
|
|
return fmt.Errorf("font: error loading font-awesome from memory")
|
|
}
|
|
|
|
return nil
|
|
}
|