File indexing completed on 2024-05-12 16:29:03

0001 /*
0002  * This file is part of Office 2007 Filters for Calligra
0003  *
0004  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
0005  *
0006  * Contact: Suresh Chande suresh.chande@nokia.com
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Lesser General Public License
0010  * version 2.1 as published by the Free Software Foundation.
0011  *
0012  * This library is distributed in the hope that it will be useful, but
0013  * WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015  * Lesser General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Lesser General Public
0018  * License along with this library; if not, write to the Free Software
0019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020  * 02110-1301 USA
0021  *
0022  */
0023 
0024 #include "ComplexShapeHandler.h"
0025 
0026 #include "MsooXmlDebug.h"
0027 
0028 QString ComplexShapeHandler::defaultEquations()
0029 {
0030     QString eqs = QLatin1String(
0031             "<draw:equation draw:name=\"width\" draw:formula=\"width\"/>"
0032             "<draw:equation draw:name=\"height\" draw:formula=\"height\"/>"
0033             "<draw:equation draw:name=\"vc\" draw:formula=\"height/2\"/>"
0034             "<draw:equation draw:name=\"hc\" draw:formula=\"width/2\"/>"
0035             "<draw:equation draw:name=\"hd2\" draw:formula=\"height/2\"/>"
0036     // Note, this is not defined, but is used
0037             "<draw:equation draw:name=\"hd3\" draw:formula=\"height/3\"/>"
0038             "<draw:equation draw:name=\"hd4\" draw:formula=\"height/4\"/>"
0039             "<draw:equation draw:name=\"hd5\" draw:formula=\"height/5\"/>"
0040             "<draw:equation draw:name=\"hd6\" draw:formula=\"height/6\"/>"
0041             "<draw:equation draw:name=\"hd8\" draw:formula=\"height/8\"/>"
0042             "<draw:equation draw:name=\"ss\" draw:formula=\"min(width,height)\"/>"
0043             "<draw:equation draw:name=\"wd2\" draw:formula=\"width/2\"/>"
0044             "<draw:equation draw:name=\"wd3\" draw:formula=\"width/3\"/>"
0045             "<draw:equation draw:name=\"wd4\" draw:formula=\"width/4\"/>"
0046             "<draw:equation draw:name=\"wd5\" draw:formula=\"width/5\"/>"
0047             "<draw:equation draw:name=\"wd6\" draw:formula=\"width/6\"/>"
0048             "<draw:equation draw:name=\"wd8\" draw:formula=\"width/8\"/>"
0049             "<draw:equation draw:name=\"wd10\" draw:formula=\"width/10\"/>"
0050             "<draw:equation draw:name=\"ls\" draw:formula=\"max(width,height)\"/>"
0051             "<draw:equation draw:name=\"ssd2\" draw:formula=\"?ss/2\"/>"
0052             "<draw:equation draw:name=\"ssd4\" draw:formula=\"?ss/4\"/>"
0053             "<draw:equation draw:name=\"ssd6\" draw:formula=\"?ss/6\"/>"
0054             "<draw:equation draw:name=\"ssd8\" draw:formula=\"?ss/8\"/>");
0055 
0056     return eqs;
0057 }
0058 
0059 QString ComplexShapeHandler::pathEquationsCreated()
0060 {
0061     return pathEquations;
0062 }
0063 
0064 QString ComplexShapeHandler::getArgument(QString& function, bool equation)
0065 {
0066     // there can be extra spaces in the beginning/in the end, removing them is necessary
0067     function = function.trimmed();
0068 
0069     QString argument;
0070     int separatorIndex = function.indexOf(' ');
0071     if (separatorIndex > 0) {
0072         argument = function.left(separatorIndex);
0073         function.remove(0, separatorIndex + 1);
0074     }
0075     else {
0076         argument = function;
0077     }
0078     bool ok;
0079     argument.toInt(&ok);
0080     if (ok) {
0081         return argument;
0082     } // These values are defined for drawingML
0083     else if (argument == "h" || argument == "b") {
0084         if (!equation) {
0085             return "?height";
0086         }
0087         return "height";
0088     }
0089     else if (argument == "w" || argument == "r") {
0090         if (!equation) {
0091             return "?width";
0092         }
0093         return "width";
0094     }
0095     else if (argument == "t" || argument == "l") {
0096         return "0";
0097     }
0098     else if (argument == "cd8") {
0099         return QString("%1").arg(2700000);
0100     }
0101     else if (argument == "cd4") {
0102         return QString("%1").arg(5400000);
0103     }
0104     else if (argument == "cd2") {
0105         return QString("%1").arg(10800000);
0106     }
0107     else if (argument == "7cd8") {
0108         return QString("%1").arg(18900000);
0109     }
0110     else if (argument == "5cd8") {
0111         return QString("%1").arg(13500000);
0112     }
0113     else if (argument == "3cd8") {
0114         return QString("%1").arg(8100000);
0115     }
0116     else if (argument == "3cd4") {
0117         return QString("%1").arg(16200000);
0118     }
0119     else {
0120        return QString("?%1").arg(argument);
0121     }
0122 }
0123 
0124 QString ComplexShapeHandler::createEquation(QString& function)
0125 {
0126     int separatorIndex = function.indexOf(' ');
0127     QString operation = function.left(separatorIndex);
0128     function.remove(0, separatorIndex + 1);
0129     QString first, second, third;
0130 
0131     if (operation == "val") {
0132         return getArgument(function, true);
0133     }
0134     else if (operation == "*/") {
0135         first = getArgument(function, true);
0136         second = getArgument(function, true);
0137         third = getArgument(function, true);
0138         return QString("(%1*%2)/%3").arg(first).arg(second).arg(third);
0139     }
0140     else if (operation == "+-") {
0141         first = getArgument(function, true);
0142         second = getArgument(function, true);
0143         third = getArgument(function, true);
0144         return QString("(%1+%2)-%3").arg(first).arg(second).arg(third);
0145     }
0146     else if (operation == "+/") {
0147         first = getArgument(function, true);
0148         second = getArgument(function, true);
0149         third = getArgument(function, true);
0150         return QString("(%1+%2)/%3").arg(first).arg(second).arg(third);
0151     }
0152     else if (operation == "abs") {
0153         first = getArgument(function, true);
0154         return QString("abs(%1)").arg(first);
0155     }
0156     else if (operation == "at2") {
0157         first = getArgument(function, true);
0158         second = getArgument(function, true);
0159         // Converting to ooxml units, since sin/cos/tan functions assume that
0160         // they will get thier inputs in those units
0161         return QString("atan2(%1,%2)*3437746.771").arg(second).arg(first);
0162     }
0163     else if (operation == "cos") {
0164         first = getArgument(function,true);
0165         second = getArgument(function, true);
0166         return QString("%1*cos(%2*0.000000291)").arg(first).arg(second);
0167     }
0168     else if (operation == "sin") {
0169         first = getArgument(function, true);
0170         second = getArgument(function, true);
0171         return QString("%1*sin(%2*0.000000291)").arg(first).arg(second);
0172     }
0173     else if (operation == "sqrt") {
0174         first = getArgument(function, true);
0175         return QString("sqrt(%1)").arg(first);
0176     }
0177     else if (operation == "tan") {
0178         first = getArgument(function, true);
0179         second = getArgument(function, true);
0180         return QString("%1*tan(%2*0.000000291)").arg(first).arg(second);
0181     }
0182     else if (operation == "min") {
0183         first = getArgument(function, true);
0184         second = getArgument(function, true);
0185         return QString("min(%1,%2)").arg(first).arg(second);
0186     }
0187     else if (operation == "max") {
0188         first = getArgument(function, true);
0189         second = getArgument(function, true);
0190         return QString("max(%1,%2)").arg(first).arg(second);
0191     }
0192     else if (operation == "?:") {
0193         first = getArgument(function, true);
0194         second = getArgument(function, true);
0195         third = getArgument(function, true);
0196         return QString("if(max(%1,0),%2,%3)").arg(first).arg(second).arg(third);
0197     }
0198     else if (operation == "cat2") {
0199         first = getArgument(function, true);
0200         second = getArgument(function, true);
0201         third = getArgument(function, true);
0202         return QString("%1*cos(atan2(%2,%3))").arg(first).arg(third).arg(second);
0203     }
0204     else if (operation == "sat2") {
0205         first = getArgument(function, true);
0206         second = getArgument(function, true);
0207         third = getArgument(function, true);
0208         return QString("%1*sin(atan2(%2,%3))").arg(first).arg(third).arg(second);
0209     }
0210     else if (operation == "mod") {
0211         first = getArgument(function, true);
0212         second = getArgument(function, true);
0213         third = getArgument(function, true);
0214         return QString("sqrt(%1*%1+%2*%2+%3*%3)").arg(first).arg(second).arg(third);
0215     }
0216     else if (operation == "pin") {
0217         first = getArgument(function, true);
0218         second = getArgument(function, true);
0219         third = getArgument(function, true);
0220         return QString("if(max(%1-%2,0),%1,if(max(%2-%3,0),%3,%2))").arg(first).arg(second).arg(third);
0221     }
0222     else {
0223         debugMsooXml << "implement UNHANDLED element" << operation;
0224         return "";
0225     }
0226 }
0227 
0228 QString ComplexShapeHandler::handle_gd(QXmlStreamReader* reader)
0229 {
0230     QXmlStreamAttributes attrs = reader->attributes();
0231 
0232     QString name = attrs.value("name").toString();
0233     QString function = attrs.value("fmla").toString();
0234 
0235     QString returnString = QString("<draw:equation draw:name=\"%1\" draw:formula=\"%2\"/>").arg(name).arg(createEquation(function));
0236 
0237     reader->readNext();
0238     return returnString;
0239 }
0240 
0241 QString ComplexShapeHandler::handle_avLst(QXmlStreamReader* reader)
0242 {
0243     QString returnString;
0244 
0245     while (!reader->atEnd()) {
0246         reader->readNext();
0247         if (reader->isEndElement() && reader->name() == "avLst") {
0248             break;
0249         }
0250         else if (reader->isStartElement() && reader->name() == "gd") {
0251             returnString += handle_gd(reader);
0252         }
0253     }
0254 
0255     return returnString;
0256 }
0257 
0258 QString ComplexShapeHandler::handle_gdLst(QXmlStreamReader* reader)
0259 {
0260     QString returnString;
0261 
0262     while (!reader->atEnd()) {
0263         reader->readNext();
0264         if (reader->isEndElement() && reader->name() == "gdLst") {
0265             break;
0266         }
0267         else if (reader->isStartElement() && reader->name() == "gd") {
0268             returnString += handle_gd(reader);
0269         }
0270     }
0271 
0272     return returnString;
0273 }
0274 
0275 QString ComplexShapeHandler::handle_rect(QXmlStreamReader* reader)
0276 {
0277     QXmlStreamAttributes attrs = reader->attributes();
0278     while (!reader->atEnd()) {
0279         reader->readNext();
0280         if (reader->isEndElement() && reader->name() == "rect") {
0281             break;
0282         }
0283     }
0284 
0285     QString left = attrs.value("l").toString(); left = getArgument(left);
0286     QString top = attrs.value("t").toString(); top = getArgument(top);
0287     QString right = attrs.value("r").toString(); right = getArgument(right);
0288     QString bottom = attrs.value("b").toString(); bottom = getArgument(bottom);
0289 
0290     return QString("%1 %2 %3 %4").arg(left).arg(top).arg(right).arg(bottom).trimmed();
0291 }
0292 
0293 QString ComplexShapeHandler::handle_close(QXmlStreamReader* reader)
0294 {
0295     while (!reader->atEnd()) {
0296         reader->readNext();
0297         if (reader->isEndElement() && reader->name() == "close") {
0298             break;
0299         }
0300     }
0301     return "Z ";
0302 }
0303 
0304 QString ComplexShapeHandler::handle_arcTo(QXmlStreamReader* reader)
0305 {
0306     QXmlStreamAttributes attrs = reader->attributes();
0307     while (!reader->atEnd()) {
0308         reader->readNext();
0309         if (reader->isEndElement() && reader->name() == "arcTo") {
0310             break;
0311         }
0312     }
0313 
0314     QString wR = attrs.value("wR").toString(); // vertical radius
0315     QString hR = attrs.value("hR").toString(); // horizontal radius
0316     QString stAng = attrs.value("stAng").toString(); // start angle
0317     QString swAng = attrs.value("swAng").toString(); // swing angle
0318 
0319     wR = getArgument(wR);
0320     hR = getArgument(hR);
0321 
0322     if (pathWidth > 0 || pathHeight > 0) {
0323         bool isNumber = false;
0324         qreal number = wR.toInt(&isNumber);
0325         if (pathWidth > 0 && isNumber) {
0326             int relWidthIndex = pathEquationIndex;
0327             ++pathEquationIndex;
0328             pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"%2*?width\"/>").
0329                 arg(relWidthIndex).arg(number/pathWidth);
0330             wR = QString("?ooxmlArc%1 ").arg(relWidthIndex);
0331         }
0332         number = hR.toInt(&isNumber);
0333         if (pathHeight > 0 && isNumber) {
0334             int relHeightIndex = pathEquationIndex;
0335             ++pathEquationIndex;
0336             pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"%2*?height\"/>").
0337                 arg(relHeightIndex).arg(number/pathHeight);
0338             hR = QString("?ooxmlArc%1 ").arg(relHeightIndex);
0339         }
0340     }
0341 
0342     stAng = getArgument(stAng);
0343     swAng = getArgument(swAng);
0344 
0345     // These equations convert ooxml arcTo to a form that is compatible with odf
0346     // Notice that the angle system used in ooxlm is reverse to normal mathematical handling
0347     // There seem to be two different ways of conversion, one to W, other one to T
0348     // both of them need end angle, x1 and y1
0349     // Most problematic case is when swAng is negative, when A should be used instead of W
0350 
0351     int endAngleIndex = pathEquationIndex;
0352     ++pathEquationIndex;
0353     // Converts to end angle
0354     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"%2+%3\"/>").
0355          arg(endAngleIndex).arg(stAng).arg(swAng);
0356 
0357     /*
0358     // Try for T
0359     int centerXIndex = pathEquationIndex;
0360     ++pathEquationIndex;
0361     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"%2 - %3 * cos(%4 * 0.000000291)\"/>").
0362          arg(centerXIndex).arg(oldX).arg(wR).arg(stAng);
0363 
0364     int centerYIndex = pathEquationIndex;
0365     ++pathEquationIndex;
0366     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"%2 - %3 * sin(%4 * 0.000000291)\"/>").
0367          arg(centerYIndex).arg(oldY).arg(hR).arg(stAng);
0368 
0369     int widthIndex = pathEquationIndex;
0370     ++pathEquationIndex;
0371     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"2 * %2\"/>").arg(widthIndex).arg(wR);
0372 
0373     int heightIndex = pathEquationIndex;
0374     ++pathEquationIndex;
0375     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"2 * %2\"/>").arg(heightIndex).arg(hR);
0376 
0377     int odfStartAngleIndex = pathEquationIndex;
0378     ++pathEquationIndex;
0379     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"360 - %2 / 60000\"/>").
0380          arg(odfStartAngleIndex).arg(stAng);
0381 
0382     int odfEndAngleIndex = pathEquationIndex;
0383     ++pathEquationIndex;
0384     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"360 - ?ooxmlArc%2 / 60000\"/>").
0385          arg(odfEndAngleIndex).arg(endAngleIndex);
0386 
0387     QString path = QString("T ?ooxmlArc%1 ?ooxmlArc%2 ?ooxmlArc%3 ?ooxmlArc%4 ?ooxmlArc%5 ?ooxmlArc%6 ").arg(centerXIndex).arg(centerYIndex).
0388         arg(widthIndex).arg(heightIndex).arg(odfStartAngleIndex).arg(odfEndAngleIndex);
0389 
0390     oldX = QString("?ooxmlArc%1 + %2 * cos(?ooxmlArc%3 * 0.000000291)").arg(centerXIndex).arg(wR).arg(endAngleIndex);
0391     oldY = QString("?ooxmlArc%1 + %2 * sin(?ooxmlArc%3 * 0.000000291)").arg(centerYIndex).arg(hR).arg(endAngleIndex);
0392     */
0393 
0394     // Try for W/A (commented out atm. T (above) seems to work better
0395     // x1, y1 marks the upper left corner
0396     int ellipseX1Index = pathEquationIndex;
0397     ++pathEquationIndex;
0398     // x1
0399     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"%2-%3*cos(%4*0.000000291)-%3\"/>").
0400          arg(ellipseX1Index).arg(oldX).arg(wR).arg(stAng);
0401 
0402     int ellipseY1Index = pathEquationIndex;
0403     ++pathEquationIndex;
0404     // y1
0405     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"%2-%3*sin(%4*0.000000291)-%3\"/>").
0406          arg(ellipseY1Index).arg(oldY).arg(hR).arg(stAng);
0407 
0408     // Try for W solution
0409     // W clockwise- (x1 y1 x2 y2 x3 y3 x y) + The same as the “A” command except, that the arcto arc is drawn clockwise.
0410 
0411     // x2, y2 marks the lower right corner
0412     int ellipseX2Index = pathEquationIndex;
0413     ++pathEquationIndex;
0414     // x2
0415     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"?ooxmlArc%2+%3*2\"/>").
0416         arg(ellipseX2Index).arg(ellipseX1Index).arg(wR);
0417 
0418     int ellipseY2Index = pathEquationIndex;
0419     ++pathEquationIndex;
0420     // y2
0421     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"?ooxmlArc%2+%3*2\"/>").
0422         arg(ellipseY2Index).arg(ellipseY1Index).arg(hR);
0423 
0424     int arcEndX = pathEquationIndex;
0425     ++pathEquationIndex;
0426     // x4
0427     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"?ooxmlArc%2+%3+%3*cos(?ooxmlArc%4*0.000000291)\"/>").
0428         arg(arcEndX).arg(ellipseX1Index).arg(wR).arg(endAngleIndex);
0429 
0430     int arcEndY = pathEquationIndex;
0431     ++pathEquationIndex;
0432     // y4
0433     pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"?ooxmlArc%2+%3+%3*sin(?ooxmlArc%4*0.000000291)\"/>").
0434         arg(arcEndY).arg(ellipseY1Index).arg(hR).arg(endAngleIndex);
0435 
0436     QString path;
0437     bool signTest = true;
0438     int temp = swAng.toInt(&signTest);
0439 
0440     if (signTest && temp < 0) {
0441         path = QString("A ?ooxmlArc%1 ?ooxmlArc%2 ?ooxmlArc%3 ?ooxmlArc%4 %5 %6 ?ooxmlArc%7 ?ooxmlArc%8 ").
0442             arg(ellipseX1Index).arg(ellipseY1Index).arg(ellipseX2Index).arg(ellipseY2Index).arg(oldX).arg(oldY).arg(arcEndX).arg(arcEndY);
0443     }
0444     else {
0445         path = QString("W ?ooxmlArc%1 ?ooxmlArc%2 ?ooxmlArc%3 ?ooxmlArc%4 %5 %6 ?ooxmlArc%7 ?ooxmlArc%8 ").
0446             arg(ellipseX1Index).arg(ellipseY1Index).arg(ellipseX2Index).arg(ellipseY2Index).arg(oldX).arg(oldY).arg(arcEndX).arg(arcEndY);
0447     }
0448     oldX = QString("?ooxmlArc%1").arg(arcEndX);
0449     oldY = QString("?ooxmlArc%1").arg(arcEndY);
0450 
0451     return path;
0452 }
0453 
0454 QString ComplexShapeHandler::handle_pt(QXmlStreamReader* reader)
0455 {
0456     QXmlStreamAttributes attrs = reader->attributes();
0457     while (!reader->atEnd()) {
0458         reader->readNext();
0459         if (reader->isEndElement() && reader->name() == "pt") {
0460             break;
0461         }
0462     }
0463 
0464     oldX = attrs.value("x").toString();
0465     oldY = attrs.value("y").toString();
0466     oldX = getArgument(oldX);
0467     oldY = getArgument(oldY);
0468 
0469     if (pathWidth > 0 || pathHeight > 0) {
0470         bool isNumber = false;
0471         qreal number = oldX.toInt(&isNumber);
0472         if (pathWidth > 0 && isNumber) {
0473             int relWidthIndex = pathEquationIndex;
0474             ++pathEquationIndex;
0475             pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"%2*?width\"/>").
0476                 arg(relWidthIndex).arg(number/pathWidth);
0477             oldX = QString("?ooxmlArc%1 ").arg(relWidthIndex);
0478         }
0479         number = oldY.toInt(&isNumber);
0480         if (pathHeight > 0 && isNumber) {
0481             int relHeightIndex = pathEquationIndex;
0482             ++pathEquationIndex;
0483             pathEquations += QString("<draw:equation draw:name=\"ooxmlArc%1\" draw:formula=\"%2*?height\"/>").
0484                 arg(relHeightIndex).arg(number/pathHeight);
0485             oldY = QString("?ooxmlArc%1 ").arg(relHeightIndex);
0486         }
0487     }
0488 
0489     return QString("%1 %2 ").arg(oldX).arg(oldY);
0490 }
0491 
0492 QString ComplexShapeHandler::handle_lnTo(QXmlStreamReader* reader)
0493 {
0494     QString returnString;
0495 
0496     while (!reader->atEnd()) {
0497         reader->readNext();
0498         if (reader->isEndElement() && reader->name() == "lnTo") {
0499             break;
0500         }
0501         else if (reader->isStartElement() && reader->name() == "pt") {
0502             returnString += handle_pt(reader);
0503         }
0504     }
0505     return QString("L %1 ").arg(returnString);
0506 }
0507 
0508 QString ComplexShapeHandler::handle_moveTo(QXmlStreamReader* reader)
0509 {
0510     QString returnString;
0511 
0512     while (!reader->atEnd()) {
0513         reader->readNext();
0514         if (reader->isEndElement() && reader->name() == "moveTo") {
0515             break;
0516         }
0517         else if (reader->isStartElement() && reader->name() == "pt") {
0518             returnString += handle_pt(reader);
0519         }
0520     }
0521     return QString("M %1").arg(returnString);
0522 }
0523 
0524 QString ComplexShapeHandler::handle_quadBezTo(QXmlStreamReader* reader)
0525 {
0526     QString returnString;
0527 
0528     while (!reader->atEnd()) {
0529         reader->readNext();
0530         if (reader->isEndElement() && reader->name() == "quadBezTo") {
0531             break;
0532         }
0533         else if (reader->isStartElement() && reader->name() == "pt") {
0534             returnString += handle_pt(reader);
0535         }
0536     }
0537     return QString("Q %1").arg(returnString);
0538 }
0539 
0540 QString ComplexShapeHandler::handle_cubicBezTo(QXmlStreamReader* reader)
0541 {
0542     QString returnString;
0543 
0544     while (!reader->atEnd()) {
0545         reader->readNext();
0546         if (reader->isEndElement() && reader->name() == "cubicBezTo") {
0547             break;
0548         }
0549         else if (reader->isStartElement() && reader->name() == "pt") {
0550             returnString += handle_pt(reader);
0551         }
0552     }
0553     return QString("C %1").arg(returnString);
0554 }
0555 
0556 QString ComplexShapeHandler::handle_path(QXmlStreamReader* reader)
0557 {
0558     QString returnString;
0559     pathWidth = 0;
0560     pathHeight = 0;
0561 
0562     QXmlStreamAttributes attrs = reader->attributes();
0563 
0564     QString width = attrs.value("w").toString();
0565     QString height = attrs.value("h").toString();
0566 
0567     if (!width.isEmpty()) {
0568         pathWidth = width.toInt();
0569     }
0570     if (!height.isEmpty()) {
0571         pathHeight = height.toInt();
0572     }
0573 
0574     while (!reader->atEnd()) {
0575         reader->readNext();
0576         if (reader->isEndElement() && reader->name() == "path") {
0577             if (attrs.value("stroke") == "false" || attrs.value("stroke") == "0" ) {
0578                 returnString += "S ";
0579             }
0580             if (attrs.value("fill") == "none") {
0581                 returnString += "F ";
0582             }
0583             break;
0584         }
0585         else if (reader->isStartElement() && reader->name() == "moveTo") {
0586             returnString += handle_moveTo(reader);
0587         }
0588         else if (reader->isStartElement() && reader->name() == "close") {
0589             returnString += handle_close(reader);
0590         }
0591         else if (reader->isStartElement() && reader->name() == "lnTo") {
0592             returnString += handle_lnTo(reader);
0593         }
0594         else if (reader->isStartElement() && reader->name() == "cubicBezTo") {
0595             returnString += handle_cubicBezTo(reader);
0596         }
0597         else if (reader->isStartElement() && reader->name() == "quadBezTo") {
0598             returnString += handle_quadBezTo(reader);
0599         }
0600         else if (reader->isStartElement() && reader->name() == "arcTo") {
0601             returnString += handle_arcTo(reader);
0602         }
0603     else if (reader->isStartElement()) {
0604             debugMsooXml << "UNHANDLED path sub element" << reader->name().toString();
0605         }
0606     }
0607 
0608     return returnString;
0609 }
0610 
0611 QString ComplexShapeHandler::handle_pathLst(QXmlStreamReader* reader)
0612 {
0613     QString returnString;
0614 
0615     pathEquationIndex = 0;
0616     pathEquations.clear();
0617 
0618     while (!reader->atEnd()) {
0619         reader->readNext();
0620         if (reader->isEndElement() && reader->name() == "pathLst") {
0621             break;
0622         }
0623         else if (reader->isStartElement() && reader->name() == "path") {
0624             returnString += handle_path(reader);
0625         }
0626     }
0627 
0628     return returnString;
0629 }