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 @@
300
-
+
@@ -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