From ba68acbc604ac73f7cbd2d1d6cc6c7a24172b3f7 Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Wed, 28 Oct 2026 10:06:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E7=BC=96=E8=BE=91=E8=83=BD=E5=8A=9B):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=87=E6=9C=AC=E6=A1=86=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E4=B8=8E=E6=94=B9=E5=AE=BD=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/webui/webui.go | 51 ++++++++++++--------------------------- ofdgo_editor_rich_text.go | 21 ++++++++++++++++ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/internal/webui/webui.go b/internal/webui/webui.go index a2c3bfd..567deec 100644 --- a/internal/webui/webui.go +++ b/internal/webui/webui.go @@ -4111,16 +4111,8 @@ func (e *businessEngine) changeCompositeObjects(args []platformValue) (any, erro if len(indexes) != 1 { return fmt.Errorf("text layout requires one member") } - layout := ofdgo.TextLayout{AutoBidi: true, Wrap: args[6].Bool(), Align: args[7].String(), LineHeight: args[8].Float(), LetterSpacing: args[9].Float(), LeftIndent: args[10].Float(), RightIndent: args[11].Float(), FirstLineIndent: args[12].Float()} - if !args[4].IsNull() { - return e.currentEditor.ResizeCompositeTextFrame(page, path, indexes[0], args[4].Float(), args[5].Float(), layout) - } - member, err := e.currentEditor.CompositeObject(page, path, indexes[0]) - if err != nil { - return err - } - value, _ := member.Object.TextObject.TextLayout() - return e.currentEditor.LayoutCompositeText(page, path, indexes[0], value, layout) + path.Children = append(slices.Clone(path.Children), indexes[0]) + return e.layoutEditorText(page, path, args[4:]) case "fit", "resetCrop": if len(indexes) != 1 { return fmt.Errorf("image operation requires one member") @@ -5317,32 +5309,21 @@ func (e *businessEngine) layoutText(args []platformValue) (any, error) { if e.currentEditor == nil { return nil, fmt.Errorf("no document is being edited") } - page, id := args[0].Int(), args[1].String() - object, err := e.currentEditor.Object(page, id) - if err != nil { - return nil, err + return e.changeObjects(func() error { + return e.layoutEditorText(args[0].Int(), ofdgo.ObjectPath{ID: args[1].String()}, args[2:]) + }) +} + +// layoutEditorText 将正文和组合内文字的段落调整交给库统一处理 +// 入参: page 页面索引, path 完整对象路径, args 偏移、宽度及段落选项 +// 返回: error 排版或提交错误 +func (e *businessEngine) layoutEditorText(page int, path ofdgo.ObjectPath, args []platformValue) error { + offset, width := 0.0, 0.0 + if !args[0].IsNull() { + offset, width = args[0].Float(), args[1].Float() } - if object.Type != "TextObject" { - return nil, fmt.Errorf("object is not text") - } - if !args[2].IsNull() { - object.TextObject, err = object.TextObject.ResizeTextFrame(args[2].Float(), args[3].Float()) - if err != nil { - return nil, err - } - } - value, _ := object.TextObject.TextLayout() - if err := e.currentEditor.LayoutText(&object.TextObject, value, ofdgo.TextLayout{AutoBidi: true, Wrap: args[4].Bool(), Align: args[5].String(), LineHeight: args[6].Float(), LetterSpacing: args[7].Float(), LeftIndent: args[8].Float(), RightIndent: args[9].Float(), FirstLineIndent: args[10].Float()}); err != nil { - return nil, err - } - revision := e.currentEditor.Revision() - if err := e.currentEditor.UpdateObject(page, id, object); err != nil { - return nil, err - } - if e.currentEditor.Revision() == revision { - return e.editorSummary(), nil - } - return e.previewEditor(e.currentEditor, e.currentSession.Renderer.RenderAnnotations) + layout := ofdgo.TextLayout{AutoBidi: true, Wrap: args[2].Bool(), Align: args[3].String(), LineHeight: args[4].Float(), LetterSpacing: args[5].Float(), LeftIndent: args[6].Float(), RightIndent: args[7].Float(), FirstLineIndent: args[8].Float()} + return e.currentEditor.LayoutTextFrame(page, path, layout, offset, width) } // replaceImage 替换图片资源并更新预览 diff --git a/ofdgo_editor_rich_text.go b/ofdgo_editor_rich_text.go index 0c8db4b..0995343 100644 --- a/ofdgo_editor_rich_text.go +++ b/ofdgo_editor_rich_text.go @@ -1231,3 +1231,24 @@ func (e *Editor) ReflowRichText(page int, path ObjectPath, value RichText) error path.Children = path.Children[:len(path.Children)-1] return e.updateCompositeRichText(page, path, index, value, 0, 0, true) } + +// LayoutTextFrame 统一调整普通文字及富文本的段落选项和局部宽度,保留原首行起点与页面变换 +// 对齐应用于所有段落;定位文字沿用自然宽度,显式改宽后采用固定宽度,提交一条撤销记录 +// 入参: page 页面索引, path 完整对象路径, options 段落选项, offset 左边界局部偏移, width 新宽度,零值保留宽度模式 +// 返回: error 路径、尺寸或排版错误 +func (e *Editor) LayoutTextFrame(page int, path ObjectPath, options TextLayout, offset, width float64) error { + if !finite(offset) || !finite(width) || width < 0 || width == 0 && offset != 0 { + return fmt.Errorf("invalid text frame") + } + value, _, _, err := e.PrepareRichText(page, path, true) + if err != nil { + return err + } + value.Layout, value.Paragraphs = options, nil + if len(path.Children) == 0 { + return e.updateRichTextFrame(page, path.ID, value, offset, width, true) + } + index := path.Children[len(path.Children)-1] + path.Children = path.Children[:len(path.Children)-1] + return e.updateCompositeRichText(page, path, index, value, offset, width, true) +}