mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-08-30 12:12:40 +08:00
feat(字体渲染): 统一字体处理位置
This commit is contained in:
+7
-62
@@ -112,10 +112,7 @@ func (fsys *FontFS) Glob(pattern string) ([]string, error) {
|
|||||||
// 入参: names 字体名称列表
|
// 入参: names 字体名称列表
|
||||||
// 返回: string 匹配字体文件, bool 是否为名称匹配
|
// 返回: string 匹配字体文件, bool 是否为名称匹配
|
||||||
func (fsys *FontFS) Match(names ...string) (string, bool) {
|
func (fsys *FontFS) Match(names ...string) (string, bool) {
|
||||||
for _, name := range names {
|
for _, name := range fontCandidateNames(names...) {
|
||||||
if strings.TrimSpace(name) == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if matches := fsys.match(name + "*"); len(matches) > 0 {
|
if matches := fsys.match(name + "*"); len(matches) > 0 {
|
||||||
return matches[0], true
|
return matches[0], true
|
||||||
}
|
}
|
||||||
@@ -142,8 +139,7 @@ func (fsys *FontFS) match(pattern string) []string {
|
|||||||
// fallbackFonts 获取回退字体文件
|
// fallbackFonts 获取回退字体文件
|
||||||
// 返回: []string 字体文件列表
|
// 返回: []string 字体文件列表
|
||||||
func (fsys *FontFS) fallbackFonts() []string {
|
func (fsys *FontFS) fallbackFonts() []string {
|
||||||
preferred := []string{"simsun.ttc", "msyh.ttc", "simhei.ttf"}
|
for _, item := range fontFallbackFiles {
|
||||||
for _, item := range preferred {
|
|
||||||
if _, ok := fsys.files[item]; ok {
|
if _, ok := fsys.files[item]; ok {
|
||||||
return []string{item}
|
return []string{item}
|
||||||
}
|
}
|
||||||
@@ -195,74 +191,23 @@ func matchFontPattern(pattern, name string) bool {
|
|||||||
}
|
}
|
||||||
stem := strings.TrimSuffix(pattern, "*")
|
stem := strings.TrimSuffix(pattern, "*")
|
||||||
stem = strings.TrimSuffix(stem, path.Ext(stem))
|
stem = strings.TrimSuffix(stem, path.Ext(stem))
|
||||||
stem = normalizeFontFileName(stem)
|
stem = fontNormalizeName(stem)
|
||||||
if stem == "" {
|
if stem == "" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
name = normalizeFontFileName(name)
|
name = fontNormalizeName(name)
|
||||||
if strings.HasPrefix(name, stem) {
|
if strings.HasPrefix(name, stem) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for _, alias := range fontNameAliases(stem) {
|
for _, alias := range fontCandidateNames(stem) {
|
||||||
if strings.HasPrefix(name, alias) {
|
alias = fontNormalizeName(alias)
|
||||||
|
if alias != "" && strings.HasPrefix(name, alias) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// normalizeFontFileName 规范化字体文件名
|
|
||||||
// 入参: name 字体文件名
|
|
||||||
// 返回: string 规范化后的字体文件名
|
|
||||||
func normalizeFontFileName(name string) string {
|
|
||||||
name = strings.TrimSuffix(path.Base(name), path.Ext(name))
|
|
||||||
name = strings.ToLower(name)
|
|
||||||
replacer := strings.NewReplacer(" ", "", "-", "", "_", "")
|
|
||||||
return replacer.Replace(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// fontNameAliases 获取字体名称别名
|
|
||||||
// 入参: name 字体名称
|
|
||||||
// 返回: []string 字体名称别名
|
|
||||||
func fontNameAliases(name string) []string {
|
|
||||||
aliases := []struct {
|
|
||||||
Keys []string
|
|
||||||
Values []string
|
|
||||||
}{
|
|
||||||
{[]string{"宋体", "新宋体", "simsun"}, []string{"simsun"}},
|
|
||||||
{[]string{"黑体", "simhei"}, []string{"simhei"}},
|
|
||||||
{[]string{"楷体", "kaiti", "simkai"}, []string{"simkai"}},
|
|
||||||
{[]string{"仿宋", "fangsong", "simfang"}, []string{"simfang"}},
|
|
||||||
{[]string{"微软雅黑", "microsoftyahei", "yahei", "msyh"}, []string{"msyh"}},
|
|
||||||
}
|
|
||||||
var result []string
|
|
||||||
for _, alias := range aliases {
|
|
||||||
for _, key := range alias.Keys {
|
|
||||||
key = normalizeFontFileName(key)
|
|
||||||
if key != "" && (name == key || strings.Contains(name, key)) {
|
|
||||||
result = append(result, alias.Values...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if strings.Contains(name, "宋") {
|
|
||||||
result = append(result, "simsun")
|
|
||||||
}
|
|
||||||
if strings.Contains(name, "黑") {
|
|
||||||
result = append(result, "simhei")
|
|
||||||
}
|
|
||||||
if strings.Contains(name, "楷") {
|
|
||||||
result = append(result, "simkai")
|
|
||||||
}
|
|
||||||
if strings.Contains(name, "仿") {
|
|
||||||
result = append(result, "simfang")
|
|
||||||
}
|
|
||||||
if strings.Contains(name, "雅") {
|
|
||||||
result = append(result, "msyh")
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// fontMemFile 内存字体文件
|
// fontMemFile 内存字体文件
|
||||||
type fontMemFile struct {
|
type fontMemFile struct {
|
||||||
*bytes.Reader
|
*bytes.Reader
|
||||||
|
|||||||
+2
-7
@@ -19,7 +19,6 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"path"
|
"path"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -183,12 +182,8 @@ func (r *Renderer) matchFont(names ...string) (string, bool) {
|
|||||||
// 入参: fsys 字体文件系统, names 字体名称列表
|
// 入参: fsys 字体文件系统, names 字体名称列表
|
||||||
// 返回: string 匹配字体文件
|
// 返回: string 匹配字体文件
|
||||||
func matchFontFS(fsys fs.FS, names ...string) string {
|
func matchFontFS(fsys fs.FS, names ...string) string {
|
||||||
for _, name := range names {
|
for _, pattern := range fontFilePatterns(names...) {
|
||||||
name = strings.TrimSpace(name)
|
matches, err := fs.Glob(fsys, pattern)
|
||||||
if name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
matches, err := fs.Glob(fsys, name+"*")
|
|
||||||
if err == nil && len(matches) > 0 {
|
if err == nil && len(matches) > 0 {
|
||||||
return matches[0]
|
return matches[0]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,219 @@
|
|||||||
|
// Copyright 2025-2026 肖其顿 (XIAO QI DUN)
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package ofdgo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fontMatchRule struct {
|
||||||
|
Keys []string
|
||||||
|
Names []string
|
||||||
|
Files []string
|
||||||
|
System string
|
||||||
|
}
|
||||||
|
|
||||||
|
var fontMatchRules = []fontMatchRule{
|
||||||
|
{
|
||||||
|
Keys: []string{"宋体", "新宋体", "simsun", "nsimsun", "songti", "书宋", "方正书宋"},
|
||||||
|
Names: []string{"宋体", "新宋体", "SimSun", "NSimSun", "SongTi"},
|
||||||
|
Files: []string{"simsun.ttc", "simsun.ttf", "nsimsun.ttf"},
|
||||||
|
System: "SimSun",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: []string{"黑体", "simhei", "heiti"},
|
||||||
|
Names: []string{"黑体", "SimHei", "HeiTi"},
|
||||||
|
Files: []string{"simhei.ttf"},
|
||||||
|
System: "SimHei",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: []string{"楷体", "kaiti", "simkai"},
|
||||||
|
Names: []string{"楷体", "KaiTi", "SimKai"},
|
||||||
|
Files: []string{"simkai.ttf", "kaiti.ttf"},
|
||||||
|
System: "KaiTi",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: []string{"仿宋", "fangsong", "simfang"},
|
||||||
|
Names: []string{"仿宋", "FangSong", "SimFang"},
|
||||||
|
Files: []string{"simfang.ttf", "fangsong.ttf"},
|
||||||
|
System: "FangSong",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: []string{"微软雅黑", "microsoftyahei", "yahei", "msyh"},
|
||||||
|
Names: []string{"微软雅黑", "Microsoft YaHei", "YaHei", "MSYH"},
|
||||||
|
Files: []string{"msyh.ttc", "msyh.ttf"},
|
||||||
|
System: "Microsoft YaHei",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: []string{"arialblack"},
|
||||||
|
Names: []string{"Arial Black", "ArialBlack"},
|
||||||
|
Files: []string{"ariblk.ttf", "arial black*.ttf", "arialblack*.ttf"},
|
||||||
|
System: "Arial Black",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: []string{"arial"},
|
||||||
|
Names: []string{"Arial"},
|
||||||
|
Files: []string{"arial.ttf", "arial*.ttf"},
|
||||||
|
System: "Arial",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: []string{"couriernew", "courier"},
|
||||||
|
Names: []string{"Courier New", "CourierNew", "Courier"},
|
||||||
|
Files: []string{"cour.ttf", "courier new*.ttf", "courier*.ttf"},
|
||||||
|
System: "Courier New",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: []string{"segoeui"},
|
||||||
|
Names: []string{"Segoe UI", "SegoeUI"},
|
||||||
|
Files: []string{"segoeui.ttf", "segoe*.ttf"},
|
||||||
|
System: "Segoe UI",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: []string{"timesnewroman", "times"},
|
||||||
|
Names: []string{"Times New Roman", "TimesNewRoman"},
|
||||||
|
Files: []string{"times.ttf", "times new roman*.ttf", "times*.ttf"},
|
||||||
|
System: "Times New Roman",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var fontFallbackFiles = []string{"simsun.ttc", "msyh.ttc", "simhei.ttf"}
|
||||||
|
|
||||||
|
// fontNormalizeName 规范化字体名称
|
||||||
|
// 入参: name 字体名称
|
||||||
|
// 返回: string 规范化后的字体名称
|
||||||
|
func fontNormalizeName(name string) string {
|
||||||
|
name = strings.TrimSuffix(path.Base(name), path.Ext(name))
|
||||||
|
name = strings.ToLower(strings.TrimSpace(name))
|
||||||
|
replacer := strings.NewReplacer(" ", "", "-", "", "_", "", "(", "", ")", "", "(", "", ")", "")
|
||||||
|
return replacer.Replace(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fontCandidateNames 获取字体候选名称
|
||||||
|
// 入参: names 字体名称列表
|
||||||
|
// 返回: []string 字体候选名称
|
||||||
|
func fontCandidateNames(names ...string) []string {
|
||||||
|
var result []string
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
for _, name := range names {
|
||||||
|
name = strings.TrimSpace(name)
|
||||||
|
if name == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = appendFontName(result, seen, name)
|
||||||
|
for _, rule := range fontMatchRules {
|
||||||
|
if fontRuleMatch(rule, name) {
|
||||||
|
result = appendFontName(result, seen, rule.System)
|
||||||
|
for _, item := range rule.Names {
|
||||||
|
result = appendFontName(result, seen, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// fontFilePatterns 获取字体文件匹配模式
|
||||||
|
// 入参: names 字体名称列表
|
||||||
|
// 返回: []string 字体文件匹配模式
|
||||||
|
func fontFilePatterns(names ...string) []string {
|
||||||
|
var result []string
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
for _, name := range fontCandidateNames(names...) {
|
||||||
|
result = appendFontPattern(result, seen, name+"*")
|
||||||
|
}
|
||||||
|
for _, name := range names {
|
||||||
|
for _, rule := range fontMatchRules {
|
||||||
|
if fontRuleMatch(rule, name) {
|
||||||
|
for _, item := range rule.Files {
|
||||||
|
result = appendFontPattern(result, seen, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// fontSystemNames 获取系统字体名称
|
||||||
|
// 入参: names 字体名称列表
|
||||||
|
// 返回: []string 系统字体名称
|
||||||
|
func fontSystemNames(names ...string) []string {
|
||||||
|
var result []string
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
for _, name := range names {
|
||||||
|
for _, item := range fontCandidateNames(name) {
|
||||||
|
result = appendFontName(result, seen, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// fontDefaultSystemNames 获取默认系统字体名称
|
||||||
|
// 返回: []string 默认系统字体名称
|
||||||
|
func fontDefaultSystemNames() []string {
|
||||||
|
return []string{
|
||||||
|
"SimHei", "Microsoft YaHei", "SimSun", "KaiTi", "FangSong",
|
||||||
|
"Arial", "Segoe UI", "Times New Roman",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fontRuleMatch 判断字体规则是否匹配
|
||||||
|
// 入参: rule 字体匹配规则, name 字体名称
|
||||||
|
// 返回: bool 是否匹配
|
||||||
|
func fontRuleMatch(rule fontMatchRule, name string) bool {
|
||||||
|
name = fontNormalizeName(name)
|
||||||
|
if name == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, key := range rule.Keys {
|
||||||
|
key = fontNormalizeName(key)
|
||||||
|
if key != "" && (name == key || strings.Contains(name, key)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// appendFontName 追加字体名称
|
||||||
|
// 入参: names 字体名称列表, seen 去重映射, name 字体名称
|
||||||
|
// 返回: []string 字体名称列表
|
||||||
|
func appendFontName(names []string, seen map[string]bool, name string) []string {
|
||||||
|
name = strings.TrimSpace(name)
|
||||||
|
if name == "" {
|
||||||
|
return names
|
||||||
|
}
|
||||||
|
key := fontNormalizeName(name)
|
||||||
|
if key == "" || seen[key] {
|
||||||
|
return names
|
||||||
|
}
|
||||||
|
seen[key] = true
|
||||||
|
return append(names, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// appendFontPattern 追加字体文件匹配模式
|
||||||
|
// 入参: patterns 匹配模式列表, seen 去重映射, pattern 匹配模式
|
||||||
|
// 返回: []string 匹配模式列表
|
||||||
|
func appendFontPattern(patterns []string, seen map[string]bool, pattern string) []string {
|
||||||
|
pattern = strings.TrimSpace(pattern)
|
||||||
|
if pattern == "" {
|
||||||
|
return patterns
|
||||||
|
}
|
||||||
|
key := strings.ToLower(pattern)
|
||||||
|
if seen[key] {
|
||||||
|
return patterns
|
||||||
|
}
|
||||||
|
seen[key] = true
|
||||||
|
return append(patterns, pattern)
|
||||||
|
}
|
||||||
@@ -21,11 +21,7 @@ import "github.com/tdewolff/canvas"
|
|||||||
// loadDefaultFonts 加载默认字体
|
// loadDefaultFonts 加载默认字体
|
||||||
// 返回: bool 是否加载成功
|
// 返回: bool 是否加载成功
|
||||||
func (r *Renderer) loadDefaultFonts() bool {
|
func (r *Renderer) loadDefaultFonts() bool {
|
||||||
sysFonts := []string{
|
for _, name := range fontDefaultSystemNames() {
|
||||||
"SimHei", "Microsoft YaHei", "SimSun", "KaiTi", "FangSong",
|
|
||||||
"Arial", "Segoe UI", "Times New Roman",
|
|
||||||
}
|
|
||||||
for _, name := range sysFonts {
|
|
||||||
if err := r.fontFamily.LoadSystemFont(name, canvas.FontRegular); err == nil {
|
if err := r.fontFamily.LoadSystemFont(name, canvas.FontRegular); err == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-60
@@ -973,7 +973,8 @@ func (r *Renderer) loadFont(fontID string) *canvas.FontFamily {
|
|||||||
fontStyle |= canvas.FontItalic
|
fontStyle |= canvas.FontItalic
|
||||||
}
|
}
|
||||||
for _, dir := range r.fontDirs {
|
for _, dir := range r.fontDirs {
|
||||||
matches := r.globFontFiles(dir, of.FontName+"*")
|
for _, pattern := range fontFilePatterns(of.FontName, of.FamilyName) {
|
||||||
|
matches := r.globFontFiles(dir, pattern)
|
||||||
for _, m := range matches {
|
for _, m := range matches {
|
||||||
if err := ff.LoadFontFile(m, fontStyle); err == nil {
|
if err := ff.LoadFontFile(m, fontStyle); err == nil {
|
||||||
r.FontMap[fontID] = ff
|
r.FontMap[fontID] = ff
|
||||||
@@ -981,8 +982,10 @@ func (r *Renderer) loadFont(fontID string) *canvas.FontFamily {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for _, fsys := range r.fontFS {
|
for _, fsys := range r.fontFS {
|
||||||
if matches, err := fs.Glob(fsys, of.FontName+"*"); err == nil {
|
for _, pattern := range fontFilePatterns(of.FontName, of.FamilyName) {
|
||||||
|
if matches, err := fs.Glob(fsys, pattern); err == nil {
|
||||||
for _, m := range matches {
|
for _, m := range matches {
|
||||||
resData, err := fs.ReadFile(fsys, m)
|
resData, err := fs.ReadFile(fsys, m)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -994,6 +997,7 @@ func (r *Renderer) loadFont(fontID string) *canvas.FontFamily {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if !canLoadSystemFonts() {
|
if !canLoadSystemFonts() {
|
||||||
for _, fsys := range r.fontFS {
|
for _, fsys := range r.fontFS {
|
||||||
if matches, err := fs.Glob(fsys, "*"); err == nil {
|
if matches, err := fs.Glob(fsys, "*"); err == nil {
|
||||||
@@ -1016,16 +1020,11 @@ func (r *Renderer) loadFont(fontID string) *canvas.FontFamily {
|
|||||||
if name == "" {
|
if name == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
targetName := fontAliasName(name)
|
for _, targetName := range fontSystemNames(name) {
|
||||||
if err := ff.LoadSystemFont(targetName, fontStyle); err == nil {
|
if err := ff.LoadSystemFont(targetName, fontStyle); err == nil {
|
||||||
r.FontMap[fontID] = ff
|
r.FontMap[fontID] = ff
|
||||||
return ff
|
return ff
|
||||||
}
|
}
|
||||||
if targetName != name {
|
|
||||||
if err := ff.LoadSystemFont(name, fontStyle); err == nil {
|
|
||||||
r.FontMap[fontID] = ff
|
|
||||||
return ff
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var sysFontDir string
|
var sysFontDir string
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
@@ -1036,19 +1035,8 @@ func (r *Renderer) loadFont(fontID string) *canvas.FontFamily {
|
|||||||
default:
|
default:
|
||||||
sysFontDir = `C:\Windows\Fonts`
|
sysFontDir = `C:\Windows\Fonts`
|
||||||
}
|
}
|
||||||
matches := r.globFontFiles(sysFontDir, "*"+targetName+"*")
|
for _, pattern := range fontFilePatterns(name) {
|
||||||
if len(matches) == 0 {
|
matches := r.globFontFiles(sysFontDir, pattern)
|
||||||
switch targetName {
|
|
||||||
case "SimSun":
|
|
||||||
matches = r.globFontFiles(sysFontDir, "simsun.ttc")
|
|
||||||
case "KaiTi":
|
|
||||||
matches = r.globFontFiles(sysFontDir, "simkai.ttf")
|
|
||||||
case "SimHei":
|
|
||||||
matches = r.globFontFiles(sysFontDir, "simhei.ttf")
|
|
||||||
case "FangSong":
|
|
||||||
matches = r.globFontFiles(sysFontDir, "simfang.ttf")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, m := range matches {
|
for _, m := range matches {
|
||||||
if err := ff.LoadFontFile(m, fontStyle); err == nil {
|
if err := ff.LoadFontFile(m, fontStyle); err == nil {
|
||||||
r.FontMap[fontID] = ff
|
r.FontMap[fontID] = ff
|
||||||
@@ -1056,49 +1044,11 @@ func (r *Renderer) loadFont(fontID string) *canvas.FontFamily {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
r.FontMap[fontID] = defaultFont
|
r.FontMap[fontID] = defaultFont
|
||||||
return defaultFont
|
return defaultFont
|
||||||
}
|
}
|
||||||
|
|
||||||
// fontAliasName 获取系统字体替代名称
|
|
||||||
// 入参: name OFD字体名称
|
|
||||||
// 返回: string 系统字体名称
|
|
||||||
func fontAliasName(name string) string {
|
|
||||||
lower := strings.ToLower(strings.TrimSpace(name))
|
|
||||||
aliases := map[string]string{
|
|
||||||
"simhei": "SimHei",
|
|
||||||
"microsoft yahei": "Microsoft YaHei",
|
|
||||||
"simsun": "SimSun",
|
|
||||||
"kaiti": "KaiTi",
|
|
||||||
"fangsong": "FangSong",
|
|
||||||
"arial": "Arial",
|
|
||||||
"segoe ui": "Segoe UI",
|
|
||||||
"times new roman": "Times New Roman",
|
|
||||||
}
|
|
||||||
if mapped, ok := aliases[lower]; ok {
|
|
||||||
return mapped
|
|
||||||
}
|
|
||||||
contains := []struct {
|
|
||||||
Key string
|
|
||||||
Value string
|
|
||||||
}{
|
|
||||||
{"黑体", "SimHei"},
|
|
||||||
{"微软雅黑", "Microsoft YaHei"},
|
|
||||||
{"仿宋", "FangSong"},
|
|
||||||
{"楷体", "KaiTi"},
|
|
||||||
{"方正书宋", "SimSun"},
|
|
||||||
{"书宋", "SimSun"},
|
|
||||||
{"宋体", "SimSun"},
|
|
||||||
{"宋", "SimSun"},
|
|
||||||
}
|
|
||||||
for _, item := range contains {
|
|
||||||
if strings.Contains(lower, item.Key) {
|
|
||||||
return item.Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
// globFontFiles 查找字体文件
|
// globFontFiles 查找字体文件
|
||||||
// 入参: dir 目录, pattern 模式
|
// 入参: dir 目录, pattern 模式
|
||||||
// 返回: []string 文件列表
|
// 返回: []string 文件列表
|
||||||
|
|||||||
Reference in New Issue
Block a user