mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 17:27:08 +08:00
feat(编辑渲染): 修复资源引用,完善注解读取
This commit is contained in:
1 parent
a5f51294eb
commit
52fc88f2b8
14 files changed
+198
-114
No files matched your search
+3
-22
@@ -1501,29 +1501,10 @@ func readAnnotation(args []js.Value) (any, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
texts := make([]string, 0)
|
||||
visiting := make(map[string]bool)
|
||||
var collect func([]ofdgo.GraphicObject)
|
||||
collect = func(objects []ofdgo.GraphicObject) {
|
||||
for _, object := range objects {
|
||||
switch object.Type {
|
||||
case "TextObject":
|
||||
value := object.TextObject.Text()
|
||||
if !slices.Contains(texts, value) {
|
||||
texts = append(texts, value)
|
||||
}
|
||||
case "CompositeObject", "CompositeGraphicUnit":
|
||||
collect(object.CompositeGraphicUnit.Objects)
|
||||
id := object.CompositeGraphicUnit.ResourceID
|
||||
if unit := currentSession.Renderer.CompositeGraphicUnits[id]; unit != nil && !visiting[id] {
|
||||
visiting[id] = true
|
||||
collect(unit.Objects)
|
||||
delete(visiting, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
texts, err := currentEditor.AnnotationTexts(args[0].Int(), annotation.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
collect(annotation.Appearance.Objects)
|
||||
info := map[string]any{"texts": texts, "remark": annotation.Remark, "creator": annotation.Creator}
|
||||
if annotation.Type == "Link" {
|
||||
info["linkKind"] = "keep"
|
||||
|
||||
+6
-6
@@ -366,7 +366,7 @@ func (r *Renderer) annotationActionSources(annotations []Annotation) []actionSou
|
||||
// appendGraphicActionSources 添加图形对象动作来源
|
||||
// 入参: sources 动作来源, object 图形对象, parent 父级变换, boundaryInCTM 边界是否参与父级变换, seen 当前资源引用链
|
||||
// 返回: []actionSource 动作来源
|
||||
func (r *Renderer) appendGraphicActionSources(sources []actionSource, object GraphicObject, parent Matrix, boundaryInCTM bool, seen map[string]bool) []actionSource {
|
||||
func (r *Renderer) appendGraphicActionSources(sources []actionSource, object GraphicObject, parent Matrix, boundaryInCTM bool, seen map[*CompositeGraphicUnit]bool) []actionSource {
|
||||
var boundary, ctm, resource string
|
||||
var actions []Action
|
||||
var children []GraphicObject
|
||||
@@ -412,14 +412,14 @@ func (r *Renderer) appendGraphicActionSources(sources []actionSource, object Gra
|
||||
}
|
||||
sources = append(sources, source)
|
||||
}
|
||||
if resource != "" && !seen[resource] {
|
||||
if unit := r.CompositeGraphicUnits[resource]; unit != nil {
|
||||
if resource != "" {
|
||||
if unit, _ := resourceValue(r.CompositeGraphicUnits, resource); unit != nil && !seen[unit] {
|
||||
if seen == nil {
|
||||
seen = make(map[string]bool)
|
||||
seen = make(map[*CompositeGraphicUnit]bool)
|
||||
}
|
||||
seen[resource] = true
|
||||
seen[unit] = true
|
||||
sources = r.appendGraphicActionSources(sources, GraphicObject{Type: "CompositeGraphicUnit", CompositeGraphicUnit: *unit}, matrix, true, seen)
|
||||
delete(seen, resource)
|
||||
delete(seen, unit)
|
||||
}
|
||||
}
|
||||
for _, child := range children {
|
||||
|
||||
+13
-16
@@ -102,26 +102,23 @@ func mergeDrawParam(base DrawParam, dp *DrawParam) *DrawParam {
|
||||
return &base
|
||||
}
|
||||
|
||||
// getDrawParam 获取绘制参数逻辑
|
||||
// 入参: id 参数ID, visited 访问记录
|
||||
// getDrawParam 解析绘制参数继承链,按实际资源识别循环引用
|
||||
// 入参: id 参数标识, visited 已访问资源
|
||||
// 返回: *DrawParam 绘制参数
|
||||
func (r *Renderer) getDrawParam(id string, visited map[string]bool) *DrawParam {
|
||||
if visited == nil {
|
||||
visited = make(map[string]bool)
|
||||
}
|
||||
if visited[id] {
|
||||
func (r *Renderer) getDrawParam(id string, visited map[*DrawParam]bool) *DrawParam {
|
||||
dp, _ := resourceValue(r.DrawParams, id)
|
||||
if dp == nil || visited[dp] {
|
||||
return nil
|
||||
}
|
||||
visited[id] = true
|
||||
if dp, ok := r.DrawParams[id]; ok {
|
||||
if dp.Relative != "" {
|
||||
base := r.getDrawParam(dp.Relative, visited)
|
||||
if base == nil {
|
||||
return dp
|
||||
}
|
||||
if visited == nil {
|
||||
visited = make(map[*DrawParam]bool)
|
||||
}
|
||||
visited[dp] = true
|
||||
if dp.Relative != "" {
|
||||
base := r.getDrawParam(dp.Relative, visited)
|
||||
if base != nil {
|
||||
return mergeDrawParam(*base, dp)
|
||||
}
|
||||
return dp
|
||||
}
|
||||
return nil
|
||||
return dp
|
||||
}
|
||||
@@ -154,6 +154,64 @@ func (e *Editor) Annotation(index int, id string) (Annotation, error) {
|
||||
return annotation, err
|
||||
}
|
||||
|
||||
// AnnotationTexts 按绘制顺序读取注解外观中的文字,展开复合资源并去重,不依赖字体或渲染后端
|
||||
// 入参: index 页面索引, id 注解标识
|
||||
// 返回: []string 文字列表, error 注解读取或资源引用错误
|
||||
func (e *Editor) AnnotationTexts(index int, id string) ([]string, error) {
|
||||
annotation, err := e.Annotation(index, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reader, err := e.Reader()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer reader.Close()
|
||||
if _, err := reader.PageContentByIndex(index); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
texts := make([]string, 0)
|
||||
seen := make(map[string]bool)
|
||||
visiting := make(map[*CompositeGraphicUnit]bool)
|
||||
collected := make(map[*CompositeGraphicUnit]bool)
|
||||
var collect func(CompositeGraphicUnit) error
|
||||
collect = func(unit CompositeGraphicUnit) error {
|
||||
if unit.ResourceID != "" {
|
||||
ref, _ := resourceValue(reader.compositeGraphicUnitCache, unit.ResourceID)
|
||||
if ref == nil || visiting[ref] {
|
||||
return fmt.Errorf("invalid composite resource %q", unit.ResourceID)
|
||||
}
|
||||
if !collected[ref] {
|
||||
visiting[ref] = true
|
||||
if err := collect(*ref); err != nil {
|
||||
return err
|
||||
}
|
||||
delete(visiting, ref)
|
||||
collected[ref] = true
|
||||
}
|
||||
}
|
||||
for object := range unit.objects() {
|
||||
switch object.Type {
|
||||
case "TextObject":
|
||||
value := object.TextObject.Text()
|
||||
if !seen[value] {
|
||||
seen[value] = true
|
||||
texts = append(texts, value)
|
||||
}
|
||||
case "CompositeObject", "CompositeGraphicUnit":
|
||||
if err := collect(object.CompositeGraphicUnit); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err := collect(CompositeGraphicUnit{Objects: annotation.Appearance.Objects}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return texts, nil
|
||||
}
|
||||
|
||||
// annotationXML 读取唯一注解的独立原文,不以类型、大小或可见性筛选
|
||||
// 入参: index 页面索引, id 注解标识
|
||||
// 返回: []byte 注解XML, error 错误信息
|
||||
|
||||
@@ -269,6 +269,9 @@ func (e *Editor) ReplaceAnnotationText(page int, id, old, value string, style Te
|
||||
count++
|
||||
} else if member.Object.Type == "CompositeObject" || member.Object.Type == "CompositeGraphicUnit" {
|
||||
resource := member.Object.CompositeGraphicUnit.ResourceID
|
||||
if id := editorResourceID(resource); id != "" {
|
||||
resource = id
|
||||
}
|
||||
if resource != "" && visiting[resource] {
|
||||
return fmt.Errorf("cyclic composite resource %q", resource)
|
||||
}
|
||||
|
||||
+11
-11
@@ -500,7 +500,8 @@ func (e *Editor) compositeMembers(n *editorCompositeNode, reader *Reader, render
|
||||
visible := n.visible && (c.Visible == nil || *c.Visible)
|
||||
alpha := mergeAlpha(n.alpha, c.Alpha)
|
||||
if c.ResourceID != "" {
|
||||
data, err := reader.readFile(reader.resourceFiles[c.ResourceID])
|
||||
name, _ := resourceValue(reader.resourceFiles, c.ResourceID)
|
||||
data, err := reader.readFile(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -508,15 +509,7 @@ func (e *Editor) compositeMembers(n *editorCompositeNode, reader *Reader, render
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var resource *editorXML
|
||||
if units := root.child("CompositeGraphicUnits"); units != nil {
|
||||
for _, child := range units.children {
|
||||
if child.name.Local == "CompositeGraphicUnit" && child.attr("ID") == c.ResourceID {
|
||||
resource = child
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
resource := editorResourceNode(root, "CompositeGraphicUnits", "CompositeGraphicUnit", c.ResourceID)
|
||||
if resource == nil {
|
||||
return nil, fmt.Errorf("composite resource %q not found", c.ResourceID)
|
||||
}
|
||||
@@ -530,7 +523,7 @@ func (e *Editor) compositeMembers(n *editorCompositeNode, reader *Reader, render
|
||||
}
|
||||
var states map[string]editorCompositeState
|
||||
for _, resource := range e.resources {
|
||||
if resource.composite == c.ResourceID {
|
||||
if sameResourceID(resource.composite, c.ResourceID) {
|
||||
states = resource.states
|
||||
break
|
||||
}
|
||||
@@ -578,6 +571,9 @@ func (e *Editor) compositeMembers(n *editorCompositeNode, reader *Reader, render
|
||||
var result []*editorCompositeNode
|
||||
if n.ref != nil {
|
||||
id := n.object.CompositeGraphicUnit.ResourceID
|
||||
if key := editorResourceID(id); key != "" {
|
||||
id = key
|
||||
}
|
||||
if visiting[id] {
|
||||
return nil, fmt.Errorf("cyclic composite resource %q", id)
|
||||
}
|
||||
@@ -1072,6 +1068,7 @@ func editorResourceReferences(data []byte) ([]string, error) {
|
||||
}
|
||||
}
|
||||
collect(root)
|
||||
normalizeResourceReferences(refs)
|
||||
return slices.Sorted(maps.Keys(refs)), nil
|
||||
}
|
||||
|
||||
@@ -1091,6 +1088,9 @@ func collectCompositeReferences(composite CompositeGraphicUnit, used map[string]
|
||||
// 入参: id 矢量资源标识
|
||||
// 返回: error 尺寸、内容或引用错误
|
||||
func (v *editorValidation) validateVector(id string) error {
|
||||
if key := editorResourceID(id); key != "" {
|
||||
id = key
|
||||
}
|
||||
if v.composites[id] {
|
||||
return fmt.Errorf("cyclic composite resource %q", id)
|
||||
}
|
||||
|
||||
@@ -264,10 +264,14 @@ func (e *Editor) compositeUngroupable(node *editorXML) bool {
|
||||
if id == "" {
|
||||
return true
|
||||
}
|
||||
if seen[id] {
|
||||
key := id
|
||||
if value := editorResourceID(id); value != "" {
|
||||
key = value
|
||||
}
|
||||
if seen[key] {
|
||||
return false
|
||||
}
|
||||
seen[id] = true
|
||||
seen[key] = true
|
||||
resource, err := e.compositeDefinition(id)
|
||||
if err != nil {
|
||||
return false
|
||||
@@ -282,14 +286,15 @@ func (e *Editor) compositeUngroupable(node *editorXML) bool {
|
||||
func (e *Editor) compositeDefinition(id string) (*editorCompositeNode, error) {
|
||||
var data []byte
|
||||
for _, resource := range e.resources {
|
||||
if resource.composite == id {
|
||||
if sameResourceID(resource.composite, id) {
|
||||
data = resource.data
|
||||
break
|
||||
}
|
||||
}
|
||||
if data == nil && e.source != nil {
|
||||
var err error
|
||||
data, err = e.source.reader.readFile(e.source.reader.resourceFiles[id])
|
||||
name, _ := resourceValue(e.source.reader.resourceFiles, id)
|
||||
data, err = e.source.reader.readFile(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -298,16 +303,12 @@ func (e *Editor) compositeDefinition(id string) (*editorCompositeNode, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if units := root.child("CompositeGraphicUnits"); units != nil {
|
||||
for _, unit := range units.children {
|
||||
if unit.name.Local == "CompositeGraphicUnit" && unit.attr("ID") == id {
|
||||
fragment, err := editorXMLStandalone(data[unit.start:unit.end], unit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newEditorCompositeNode(fragment)
|
||||
}
|
||||
if unit := editorResourceNode(root, "CompositeGraphicUnits", "CompositeGraphicUnit", id); unit != nil {
|
||||
fragment, err := editorXMLStandalone(data[unit.start:unit.end], unit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newEditorCompositeNode(fragment)
|
||||
}
|
||||
return nil, fmt.Errorf("composite resource %q not found", id)
|
||||
}
|
||||
+14
-13
@@ -25,14 +25,15 @@ import (
|
||||
func (e *Editor) drawParamXML(id string) ([]byte, error) {
|
||||
var data []byte
|
||||
for _, resource := range e.resources {
|
||||
if resource.draw != nil && resource.draw.ID == id {
|
||||
if resource.draw != nil && sameResourceID(resource.draw.ID, id) {
|
||||
data = resource.data
|
||||
break
|
||||
}
|
||||
}
|
||||
if data == nil && e.source != nil {
|
||||
var err error
|
||||
data, err = e.source.reader.readFile(e.source.reader.resourceFiles[id])
|
||||
name, _ := resourceValue(e.source.reader.resourceFiles, id)
|
||||
data, err = e.source.reader.readFile(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -41,12 +42,8 @@ func (e *Editor) drawParamXML(id string) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if params := root.child("DrawParams"); params != nil {
|
||||
for _, node := range params.children {
|
||||
if node.name.Local == "DrawParam" && node.attr("ID") == id && classifyOFDNamespace(node.name.Space) != ofdXMLUnknown {
|
||||
return editorXMLStandalone(data[node.start:node.end], node)
|
||||
}
|
||||
}
|
||||
if node := editorResourceNode(root, "DrawParams", "DrawParam", id); node != nil {
|
||||
return editorXMLStandalone(data[node.start:node.end], node)
|
||||
}
|
||||
return nil, fmt.Errorf("draw parameter %q not found", id)
|
||||
}
|
||||
@@ -55,13 +52,17 @@ func (e *Editor) drawParamXML(id string) ([]byte, error) {
|
||||
// 入参: id 源参数标识, base 独立基准标识, visited 当前继承链
|
||||
// 返回: string 新继承链末端标识, error 错误信息
|
||||
func (e *Editor) copyDrawParam(id, base string, visited map[string]bool) (string, error) {
|
||||
if id == "" || id == base {
|
||||
if id == "" || sameResourceID(id, base) {
|
||||
return base, nil
|
||||
}
|
||||
if visited[id] {
|
||||
key := id
|
||||
if value := editorResourceID(id); value != "" {
|
||||
key = value
|
||||
}
|
||||
if visited[key] {
|
||||
return "", fmt.Errorf("cyclic draw parameter %q", id)
|
||||
}
|
||||
visited[id] = true
|
||||
visited[key] = true
|
||||
data, err := e.drawParamXML(id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -70,7 +71,7 @@ func (e *Editor) copyDrawParam(id, base string, visited map[string]bool) (string
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if root.attr("Relative") == base {
|
||||
if sameResourceID(root.attr("Relative"), base) {
|
||||
return id, nil
|
||||
}
|
||||
base, err = e.copyDrawParam(root.attr("Relative"), base, visited)
|
||||
@@ -78,7 +79,7 @@ func (e *Editor) copyDrawParam(id, base string, visited map[string]bool) (string
|
||||
return "", err
|
||||
}
|
||||
for _, resource := range e.resources {
|
||||
if resource.drawSource == id && resource.draw.Relative == base {
|
||||
if sameResourceID(resource.drawSource, id) && sameResourceID(resource.draw.Relative, base) {
|
||||
return resource.draw.ID, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,6 +313,33 @@ func editorResourceID(value string) string {
|
||||
return strconv.FormatUint(id, 10)
|
||||
}
|
||||
|
||||
// normalizeResourceReferences 合并数值等价的资源引用,保留内部非数字标识
|
||||
// 入参: references 待规范化的引用集合
|
||||
func normalizeResourceReferences(references map[string]bool) {
|
||||
for id, used := range references {
|
||||
if key := editorResourceID(id); key != "" && key != id {
|
||||
references[key] = references[key] || used
|
||||
delete(references, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// editorResourceNode 按资源标识查找标准资源节点,等价别名冲突时不猜测
|
||||
// 入参: root 资源文件根节点, group 资源集合名称, kind 资源类型, id 资源标识
|
||||
// 返回: *editorXML 资源节点,未找到时为nil
|
||||
func editorResourceNode(root *editorXML, group, kind, id string) *editorXML {
|
||||
nodes := make(map[string]*editorXML)
|
||||
if collection := root.child(group); collection != nil {
|
||||
for _, node := range collection.children {
|
||||
if node.matchesOFD(kind) {
|
||||
nodes[node.attr("ID")] = node
|
||||
}
|
||||
}
|
||||
}
|
||||
node, _ := resourceValue(nodes, id)
|
||||
return node
|
||||
}
|
||||
|
||||
// editorResourceLocation 按ST_Loc与Res.BaseLoc解析路径,大小写折叠用于保守保留共享文件
|
||||
// 入参: name 所在XML, base 资源目录, value 路径值
|
||||
// 返回: string 包内路径
|
||||
|
||||
@@ -98,12 +98,12 @@ func (e *Editor) DrawParam(id string, resolved bool) (*DrawParam, error) {
|
||||
return cloneEditorData(draw), nil
|
||||
}
|
||||
for _, resource := range e.resources {
|
||||
if resource.draw != nil && resource.draw.ID == id {
|
||||
if resource.draw != nil && sameResourceID(resource.draw.ID, id) {
|
||||
return cloneEditorData(resource.draw), nil
|
||||
}
|
||||
}
|
||||
if e.source != nil {
|
||||
if value := e.source.reader.drawParamCache[id]; value != nil {
|
||||
if value, _ := resourceValue(e.source.reader.drawParamCache, id); value != nil {
|
||||
return cloneEditorData(value), nil
|
||||
}
|
||||
}
|
||||
@@ -425,13 +425,16 @@ func (e *Editor) editorDrawParam(id string, visited map[string]bool) (*DrawParam
|
||||
}
|
||||
var dp *DrawParam
|
||||
for _, resource := range e.resources {
|
||||
if resource.draw != nil && resource.draw.ID == id {
|
||||
if resource.draw != nil && sameResourceID(resource.draw.ID, id) {
|
||||
dp = resource.draw
|
||||
break
|
||||
}
|
||||
}
|
||||
if dp == nil && e.source != nil {
|
||||
dp = e.source.reader.drawParamCache[id]
|
||||
dp, _ = resourceValue(e.source.reader.drawParamCache, id)
|
||||
}
|
||||
if key := editorResourceID(id); key != "" {
|
||||
id = key
|
||||
}
|
||||
if dp == nil || visited[id] {
|
||||
return nil, &EditError{Code: EditUnsupportedStyle, Err: fmt.Errorf("invalid draw parameter reference %q", id)}
|
||||
|
||||
+13
-13
@@ -68,7 +68,7 @@ type fontUsagePage struct {
|
||||
|
||||
// fontUsageReferences 保存字体统计中的当前引用路径,不合并共享内容的用量
|
||||
type fontUsageReferences struct {
|
||||
composites map[string]bool
|
||||
composites map[*CompositeGraphicUnit]bool
|
||||
patterns map[*Pattern]bool
|
||||
}
|
||||
|
||||
@@ -577,20 +577,20 @@ func (r *Renderer) countCompositeFonts(cgu CompositeGraphicUnit, usage map[strin
|
||||
r.countClipFonts(cgu.Clips, usage)
|
||||
defaults = r.drawParamDefaults(cgu.DrawParam, defaults)
|
||||
if cgu.ResourceID != "" {
|
||||
if visited == nil {
|
||||
visited = &fontUsageReferences{}
|
||||
}
|
||||
if visited.composites[cgu.ResourceID] {
|
||||
return
|
||||
}
|
||||
if visited.composites == nil {
|
||||
visited.composites = make(map[string]bool)
|
||||
}
|
||||
visited.composites[cgu.ResourceID] = true
|
||||
if ref := r.CompositeGraphicUnits[cgu.ResourceID]; ref != nil {
|
||||
if ref, _ := resourceValue(r.CompositeGraphicUnits, cgu.ResourceID); ref != nil {
|
||||
if visited == nil {
|
||||
visited = &fontUsageReferences{}
|
||||
}
|
||||
if visited.composites[ref] {
|
||||
return
|
||||
}
|
||||
if visited.composites == nil {
|
||||
visited.composites = make(map[*CompositeGraphicUnit]bool)
|
||||
}
|
||||
visited.composites[ref] = true
|
||||
r.countCompositeFonts(*ref, usage, defaults, visited)
|
||||
defer delete(visited.composites, ref)
|
||||
}
|
||||
defer delete(visited.composites, cgu.ResourceID)
|
||||
}
|
||||
for object := range cgu.objects() {
|
||||
r.countObjectFonts(object, usage, defaults, visited)
|
||||
|
||||
+15
-15
@@ -169,7 +169,7 @@ func (r *Renderer) walkLayers(layers []Layer, order int, visitor PageVisitor) er
|
||||
// walkObject 访问对象并传递当前资源引用链
|
||||
// 入参: object 源对象, state 继承状态, visitor 页面访问器, references 当前资源引用链
|
||||
// 返回: error 遍历或访问器错误
|
||||
func (r *Renderer) walkObject(object *GraphicObject, state RenderState, visitor PageVisitor, references map[string]bool) error {
|
||||
func (r *Renderer) walkObject(object *GraphicObject, state RenderState, visitor PageVisitor, references map[*CompositeGraphicUnit]bool) error {
|
||||
if r.pageContext != nil {
|
||||
if err := r.pageContext.Err(); err != nil {
|
||||
return err
|
||||
@@ -191,16 +191,16 @@ func (r *Renderer) walkObject(object *GraphicObject, state RenderState, visitor
|
||||
// walkComposite 展开复合图元的资源、成员与透明度,不修改共享资源
|
||||
// 入参: object 复合图元, state 继承状态, visitor 页面访问器, references 当前资源引用链
|
||||
// 返回: error 几何或访问器错误
|
||||
func (r *Renderer) walkComposite(object CompositeGraphicUnit, state RenderState, visitor PageVisitor, references map[string]bool) error {
|
||||
func (r *Renderer) walkComposite(object CompositeGraphicUnit, state RenderState, visitor PageVisitor, references map[*CompositeGraphicUnit]bool) error {
|
||||
if object.Visible != nil && !*object.Visible {
|
||||
if groups, ok := visitor.(PageGroups); ok {
|
||||
count, ref, seen := len(object.Objects), object.ResourceID, make(map[string]bool)
|
||||
for ref != "" && !seen[ref] {
|
||||
seen[ref] = true
|
||||
unit := r.CompositeGraphicUnits[ref]
|
||||
if unit == nil {
|
||||
count, ref, seen := len(object.Objects), object.ResourceID, make(map[*CompositeGraphicUnit]bool)
|
||||
for ref != "" {
|
||||
unit, _ := resourceValue(r.CompositeGraphicUnits, ref)
|
||||
if unit == nil || seen[unit] {
|
||||
break
|
||||
}
|
||||
seen[unit] = true
|
||||
count, ref = count+len(unit.Objects), unit.ResourceID
|
||||
}
|
||||
groups.SkipObjects(count)
|
||||
@@ -241,20 +241,20 @@ func (r *Renderer) walkComposite(object CompositeGraphicUnit, state RenderState,
|
||||
state.Defaults = r.drawParamDefaults(object.DrawParam, state.Defaults)
|
||||
state.Parent = &matrix
|
||||
if object.ResourceID != "" {
|
||||
if references[object.ResourceID] {
|
||||
return fmt.Errorf("cyclic composite resource %q", object.ResourceID)
|
||||
}
|
||||
if ref, ok := r.CompositeGraphicUnits[object.ResourceID]; ok {
|
||||
if references == nil {
|
||||
references = make(map[string]bool)
|
||||
if ref, _ := resourceValue(r.CompositeGraphicUnits, object.ResourceID); ref != nil {
|
||||
if references[ref] {
|
||||
return fmt.Errorf("cyclic composite resource %q", object.ResourceID)
|
||||
}
|
||||
references[object.ResourceID] = true
|
||||
if references == nil {
|
||||
references = make(map[*CompositeGraphicUnit]bool)
|
||||
}
|
||||
references[ref] = true
|
||||
copy := *ref
|
||||
copy.Alpha = mergeAlpha(copy.Alpha, object.Alpha)
|
||||
referenceState := state
|
||||
referenceState.BoundaryInCTM = true
|
||||
err := r.walkComposite(copy, referenceState, visitor, references)
|
||||
delete(references, object.ResourceID)
|
||||
delete(references, ref)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -132,6 +132,17 @@ type CompositeGraphicUnit struct {
|
||||
extentSet bool
|
||||
}
|
||||
|
||||
// sameResourceID 判断资源标识是否相同,数字标识按数值比较
|
||||
// 入参: first 第一个标识, second 第二个标识
|
||||
// 返回: bool 是否相同
|
||||
func sameResourceID(first, second string) bool {
|
||||
if first == second {
|
||||
return true
|
||||
}
|
||||
id := editorResourceID(first)
|
||||
return id != "" && id == editorResourceID(second)
|
||||
}
|
||||
|
||||
// resourceValue 优先查找原标识与标准十进制标识,回退别名有冲突时不猜测
|
||||
// 入参: values 已加载资源, id 标识文本
|
||||
// 返回: T 资源值, bool 是否存在唯一结果
|
||||
|
||||
+3
-1
@@ -512,6 +512,8 @@ func (e *Editor) usedResources() (fonts, images []editorResource, spaces []Color
|
||||
}
|
||||
}
|
||||
}
|
||||
normalizeResourceReferences(used)
|
||||
normalizeResourceReferences(promoted)
|
||||
for i := len(e.resources) - 1; i >= 0; i-- {
|
||||
resource := e.resources[i]
|
||||
if resource.definition() != "" && used[resource.definition()] {
|
||||
@@ -541,7 +543,7 @@ func (e *Editor) usedResources() (fonts, images []editorResource, spaces []Color
|
||||
}
|
||||
}
|
||||
for id := range promoted {
|
||||
if name := e.source.reader.resourceFiles[id]; name != "" {
|
||||
if name, _ := resourceValue(e.source.reader.resourceFiles, id); name != "" {
|
||||
files[name] = true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user