示例#1
0
void
SVGPathParser::parseSVG( const DeprecatedString &s, bool process )
{
    if(!s.isEmpty())
    {
        DeprecatedString d = s;
        d = d.replace(',', ' ');
        d = d.simplifyWhiteSpace();
        const char *ptr = d.latin1();
        const char *end = d.latin1() + d.length() + 1;

        double contrlx, contrly, curx, cury, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc;
        double px1, py1, px2, py2, px3, py3;
        bool relative, closed = true;
        char command = *(ptr++), lastCommand = ' ';

        subpathx = subpathy = curx = cury = contrlx = contrly = 0.0;
        while( ptr < end )
        {
            if( *ptr == ' ' )
                ptr++;

            relative = false;

            //std::cout << "Command : " << command << std::endl;
            switch( command )
            {
                case 'm':
                    relative = true;
                case 'M':
                {
                    ptr = parseCoord( ptr, tox );
                    ptr = parseCoord( ptr, toy );

                    if( process )
                    {
                        subpathx = curx = relative ? curx + tox : tox;
                        subpathy = cury = relative ? cury + toy : toy;

                        svgMoveTo( curx, cury, closed );
                    }
                    else
                        svgMoveTo( tox, toy, closed, !relative );
                    closed = false;
                    break;
                }
                case 'l':
                    relative = true;
                case 'L':
                {
                    ptr = parseCoord( ptr, tox );
                    ptr = parseCoord( ptr, toy );

                    if( process )
                    {
                        curx = relative ? curx + tox : tox;
                        cury = relative ? cury + toy : toy;

                        svgLineTo( curx, cury );
                    }
                    else
                        svgLineTo( tox, toy, !relative );
                    break;
                }
                case 'h':
                {
                    ptr = parseCoord( ptr, tox );
                    if( process )
                    {
                        curx = curx + tox;
                        svgLineTo( curx, cury );
                    }
                    else
                        svgLineToHorizontal( tox, false );
                    break;
                }
                case 'H':
                {
                    ptr = parseCoord( ptr, tox );
                    if( process )
                    {
                        curx = tox;
                        svgLineTo( curx, cury );
                    }
                    else
                        svgLineToHorizontal( tox );
                    break;
                }
                case 'v':
                {
                    ptr = parseCoord( ptr, toy );
                    if( process )
                    {
                        cury = cury + toy;
                        svgLineTo( curx, cury );
                    }
                    else
                        svgLineToVertical( toy, false );
                    break;
                }
                case 'V':
                {
                    ptr = parseCoord( ptr, toy );
                    if( process )
                    {
                        cury = toy;
                        svgLineTo( curx, cury );
                    }
                    else
                        svgLineToVertical( toy );
                    break;
                }
                case 'z':
                case 'Z':
                {
                    // reset curx, cury for next path
                    if( process )
                    {
                        curx = subpathx;
                        cury = subpathy;
                    }
                    closed = true;
                    svgClosePath();
                    break;
                }
                case 'c':
                    relative = true;
                case 'C':
                {
                    ptr = parseCoord( ptr, x1 );
                    ptr = parseCoord( ptr, y1 );
                    ptr = parseCoord( ptr, x2 );
                    ptr = parseCoord( ptr, y2 );
                    ptr = parseCoord( ptr, tox );
                    ptr = parseCoord( ptr, toy );

                    if( process )
                    {
                        px1 = relative ? curx + x1 : x1;
                        py1 = relative ? cury + y1 : y1;
                        px2 = relative ? curx + x2 : x2;
                        py2 = relative ? cury + y2 : y2;
                        px3 = relative ? curx + tox : tox;
                        py3 = relative ? cury + toy : toy;

                        svgCurveToCubic( px1, py1, px2, py2, px3, py3 );

                        contrlx = relative ? curx + x2 : x2;
                        contrly = relative ? cury + y2 : y2;
                        curx = relative ? curx + tox : tox;
                        cury = relative ? cury + toy : toy;
                    }
                    else
                        svgCurveToCubic( x1, y1, x2, y2, tox, toy, !relative );

                    break;
                }
                case 's':
                    relative = true;
                case 'S':
                {
                    ptr = parseCoord( ptr, x2 );
                    ptr = parseCoord( ptr, y2 );
                    ptr = parseCoord( ptr, tox );
                    ptr = parseCoord( ptr, toy );
                    if(!(lastCommand == 'c' || lastCommand == 'C' ||
                         lastCommand == 's' || lastCommand == 'S')) {
                        contrlx = curx;
                        contrly = cury;
                    }

                    if( process )
                    {
                        px1 = 2 * curx - contrlx;
                        py1 = 2 * cury - contrly;
                        px2 = relative ? curx + x2 : x2;
                        py2 = relative ? cury + y2 : y2;
                        px3 = relative ? curx + tox : tox;
                        py3 = relative ? cury + toy : toy;

                        svgCurveToCubic( px1, py1, px2, py2, px3, py3 );

                        contrlx = relative ? curx + x2 : x2;
                        contrly = relative ? cury + y2 : y2;
                        curx = relative ? curx + tox : tox;
                        cury = relative ? cury + toy : toy;
                    }
                    else
                        svgCurveToCubicSmooth( x2, y2, tox, toy, !relative );
                    break;
                }
                case 'q':
                    relative = true;
                case 'Q':
                {
                    ptr = parseCoord( ptr, x1 );
                    ptr = parseCoord( ptr, y1 );
                    ptr = parseCoord( ptr, tox );
                    ptr = parseCoord( ptr, toy );

                    if( process )
                    {
                        px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0);
                        py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0);
                        px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0);
                        py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0);
                        px3 = relative ? curx + tox : tox;
                        py3 = relative ? cury + toy : toy;

                        svgCurveToCubic( px1, py1, px2, py2, px3, py3 );

                        contrlx = relative ? curx + x1 : x1;
                        contrly = relative ? cury + y1 : y1;
                        curx = relative ? curx + tox : tox;
                        cury = relative ? cury + toy : toy;
                    }
                    else
                        svgCurveToQuadratic( x1, y1, tox, toy, !relative );
                    break;
                }
                case 't':
                    relative = true;
                case 'T':
                {
                    ptr = parseCoord(ptr, tox);
                    ptr = parseCoord(ptr, toy);
                    if(!(lastCommand == 'q' || lastCommand == 'Q' ||
                         lastCommand == 't' || lastCommand == 'T')) {
                        contrlx = curx;
                        contrly = cury;
                    }

                    if( process )
                    {
                        xc = 2 * curx - contrlx;
                        yc = 2 * cury - contrly;

                        px1 = relative ? (curx + 2 * xc) * (1.0 / 3.0) : (curx + 2 * xc) * (1.0 / 3.0);
                        py1 = relative ? (cury + 2 * yc) * (1.0 / 3.0) : (cury + 2 * yc) * (1.0 / 3.0);
                        px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0);
                        py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0);
                        px3 = relative ? curx + tox : tox;
                        py3 = relative ? cury + toy : toy;

                        svgCurveToCubic( px1, py1, px2, py2, px3, py3 );

                        contrlx = xc;
                        contrly = yc;
                        curx = relative ? curx + tox : tox;
                        cury = relative ? cury + toy : toy;
                    }
                    else
                        svgCurveToQuadraticSmooth( tox, toy, !relative );
                    break;
                }
                case 'a':
                    relative = true;
                case 'A':
                {
                    bool largeArc, sweep;
                    double angle, rx, ry;
                    ptr = parseCoord( ptr, rx );
                    ptr = parseCoord( ptr, ry );
                    ptr = parseCoord( ptr, angle );
                    ptr = parseCoord( ptr, tox );
                    largeArc = tox == 1;
                    ptr = parseCoord( ptr, tox );
                    sweep = tox == 1;
                    ptr = parseCoord( ptr, tox );
                    ptr = parseCoord( ptr, toy );

                    // Spec: radii are nonnegative numbers
                    rx = fabs(rx);
                    ry = fabs(ry);

                    if( process )
                        calculateArc( relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep );
                    else
                        svgArcTo( tox, toy, rx, ry, angle, largeArc, sweep, !relative );
                    break;
                }
                default:
                    // FIXME: An error should go to the JavaScript console, or the like.
                    return;
            }
            lastCommand = command;

            if(*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9'))
            {
                // there are still coords in this command
                if(command == 'M')
                    command = 'L';
                else if(command == 'm')
                    command = 'l';
            }
            else
                command = *(ptr++);

            if( lastCommand != 'C' && lastCommand != 'c' &&
                lastCommand != 'S' && lastCommand != 's' &&
                lastCommand != 'Q' && lastCommand != 'q' &&
                lastCommand != 'T' && lastCommand != 't' ) 
            {
                contrlx = curx;
                contrly = cury;
            }
        }
    }
}
void KoPathShapeLoaderPrivate::parseSvg(const QString &s, bool process)
{
    if (!s.isEmpty()) {
        QString d = s;
        d = d.replace(',', ' ');
        d = d.simplified();

        const QByteArray buffer = d.toLatin1();
        const char *ptr = buffer.constData();
        const char *end = buffer.constData() + buffer.length() + 1;

        qreal curx = 0.0;
        qreal cury = 0.0;
        qreal contrlx, contrly, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc;
        qreal px1, py1, px2, py2, px3, py3;
        bool relative;
        char command = *(ptr++), lastCommand = ' ';

        subpathx = subpathy = curx = cury = contrlx = contrly = 0.0;
        while (ptr < end) {
            if (*ptr == ' ')
                ++ptr;

            relative = false;

            switch (command) {
            case 'm':
                relative = true;
            case 'M': {
                ptr = getCoord(ptr, tox);
                ptr = getCoord(ptr, toy);

                if (process) {
                    subpathx = curx = relative ? curx + tox : tox;
                    subpathy = cury = relative ? cury + toy : toy;

                    svgMoveTo(curx, cury);
                } else
                    svgMoveTo(tox, toy, !relative);
                break;
            }
            case 'l':
                relative = true;
            case 'L': {
                ptr = getCoord(ptr, tox);
                ptr = getCoord(ptr, toy);

                if (process) {
                    curx = relative ? curx + tox : tox;
                    cury = relative ? cury + toy : toy;

                    svgLineTo(curx, cury);
                } else
                    svgLineTo(tox, toy, !relative);
                break;
            }
            case 'h': {
                ptr = getCoord(ptr, tox);
                if (process) {
                    curx = curx + tox;
                    svgLineTo(curx, cury);
                } else
                    svgLineToHorizontal(tox, false);
                break;
            }
            case 'H': {
                ptr = getCoord(ptr, tox);
                if (process) {
                    curx = tox;
                    svgLineTo(curx, cury);
                } else
                    svgLineToHorizontal(tox);
                break;
            }
            case 'v': {
                ptr = getCoord(ptr, toy);
                if (process) {
                    cury = cury + toy;
                    svgLineTo(curx, cury);
                } else
                    svgLineToVertical(toy, false);
                break;
            }
            case 'V': {
                ptr = getCoord(ptr, toy);
                if (process) {
                    cury = toy;
                    svgLineTo(curx, cury);
                } else
                    svgLineToVertical(toy);
                break;
            }
            case 'z':
            case 'Z': {
                // reset curx, cury for next path
                if (process) {
                    // The "closepath" (Z or z) ends the current subpath and causes an automatic
                    // straight line to be drawn from the current point to the initial point of the
                    // current subpath. If a "closepath" is followed immediately by a "moveto", then
                    // the "moveto" identifies the start point of the next subpath. If a "closepath"
                    // is followed immediately by any other command, then the next subpath starts at
                    // the same initial point as the current subpath.
                    if (*ptr != 'm' && *ptr != 'M') {
                        curx = subpathx;
                        cury = subpathy;
                    }
                }
                svgClosePath();
                break;
            }
            case 'c':
                relative = true;
            case 'C': {
                ptr = getCoord(ptr, x1);
                ptr = getCoord(ptr, y1);
                ptr = getCoord(ptr, x2);
                ptr = getCoord(ptr, y2);
                ptr = getCoord(ptr, tox);
                ptr = getCoord(ptr, toy);

                if (process) {
                    px1 = relative ? curx + x1 : x1;
                    py1 = relative ? cury + y1 : y1;
                    px2 = relative ? curx + x2 : x2;
                    py2 = relative ? cury + y2 : y2;
                    px3 = relative ? curx + tox : tox;
                    py3 = relative ? cury + toy : toy;

                    svgCurveToCubic(px1, py1, px2, py2, px3, py3);

                    contrlx = relative ? curx + x2 : x2;
                    contrly = relative ? cury + y2 : y2;
                    curx = relative ? curx + tox : tox;
                    cury = relative ? cury + toy : toy;
                } else
                    svgCurveToCubic(x1, y1, x2, y2, tox, toy, !relative);

                break;
            }
            case 's':
                relative = true;
            case 'S': {
                ptr = getCoord(ptr, x2);
                ptr = getCoord(ptr, y2);
                ptr = getCoord(ptr, tox);
                ptr = getCoord(ptr, toy);
                if (!(lastCommand == 'c' || lastCommand == 'C' ||
                        lastCommand == 's' || lastCommand == 'S')) {
                    contrlx = curx;
                    contrly = cury;
                }

                if (process) {
                    px1 = 2 * curx - contrlx;
                    py1 = 2 * cury - contrly;
                    px2 = relative ? curx + x2 : x2;
                    py2 = relative ? cury + y2 : y2;
                    px3 = relative ? curx + tox : tox;
                    py3 = relative ? cury + toy : toy;

                    svgCurveToCubic(px1, py1, px2, py2, px3, py3);

                    contrlx = relative ? curx + x2 : x2;
                    contrly = relative ? cury + y2 : y2;
                    curx = relative ? curx + tox : tox;
                    cury = relative ? cury + toy : toy;
                } else
                    svgCurveToCubicSmooth(x2, y2, tox, toy, !relative);
                break;
            }
            case 'q':
                relative = true;
            case 'Q': {
                ptr = getCoord(ptr, x1);
                ptr = getCoord(ptr, y1);
                ptr = getCoord(ptr, tox);
                ptr = getCoord(ptr, toy);

                if (process) {
                    px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0);
                    py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0);
                    px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0);
                    py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0);
                    px3 = relative ? curx + tox : tox;
                    py3 = relative ? cury + toy : toy;

                    svgCurveToCubic(px1, py1, px2, py2, px3, py3);

                    contrlx = relative ? curx + x1 : x1;
                    contrly = relative ? cury + y1 : y1;
                    curx = relative ? curx + tox : tox;
                    cury = relative ? cury + toy : toy;
                } else
                    svgCurveToQuadratic(x1, y1, tox, toy, !relative);
                break;
            }
            case 't':
                relative = true;
            case 'T': {
                ptr = getCoord(ptr, tox);
                ptr = getCoord(ptr, toy);
                if (!(lastCommand == 'q' || lastCommand == 'Q' ||
                        lastCommand == 't' || lastCommand == 'T')) {
                    contrlx = curx;
                    contrly = cury;
                }

                if (process) {
                    xc = 2 * curx - contrlx;
                    yc = 2 * cury - contrly;

                    px1 = (curx + 2 * xc) * (1.0 / 3.0);
                    py1 = (cury + 2 * yc) * (1.0 / 3.0);
                    px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0);
                    py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0);
                    px3 = relative ? curx + tox : tox;
                    py3 = relative ? cury + toy : toy;

                    svgCurveToCubic(px1, py1, px2, py2, px3, py3);

                    contrlx = xc;
                    contrly = yc;
                    curx = relative ? curx + tox : tox;
                    cury = relative ? cury + toy : toy;
                } else
                    svgCurveToQuadraticSmooth(tox, toy, !relative);
                break;
            }
            case 'a':
                relative = true;
            case 'A': {
                bool largeArc, sweep;
                qreal angle, rx, ry;
                ptr = getCoord(ptr, rx);
                ptr = getCoord(ptr, ry);
                ptr = getCoord(ptr, angle);
                ptr = getCoord(ptr, tox);
                largeArc = tox == 1;
                ptr = getCoord(ptr, tox);
                sweep = tox == 1;
                ptr = getCoord(ptr, tox);
                ptr = getCoord(ptr, toy);

                // Spec: radii are nonnegative numbers
                rx = fabs(rx);
                ry = fabs(ry);

                if (process)
                    calculateArc(relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep);
                else
                    svgArcTo(tox, toy, rx, ry, angle, largeArc, sweep, !relative);
                break;
            }
            default: {
                // when svg parser is used for a parsing an odf path an unknown command
                // can be encountered, so we stop parsing here
                kDebug(30006) << "KoSvgPathParser::parseSVG(): unknown command \"" << command << "\"";
                return;
            }
            }

            lastCommand = command;

            if (*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9')) {
                // there are still coords in this command
                if (command == 'M')
                    command = 'L';
                else if (command == 'm')
                    command = 'l';
            } else
                command = *(ptr++);

            if (lastCommand != 'C' && lastCommand != 'c' &&
                    lastCommand != 'S' && lastCommand != 's' &&
                    lastCommand != 'Q' && lastCommand != 'q' &&
                    lastCommand != 'T' && lastCommand != 't') {
                contrlx = curx;
                contrly = cury;
            }
        }
    }
}
示例#3
0
void ShapePlug::parseGroupProperties(QDomNode &DOC, double &minXCoor, double &minYCoor, double &maxXCoor, double &maxYCoor, bool &firstCheck)
{
    QString FillCol = "White";
    QString StrokeCol = "Black";
    while(!DOC.isNull())
    {
        double x1, y1, x2, y2;
        FPointArray PoLine;
        PoLine.resize(0);
        QDomElement pg = DOC.toElement();
        QString STag = pg.tagName();
        if (STag == "svg:line")
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("x1")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("y1")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("x2")) * Conversion;
            y2 = ScCLocale::toDoubleC(pg.attribute("y2")) * Conversion;
            PoLine.addPoint(x1, y1);
            PoLine.addPoint(x1, y1);
            PoLine.addPoint(x2, y2);
            PoLine.addPoint(x2, y2);
        }
        else if (STag == "svg:rect")
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("x")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("y")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("width")) * Conversion;
            y2 = ScCLocale::toDoubleC(pg.attribute("height")) * Conversion;
            static double rect[] = {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0,
                                    1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0,
                                    0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0
                                   };
            for (int a = 0; a < 29; a += 4)
            {
                double xa = x2 * rect[a];
                double ya = y2 * rect[a+1];
                double xb = x2 * rect[a+2];
                double yb = y2 * rect[a+3];
                PoLine.addPoint(x1+xa, y1+ya);
                PoLine.addPoint(x1+xb, y1+yb);
            }
        }
        else if ((STag == "svg:polygon") || (STag == "svg:polyline"))
        {
            bool bFirst = true;
            double x = 0.0;
            double y = 0.0;
            QString points = pg.attribute( "points" ).simplified().replace(',', " ");
            QStringList pointList = points.split(' ', QString::SkipEmptyParts);
            FirstM = true;
            for( QStringList::Iterator it1 = pointList.begin(); it1 != pointList.end(); it1++ )
            {
                x = ScCLocale::toDoubleC(*(it1++));
                y = ScCLocale::toDoubleC(*it1);
                if( bFirst )
                {
                    svgMoveTo(x * Conversion, y * Conversion);
                    bFirst = false;
                    WasM = true;
                }
                else
                {
                    svgLineTo(&PoLine, x * Conversion, y * Conversion);
                }
            }
            if (STag == "svg:polygon")
                svgClosePath(&PoLine);
            if (PoLine.size() < 4)
            {
                DOC = DOC.nextSibling();
                continue;
            }
        }
        else if (STag == "svg:circle")
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("r")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("r")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("cx")) * Conversion - x1;
            y2 = ScCLocale::toDoubleC(pg.attribute("cy")) * Conversion - y1;
            x1 *= 2.0;
            y1 *= 2.0;
            static double rect[] = {1.0, 0.5, 1.0, 0.77615235,0.5, 1.0, 0.77615235, 1.0,
                                    0.5, 1.0, 0.22385765, 1.0, 0.0, 0.5, 0.0, 0.77615235,
                                    0.0, 0.5, 0.0, 0.22385765, 0.5, 0.0, 0.22385765, 0.0,
                                    0.5, 0.0, 0.77615235, 0.0, 1.0, 0.5, 1.0, 0.22385765
                                   };
            for (int a = 0; a < 29; a += 4)
            {
                double xa = x1 * rect[a];
                double ya = y1 * rect[a+1];
                double xb = x1 * rect[a+2];
                double yb = y1 * rect[a+3];
                PoLine.addPoint(x2+xa, y2+ya);
                PoLine.addPoint(x2+xb, y2+yb);
            }
        }
        else if (STag == "svg:ellipse")
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("rx")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("ry")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("cx")) * Conversion - x1;
            y2 = ScCLocale::toDoubleC(pg.attribute("cy")) * Conversion - y1;
            x1 *= 2.0;
            y1 *= 2.0;
            static double rect[] = {1.0, 0.5, 1.0, 0.77615235,0.5, 1.0, 0.77615235, 1.0,
                                    0.5, 1.0, 0.22385765, 1.0, 0.0, 0.5, 0.0, 0.77615235,
                                    0.0, 0.5, 0.0, 0.22385765, 0.5, 0.0, 0.22385765, 0.0,
                                    0.5, 0.0, 0.77615235, 0.0, 1.0, 0.5, 1.0, 0.22385765
                                   };
            for (int a = 0; a < 29; a += 4)
            {
                double xa = x1 * rect[a];
                double ya = y1 * rect[a+1];
                double xb = x1 * rect[a+2];
                double yb = y1 * rect[a+3];
                PoLine.addPoint(x2+xa, y2+ya);
                PoLine.addPoint(x2+xb, y2+yb);
            }
        }
        else if (STag == "svg:path")
        {
            parseSVG( pg.attribute( "d" ), &PoLine );
            if (PoLine.size() < 4)
            {
                DOC = DOC.nextSibling();
                continue;
            }
        }
        else if (STag == "svg:g")
        {
            QDomNode child = DOC.firstChild();
            parseGroupProperties(child, minXCoor, minYCoor, maxXCoor, maxYCoor, firstCheck);
        }
        if (PoLine.size() < 4)
        {
            DOC = DOC.nextSibling();
            continue;
        }
        FPoint tp2(getMinClipF(&PoLine));
        PoLine.translate(-tp2.x(), -tp2.y());
        FPoint wh(getMaxClipF(&PoLine));
        if (firstCheck)
        {
            minXCoor = tp2.x();
            minYCoor = tp2.y();
            maxXCoor = tp2.x() + wh.x();
            maxYCoor = tp2.y() + wh.y();
            firstCheck = false;
        }
        else
        {
            minXCoor = qMin(minXCoor, tp2.x());
            minYCoor = qMin(minYCoor, tp2.y());
            maxXCoor = qMax(maxXCoor, tp2.x() + wh.x());
            maxYCoor = qMax(maxYCoor, tp2.y() + wh.y());
        }
        DOC = DOC.nextSibling();
    }
}
示例#4
0
bool ShapePlug::parseSVG( const QString &s, FPointArray *ite )
{
    QString d = s;
    d = d.replace( QRegExp( "," ), " ");
    bool ret = false;
    if( !d.isEmpty() )
    {
        d = d.simplified();
        QByteArray pathData = d.toLatin1();
        const char *ptr = pathData.constData();
        const char *end = pathData.constData() + pathData.length() + 1;
        double contrlx, contrly, curx, cury, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc;
        double px1, py1, px2, py2, px3, py3;
        bool relative;
        FirstM = true;
        char command = *(ptr++), lastCommand = ' ';
        subpathx = subpathy = curx = cury = contrlx = contrly = 0.0;
        while( ptr < end )
        {
            if( *ptr == ' ' )
                ptr++;
            relative = false;
            switch( command )
            {
            case 'm':
                relative = true;
            case 'M':
            {
                ptr = getCoord( ptr, tox );
                ptr = getCoord( ptr, toy );
                tox *= Conversion;
                toy *= Conversion;
                WasM = true;
                subpathx = curx = relative ? curx + tox : tox;
                subpathy = cury = relative ? cury + toy : toy;
                svgMoveTo(curx, cury );
                break;
            }
            case 'l':
                relative = true;
            case 'L':
            {
                ptr = getCoord( ptr, tox );
                ptr = getCoord( ptr, toy );
                tox *= Conversion;
                toy *= Conversion;
                curx = relative ? curx + tox : tox;
                cury = relative ? cury + toy : toy;
                svgLineTo(ite, curx, cury );
                break;
            }
            case 'h':
            {
                ptr = getCoord( ptr, tox );
                tox *= Conversion;
                curx = curx + tox;
                svgLineTo(ite, curx, cury );
                break;
            }
            case 'H':
            {
                ptr = getCoord( ptr, tox );
                tox *= Conversion;
                curx = tox;
                svgLineTo(ite, curx, cury );
                break;
            }
            case 'v':
            {
                ptr = getCoord( ptr, toy );
                toy *= Conversion;
                cury = cury + toy;
                svgLineTo(ite, curx, cury );
                break;
            }
            case 'V':
            {
                ptr = getCoord( ptr, toy );
                toy *= Conversion;
                cury = toy;
                svgLineTo(ite,  curx, cury );
                break;
            }
            case 'z':
            case 'Z':
            {
                curx = subpathx;
                cury = subpathy;
                svgClosePath(ite);
                break;
            }
            case 'c':
                relative = true;
            case 'C':
            {
                ptr = getCoord( ptr, x1 );
                ptr = getCoord( ptr, y1 );
                ptr = getCoord( ptr, x2 );
                ptr = getCoord( ptr, y2 );
                ptr = getCoord( ptr, tox );
                ptr = getCoord( ptr, toy );
                tox *= Conversion;
                toy *= Conversion;
                x1 *= Conversion;
                y1 *= Conversion;
                x2 *= Conversion;
                y2 *= Conversion;
                px1 = relative ? curx + x1 : x1;
                py1 = relative ? cury + y1 : y1;
                px2 = relative ? curx + x2 : x2;
                py2 = relative ? cury + y2 : y2;
                px3 = relative ? curx + tox : tox;
                py3 = relative ? cury + toy : toy;
                svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
                contrlx = relative ? curx + x2 : x2;
                contrly = relative ? cury + y2 : y2;
                curx = relative ? curx + tox : tox;
                cury = relative ? cury + toy : toy;
                break;
            }
            case 's':
                relative = true;
            case 'S':
            {
                ptr = getCoord( ptr, x2 );
                ptr = getCoord( ptr, y2 );
                ptr = getCoord( ptr, tox );
                ptr = getCoord( ptr, toy );
                tox *= Conversion;
                toy *= Conversion;
                x2 *= Conversion;
                y2 *= Conversion;
                px1 = 2 * curx - contrlx;
                py1 = 2 * cury - contrly;
                px2 = relative ? curx + x2 : x2;
                py2 = relative ? cury + y2 : y2;
                px3 = relative ? curx + tox : tox;
                py3 = relative ? cury + toy : toy;
                svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
                contrlx = relative ? curx + x2 : x2;
                contrly = relative ? cury + y2 : y2;
                curx = relative ? curx + tox : tox;
                cury = relative ? cury + toy : toy;
                break;
            }
            case 'q':
                relative = true;
            case 'Q':
            {
                ptr = getCoord( ptr, x1 );
                ptr = getCoord( ptr, y1 );
                ptr = getCoord( ptr, tox );
                ptr = getCoord( ptr, toy );
                tox *= Conversion;
                toy *= Conversion;
                x1 *= Conversion;
                y1 *= Conversion;
                px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0);
                py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0);
                px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0);
                py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0);
                px3 = relative ? curx + tox : tox;
                py3 = relative ? cury + toy : toy;
                svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
                contrlx = relative ? curx + x1 : (tox + 2 * x1) * (1.0 / 3.0);
                contrly = relative ? cury + y1 : (toy + 2 * y1) * (1.0 / 3.0);
                curx = relative ? curx + tox : tox;
                cury = relative ? cury + toy : toy;
                break;
            }
            case 't':
                relative = true;
            case 'T':
            {
                ptr = getCoord(ptr, tox);
                ptr = getCoord(ptr, toy);
                tox *= Conversion;
                toy *= Conversion;
                xc = 2 * curx - contrlx;
                yc = 2 * cury - contrly;
                px1 = relative ? (curx + 2 * xc) * (1.0 / 3.0) : (curx + 2 * xc) * (1.0 / 3.0);
                py1 = relative ? (cury + 2 * yc) * (1.0 / 3.0) : (cury + 2 * yc) * (1.0 / 3.0);
                px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0);
                py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0);
                px3 = relative ? curx + tox : tox;
                py3 = relative ? cury + toy : toy;
                svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
                contrlx = xc;
                contrly = yc;
                curx = relative ? curx + tox : tox;
                cury = relative ? cury + toy : toy;
                break;
            }
            }
            lastCommand = command;
            if(*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9'))
            {
                // there are still coords in this command
                if(command == 'M')
                    command = 'L';
                else if(command == 'm')
                    command = 'l';
            }
            else
                command = *(ptr++);

            if( lastCommand != 'C' && lastCommand != 'c' &&
                    lastCommand != 'S' && lastCommand != 's' &&
                    lastCommand != 'Q' && lastCommand != 'q' &&
                    lastCommand != 'T' && lastCommand != 't')
            {
                contrlx = curx;
                contrly = cury;
            }
        }
        if ((lastCommand != 'z') && (lastCommand != 'Z'))
            ret = true;
        if (ite->size() > 2)
        {
            if ((ite->point(0).x() == ite->point(ite->size()-2).x()) && (ite->point(0).y() == ite->point(ite->size()-2).y()))
                ret = false;
        }
    }
    return ret;
}
示例#5
0
void ShapePlug::parseGroup(QDomNode &DOC)
{
    QString tmp = "";
    QString FillCol = "White";
    QString StrokeCol = "Black";
    QString defFillCol = "White";
    QString defStrokeCol = "Black";
    QColor stroke = Qt::black;
    QColor fill = Qt::white;
//	Qt::PenStyle Dash = Qt::SolidLine;
    Qt::PenCapStyle LineEnd = Qt::FlatCap;
    Qt::PenJoinStyle LineJoin = Qt::MiterJoin;
//	int fillStyle = 1;
    double strokewidth = 0.1;
//	bool poly = false;
    while(!DOC.isNull())
    {
        double x1, y1, x2, y2;
        StrokeCol = defStrokeCol;
        FillCol = defFillCol;
        stroke = Qt::black;
        fill = Qt::white;
        //	fillStyle = 1;
        strokewidth = 1.0;
        //	Dash = Qt::SolidLine;
        LineEnd = Qt::FlatCap;
        LineJoin = Qt::MiterJoin;
        FPointArray PoLine;
        PoLine.resize(0);
        QDomElement pg = DOC.toElement();
        QString STag = pg.tagName();
        QString style = pg.attribute( "style", "" ).simplified();
        if (style.isEmpty())
            style = pg.attribute( "svg:style", "" ).simplified();
        QStringList substyles = style.split(';', QString::SkipEmptyParts);
        for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it )
        {
            QStringList substyle = (*it).split(':', QString::SkipEmptyParts);
            QString command(substyle[0].trimmed());
            QString params(substyle[1].trimmed());
            if (command == "fill")
            {
                if (!((params == "foreground") || (params == "background") || (params == "fg") || (params == "bg") || (params == "none") || (params == "default") || (params == "inverse")))
                {
                    if (params == "nofill")
                        FillCol = CommonStrings::None;
                    else
                    {
                        fill.setNamedColor( params );
                        FillCol = "FromDia"+fill.name();
                        ScColor tmp;
                        tmp.fromQColor(fill);
                        tmp.setSpotColor(false);
                        tmp.setRegistrationColor(false);
                        QString fNam = m_Doc->PageColors.tryAddColor(FillCol, tmp);
                        if (fNam == FillCol)
                            importedColors.append(FillCol);
                        FillCol = fNam;
                    }
                }
            }
            else if (command == "stroke")
            {
                if (!((params == "foreground") || (params == "background") || (params == "fg") || (params == "bg") || (params == "none") || (params == "default")) || (params == "inverse"))
                {
                    stroke.setNamedColor( params );
                    StrokeCol = "FromDia"+stroke.name();
                    ScColor tmp;
                    tmp.fromQColor(stroke);
                    tmp.setSpotColor(false);
                    tmp.setRegistrationColor(false);
                    QString fNam = m_Doc->PageColors.tryAddColor(StrokeCol, tmp);
                    if (fNam == StrokeCol)
                        importedColors.append(StrokeCol);
                    StrokeCol = fNam;
                }
            }
            else if (command == "stroke-width")
                strokewidth = ScCLocale::toDoubleC(params);
            else if( command == "stroke-linejoin" )
            {
                if( params == "miter" )
                    LineJoin = Qt::MiterJoin;
                else if( params == "round" )
                    LineJoin = Qt::RoundJoin;
                else if( params == "bevel" )
                    LineJoin = Qt::BevelJoin;
            }
            else if( command == "stroke-linecap" )
            {
                if( params == "butt" )
                    LineEnd = Qt::FlatCap;
                else if( params == "round" )
                    LineEnd = Qt::RoundCap;
                else if( params == "square" )
                    LineEnd = Qt::SquareCap;
            }
        }
        if (STag == "svg:line")
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("x1")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("y1")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("x2")) * Conversion;
            y2 = ScCLocale::toDoubleC(pg.attribute("y2")) * Conversion;
            PoLine.addPoint(x1, y1);
            PoLine.addPoint(x1, y1);
            PoLine.addPoint(x2, y2);
            PoLine.addPoint(x2, y2);
            int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, strokewidth, CommonStrings::None, StrokeCol);
            m_Doc->Items->at(z)->PoLine = PoLine.copy();
            finishItem(m_Doc->Items->at(z));
        }
        else if (STag == "svg:rect")
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("x")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("y")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("width")) * Conversion;
            y2 = ScCLocale::toDoubleC(pg.attribute("height")) * Conversion;
            int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + x1, baseY + y1, x2, y2, strokewidth, FillCol, StrokeCol);
            m_Doc->Items->at(z)->setLineJoin(LineJoin);
            m_Doc->Items->at(z)->setLineEnd(LineEnd);
            finishItem(m_Doc->Items->at(z));
        }
        else if ((STag == "svg:polygon") || (STag == "svg:polyline"))
        {
            bool bFirst = true;
            double x = 0.0;
            double y = 0.0;
            QString points = pg.attribute( "points" ).simplified().replace(',', " ");
            QStringList pointList = points.split(' ', QString::SkipEmptyParts);
            FirstM = true;
            for( QStringList::Iterator it = pointList.begin(); it != pointList.end(); it++ )
            {
                x = ScCLocale::toDoubleC(*(it++));
                y = ScCLocale::toDoubleC(*it);
                if( bFirst )
                {
                    svgMoveTo(x * Conversion, y * Conversion);
                    bFirst = false;
                    WasM = true;
                }
                else
                {
                    svgLineTo(&PoLine, x * Conversion, y * Conversion);
                }
            }
            if (STag == "svg:polygon")
                svgClosePath(&PoLine);
            if (PoLine.size() < 4)
            {
                DOC = DOC.nextSibling();
                continue;
            }
            int z;
            if (STag == "svg:polygon")
                z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, strokewidth, FillCol, StrokeCol);
            else
                z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, strokewidth, CommonStrings::None, StrokeCol);
            m_Doc->Items->at(z)->PoLine = PoLine.copy();
            finishItem(m_Doc->Items->at(z));
        }
        else if ((STag == "svg:circle") || (STag == "svg:ellipse"))
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("r")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("r")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("cx")) * Conversion - x1;
            y2 = ScCLocale::toDoubleC(pg.attribute("cy")) * Conversion - y1;
            x1 *= 2.0;
            y1 *= 2.0;
            int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + x1, baseY + y1, x2, y2, strokewidth, FillCol, StrokeCol);
            m_Doc->Items->at(z)->setLineJoin(LineJoin);
            m_Doc->Items->at(z)->setLineEnd(LineEnd);
            finishItem(m_Doc->Items->at(z));
        }
        else if (STag == "svg:path")
        {
            //	poly =
            parseSVG( pg.attribute( "d" ), &PoLine );
            if (PoLine.size() < 4)
            {
                DOC = DOC.nextSibling();
                continue;
            }
            int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, strokewidth, FillCol, StrokeCol);
            m_Doc->Items->at(z)->PoLine = PoLine.copy();
            finishItem(m_Doc->Items->at(z));
        }
        else if (STag == "svg:g")
        {
            int z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, baseX, baseX, 1, 1, 0, CommonStrings::None, CommonStrings::None);
            PageItem *neu = m_Doc->Items->at(z);
            Elements.append(neu);
            if (groupStack.count() > 0)
                groupStack.top().append(neu);
            QList<PageItem*> gElements;
            groupStack.push(gElements);
            QDomNode child = DOC.firstChild();
            parseGroup(child);
            if (gElements.count() == 0)
            {
                groupStack.pop();
                Elements.removeAll(neu);
                groupStack.top().removeAll(neu);
                Selection tmpSelection(m_Doc, false);
                tmpSelection.addItem(neu);
                m_Doc->itemSelection_DeleteItem(&tmpSelection);
            }
            else
            {
                QList<PageItem*> gElem = groupStack.pop();
                double minx =  std::numeric_limits<double>::max();
                double miny =  std::numeric_limits<double>::max();
                double maxx = -std::numeric_limits<double>::max();
                double maxy = -std::numeric_limits<double>::max();
                for (int gr = 0; gr < gElements.count(); ++gr)
                {
                    PageItem* currItem = gElem.at(gr);
                    double x1, x2, y1, y2;
                    currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
                    minx = qMin(minx, x1);
                    miny = qMin(miny, y1);
                    maxx = qMax(maxx, x2);
                    maxy = qMax(maxy, y2);
                }
                double gx = minx;
                double gy = miny;
                double gw = maxx - minx;
                double gh = maxy - miny;
                neu->setXYPos(gx, gy, true);
                neu->setWidthHeight(gw, gh, true);
                neu->SetRectFrame();
                neu->Clip = FlattenPath(neu->PoLine, neu->Segments);
                neu->setItemName( tr("Group%1").arg(m_Doc->GroupCounter));
                neu->AutoName = false;
                neu->gXpos = neu->xPos() - gx;
                neu->gYpos = neu->yPos() - gy;
                neu->groupWidth = gw;
                neu->groupHeight = gh;
                for (int gr = 0; gr < gElem.count(); ++gr)
                {
                    PageItem* currItem = gElem.at(gr);
                    currItem->gXpos = currItem->xPos() - gx;
                    currItem->gYpos = currItem->yPos() - gy;
                    currItem->gWidth = gw;
                    currItem->gHeight = gh;
                    currItem->Parent = neu;
                    neu->groupItemList.append(currItem);
                    m_Doc->Items->removeAll(currItem);
                    Elements.removeAll(currItem);
                }
                neu->setRedrawBounding();
                neu->setTextFlowMode(PageItem::TextFlowDisabled);
                m_Doc->GroupCounter++;
            }
        }
        DOC = DOC.nextSibling();
    }
}