diff --git a/ofdgo_reader.go b/ofdgo_reader.go index 9cb2532..80b8af9 100644 --- a/ofdgo_reader.go +++ b/ofdgo_reader.go @@ -36,6 +36,7 @@ type Reader struct { compositeGraphicUnitCache map[string]*CompositeGraphicUnit doc *Document Stamps map[string][]Stamp + fileIndex map[string]*zip.File } // Close 关闭阅读器 @@ -50,6 +51,10 @@ func (r *Reader) Close() error { // initRoot 读取根节点信息 // 返回: error 错误信息 func (r *Reader) initRoot() error { + r.fileIndex = make(map[string]*zip.File) + for _, f := range r.Zip.File { + r.fileIndex[f.Name] = f + } data, err := r.readFile("OFD.xml") if err != nil { return fmt.Errorf("failed to read ofd.xml: %w", err) @@ -72,10 +77,8 @@ func (r *Reader) initRoot() error { func (r *Reader) readFile(name string) ([]byte, error) { name = strings.ReplaceAll(name, "\\", "/") name = strings.TrimPrefix(name, "/") - for _, f := range r.Zip.File { - if f.Name == name { - return readZipFile(f) - } + if f, ok := r.fileIndex[name]; ok { + return readZipFile(f) } return nil, fmt.Errorf("file not found: %s", name) } @@ -86,10 +89,8 @@ func (r *Reader) readFile(name string) ([]byte, error) { func (r *Reader) openFile(name string) (io.ReadCloser, error) { name = strings.ReplaceAll(name, "\\", "/") name = strings.TrimPrefix(name, "/") - for _, f := range r.Zip.File { - if f.Name == name { - return f.Open() - } + if f, ok := r.fileIndex[name]; ok { + return f.Open() } return nil, fmt.Errorf("file not found: %s", name) } diff --git a/ofdgo_renderer.go b/ofdgo_renderer.go index 70a6e39..7bd5cde 100644 --- a/ofdgo_renderer.go +++ b/ofdgo_renderer.go @@ -23,6 +23,7 @@ import ( "io/fs" "math" "path/filepath" + "runtime" "strconv" "strings" @@ -777,18 +778,26 @@ func (r *Renderer) loadFont(fontID string) *canvas.FontFamily { return ff } } - winFontDir := `C:\Windows\Fonts` - matches := r.globFontFiles(winFontDir, "*"+targetName+"*") + var sysFontDir string + switch runtime.GOOS { + case "linux": + sysFontDir = `/usr/share/fonts` + case "darwin": + sysFontDir = `/Library/Fonts` + default: + sysFontDir = `C:\Windows\Fonts` + } + matches := r.globFontFiles(sysFontDir, "*"+targetName+"*") if len(matches) == 0 { switch targetName { case "SimSun": - matches = r.globFontFiles(winFontDir, "simsun.ttc") + matches = r.globFontFiles(sysFontDir, "simsun.ttc") case "KaiTi": - matches = r.globFontFiles(winFontDir, "simkai.ttf") + matches = r.globFontFiles(sysFontDir, "simkai.ttf") case "SimHei": - matches = r.globFontFiles(winFontDir, "simhei.ttf") + matches = r.globFontFiles(sysFontDir, "simhei.ttf") case "FangSong": - matches = r.globFontFiles(winFontDir, "simfang.ttf") + matches = r.globFontFiles(sysFontDir, "simfang.ttf") } } for _, m := range matches { diff --git a/ofdgo_sign.go b/ofdgo_sign.go index ce6b3f5..1b0bc29 100644 --- a/ofdgo_sign.go +++ b/ofdgo_sign.go @@ -71,28 +71,29 @@ func (r *Reader) parseSignatures(doc *Document) error { return err } for _, sigRef := range signatures.List { - sigPath := path.Join(path.Dir(doc.Signatures), sigRef.BaseLoc) - sf, err := r.openFile(sigPath) - if err != nil { - continue - } - var sigFile SignatureFile - if err := xml.NewDecoder(sf).Decode(&sigFile); err != nil { - sf.Close() - continue - } - sf.Close() - signedValuePath := path.Join(path.Dir(sigPath), sigFile.SignedValue) - svData, err := r.ResData(signedValuePath) - if err != nil { - continue - } - sealType, sealData := extractSeal(svData) - for _, annot := range sigFile.SignedInfo.StampAnnot { - pageID := annot.PageRef - bbox, _ := ParseBox(annot.Boundary) - r.addStamp(pageID, bbox, sealType, sealData) - } + func(sigRef OFDSignature) { + sigPath := path.Join(path.Dir(doc.Signatures), sigRef.BaseLoc) + sf, err := r.openFile(sigPath) + if err != nil { + return + } + defer sf.Close() + var sigFile SignatureFile + if err := xml.NewDecoder(sf).Decode(&sigFile); err != nil { + return + } + signedValuePath := path.Join(path.Dir(sigPath), sigFile.SignedValue) + svData, err := r.ResData(signedValuePath) + if err != nil { + return + } + sealType, sealData := extractSeal(svData) + for _, annot := range sigFile.SignedInfo.StampAnnot { + pageID := annot.PageRef + bbox, _ := ParseBox(annot.Boundary) + r.addStamp(pageID, bbox, sealType, sealData) + } + }(sigRef) } return nil }