Enhance GlyphOutlineMapper by adding standardFontLastRune and findLastRune method for improved glyph mapping efficiency.

This commit is contained in:
2025-08-27 14:03:49 +10:00
parent 56c76d8202
commit feb0836187

View File

@@ -10,11 +10,12 @@ import (
) )
type GlyphOutlineMapper struct { type GlyphOutlineMapper struct {
specialFont *truetype.Font specialFont *truetype.Font
standardFont *truetype.Font standardFont *truetype.Font
concurrent int standardFontLastRune rune
wg *sync.WaitGroup concurrent int
sem chan struct{} wg *sync.WaitGroup
sem chan struct{}
} }
func NewGlyphOutlineMapper(specialFontData, standardFontData []byte) (*GlyphOutlineMapper, error) { func NewGlyphOutlineMapper(specialFontData, standardFontData []byte) (*GlyphOutlineMapper, error) {
@@ -35,6 +36,7 @@ func NewGlyphOutlineMapper(specialFontData, standardFontData []byte) (*GlyphOutl
return nil, fmt.Errorf("parse standard font failed: %w", err) return nil, fmt.Errorf("parse standard font failed: %w", err)
} }
mapper.standardFont = standardFont mapper.standardFont = standardFont
mapper.standardFontLastRune = mapper.findLastRune(standardFont)
return &mapper, nil return &mapper, nil
} }
@@ -107,6 +109,20 @@ func (g *GlyphOutlineMapper) compareGlyphOutlines(buf1, buf2 *truetype.GlyphBuf)
return true return true
} }
func (g *GlyphOutlineMapper) findLastRune(font *truetype.Font) rune {
if font == nil {
return 0
}
// Iterate downwards from the highest possible rune to find the last one with a glyph.
// This can be slow on startup.
for r := rune(0x10FFFF); r >= 0; r-- {
if font.Index(r) > 0 {
return r
}
}
return 0
}
func (g *GlyphOutlineMapper) Mapping(start, end rune) map[rune]rune { func (g *GlyphOutlineMapper) Mapping(start, end rune) map[rune]rune {
results := &sync.Map{} results := &sync.Map{}
for i := start; i <= end; i++ { for i := start; i <= end; i++ {
@@ -136,13 +152,21 @@ func (g *GlyphOutlineMapper) MappingRune(unicode rune) (specialRune, standardRun
if ok = g.hasGlyph(g.specialFont, unicode); !ok { if ok = g.hasGlyph(g.specialFont, unicode); !ok {
return return
} }
for j := 0x4e00; j <= 0x9fff; j++ { if ok = g.hasGlyph(g.standardFont, unicode); ok {
if ok = g.hasGlyph(g.standardFont, rune(j)); !ok { if ok = g.GlyphOutlineEqual(unicode, unicode); ok {
specialRune = unicode
standardRune = unicode
return
}
}
for j := rune(0); j <= g.standardFontLastRune; j++ {
if ok = g.hasGlyph(g.standardFont, j); !ok {
continue continue
} }
if ok = g.GlyphOutlineEqual(rune(unicode), rune(j)); ok { if ok = g.GlyphOutlineEqual(unicode, j); ok {
specialRune = rune(unicode) specialRune = unicode
standardRune = rune(j) standardRune = j
return return
} }
} }