mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-16 22:50:13 +01:00
🐛 Loading certain font files causes kernel panic https://github.com/siyuan-note/siyuan/issues/13739
This commit is contained in:
parent
7ce19306ac
commit
72603bcfbf
1 changed files with 93 additions and 61 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue