title: fyne Chinese Font Permanent Solution
date: 2021-09-07 14:32:00
toc: true
category:
- Golang
- fyne
tags: - Golang
- fyne
- support
- Chinese
- font
- permanent
- solution
Background#
The current version of fyne does not have good support for Chinese characters. When trying to display Chinese characters using fyne, the effect is as shown in the image:
The code is as follows:
package main
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
)
func main() {
a := app.New()
w := a.NewWindow("font")
w.Resize(fyne.NewSize(300, 200))
w.SetContent(
fyne.NewContainerWithLayout(
layout.NewVBoxLayout(),
layout.NewSpacer(),
widget.NewLabel("撒旦撒旦"),
widget.NewLabel("委屈额为"),
widget.NewButton("请问犬瘟热第三方", func() {
dialog.ShowInformation("非官方的", "从v风格化风格化", w)
}),
layout.NewSpacer(),
),
)
w.ShowAndRun()
}
Now, to make fyne support Chinese characters, you need to read the official documentation in detail (Text | Develop using Fyne) to get the answer.
Chinese Support in fyne#
The documentation provides two solutions:
- Use the environment variable
FYNE_FONT
to specify a.ttf
font file, see: Text | Develop using Fyne - Bundle font files (custom theme), see: Creating a Custom Theme | Develop using Fyne
Using the environment variable FYNE_FONT
#
When using the built-in themes in fyne, if the environment variable specifies a font file, it can be used as the font.
Specifying the environment variable on Windows#
On Windows, set the environment variable FYNE_FONT
to the Chinese font supported by the current system, such as the font "华文隶书 常规" obtained through the "Properties" menu:
Then set the environment variable:
Specifying the environment variable on Linux and other Unix operating systems#
FYNE_FONT=STLITI.TTF go run main.go
Running the code will display Chinese content.
The code is as follows:
package main
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
)
func main() {
a := app.New()
w := a.NewWindow("font")
w.Resize(fyne.NewSize(300, 200))
w.SetContent(
fyne.NewContainerWithLayout(
layout.NewVBoxLayout(),
layout.NewSpacer(),
widget.NewLabel("撒旦撒旦"),
widget.NewLabel("委屈额为"),
widget.NewButton("请问犬瘟热第三方", func() {
dialog.ShowInformation("非官方的", "从v风格化风格化", w)
}),
layout.NewSpacer(),
),
)
w.ShowAndRun()
}
Disadvantages of the environment variable method#
Although it looks good, this method will cause many problems when distributing compiled programs.
Bundling Font Files (Custom Theme)#
fyne provides a default theme, and since the theme's configurable options include fonts, any font can be used by creating a custom theme.
Custom themes can be obtained by implementing the Theme interface.
Binding Fonts with Go Code#
For example, binding the fonts "Regular" and "Bold".
The commands are:
fyne bundle STLITI.ttf > bundle.go
fyne bundle -append STLITI-bold.ttf >> bundle.go
fyne bundle
command#
In GUI applications, if you want to use an image as the icon of a button, you can merge resource files (such as image files) into a single binary file for distribution.
Fyne provides a mechanism and useful commands for this purpose.
fyne bundle
converts resource files (such as images) into data that Fyne can handle (a structure with raw byte data) using commands.
For more information, refer to: https://github.com/fyne-io/fyne/tree/master/cmd/fyne
Define the Theme Struct
#
Define the name of the theme struct
to be used and implement the fyne.Theme
interface.
Please handle the Font
according to the business logic.
type Theme interface {
Color(ThemeColorName, ThemeVariant) color.Color
Font(TextStyle) Resource
Icon(ThemeIconName) Resource
Size(ThemeSizeName) float32
}
The code is as follows:
package main
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/theme"
)
type Biu struct{}
func (b Biu) Font(s fyne.TextStyle) fyne.Resource {
if s.Monospace {
return theme.DefaultTheme().Font(s)
}
if s.Bold {
if s.Italic {
return theme.DefaultTheme().Font(s)
}
return resourceSTLITITTF
}
if s.Italic {
return theme.DefaultTheme().Font(s)
}
return resourceSTLITITTF
}
func (b Biu) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color {
return theme.DefaultTheme().Color(name, variant)
}
func (b Biu) Icon(name fyne.ThemeIconName) fyne.Resource {
return theme.DefaultTheme().Icon(name)
}
func (b Biu) Size(name fyne.ThemeSizeName) float32 {
return theme.DefaultTheme().Size(name)
}
Using the Custom Theme#
Implement it through the fyne.App
's Settings().SetTheme()
method, for example:
package main
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
)
func main() {
a := app.New()
w := a.NewWindow("font")
a.Settings().SetTheme(&Biu{})
w.Resize(fyne.NewSize(300, 200))
w.SetContent(
fyne.NewContainerWithLayout(
layout.NewVBoxLayout(),
layout.NewSpacer(),
widget.NewLabel("撒旦撒旦"),
widget.NewLabel("委屈额为"),
widget.NewButton("请问犬瘟热第三方", func() {
dialog.ShowInformation("非官方的", "从v风格化风格化", w)
}),
layout.NewSpacer(),
),
)
w.ShowAndRun()
}
The specific call is a.Settings().SetTheme(&Biu{})
, and the result is: