OpenOffice绘图:增强的几何图形解析

OpenOffice draw:enhanced-geometry parsing

本文关键字:几何图形 增强的 绘图 OpenOffice      更新时间:2023-09-26

我正在编写OOo转换器,并被困在draw:enhanced-geometry>draw:enhanced-pathdraw:equation上,找不到任何关于这一部分的解决方案或广泛的文档。至少mb有人可以推荐如何评估它?

我贴在上面的示例代码(画气球):

                        "draw:enhanced-geometry": [{
                            "$": {
                                "svg:viewBox": "0 0 21600 21600",
                                "draw:text-areas": "800 800 20800 20800",
                                "draw:type": "round-rectangular-callout",
                                "draw:modifiers": "3289.58566629339 27438.6415787058",
                                "draw:enhanced-path": "M 3590 0 X 0 3590 L ?f2 ?f3 0 8970 0 12630 ?f4 ?f5 0 18010 Y 3590 21600 L ?f6 ?f7 8970 21600 12630 21600 ?f8 ?f9 18010 21600 X 21600 18010 L ?f10 ?f11 21600 12630 21600 8970 ?f12 ?f13 21600 3590 Y 18010 0 L ?f14 ?f15 12630 0 8970 0 ?f16 ?f17 Z N"
                            },
                            "draw:equation": [{
                                "$": {
                                    "draw:name": "f0",
                                    "draw:formula": "$0 -10800"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f1",
                                    "draw:formula": "$1 -10800"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f2",
                                    "draw:formula": "if(?f18 ,$0 ,0)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f3",
                                    "draw:formula": "if(?f18 ,$1 ,6280)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f4",
                                    "draw:formula": "if(?f23 ,$0 ,0)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f5",
                                    "draw:formula": "if(?f23 ,$1 ,15320)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f6",
                                    "draw:formula": "if(?f26 ,$0 ,6280)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f7",
                                    "draw:formula": "if(?f26 ,$1 ,21600)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f8",
                                    "draw:formula": "if(?f29 ,$0 ,15320)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f9",
                                    "draw:formula": "if(?f29 ,$1 ,21600)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f10",
                                    "draw:formula": "if(?f32 ,$0 ,21600)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f11",
                                    "draw:formula": "if(?f32 ,$1 ,15320)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f12",
                                    "draw:formula": "if(?f34 ,$0 ,21600)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f13",
                                    "draw:formula": "if(?f34 ,$1 ,6280)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f14",
                                    "draw:formula": "if(?f36 ,$0 ,15320)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f15",
                                    "draw:formula": "if(?f36 ,$1 ,0)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f16",
                                    "draw:formula": "if(?f38 ,$0 ,6280)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f17",
                                    "draw:formula": "if(?f38 ,$1 ,0)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f18",
                                    "draw:formula": "if($0 ,-1,?f19 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f19",
                                    "draw:formula": "if(?f1 ,-1,?f22 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f20",
                                    "draw:formula": "abs(?f0 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f21",
                                    "draw:formula": "abs(?f1 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f22",
                                    "draw:formula": "?f20 -?f21 "
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f23",
                                    "draw:formula": "if($0 ,-1,?f24 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f24",
                                    "draw:formula": "if(?f1 ,?f22 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f25",
                                    "draw:formula": "$1 -21600"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f26",
                                    "draw:formula": "if(?f25 ,?f27 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f27",
                                    "draw:formula": "if(?f0 ,-1,?f28 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f28",
                                    "draw:formula": "?f21 -?f20 "
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f29",
                                    "draw:formula": "if(?f25 ,?f30 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f30",
                                    "draw:formula": "if(?f0 ,?f28 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f31",
                                    "draw:formula": "$0 -21600"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f32",
                                    "draw:formula": "if(?f31 ,?f33 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f33",
                                    "draw:formula": "if(?f1 ,?f22 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f34",
                                    "draw:formula": "if(?f31 ,?f35 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f35",
                                    "draw:formula": "if(?f1 ,-1,?f22 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f36",
                                    "draw:formula": "if($1 ,-1,?f37 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f37",
                                    "draw:formula": "if(?f0 ,?f28 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f38",
                                    "draw:formula": "if($1 ,-1,?f39 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f39",
                                    "draw:formula": "if(?f0 ,-1,?f28 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f40",
                                    "draw:formula": "$0 "
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f41",
                                    "draw:formula": "$1 "
                                }
                            }],
                            "draw:handle": [{
                                "$": {
                                    "draw:handle-position": "$0 $1"
                                }
                            }]
                        }]

draw:enhanced path可以放在svg path元素中。你会得到这样的东西:

<svg viewBox="0 0 21600 21600" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <path d="M 3590 0 X 0 3590 L ?f2 ?f3 0 8970 0 12630 ?f4 ?f5 0 18010 Y 3590 21600 L ?f6 ?f7 8970 21600 12630 21600 ?f8 ?f9 18010 21600 X 21600 18010 L ?f10 ?f11 21600 12630 21600 8970 ?f12 ?f13 21600 3590 Y 18010 0 L ?f14 ?f15 12630 0 8970 0 ?f16 ?f17 Z N"/>
</svg>

然后,您应该展开所有变量(如?f2)和自变量(如$0)。查看下面的剪切笔以获取示例。然而,我不知道该如何处理路径中的"X"answers"Y"文字。我没有在这个文档中找到它们http://www.w3.org/TR/SVG/paths.html。

function extractPath(dataObj, args) {
	// collect variables
	var variableSource = dataObj['draw:enhanced-geometry'][0]['draw:equation'];
	var variables = {};
	for (var i = 0; i < variableSource.length; i++) {
		var name = variableSource[i]['$']['draw:name'];
		var value = variableSource[i]['$']['draw:formula'];
		variables[name] = value;
	}
	
	var evaluateVariable = function(name) {
		var value = evaluateExpression(variables[name]);
		return value; 
	}	
	var evaluateExpression = function(expr) {
		if (expr.match('if''(([^),]+),([^),]+),([^),]+)'')')) {
			var literals = expr.match('if''(([^),]+),([^),]+),([^),]+)'')').slice(1);
			if (evaluateLiteral(literals[0]) > 0) {
				return evaluateLiteral(literals[1]);
			}
			else {
				return evaluateLiteral(literals[2]);
			}
		}
		else if (expr.match('abs''(([^)]+)'')')) {
			var literals = expr.match('abs''(([^)]+)'')').slice(1);
			return Math.abs(evaluateLiteral(literals[0]));
		}
		else if (expr.match('([^()-''s]+[''s]?)-([^()-''s]+[''s]?)')) {
			var literals = expr.match('([^()-''s]+[''s]?)-([^()-''s]+[''s]?)').slice(1);
			return evaluateLiteral(literals[0]) - evaluateLiteral(literals[1]);
		}
	}		
	var evaluateLiteral = function(literal) {
		if (literal.match('^''?f[''d]+[''s]*$')) {
			return evaluateVariable(literal.match('f[''d]+')[0].trim());
		}
		else if (literal.match('^''$[''d]+[''s]*$')) {
			return args[literal.match('[''d]+')[0].trim()];
		}
		else if (!isNaN(parseFloat(literal.trim()))) {
			return parseFloat(literal.trim());
		}
		console.error("couldn't evaluate literal '" + literal + "'");
		return literal;
	}	
	var pathSource = dataObj['draw:enhanced-geometry'][0]['$']['draw:enhanced-path'];
	
	var loopLimit = 1000; // to avoid infinite loop
	var path = pathSource;
	while (path.match('''?f[''d]+')) {
		var variable = path.match('''?f[''d]+')[0].slice(1);
		var calculatedValue = evaluateVariable(variable);
		path = path.replace('?' + variable, calculatedValue);
		if (loopLimit-- < 0) {
			console.error('loopLimit is out, looks like you have got an infinite loop here');
		}
	}
    alert('path = "' + path + '"');
	return path;
}
function onLoad() {
	var jsonObj = '{"draw:enhanced-geometry": [{'
            "$": {'
                "svg:viewBox": "0 0 21600 21600",'
                "draw:text-areas": "800 800 20800 20800",'
                "draw:type": "round-rectangular-callout",'
                "draw:modifiers": "3289.58566629339 27438.6415787058",'
                "draw:enhanced-path": "M 3590 0 X 0 3590 L ?f2 ?f3 0 8970 0 12630 ?f4 ?f5 0 18010 Y 3590 21600 L ?f6 ?f7 8970 21600 12630 21600 ?f8 ?f9 18010 21600 X 21600 18010 L ?f10 ?f11 21600 12630 21600 8970 ?f12 ?f13 21600 3590 Y 18010 0 L ?f14 ?f15 12630 0 8970 0 ?f16 ?f17 Z N"'
            },'
            "draw:equation": [{'
                "$": {'
                    "draw:name": "f0",'
                    "draw:formula": "$0 -10800"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f1",'
                    "draw:formula": "$1 -10800"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f2",'
                    "draw:formula": "if(?f18 ,$0 ,0)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f3",'
                    "draw:formula": "if(?f18 ,$1 ,6280)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f4",'
                    "draw:formula": "if(?f23 ,$0 ,0)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f5",'
                    "draw:formula": "if(?f23 ,$1 ,15320)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f6",'
                    "draw:formula": "if(?f26 ,$0 ,6280)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f7",'
                    "draw:formula": "if(?f26 ,$1 ,21600)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f8",'
                    "draw:formula": "if(?f29 ,$0 ,15320)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f9",'
                    "draw:formula": "if(?f29 ,$1 ,21600)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f10",'
                    "draw:formula": "if(?f32 ,$0 ,21600)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f11",'
                    "draw:formula": "if(?f32 ,$1 ,15320)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f12",'
                    "draw:formula": "if(?f34 ,$0 ,21600)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f13",'
                    "draw:formula": "if(?f34 ,$1 ,6280)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f14",'
                    "draw:formula": "if(?f36 ,$0 ,15320)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f15",'
                    "draw:formula": "if(?f36 ,$1 ,0)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f16",'
                    "draw:formula": "if(?f38 ,$0 ,6280)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f17",'
                    "draw:formula": "if(?f38 ,$1 ,0)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f18",'
                    "draw:formula": "if($0 ,-1,?f19 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f19",'
                    "draw:formula": "if(?f1 ,-1,?f22 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f20",'
                    "draw:formula": "abs(?f0 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f21",'
                    "draw:formula": "abs(?f1 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f22",'
                    "draw:formula": "?f20 -?f21 "'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f23",'
                    "draw:formula": "if($0 ,-1,?f24 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f24",'
                    "draw:formula": "if(?f1 ,?f22 ,-1)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f25",'
                    "draw:formula": "$1 -21600"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f26",'
                    "draw:formula": "if(?f25 ,?f27 ,-1)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f27",'
                    "draw:formula": "if(?f0 ,-1,?f28 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f28",'
                    "draw:formula": "?f21 -?f20 "'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f29",'
                    "draw:formula": "if(?f25 ,?f30 ,-1)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f30",'
                    "draw:formula": "if(?f0 ,?f28 ,-1)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f31",'
                    "draw:formula": "$0 -21600"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f32",'
                    "draw:formula": "if(?f31 ,?f33 ,-1)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f33",'
                    "draw:formula": "if(?f1 ,?f22 ,-1)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f34",'
                    "draw:formula": "if(?f31 ,?f35 ,-1)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f35",'
                    "draw:formula": "if(?f1 ,-1,?f22 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f36",'
                    "draw:formula": "if($1 ,-1,?f37 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f37",'
                    "draw:formula": "if(?f0 ,?f28 ,-1)"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f38",'
                    "draw:formula": "if($1 ,-1,?f39 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f39",'
                    "draw:formula": "if(?f0 ,-1,?f28 )"'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f40",'
                    "draw:formula": "$0 "'
                }'
            },'
            {'
                "$": {'
                    "draw:name": "f41",'
                    "draw:formula": "$1 "'
                }'
            }],'
            "draw:handle": [{'
                "$": {'
                    "draw:handle-position": "$0 $1"'
                }'
            }]'
        }]}';
    var obj = JSON.parse(jsonObj);
    console.log(obj);
    var svgTag = document.getElementsByTagName('svg')[0];
    console.log(svgTag);
    var viewBox = document.createAttribute('viewBox');
    viewBox.value = obj['draw:enhanced-geometry'][0]['$']['svg:viewBox'];
    svgTag.setAttributeNode(viewBox);
    var svgPathTag = document.createElement('path');
    var stroke = document.createAttribute('stroke');
    stroke.value = 'black';
    svgPathTag.setAttributeNode(stroke);
    var strokeWidth = document.createAttribute('stroke-width');
    strokeWidth.value = '3';
    svgPathTag.setAttributeNode(strokeWidth);
    var pathData = document.createAttribute('d');
    pathData.value = extractPath(obj, [1, 2]);
    svgPathTag.setAttributeNode(pathData);
    svgTag.appendChild(svgPathTag);
}
<body onload="onLoad()">
	<svg xmlns="http://www.w3.org/2000/svg" version="1.1"/>
</body>

我希望这个答案会有所帮助。