mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 08:46:55 +08:00
This commit is contained in:
1 parent
460701f4d9
commit
627a06cda3
4 files changed
+69
-47
No files matched your search
@@ -717,7 +717,7 @@ func (h *Host) readFonts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loadFont 按转换请求读取单个系统字体
|
// loadFont 按转换请求读取单个系统字体
|
||||||
// 入参: ctx 调用上下文, name 字体文件路径及字体索引
|
// 入参: ctx 调用上下文, name 字体别名对应的文件名
|
||||||
// 返回: []byte 字体数据, error 读取错误
|
// 返回: []byte 字体数据, error 读取错误
|
||||||
func (h *Host) loadFont(ctx context.Context, name string) ([]byte, error) {
|
func (h *Host) loadFont(ctx context.Context, name string) ([]byte, error) {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
|
|||||||
+19
-5
@@ -82,6 +82,12 @@ func (p *ConversionPool) memoryLimit() int64 {
|
|||||||
// 入参: ctx 取消上下文, image 是否为图像任务, size 图像工作量
|
// 入参: ctx 取消上下文, image 是否为图像任务, size 图像工作量
|
||||||
// 返回: error 取消错误
|
// 返回: error 取消错误
|
||||||
func (p *ConversionPool) acquire(ctx context.Context, image bool, size int64) error {
|
func (p *ConversionPool) acquire(ctx context.Context, image bool, size int64) error {
|
||||||
|
var timer *time.Timer
|
||||||
|
defer func() {
|
||||||
|
if timer != nil {
|
||||||
|
timer.Stop()
|
||||||
|
}
|
||||||
|
}()
|
||||||
for {
|
for {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -104,15 +110,23 @@ func (p *ConversionPool) acquire(ctx context.Context, image bool, size int64) er
|
|||||||
}
|
}
|
||||||
changed := p.changed
|
changed := p.changed
|
||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
timer := time.NewTimer(250 * time.Millisecond)
|
var tick <-chan time.Time
|
||||||
|
if p.options.AvailableMemory != nil {
|
||||||
|
if timer == nil {
|
||||||
|
timer = time.NewTimer(250 * time.Millisecond)
|
||||||
|
} else {
|
||||||
|
timer.Reset(250 * time.Millisecond)
|
||||||
|
}
|
||||||
|
tick = timer.C
|
||||||
|
}
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
timer.Stop()
|
|
||||||
return ctx.Err()
|
|
||||||
case <-changed:
|
case <-changed:
|
||||||
case <-timer.C:
|
case <-tick:
|
||||||
|
}
|
||||||
|
if timer != nil {
|
||||||
|
timer.Stop()
|
||||||
}
|
}
|
||||||
timer.Stop()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,13 @@ func (e *Editor) CompositeObjectsAt(page int, path ObjectPath, indexes []int) ([
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
return e.measureCompositeSelection(renderer, nodes, indexes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// measureCompositeSelection 复用已解析范围,按输入索引度量成员并保留容器位置
|
||||||
|
// 入参: renderer 资源渲染器, nodes 范围内全部成员, indexes 不重复的成员序号
|
||||||
|
// 返回: []CompositeMember 独立成员快照, error 索引或度量错误
|
||||||
|
func (e *Editor) measureCompositeSelection(renderer *Renderer, nodes []*editorCompositeNode, indexes []int) ([]CompositeMember, error) {
|
||||||
selected := make([]*editorCompositeNode, len(indexes))
|
selected := make([]*editorCompositeNode, len(indexes))
|
||||||
seen := make(map[int]bool, len(indexes))
|
seen := make(map[int]bool, len(indexes))
|
||||||
for i, index := range indexes {
|
for i, index := range indexes {
|
||||||
|
|||||||
@@ -118,15 +118,15 @@ func (e *Editor) analyzeTextSelection(page int, selection TextSelection) (TextSe
|
|||||||
if len(selection.IDs) != 0 || len(selection.Indexes) == 0 {
|
if len(selection.IDs) != 0 || len(selection.Indexes) == 0 {
|
||||||
return result, fmt.Errorf("composite selection requires indexes only")
|
return result, fmt.Errorf("composite selection requires indexes only")
|
||||||
}
|
}
|
||||||
members, err := e.CompositeObjectsAt(page, root, selection.Indexes)
|
reader, renderer, _, nodes, err := e.compositeScope(page, root)
|
||||||
if err != nil {
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
reader, _, _, nodes, err := e.compositeScope(page, root)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
members, err := e.measureCompositeSelection(renderer, nodes, selection.Indexes)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
for i, member := range members {
|
for i, member := range members {
|
||||||
if member.Object.Type != "TextObject" || !member.Capabilities.RewriteText {
|
if member.Object.Type != "TextObject" || !member.Capabilities.RewriteText {
|
||||||
return result, fmt.Errorf("selection member is not editable text")
|
return result, fmt.Errorf("selection member is not editable text")
|
||||||
@@ -648,19 +648,21 @@ func (e *Editor) prepareTextSelectionEdit(edit *TextSelectionEdit) error {
|
|||||||
// 返回: TextSelection 提交后可用于重新枚举的选择
|
// 返回: TextSelection 提交后可用于重新枚举的选择
|
||||||
func selectionAfterTextEdit(analysis TextSelectionAnalysis, parts []TextSelectionPart, reflow bool) TextSelection {
|
func selectionAfterTextEdit(analysis TextSelectionAnalysis, parts []TextSelectionPart, reflow bool) TextSelection {
|
||||||
result := TextSelection{Root: analysis.Selection.Root}
|
result := TextSelection{Root: analysis.Selection.Root}
|
||||||
deleted := make(map[int]bool)
|
var deleted []int
|
||||||
if reflow {
|
if reflow {
|
||||||
for _, part := range analysis.Parts[1:] {
|
for _, part := range analysis.Parts[1:] {
|
||||||
deleted[part.Index] = true
|
deleted = append(deleted, part.Index)
|
||||||
}
|
}
|
||||||
parts = analysis.Parts[:1]
|
parts = analysis.Parts[:1]
|
||||||
} else {
|
} else {
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
if part.Deleted {
|
if part.Deleted {
|
||||||
deleted[part.Index] = true
|
deleted = append(deleted, part.Index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
slices.Sort(deleted)
|
||||||
|
deleted = slices.Compact(deleted)
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
if part.Deleted {
|
if part.Deleted {
|
||||||
continue
|
continue
|
||||||
@@ -669,13 +671,8 @@ func selectionAfterTextEdit(analysis TextSelectionAnalysis, parts []TextSelectio
|
|||||||
result.IDs = append(result.IDs, part.ID)
|
result.IDs = append(result.IDs, part.ID)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
index := part.Index
|
removed, _ := slices.BinarySearch(deleted, part.Index)
|
||||||
for removed := range deleted {
|
result.Indexes = append(result.Indexes, part.Index-removed)
|
||||||
if removed < part.Index {
|
|
||||||
index--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.Indexes = append(result.Indexes, index)
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -700,35 +697,39 @@ func (e *Editor) UpdateTextSelection(page int, selection TextSelection, edit Tex
|
|||||||
return e.reflowTextSelection(page, selection, edit, preview)
|
return e.reflowTextSelection(page, selection, edit, preview)
|
||||||
}
|
}
|
||||||
if selection.Root != nil {
|
if selection.Root != nil {
|
||||||
|
parts := make(map[int]int, len(preview.Parts))
|
||||||
|
for i, part := range preview.Parts {
|
||||||
|
parts[part.Index] = i
|
||||||
|
}
|
||||||
return e.editCompositeObjects(page, *selection.Root, selection.Indexes, func(_ *Renderer, nodes []*editorCompositeNode, _ []CompositeMember) error {
|
return e.editCompositeObjects(page, *selection.Root, selection.Indexes, func(_ *Renderer, nodes []*editorCompositeNode, _ []CompositeMember) error {
|
||||||
for i, node := range nodes {
|
for i, node := range nodes {
|
||||||
for _, part := range preview.Parts {
|
index, exists := parts[selection.Indexes[i]]
|
||||||
if part.Index != selection.Indexes[i] {
|
if !exists {
|
||||||
continue
|
continue
|
||||||
}
|
|
||||||
if part.Deleted {
|
|
||||||
node.owner.patches = append(node.owner.patches, editorXMLPatch{node.span.start, node.span.end, nil})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
object := cloneEditorData(node.object)
|
|
||||||
object.TextObject.TextCode, object.TextObject.CGTransform = part.TextObject.TextCode, part.TextObject.CGTransform
|
|
||||||
if edit.Font != "" {
|
|
||||||
object.TextObject.Font = part.TextObject.Font
|
|
||||||
}
|
|
||||||
if edit.Size != 0 {
|
|
||||||
object.TextObject.Size = part.TextObject.Size
|
|
||||||
}
|
|
||||||
if edit.Color != "" {
|
|
||||||
object.TextObject.FillColor = part.TextObject.FillColor
|
|
||||||
}
|
|
||||||
if reflect.DeepEqual(object, node.object) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := node.update(object); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
node.setState(editorCompositeState{})
|
|
||||||
}
|
}
|
||||||
|
part := &preview.Parts[index]
|
||||||
|
if part.Deleted {
|
||||||
|
node.owner.patches = append(node.owner.patches, editorXMLPatch{node.span.start, node.span.end, nil})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
object := cloneEditorData(node.object)
|
||||||
|
object.TextObject.TextCode, object.TextObject.CGTransform = part.TextObject.TextCode, part.TextObject.CGTransform
|
||||||
|
if edit.Font != "" {
|
||||||
|
object.TextObject.Font = part.TextObject.Font
|
||||||
|
}
|
||||||
|
if edit.Size != 0 {
|
||||||
|
object.TextObject.Size = part.TextObject.Size
|
||||||
|
}
|
||||||
|
if edit.Color != "" {
|
||||||
|
object.TextObject.FillColor = part.TextObject.FillColor
|
||||||
|
}
|
||||||
|
if reflect.DeepEqual(object, node.object) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := node.update(object); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
node.setState(editorCompositeState{})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in new issue
Block a user