diff --git a/kernel/util/font.go b/kernel/util/font.go index 0b1824ee4..f11ca9e75 100644 --- a/kernel/util/font.go +++ b/kernel/util/font.go @@ -79,68 +79,22 @@ func loadFonts() (ret []*Font) { ret = []*Font{} for _, fontPath := range findfont.List() { if strings.HasSuffix(strings.ToLower(fontPath), ".ttc") { - data, err := os.ReadFile(fontPath) - if err != nil { - logging.LogErrorf("read font file [%s] failed: %s", fontPath, err) - continue - } - collection, err := ttc.ParseCollection(data) - if err != nil { - //LogErrorf("parse font collection [%s] failed: %s", fontPath, err) - continue - } - - for i := 0; i < collection.NumFonts(); i++ { - font, err := collection.Font(i) - if err != nil { - //LogErrorf("get font [%s] failed: %s", fontPath, err) + families := parseTTCFontFamily(fontPath) + for _, family := range families { + if existFont(family, ret) { continue } - if family := parseFontFamily(font); "" != family { - ret = append(ret, &Font{fontPath, family}) - //LogInfof("[%s] [%s]", fontPath, family) - } + + ret = append(ret, &Font{fontPath, family}) + //LogInfof("[%s] [%s]", fontPath, family) } } else if strings.HasSuffix(strings.ToLower(fontPath), ".otf") || strings.HasSuffix(strings.ToLower(fontPath), ".ttf") { - fontFile, err := os.Open(fontPath) - if err != nil { - //LogErrorf("open font file [%s] failed: %s", fontPath, err) - continue - } - font, err := sfnt.Parse(fontFile) - if err != nil { - //LogErrorf("parse font [%s] failed: %s", fontPath, err) - continue - } - - t, err := font.NameTable() - if err != nil { - //LogErrorf("parse font name table [%s] failed: %s", fontPath, err) - return - } - fontFile.Close() - var family string - for _, e := range t.List() { - if sfnt.NameFontFamily != e.NameID && sfnt.NamePreferredFamily != e.NameID { + family := parseTTFFontFamily(fontPath) + if "" != family { + if existFont(family, ret) { continue } - if sfnt.PlatformLanguageID(1033) == e.LanguageID || sfnt.PlatformLanguageID(2052) == e.LanguageID { - v, _, err := transform.Bytes(textUnicode.UTF16(textUnicode.BigEndian, textUnicode.IgnoreBOM).NewDecoder(), e.Value) - if err != nil { - //LogErrorf("decode font family [%s] failed: %s", fontPath, err) - continue - } - val := string(v) - if sfnt.NameFontFamily == e.NameID && "" != val { - family = val - } - if sfnt.NamePreferredFamily == e.NameID && "" != val { - family = val - } - } - } - if "" != family && !strings.HasPrefix(family, ".") { ret = append(ret, &Font{fontPath, family}) //logging.LogInfof("[%s] [%s]", fontPath, family) } @@ -149,13 +103,91 @@ func loadFonts() (ret []*Font) { return } -func parseFontFamily(font *ttc.Font) string { - family, _ := font.Name(nil, ttc.NameIDTypographicFamily) - if "" == family { - family, _ = font.Name(nil, ttc.NameIDFamily) +func existFont(family string, fonts []*Font) bool { + for _, font := range fonts { + if strings.EqualFold(family, font.Family) { + return true + } } - if strings.HasPrefix(family, ".") { + return false +} + +func parseTTCFontFamily(fontPath string) (ret []string) { + defer logging.Recover() + + data, err := os.ReadFile(fontPath) + if err != nil { + //logging.LogErrorf("read font file [%s] failed: %s", fontPath, err) + return + } + collection, err := ttc.ParseCollection(data) + if err != nil { + //LogErrorf("parse font collection [%s] failed: %s", fontPath, err) + return + } + + for i := 0; i < collection.NumFonts(); i++ { + font, err := collection.Font(i) + if err != nil { + //LogErrorf("get font [%s] failed: %s", fontPath, err) + continue + } + + family, _ := font.Name(nil, ttc.NameIDTypographicFamily) + if "" == family { + family, _ = font.Name(nil, ttc.NameIDFamily) + } + family = strings.TrimSpace(family) + if "" == family || strings.HasPrefix(family, ".") { + continue + } + ret = append(ret, family) + } + return +} + +func parseTTFFontFamily(fontPath string) (ret string) { + defer logging.Recover() + + fontFile, err := os.Open(fontPath) + if err != nil { + //LogErrorf("open font file [%s] failed: %s", fontPath, err) + return + } + font, err := sfnt.Parse(fontFile) + if err != nil { + //LogErrorf("parse font [%s] failed: %s", fontPath, err) + return + } + + t, err := font.NameTable() + if err != nil { + return + } + + for _, e := range t.List() { + if sfnt.NameFontFamily != e.NameID && sfnt.NamePreferredFamily != e.NameID { + continue + } + + if sfnt.PlatformLanguageID(1033) == e.LanguageID || sfnt.PlatformLanguageID(2052) == e.LanguageID { + v, _, err := transform.Bytes(textUnicode.UTF16(textUnicode.BigEndian, textUnicode.IgnoreBOM).NewDecoder(), e.Value) + if err != nil { + return "" + } + val := string(v) + if sfnt.NameFontFamily == e.NameID && "" != val { + ret = val + } + if sfnt.NamePreferredFamily == e.NameID && "" != val { + ret = val + } + } + } + + ret = strings.TrimSpace(ret) + if strings.HasPrefix(ret, ".") { return "" } - return family + return }