Skip to content

Commit

Permalink
FontAtlasProssesor: refactoring
Browse files Browse the repository at this point in the history
- add FontAtlas type
- put font atlas in context
- make all FontAtlasProssesor functions a methods of FontAtlas
  • Loading branch information
gucio321 committed Oct 21, 2021
1 parent 1a18181 commit cd8e82c
Show file tree
Hide file tree
Showing 18 changed files with 121 additions and 115 deletions.
2 changes: 1 addition & 1 deletion Canvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (c *Canvas) AddRectFilled(pMin, pMax image.Point, col color.Color, rounding

// AddText draws text.
func (c *Canvas) AddText(pos image.Point, col color.Color, text string) {
c.drawlist.AddText(ToVec2(pos), ToVec4Color(col), tStr(text))
c.drawlist.AddText(ToVec2(pos), ToVec4Color(col), Context.FontAtlas.tStr(text))
}

// AddBezierCubic draws bezier cubic.
Expand Down
14 changes: 7 additions & 7 deletions ClickableWidgets.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (b *ButtonWidget) Build() {
defer imgui.EndDisabled()
}

if imgui.ButtonV(tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil {
if imgui.ButtonV(Context.FontAtlas.tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil {
b.onClick()
}
}
Expand Down Expand Up @@ -130,7 +130,7 @@ func SmallButtonf(format string, args ...interface{}) *SmallButtonWidget {

// Build implements Widget interface.
func (b *SmallButtonWidget) Build() {
if imgui.SmallButton(tStr(b.id)) && b.onClick != nil {
if imgui.SmallButton(Context.FontAtlas.tStr(b.id)) && b.onClick != nil {
b.onClick()
}
}
Expand Down Expand Up @@ -170,7 +170,7 @@ func InvisibleButton() *InvisibleButtonWidget {

// Build implements Widget interface.
func (b *InvisibleButtonWidget) Build() {
if imgui.InvisibleButton(tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil {
if imgui.InvisibleButton(Context.FontAtlas.tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil {
b.onClick()
}
}
Expand Down Expand Up @@ -325,7 +325,7 @@ type CheckboxWidget struct {

// Build implements Widget interface.
func (c *CheckboxWidget) Build() {
if imgui.Checkbox(tStr(c.text), c.selected) && c.onChange != nil {
if imgui.Checkbox(Context.FontAtlas.tStr(c.text), c.selected) && c.onChange != nil {
c.onChange()
}
}
Expand Down Expand Up @@ -355,7 +355,7 @@ type RadioButtonWidget struct {

// Build implements Widget interface.
func (r *RadioButtonWidget) Build() {
if imgui.RadioButton(tStr(r.text), r.active) && r.onChange != nil {
if imgui.RadioButton(Context.FontAtlas.tStr(r.text), r.active) && r.onChange != nil {
r.onChange()
}
}
Expand Down Expand Up @@ -434,7 +434,7 @@ func (s *SelectableWidget) Build() {
s.flags |= SelectableFlagsAllowDoubleClick
}

if imgui.SelectableV(tStr(s.label), s.selected, int(s.flags), imgui.Vec2{X: s.width, Y: s.height}) && s.onClick != nil {
if imgui.SelectableV(Context.FontAtlas.tStr(s.label), s.selected, int(s.flags), imgui.Vec2{X: s.width, Y: s.height}) && s.onClick != nil {
s.onClick()
}

Expand All @@ -454,7 +454,7 @@ type TreeNodeWidget struct {

func TreeNode(label string) *TreeNodeWidget {
return &TreeNodeWidget{
label: tStr(label),
label: Context.FontAtlas.tStr(label),
flags: 0,
layout: nil,
eventHandler: nil,
Expand Down
2 changes: 1 addition & 1 deletion CodeEditor.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (ce *CodeEditorWidget) Build() {
s := ce.getState()

// register text in font atlas
tStr(s.editor.GetText())
Context.FontAtlas.tStr(s.editor.GetText())

// build editor
s.editor.Render(ce.title, imgui.Vec2{X: ce.width, Y: ce.height}, ce.border)
Expand Down
1 change: 1 addition & 0 deletions Context.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type context struct {
state sync.Map

InputHandler InputHandler
FontAtlas FontAtlas
}

func (c *context) GetRenderer() imgui.Renderer {
Expand Down
6 changes: 3 additions & 3 deletions ExtraWidgets.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,10 @@ func (ttr *TreeTableRowWidget) Build() {

open := false
if len(ttr.children) > 0 {
open = imgui.TreeNodeV(tStr(ttr.label), int(ttr.flags))
open = imgui.TreeNodeV(Context.FontAtlas.tStr(ttr.label), int(ttr.flags))
} else {
ttr.flags |= TreeNodeFlagsLeaf | TreeNodeFlagsNoTreePushOnOpen
imgui.TreeNodeV(tStr(ttr.label), int(ttr.flags))
imgui.TreeNodeV(Context.FontAtlas.tStr(ttr.label), int(ttr.flags))
}

for _, w := range ttr.layout {
Expand Down Expand Up @@ -544,7 +544,7 @@ func (d *DatePickerWidget) Build() {
const yearButtonSize = 25

Row(
Label(tStr(" Year")),
Label(Context.FontAtlas.tStr(" Year")),
Labelf("%14d", d.date.Year()),
Button("-##"+d.id+"year").OnClick(func() {
*d.date = d.date.AddDate(-1, 0, 0)
Expand Down
107 changes: 55 additions & 52 deletions FontAtlasProsessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@ import (
"github.com/AllenDang/imgui-go"
)

var (
shouldRebuildFontAtlas bool
stringMap sync.Map // key is rune, value indicates whether it's a new rune.
defaultFonts []FontInfo
extraFonts []FontInfo
extraFontMap map[string]*imgui.Font
)

const (
preRegisterString = " \"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
windows = "windows"
Expand All @@ -36,36 +28,45 @@ func (f *FontInfo) String() string {
return fmt.Sprintf("%s:%.2f", f.fontName, f.size)
}

func init() {
extraFontMap = make(map[string]*imgui.Font)
type FontAtlas struct {
shouldRebuildFontAtlas bool
stringMap sync.Map // key is rune, value indicates whether it's a new rune.
defaultFonts []FontInfo
extraFonts []FontInfo
extraFontMap map[string]*imgui.Font
}

func newFontAtlas() FontAtlas {
result := FontAtlas{
extraFontMap: make(map[string]*imgui.Font),
}

// Pre register numbers
tStr(preRegisterString)
result.tStr(preRegisterString)

// Pre-register fonts
os := runtime.GOOS
switch os {
switch runtime.GOOS {
case "darwin":
// English font
registerDefaultFont("Menlo", 14)
result.registerDefaultFont("Menlo", 14)
// Chinese font
registerDefaultFont("STHeiti", 13)
result.registerDefaultFont("STHeiti", 13)
// Jananese font
registerDefaultFont("ヒラギノ角ゴシック W0", 17)
result.registerDefaultFont("ヒラギノ角ゴシック W0", 17)
// Korean font
registerDefaultFont("AppleSDGothicNeo", 16)
result.registerDefaultFont("AppleSDGothicNeo", 16)
case windows:
// English font
registerDefaultFont("Calibri", 16)
result.registerDefaultFont("Calibri", 16)
// Chinese font
registerDefaultFont("MSYH", 16)
result.registerDefaultFont("MSYH", 16)
// Japanese font
registerDefaultFont("MSGOTHIC", 16)
result.registerDefaultFont("MSGOTHIC", 16)
// Korean font
registerDefaultFont("MALGUNSL", 16)
result.registerDefaultFont("MALGUNSL", 16)
case "linux":
// English fonts
registerDefaultFonts([]FontInfo{
result.registerDefaultFonts([]FontInfo{
{
fontName: "FreeSans.ttf",
size: 15,
Expand All @@ -76,33 +77,35 @@ func init() {
},
})
}

return result
}

// SetDefaultFont changes default font.
func SetDefaultFont(fontName string, size float32) {
func (a *FontAtlas) SetDefaultFont(fontName string, size float32) {
fontPath, err := findfont.Find(fontName)
if err != nil {
log.Fatalf("Cannot find font %s", fontName)
return
}

fontInfo := FontInfo{fontName: fontName, fontPath: fontPath, size: size}
defaultFonts = append([]FontInfo{fontInfo}, defaultFonts...)
a.defaultFonts = append([]FontInfo{fontInfo}, a.defaultFonts...)
}

// SetDefaultFontFromBytes changes default font by bytes of the font file.
func SetDefaultFontFromBytes(fontBytes []byte, size float32) {
defaultFonts = append([]FontInfo{
func (a *FontAtlas) SetDefaultFontFromBytes(fontBytes []byte, size float32) {
a.defaultFonts = append([]FontInfo{
{
fontByte: fontBytes,
size: size,
},
}, defaultFonts...)
}, a.defaultFonts...)
}

// AddFont adds font by name, if the font is found, return *FontInfo, otherwise return nil.
// To use added font, use giu.Style().SetFont(...).
func AddFont(fontName string, size float32) *FontInfo {
func (a *FontAtlas) AddFont(fontName string, size float32) *FontInfo {
fontPath, err := findfont.Find(fontName)
if err != nil {
fmt.Printf("[Warning]Cannot find font %s at system, related text will not be rendered.\n", fontName)
Expand All @@ -115,35 +118,35 @@ func AddFont(fontName string, size float32) *FontInfo {
size: size,
}

extraFonts = append(extraFonts, fi)
a.extraFonts = append(a.extraFonts, fi)

return &fi
}

// AddFontFromBytes does similar to AddFont, but using data from memory.
func AddFontFromBytes(fontName string, fontBytes []byte, size float32) *FontInfo {
func (a *FontAtlas) AddFontFromBytes(fontName string, fontBytes []byte, size float32) *FontInfo {
fi := FontInfo{
fontName: fontName,
fontByte: fontBytes,
size: size,
}

extraFonts = append(extraFonts, fi)
a.extraFonts = append(a.extraFonts, fi)

return &fi
}

func registerDefaultFont(fontName string, size float32) {
func (a *FontAtlas) registerDefaultFont(fontName string, size float32) {
fontPath, err := findfont.Find(fontName)
if err != nil {
return
}

fontInfo := FontInfo{fontName: fontName, fontPath: fontPath, size: size}
defaultFonts = append(defaultFonts, fontInfo)
a.defaultFonts = append(a.defaultFonts, fontInfo)
}

func registerDefaultFonts(fontInfos []FontInfo) {
func (a *FontAtlas) registerDefaultFonts(fontInfos []FontInfo) {
var firstFoundFont *FontInfo
for _, fi := range fontInfos {
fontPath, err := findfont.Find(fi.fontName)
Expand All @@ -154,17 +157,17 @@ func registerDefaultFonts(fontInfos []FontInfo) {
}

if firstFoundFont != nil {
defaultFonts = append(defaultFonts, *firstFoundFont)
a.defaultFonts = append(a.defaultFonts, *firstFoundFont)
}
}

// Register string to font atlas builder.
// Note only register strings that will be displayed on the UI.
func tStr(str string) string {
func (a *FontAtlas) tStr(str string) string {
for _, s := range str {
if _, ok := stringMap.Load(s); !ok {
stringMap.Store(s, false)
shouldRebuildFontAtlas = true
if _, ok := a.stringMap.Load(s); !ok {
a.stringMap.Store(s, false)
a.shouldRebuildFontAtlas = true
}
}

Expand All @@ -173,22 +176,22 @@ func tStr(str string) string {

// Register string pointer to font atlas builder.
// Note only register strings that will be displayed on the UI.
func tStrPtr(str *string) *string {
tStr(*str)
func (a *FontAtlas) tStrPtr(str *string) *string {
a.tStr(*str)
return str
}

func tStrSlice(str []string) []string {
func (a *FontAtlas) tStrSlice(str []string) []string {
for _, s := range str {
tStr(s)
a.tStr(s)
}

return str
}

// Rebuild font atlas when necessary.
func rebuildFontAtlas() {
if !shouldRebuildFontAtlas {
func (a *FontAtlas) rebuildFontAtlas() {
if !a.shouldRebuildFontAtlas {
return
}

Expand All @@ -197,8 +200,8 @@ func rebuildFontAtlas() {

var sb strings.Builder

stringMap.Range(func(k, v interface{}) bool {
stringMap.Store(k, true)
a.stringMap.Range(func(k, v interface{}) bool {
a.stringMap.Store(k, true)
if ks, ok := k.(rune); ok {
sb.WriteRune(ks)
}
Expand All @@ -218,13 +221,13 @@ func rebuildFontAtlas() {

builder.BuildRanges(ranges)

if len(defaultFonts) > 0 {
if len(a.defaultFonts) > 0 {
fontConfig := imgui.NewFontConfig()
fontConfig.SetOversampleH(2)
fontConfig.SetOversampleV(2)
fontConfig.SetRasterizerMultiply(1.5)

for i, fontInfo := range defaultFonts {
for i, fontInfo := range a.defaultFonts {
if i > 0 {
fontConfig.SetMergeMode(true)
}
Expand All @@ -250,7 +253,7 @@ func rebuildFontAtlas() {
}

// Add extra fonts
for _, fontInfo := range extraFonts {
for _, fontInfo := range a.extraFonts {
// Scale font size with DPI scale factor
if runtime.GOOS == windows {
fontInfo.size *= Context.GetPlatform().GetContentScale()
Expand All @@ -263,11 +266,11 @@ func rebuildFontAtlas() {
} else {
f = fonts.AddFontFromMemoryTTFV(fontInfo.fontByte, fontInfo.size, imgui.DefaultFontConfig, ranges.Data())
}
extraFontMap[fontInfo.String()] = &f
a.extraFontMap[fontInfo.String()] = &f
}

fontTextureImg := fonts.TextureDataRGBA32()
Context.renderer.SetFontTexture(fontTextureImg)

shouldRebuildFontAtlas = false
a.shouldRebuildFontAtlas = false
}
Loading

0 comments on commit cd8e82c

Please sign in to comment.