diff --git a/assets/webui/index.html b/assets/webui/index.html index 2f0e4fd..6b60d43 100644 --- a/assets/webui/index.html +++ b/assets/webui/index.html @@ -57,7 +57,7 @@ - + @@ -184,7 +184,7 @@
-
+
diff --git a/assets/webui/ofdgo.js b/assets/webui/ofdgo.js index 1a81569..766457d 100644 --- a/assets/webui/ofdgo.js +++ b/assets/webui/ofdgo.js @@ -1381,7 +1381,7 @@ document.addEventListener("selectionchange", syncSelection); el.exportFormat.addEventListener("change", () => updateDPIControl()); el.outputCompression.addEventListener("change", () => { el.compressionValue.textContent = el.outputCompression.selectedOptions[0].textContent; - el.compressionValue.dataset.short = ["默", "无", "轻", "均", "强"][Number(el.outputCompression.value)]; + el.compressionValue.dataset.short = ["原", "无", "轻", "均", "强"][Number(el.outputCompression.value)]; }); el.exportPageButton.addEventListener("click", () => exportFile(false)); el.exportButton.addEventListener("click", () => openExportPanel()); diff --git a/go.mod b/go.mod index 4f5d5be..db2b0b6 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/tdewolff/font v0.0.0-20260913163313-54f98bb59ee6 github.com/xiaoqidun/j2kgo v0.0.0-20261009063910-4865a21ef893 github.com/xiaoqidun/jbig2 v1.1.4 - github.com/xiaoqidun/pdfgo v0.0.0-20261010014421-57af90cea2c6 + github.com/xiaoqidun/pdfgo v0.0.0-20261010042215-c8c66c83f031 golang.org/x/crypto v0.58.0 golang.org/x/image v0.47.0 golang.org/x/text v0.43.0 diff --git a/go.sum b/go.sum index c56030e..3292087 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/xiaoqidun/j2kgo v0.0.0-20261009063910-4865a21ef893 h1:jmQlBO7R+bcimOM github.com/xiaoqidun/j2kgo v0.0.0-20261009063910-4865a21ef893/go.mod h1:DCwAfuDzCDYqUiAlZ7BDwigTjaXw7o9L1FtEma/D1aA= github.com/xiaoqidun/jbig2 v1.1.4 h1:LF6J1si4JY+TszTh9+m4KAg9/ba0JjfXoGtQTQC2S8c= github.com/xiaoqidun/jbig2 v1.1.4/go.mod h1:9jromqVwMqlptUDEt6Yip8vqYA5I1YjhG7FgMl/Z2dA= -github.com/xiaoqidun/pdfgo v0.0.0-20261010014421-57af90cea2c6 h1:APuDHlsRUfDMkV7+ONj2FwRFRGkO+KzbHqBoWh2aG54= -github.com/xiaoqidun/pdfgo v0.0.0-20261010014421-57af90cea2c6/go.mod h1:fXz1emtF1YCpcIv+fglDZstjkHxjS2l3G4DVMgUzVnk= +github.com/xiaoqidun/pdfgo v0.0.0-20261010042215-c8c66c83f031 h1:FV9MPGAQ08+AGYMPKesJWl42eLL5TPU+4niOlY1sVTY= +github.com/xiaoqidun/pdfgo v0.0.0-20261010042215-c8c66c83f031/go.mod h1:fXz1emtF1YCpcIv+fglDZstjkHxjS2l3G4DVMgUzVnk= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA= diff --git a/ofdgo_compression.go b/ofdgo_compression.go index 2e78da8..364b752 100644 --- a/ofdgo_compression.go +++ b/ofdgo_compression.go @@ -46,13 +46,13 @@ const ( // outputOptimizationBufferLimit 限制压缩时的单个输出缓冲,单位为字节 const outputOptimizationBufferLimit = 64 << 20 -// CompressionMode 选择默认、无损或有损输出策略 +// CompressionMode 选择原始、无损或有损输出策略 type CompressionMode = pdfgo.CompressionMode // CompressionLevel 选择轻压、均衡或强压,仅用于有损模式 type CompressionLevel = pdfgo.CompressionLevel -// CompressionOptions 配置输出压缩,默认模式沿用现有输出策略,不额外优化 +// CompressionOptions 配置输出压缩,原始模式沿用现有输出策略,不额外优化 // Quality和MaxDPI为零时按Level使用预设,不改变页面尺寸或整页导出精度 // 无损表示不引入额外损失,不保证跨格式转换可逆;有损不栅格化文字和矢量 type CompressionOptions = pdfgo.CompressionOptions diff --git a/ofdgo_convert.go b/ofdgo_convert.go index 0bfee60..b6baaaf 100644 --- a/ofdgo_convert.go +++ b/ofdgo_convert.go @@ -108,7 +108,7 @@ func OutputFormats() []OutputFormat { } // Convert 将PDF或OFD转换为指定格式,不关闭调用方的输入和输出 -// 默认模式完整OFD另存保持源字节;选页和跨格式输出重新生成文档,压缩仅作用于输出副本 +// 原始模式完整OFD另存保持源字节;选页和跨格式输出重新生成文档,压缩仅作用于输出副本 // 输入按需随机读取,输出分块写出;解析对象及后端可能缓存资源,不保证恒定内存 // 出错时报告保留已有诊断,调用方应丢弃未完成输出;只有返回nil才表示转换成功 // 入参: ctx 取消上下文, source 源数据, size 源字节数, output 输出流, options 转换选项 diff --git a/ofdgo_editor_annot_ops.go b/ofdgo_editor_annot_ops.go index 6599b36..033b15c 100644 --- a/ofdgo_editor_annot_ops.go +++ b/ofdgo_editor_annot_ops.go @@ -25,6 +25,7 @@ import ( // 来源修改或删除不影响快照,不用于跨文档传输 type AnnotationSelection struct { editor *Editor + document editorDocumentIdentity data [][]byte resources []string states map[string]map[string]editorCompositeState @@ -38,7 +39,7 @@ func (e *Editor) CaptureAnnotations(page int, ids []string) (*AnnotationSelectio if err != nil { return nil, err } - selection := &AnnotationSelection{editor: e, states: make(map[string]map[string]editorCompositeState)} + selection := &AnnotationSelection{editor: e, document: e.documentIdentity(), states: make(map[string]map[string]editorCompositeState)} seen := make(map[string]bool) for _, id := range ids { if seen[id] { @@ -73,7 +74,7 @@ func (e *Editor) CaptureAnnotations(page int, ids []string) (*AnnotationSelectio // 入参: page 目标页面索引, selection 当前编辑器快照, dx 横向位移,单位为毫米, dy 纵向位移,单位为毫米 // 返回: []string 新注解标识, error 错误信息 func (e *Editor) PasteAnnotations(page int, selection *AnnotationSelection, dx, dy float64) ([]string, error) { - if selection == nil || selection.editor != e || !finite(dx) || !finite(dy) { + if selection == nil || selection.editor != e || !e.documentIdentity().matches(selection.document) || !finite(dx) || !finite(dy) { return nil, fmt.Errorf("invalid annotation selection or offset") } var result []string diff --git a/ofdgo_editor_composite_copy.go b/ofdgo_editor_composite_copy.go index ee171b2..7392644 100644 --- a/ofdgo_editor_composite_copy.go +++ b/ofdgo_editor_composite_copy.go @@ -27,6 +27,7 @@ import ( // 父路径的祖先成员增删或排序后需重新捕获,避免使用已失效的序号路径 type CompositeSelection struct { editor *Editor + document editorDocumentIdentity page string path ObjectPath references int @@ -70,7 +71,7 @@ func (e *Editor) CaptureCompositeObjects(page int, path ObjectPath, indexes []in slices.Sort(indexes) var owner *editorCompositeNode var container *editorXML - selection := &CompositeSelection{editor: e, page: e.pages[page].ID, path: ObjectPath{ID: path.ID, Annotation: path.Annotation, Children: slices.Clone(path.Children)}} + selection := &CompositeSelection{editor: e, document: e.documentIdentity(), page: e.pages[page].ID, path: ObjectPath{ID: path.ID, Annotation: path.Annotation, Children: slices.Clone(path.Children)}} if path.Annotation == "" { selection.source = e.objectOrigin(path.ID).page } else if e.source != nil { @@ -112,8 +113,8 @@ func (e *Editor) CaptureCompositeObjects(page int, path ObjectPath, indexes []in // 入参: page 页面索引, path 父复合路径, selection 捕获的快照, dx 页面横向位移, dy 页面纵向位移 // 返回: []int 新成员序号, error 错误信息 func (e *Editor) PasteCompositeObjects(page int, path ObjectPath, selection *CompositeSelection, dx, dy float64) ([]int, error) { - if selection == nil || selection.editor != e { - return nil, fmt.Errorf("composite selection belongs to another editor") + if selection == nil || selection.editor != e || !e.documentIdentity().matches(selection.document) { + return nil, fmt.Errorf("composite selection belongs to another document or editor") } if !finite(dx) || !finite(dy) { return nil, fmt.Errorf("paste requires finite offsets") @@ -198,8 +199,8 @@ func (e *Editor) PasteCompositeObjects(page int, path ObjectPath, selection *Com // 入参: selection 独立内部快照, paste 目标范围粘贴操作 // 返回: error 错误信息 func (e *Editor) pasteCompositeSelection(selection *CompositeSelection, paste func([]GraphicObject) error) (err error) { - if selection == nil || selection.editor != e { - return fmt.Errorf("composite selection belongs to another editor") + if selection == nil || selection.editor != e || !e.documentIdentity().matches(selection.document) { + return fmt.Errorf("composite selection belongs to another document or editor") } count, maximum := len(e.resources), e.maxID ready := e.source != nil && e.source.idsReady @@ -324,7 +325,7 @@ func (e *Editor) pasteCompositeSelection(selection *CompositeSelection, paste fu object.CompositeGraphicUnit.states = maps.Clone(copy.states) copy.object.CompositeGraphicUnit.states = object.CompositeGraphicUnit.states } - object.origin = &editorObjectOrigin{editor: e, page: selection.source, data: copy.data, node: copy.node, object: copy.object} + object.origin = &editorObjectOrigin{editor: e, document: e.documentIdentity(), page: selection.source, data: copy.data, node: copy.node, object: copy.object} objects = append(objects, object) } return paste(objects) diff --git a/ofdgo_editor_composite_group.go b/ofdgo_editor_composite_group.go index efc8be7..2cf4886 100644 --- a/ofdgo_editor_composite_group.go +++ b/ofdgo_editor_composite_group.go @@ -201,7 +201,7 @@ func (e *Editor) ungroupCompositeNode(renderer *Renderer, node *editorCompositeN return fmt.Errorf("group member cannot be expanded") } } - return e.pasteCompositeSelection(&CompositeSelection{editor: e, nodes: members}, func(objects []GraphicObject) error { + return e.pasteCompositeSelection(&CompositeSelection{editor: e, document: e.documentIdentity(), nodes: members}, func(objects []GraphicObject) error { ids := make(map[string]string) if copy.ref != nil { for _, object := range objects { @@ -244,7 +244,7 @@ func (e *Editor) ungroupCompositeNode(renderer *Renderer, node *editorCompositeN member.object.state = states[editorObjectID(member.object)] member.object.TextObject.layout = member.object.state.layout member.object.CompositeGraphicUnit.states = states - member.object.origin = &editorObjectOrigin{editor: e, data: member.data, node: member.node, object: member.object} + member.object.origin = &editorObjectOrigin{editor: e, document: e.documentIdentity(), data: member.data, node: member.node, object: member.object} objects[i] = member.object } return replace(objects) diff --git a/ofdgo_editor_copy.go b/ofdgo_editor_copy.go index 83ededd..fa8fe8e 100644 --- a/ofdgo_editor_copy.go +++ b/ofdgo_editor_copy.go @@ -37,7 +37,7 @@ func (e *Editor) copiedObjectStyle(object GraphicObject, layer string) (GraphicO // 返回: *editorObjectOrigin 原文来源 func (e *Editor) snapshotOrigin(object GraphicObject) *editorObjectOrigin { if object.origin != nil { - if object.origin.editor == e || object.origin.page != nil && e.source != nil && e.source.pages[object.origin.page.ref.ID] == object.origin.page { + if object.origin.editor == e && e.documentIdentity().matches(object.origin.document) || object.origin.page != nil && e.source != nil && e.source.pages[object.origin.page.ref.ID] == object.origin.page { return object.origin } return nil diff --git a/ofdgo_editor_documents.go b/ofdgo_editor_documents.go index b884bb0..2742bce 100644 --- a/ofdgo_editor_documents.go +++ b/ofdgo_editor_documents.go @@ -27,6 +27,15 @@ import ( "strings" ) +// editorDocumentIdentity 标记编辑状态所属的文档,不持有页面或资源数据 +type editorDocumentIdentity struct { + root string + id string + fresh bool + single bool + fromNew bool +} + // DocumentCount 获取编辑包内的文档数量,新建编辑器包含一个当前文档 // 返回: int 文档数量 func (e *Editor) DocumentCount() int { @@ -329,15 +338,31 @@ func (e *Editor) documentRoot() string { // 入参: other 编辑快照 // 返回: bool 是否为同一文档 func (e *Editor) sameDocument(other *Editor) bool { - if e.source == nil || other.source == nil { - if e.source == nil && other.source == nil { + return e.documentIdentity().matches(other.documentIdentity()) +} + +// documentIdentity 获取当前文档的入口与原始标识,文档排序不改变身份 +// 返回: editorDocumentIdentity 文档身份 +func (e *Editor) documentIdentity() editorDocumentIdentity { + if e.source == nil { + return editorDocumentIdentity{id: e.Info.DocID, fresh: true} + } + return editorDocumentIdentity{root: e.documentRoot(), id: e.source.info.DocID, single: e.DocumentCount() == 1, fromNew: e.source.fromNew} +} + +// matches 判断两个编辑状态是否属于同一文档,允许新文档首次建立包结构 +// 入参: other 另一编辑状态的文档身份 +// 返回: bool 是否为同一文档 +func (identity editorDocumentIdentity) matches(other editorDocumentIdentity) bool { + if identity.fresh || other.fresh { + if identity.fresh && other.fresh { return true } - fresh, packaged := e, other - if fresh.source != nil { - fresh, packaged = other, e + fresh, packaged := identity, other + if !fresh.fresh { + fresh, packaged = other, identity } - return len(packaged.source.reader.OFD.DocBody) == 1 && (packaged.source.fromNew || fresh.Info.DocID != "" && fresh.Info.DocID == packaged.source.info.DocID) + return packaged.single && (packaged.fromNew || fresh.id != "" && fresh.id == packaged.id) } - return e.documentRoot() == other.documentRoot() && e.source.info.DocID == other.source.info.DocID + return identity.root == other.root && identity.id == other.id } diff --git a/ofdgo_editor_font_binding.go b/ofdgo_editor_font_binding.go index be16b8b..d4a99e2 100644 --- a/ofdgo_editor_font_binding.go +++ b/ofdgo_editor_font_binding.go @@ -91,6 +91,11 @@ func (e *Editor) changeFont(ctx context.Context, id string, mode FontMode, file if err != nil || !changed { return err } + if mode == FontExternal { + if err := pruneExternalFontFiles(ctx, reader, scan.fonts[editorResourceID(id)].location); err != nil { + return err + } + } return e.commitFontSnapshot(ctx, reader) } @@ -133,6 +138,7 @@ func (e *Editor) ProcessFontsWithOptions(ctx context.Context, options FontProces return nil, err } var report []FontChange + var externalFiles []string changed := false for document := range reader.DocumentCount() { if err := progress("scan", document, reader.DocumentCount()); err != nil { @@ -172,6 +178,9 @@ func (e *Editor) ProcessFontsWithOptions(ctx context.Context, options FontProces } if item.Changed { changed = true + if mode == FontExternal { + externalFiles = append(externalFiles, declaration.location) + } scan, err = scanEditorFonts(ctx, reader, document) if err != nil { return nil, err @@ -186,6 +195,9 @@ func (e *Editor) ProcessFontsWithOptions(ctx context.Context, options FontProces if err := progress("commit", 0, 1); err != nil { return nil, err } + if err := pruneExternalFontFiles(ctx, reader, externalFiles...); err != nil { + return nil, err + } err = e.commitFontSnapshot(ctx, reader) } return report, err @@ -343,11 +355,6 @@ func (e *Editor) changeFontSnapshot(ctx context.Context, scan *editorFontDocumen if err := working.initRoot(); err != nil { return false, err } - if mode == FontExternal { - if err := pruneExternalFontFiles(ctx, &working, declaration.location); err != nil { - return false, err - } - } *scan.reader = working return true, nil } @@ -502,6 +509,9 @@ func (e *Editor) commitFontSnapshot(ctx context.Context, reader *Reader) error { if err != nil { return err } + if err := ctx.Err(); err != nil { + return err + } before := e.transactionSnapshot() e.restoreFontSnapshot(*next) if change := e.recordChange(); change != nil { @@ -525,11 +535,22 @@ func (e *Editor) restoreFontSnapshot(state Editor) { *e = state } -// pruneExternalFontFiles 保留全包仍引用的字体,未确认的扩展引用使清理保持保守 -// 入参: ctx 取消上下文, reader 包快照, candidate 原字体路径 +// pruneExternalFontFiles 清理全包不再引用的字体文件,遇到无法识别的扩展时保留资源 +// 入参: ctx 取消上下文, reader 包快照, candidates 待清理的字体路径 // 返回: error 取消或读取错误 -func pruneExternalFontFiles(ctx context.Context, reader *Reader, candidate string) error { - used := make(map[string]bool) +func pruneExternalFontFiles(ctx context.Context, reader *Reader, candidates ...string) error { + if err := ctx.Err(); err != nil { + return err + } + removed := make(map[string]bool, len(candidates)) + for _, candidate := range candidates { + if key := strings.ToLower(cleanPackagePath(candidate)); key != "" { + removed[key] = true + } + } + if len(removed) == 0 { + return nil + } for i := range reader.DocumentCount() { files, err := reader.documentFiles(ctx, i) if err != nil { @@ -538,12 +559,12 @@ func pruneExternalFontFiles(ctx context.Context, reader *Reader, candidate strin } return nil } - maps.Copy(used, files) - } - removed := make(map[string]bool) - key := strings.ToLower(cleanPackagePath(candidate)) - if used[key] { - return nil + for name := range files { + delete(removed, name) + } + if len(removed) == 0 { + return nil + } } for _, name := range reader.fileNamesFold { if err := ctx.Err(); err != nil { @@ -574,20 +595,21 @@ func pruneExternalFontFiles(ctx context.Context, reader *Reader, candidate strin return true } } - if node.matchesOFD("FontFile") && strings.EqualFold(resolveResourcePath(name, base, strings.TrimSpace(editorImportText(data, node))), candidate) { - return true + if node.matchesOFD("FontFile") { + location := resolveResourcePath(name, base, strings.TrimSpace(editorImportText(data, node))) + delete(removed, strings.ToLower(cleanPackagePath(location))) } return slices.ContainsFunc(node.children, retains) } - if retains(root) { + if retains(root) || len(removed) == 0 { return nil } } - if !used[key] { - removed[key] = true + if err := ctx.Err(); err != nil { + return err } for name := range reader.files { - if removed[strings.ToLower(name)] { + if removed[strings.ToLower(cleanPackagePath(name))] { delete(reader.files, name) } } diff --git a/ofdgo_editor_import.go b/ofdgo_editor_import.go index 3017f6d..f7bb292 100644 --- a/ofdgo_editor_import.go +++ b/ofdgo_editor_import.go @@ -216,7 +216,7 @@ func (e *Editor) ImportObjects(source *Editor, sourcePage int, ids []string, pag imported[i].TextObject.layout = objects[i].TextObject.layout imported[i].state = objects[i].state imported[i].CompositeGraphicUnit.states = remapCompositeStates(objects[i].CompositeGraphicUnit.states, migration.ids) - imported[i].origin = &editorObjectOrigin{editor: editor, data: data, node: root.child("Layer").children[0], object: object} + imported[i].origin = &editorObjectOrigin{editor: editor, document: editor.documentIdentity(), data: data, node: root.child("Layer").children[0], object: object} } copied, err = editor.CopyObjects(page, imported, options.DX, options.DY) return err diff --git a/ofdgo_editor_open.go b/ofdgo_editor_open.go index cb3f00f..41c1a27 100644 --- a/ofdgo_editor_open.go +++ b/ofdgo_editor_open.go @@ -47,12 +47,13 @@ type editorSource struct { // editorObjectOrigin 保留原对象的XML语义,供复制和局部更新复用 type editorObjectOrigin struct { - editor *Editor - page *editorSourcePage - data []byte - node *editorXML - object GraphicObject - reason error + editor *Editor + document editorDocumentIdentity + page *editorSourcePage + data []byte + node *editorXML + object GraphicObject + reason error } // editorSourcePage 保存页面原文、解析快照及图层和页块内的对象位置 @@ -613,6 +614,7 @@ func (e *Editor) setObjectOrigin(id string, origin *editorObjectOrigin) { if origin != nil && origin.page == nil && origin.editor == nil { copy := *origin copy.editor = e + copy.document = e.documentIdentity() origin = © } e.origins[id] = origin diff --git a/ofdgo_editor_selection_copy.go b/ofdgo_editor_selection_copy.go index dc7eba3..ee19245 100644 --- a/ofdgo_editor_selection_copy.go +++ b/ofdgo_editor_selection_copy.go @@ -20,6 +20,7 @@ import "fmt" // 来源修改、删除或撤销不改变快照,不用于跨文档传输 type ObjectSelection struct { editor *Editor + document editorDocumentIdentity objects []GraphicObject annotations *AnnotationSelection } @@ -32,7 +33,7 @@ func (e *Editor) CaptureSelection(page int, objects, annotations []string) (*Obj if err != nil { return nil, err } - selection := &ObjectSelection{editor: e, objects: items} + selection := &ObjectSelection{editor: e, document: e.documentIdentity(), objects: items} if len(annotations) != 0 { selection.annotations, err = e.CaptureAnnotations(page, annotations) if err != nil { @@ -46,7 +47,7 @@ func (e *Editor) CaptureSelection(page int, objects, annotations []string) (*Obj // 入参: page 目标页面索引, selection 当前编辑器快照, dx 横向位移,单位为毫米, dy 纵向位移,单位为毫米 // 返回: []string 新正文标识, []string 新注解标识, error 标识、资源或编辑错误 func (e *Editor) PasteSelection(page int, selection *ObjectSelection, dx, dy float64) ([]string, []string, error) { - if selection == nil || selection.editor != e || !finite(dx) || !finite(dy) { + if selection == nil || selection.editor != e || !e.documentIdentity().matches(selection.document) || !finite(dx) || !finite(dy) { return nil, nil, fmt.Errorf("invalid object selection or offset") } var objects, annotations []string @@ -68,8 +69,8 @@ func (e *Editor) PasteSelection(page int, selection *ObjectSelection, dx, dy flo // 入参: page 目标页面索引, path 父复合路径, selection 当前编辑器快照, dx 横向位移,单位为毫米, dy 纵向位移,单位为毫米 // 返回: []int 新成员序号, error 选区、资源或编辑错误 func (e *Editor) PasteSelectionToComposite(page int, path ObjectPath, selection *ObjectSelection, dx, dy float64) ([]int, error) { - if selection == nil || selection.editor != e { - return nil, fmt.Errorf("object selection belongs to another editor") + if selection == nil || selection.editor != e || !e.documentIdentity().matches(selection.document) { + return nil, fmt.Errorf("object selection belongs to another document or editor") } if selection.annotations != nil { return nil, fmt.Errorf("annotations cannot be nested in a page object") diff --git a/ofdgo_editor_style.go b/ofdgo_editor_style.go index 8a419c1..a5aa61e 100644 --- a/ofdgo_editor_style.go +++ b/ofdgo_editor_style.go @@ -207,7 +207,7 @@ func (e *Editor) SetObjectDrawParam(page int, ids []string, id string) error { if err != nil { return err } - updated := &editorObjectOrigin{editor: e, data: data, node: root, object: next} + updated := &editorObjectOrigin{editor: e, document: e.documentIdentity(), data: data, node: root, object: next} if origin != nil { updated.page, root.parent = origin.page, origin.node.parent } else { diff --git a/ofdgo_pdf.go b/ofdgo_pdf.go index 7dcd5a1..2a78223 100644 --- a/ofdgo_pdf.go +++ b/ofdgo_pdf.go @@ -37,7 +37,7 @@ var ErrPDFPassword = pdfgo.ErrPassword // ResolveFile读取PDF引用的外部媒体、附件和页面,默认不访问网络或本地路径 // ResolveReference可提供已解密的引用页面,目标阅读器由调用方维护 // Halftones提供只读设备命名网屏,所属阅读器由调用方维护,连续色调输出不网屏化 -// Compression配置转换输出,有损模式按图片实际尺寸降采样,默认及无损保持完整采样 +// Compression配置转换输出,有损模式按图片实际尺寸降采样,原始及无损模式保持完整采样 type PDFImportOptions struct { Password []byte PasswordUTF8 bool