OpenOffice draw:enhanced-几何解析

OpenOffice draw:enhanced-geometry parsing

我正在编写 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": "[=11=] -10800"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f1",
                                    "draw:formula": " -10800"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f2",
                                    "draw:formula": "if(?f18 ,[=11=] ,0)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f3",
                                    "draw:formula": "if(?f18 , ,6280)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f4",
                                    "draw:formula": "if(?f23 ,[=11=] ,0)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f5",
                                    "draw:formula": "if(?f23 , ,15320)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f6",
                                    "draw:formula": "if(?f26 ,[=11=] ,6280)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f7",
                                    "draw:formula": "if(?f26 , ,21600)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f8",
                                    "draw:formula": "if(?f29 ,[=11=] ,15320)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f9",
                                    "draw:formula": "if(?f29 , ,21600)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f10",
                                    "draw:formula": "if(?f32 ,[=11=] ,21600)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f11",
                                    "draw:formula": "if(?f32 , ,15320)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f12",
                                    "draw:formula": "if(?f34 ,[=11=] ,21600)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f13",
                                    "draw:formula": "if(?f34 , ,6280)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f14",
                                    "draw:formula": "if(?f36 ,[=11=] ,15320)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f15",
                                    "draw:formula": "if(?f36 , ,0)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f16",
                                    "draw:formula": "if(?f38 ,[=11=] ,6280)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f17",
                                    "draw:formula": "if(?f38 , ,0)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f18",
                                    "draw:formula": "if([=11=] ,-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([=11=] ,-1,?f24 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f24",
                                    "draw:formula": "if(?f1 ,?f22 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f25",
                                    "draw:formula": " -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": "[=11=] -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,?f37 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f37",
                                    "draw:formula": "if(?f0 ,?f28 ,-1)"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f38",
                                    "draw:formula": "if( ,-1,?f39 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f39",
                                    "draw:formula": "if(?f0 ,-1,?f28 )"
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f40",
                                    "draw:formula": "[=11=] "
                                }
                            },
                            {
                                "$": {
                                    "draw:name": "f41",
                                    "draw:formula": " "
                                }
                            }],
                            "draw:handle": [{
                                "$": {
                                    "draw:handle-position": "[=11=] "
                                }
                            }]
                        }]

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

<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' 和 '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": "[=11=] -10800"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f1",\
                    "draw:formula": " -10800"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f2",\
                    "draw:formula": "if(?f18 ,[=11=] ,0)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f3",\
                    "draw:formula": "if(?f18 , ,6280)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f4",\
                    "draw:formula": "if(?f23 ,[=11=] ,0)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f5",\
                    "draw:formula": "if(?f23 , ,15320)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f6",\
                    "draw:formula": "if(?f26 ,[=11=] ,6280)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f7",\
                    "draw:formula": "if(?f26 , ,21600)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f8",\
                    "draw:formula": "if(?f29 ,[=11=] ,15320)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f9",\
                    "draw:formula": "if(?f29 , ,21600)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f10",\
                    "draw:formula": "if(?f32 ,[=11=] ,21600)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f11",\
                    "draw:formula": "if(?f32 , ,15320)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f12",\
                    "draw:formula": "if(?f34 ,[=11=] ,21600)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f13",\
                    "draw:formula": "if(?f34 , ,6280)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f14",\
                    "draw:formula": "if(?f36 ,[=11=] ,15320)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f15",\
                    "draw:formula": "if(?f36 , ,0)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f16",\
                    "draw:formula": "if(?f38 ,[=11=] ,6280)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f17",\
                    "draw:formula": "if(?f38 , ,0)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f18",\
                    "draw:formula": "if([=11=] ,-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([=11=] ,-1,?f24 )"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f24",\
                    "draw:formula": "if(?f1 ,?f22 ,-1)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f25",\
                    "draw:formula": " -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": "[=11=] -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,?f37 )"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f37",\
                    "draw:formula": "if(?f0 ,?f28 ,-1)"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f38",\
                    "draw:formula": "if( ,-1,?f39 )"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f39",\
                    "draw:formula": "if(?f0 ,-1,?f28 )"\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f40",\
                    "draw:formula": "[=11=] "\
                }\
            },\
            {\
                "$": {\
                    "draw:name": "f41",\
                    "draw:formula": " "\
                }\
            }],\
            "draw:handle": [{\
                "$": {\
                    "draw:handle-position": "[=11=] "\
                }\
            }]\
        }]}';
    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>

希望这个回答对您有所帮助。