mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
1 parent
7bce701907
commit
92149b220e
3 files changed
+39
-38
No files matched your search
+14
-21
@@ -283,17 +283,12 @@ func subsetSourceSFNTFont(data []byte, usage *editorFontUsage) []byte {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
for id := range glyphs {
|
||||
if id >= sfnt.NumGlyphs() {
|
||||
return nil
|
||||
}
|
||||
dependencies, err := sfnt.glyphDependencies(id)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
for _, dependency := range dependencies {
|
||||
glyphs[dependency] = true
|
||||
}
|
||||
dependencies, err := sfnt.glyphDependencies(slices.Collect(maps.Keys(glyphs))...)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
for _, dependency := range dependencies {
|
||||
glyphs[dependency] = true
|
||||
}
|
||||
var glyf, loca []byte
|
||||
for id := 0; id <= int(sfnt.NumGlyphs()); id++ {
|
||||
@@ -426,16 +421,14 @@ func subsetCompactSFNTFont(sfnt *sfntFont, glyphs []uint16) ([]byte, error) {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
for index := 0; index < len(ids); index++ {
|
||||
dependencies, err := sfnt.glyphDependencies(ids[index])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, id := range dependencies {
|
||||
if _, ok := remap[id]; !ok {
|
||||
remap[id] = uint16(len(ids))
|
||||
ids = append(ids, id)
|
||||
}
|
||||
dependencies, err := sfnt.glyphDependencies(ids...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, id := range dependencies {
|
||||
if _, ok := remap[id]; !ok {
|
||||
remap[id] = uint16(len(ids))
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
table := make(map[string][]byte)
|
||||
|
||||
+17
-9
@@ -263,21 +263,24 @@ func (f *sfntFont) VerticalMetrics() (uint16, uint16, uint16) {
|
||||
// 返回: []byte 独立字体
|
||||
func (f *sfntFont) Write() []byte { data, _ := serializeOTF(f.Tables); return data }
|
||||
|
||||
// glyphDependencies 收集复合字形依赖,拒绝循环引用和截断记录
|
||||
// 入参: gid 字形编号
|
||||
// glyphDependencies 批量收集复合字形依赖,校验引用、记录长度和嵌套深度
|
||||
// 入参: glyphs 字形编号
|
||||
// 返回: []uint16 依赖字形, error 字形错误
|
||||
func (f *sfntFont) glyphDependencies(gid uint16) ([]uint16, error) {
|
||||
seen, active := make(map[uint16]bool), make(map[uint16]bool)
|
||||
func (f *sfntFont) glyphDependencies(glyphs ...uint16) ([]uint16, error) {
|
||||
heights, active := make(map[uint16]int), make(map[uint16]bool)
|
||||
var result []uint16
|
||||
var visit func(uint16) error
|
||||
visit = func(id uint16) error {
|
||||
if id >= f.count || active[id] || len(active) > 64 {
|
||||
return fmt.Errorf("invalid composite glyph reference")
|
||||
}
|
||||
if seen[id] {
|
||||
if height := heights[id]; height != 0 {
|
||||
if len(active)+height > 65 {
|
||||
return fmt.Errorf("invalid composite glyph reference")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
seen[id], active[id] = true, true
|
||||
heights[id], active[id] = 1, true
|
||||
defer delete(active, id)
|
||||
data, err := trueTypeGlyphData(f.Tables, id)
|
||||
if err != nil {
|
||||
@@ -315,18 +318,23 @@ func (f *sfntFont) glyphDependencies(gid uint16) ([]uint16, error) {
|
||||
if pos > len(data) {
|
||||
return fmt.Errorf("truncated composite transform")
|
||||
}
|
||||
if !seen[child] {
|
||||
if heights[child] == 0 {
|
||||
result = append(result, child)
|
||||
}
|
||||
if err := visit(child); err != nil {
|
||||
return err
|
||||
}
|
||||
heights[id] = max(heights[id], heights[child]+1)
|
||||
if flags&0x20 == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := visit(gid)
|
||||
return result, err
|
||||
for _, id := range glyphs {
|
||||
if err := visit(id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -17,6 +17,8 @@ package ofdgo
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"maps"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// variableSFNTSubsettable 核对TrueType可变轴与字形变化表的基本结构
|
||||
@@ -51,14 +53,12 @@ func subsetVariableSFNTFont(sfnt *sfntFont, glyphs []uint16) ([]byte, error) {
|
||||
usage.chars[char] = true
|
||||
}
|
||||
}
|
||||
for gid := range usage.glyphs {
|
||||
dependencies, err := sfnt.glyphDependencies(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, dependency := range dependencies {
|
||||
usage.glyphs[dependency] = true
|
||||
}
|
||||
dependencies, err := sfnt.glyphDependencies(slices.Collect(maps.Keys(usage.glyphs))...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, dependency := range dependencies {
|
||||
usage.glyphs[dependency] = true
|
||||
}
|
||||
mapping := make(map[rune]uint16, len(usage.chars))
|
||||
for char := range usage.chars {
|
||||
|
||||
Reference in new issue
Block a user