From 3b2950a9c13c9e981446d0bd6d3177fb34883939 Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Sat, 12 Sep 2026 17:34:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96):=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=B5=84=E6=BA=90=E5=A4=8D=E7=94=A8=E3=80=81?= =?UTF-8?q?=E5=AD=97=E4=BD=93=E6=A0=A1=E9=AA=8C=E5=92=8C=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ofdgo_font_info.go | 16 ++++++++++++---- ofdgo_reader.go | 8 ++++++++ ofdgo_renderer_output.go | 25 +++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/ofdgo_font_info.go b/ofdgo_font_info.go index 2f40f4d..77e7027 100644 --- a/ofdgo_font_info.go +++ b/ofdgo_font_info.go @@ -168,10 +168,18 @@ func (r *Renderer) fontInfo(font Font) FontInfo { Embedded: font.FontFile != "", } if info.Embedded { - file, err := r.Reader.openFile(r.Reader.ResPath(font.FontFile)) - if err == nil { - _, err = io.Copy(io.Discard, file) - file.Close() + name := r.Reader.ResPath(font.FontFile) + var err error + if !r.Reader.fontFilesChecked[name] { + var file io.ReadCloser + file, err = r.Reader.openFile(name) + if err == nil { + _, err = io.Copy(io.Discard, file) + file.Close() + if err == nil { + r.Reader.fontFilesChecked[name] = true + } + } } if err == nil { info.Status = FontStatusEmbedded diff --git a/ofdgo_reader.go b/ofdgo_reader.go index 58d4c65..2d5c289 100644 --- a/ofdgo_reader.go +++ b/ofdgo_reader.go @@ -31,8 +31,10 @@ type Reader struct { OFD *OFD RootDir string ResMap map[string]string + resourcesRead map[string]bool fontCache map[string]*Font fontResourcesRead bool + fontFilesChecked map[string]bool colorSpaceCache map[string]*ColorSpace drawParamCache map[string]*DrawParam compositeGraphicUnitCache map[string]*CompositeGraphicUnit @@ -76,7 +78,9 @@ func (r *Reader) initRoot() error { } r.OFD = &ofd r.ResMap = make(map[string]string) + r.resourcesRead = make(map[string]bool) r.fontCache = make(map[string]*Font) + r.fontFilesChecked = make(map[string]bool) r.colorSpaceCache = make(map[string]*ColorSpace) r.drawParamCache = make(map[string]*DrawParam) r.compositeGraphicUnitCache = make(map[string]*CompositeGraphicUnit) @@ -182,6 +186,9 @@ func (r *Reader) loadRes(resPath string) { return } fullPath := r.ResPath(resPath) + if r.resourcesRead[fullPath] { + return + } data, err := r.readFile(fullPath) if err != nil { return @@ -217,6 +224,7 @@ func (r *Reader) loadRes(resPath string) { cgu := &res.CompositeGraphicUnits.CompositeGraphicUnit[i] r.compositeGraphicUnitCache[cgu.ID] = cgu } + r.resourcesRead[fullPath] = true } // resolveResourcePath 解析资源文件路径 diff --git a/ofdgo_renderer_output.go b/ofdgo_renderer_output.go index ee27d47..41e62f3 100644 --- a/ofdgo_renderer_output.go +++ b/ofdgo_renderer_output.go @@ -26,16 +26,37 @@ import ( "github.com/tdewolff/canvas/renderers/rasterizer" ) +// rasterRenderer 保留页面物理尺寸的光栅渲染器 +type rasterRenderer struct { + *rasterizer.Rasterizer + width, height float64 +} + +// Size 返回页面物理尺寸 +// 返回: float64 宽度, float64 高度 +func (r *rasterRenderer) Size() (float64, float64) { + return r.width, r.height +} + // RenderToImage 渲染为光栅图 // 入参: page 页面内容 // 返回: image.Image 图像对象, error 错误信息 func (r *Renderer) RenderToImage(page *PageContent) (image.Image, error) { - c, err := r.RenderPage(page) + box, err := r.GetPageBox(page) if err != nil { return nil, err } dpmm := r.DPI / 25.4 - return rasterizer.Draw(c, canvas.DPMM(dpmm), canvas.DefaultColorSpace), nil + raster := &rasterRenderer{ + Rasterizer: rasterizer.New(box.W, box.H, canvas.DPMM(dpmm), canvas.DefaultColorSpace), + width: box.W, + height: box.H, + } + if err := r.RenderPageToContext(canvas.NewContext(raster), page); err != nil { + return nil, err + } + raster.Close() + return raster.Image, nil } // RenderToSVG 渲染为SVG