⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 q3paintengine_svg.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        index += reg.matchedLength();    }}/*!    \internal    Push the current drawing attributes on a stack.    \sa restoreAttributes()*/void Q3SVGPaintEnginePrivate::saveAttributes(QPainter *pt){    pt->save();    // copy old state    Q3SVGPaintEngineState st(*curr);    stack.append(st);    curr = &stack.last();}/*!    \internal    Pop the current drawing attributes off the stack.    \sa saveAttributes()*/void Q3SVGPaintEnginePrivate::restoreAttributes(QPainter *pt){    pt->restore();    Q_ASSERT(stack.count() > 1);    stack.removeLast();    curr = &stack.last();}void Q3SVGPaintEnginePrivate::setStyle(const QString &s, QPainter *pt){    QStringList rules = s.split(QLatin1Char(';'), QString::SkipEmptyParts);    QPen pen = pt->pen();    QFont font = pt->font();    QStringList::ConstIterator it = rules.constBegin();    for (; it != rules.constEnd(); it++) {        int col = (*it).indexOf(QLatin1Char(':'));        if (col > 0) {            QString prop = (*it).left(col).simplified();            QString val = (*it).right((*it).length() - col - 1);            val = val.toLower().trimmed();            setStyleProperty(prop, val, &pen, &font, &curr->textalign, pt);        }    }    pt->setPen(pen);    pt->setFont(font);}void Q3SVGPaintEnginePrivate::setStyleProperty(const QString &prop, const QString &val, QPen *pen,                                       QFont *font, int *talign, QPainter *pt){    if (prop == QLatin1String("stroke")) {        if (val == QLatin1String("none")) {            pen->setStyle(Qt::NoPen);        } else {            pen->setColor(parseColor(val));            if (pen->style() == Qt::NoPen)                pen->setStyle(Qt::SolidLine);            if (pen->width() == 0)                pen->setWidth(1);        }    } else if (prop == QLatin1String("stroke-opacity")) {        double opacity = parseLen(val);        QColor c = pen->color();        c.setAlpha((int)(opacity*255));        pen->setColor(c);    } else if (prop == QLatin1String("fill-opacity")) {        double opacity = parseLen(val);        QColor c = pt->brush().color();        c.setAlpha((int)(opacity*255));        pt->setBrush(c);    } else if (prop == QLatin1String("stroke-width")) {        double w = parseLen(val);        if (w > 0.0001)            pen->setWidth(int(w));        else            pen->setStyle(Qt::NoPen);    } else if (prop == QLatin1String("stroke-linecap")) {        if (val == QLatin1String("butt"))            pen->setCapStyle(Qt::FlatCap);        else if (val == QLatin1String("round"))            pen->setCapStyle(Qt::RoundCap);        else if (val == QLatin1String("square"))            pen->setCapStyle(Qt::SquareCap);    } else if (prop == QLatin1String("stroke-linejoin")) {        if (val == QLatin1String("miter"))            pen->setJoinStyle(Qt::MiterJoin);        else if (val == QLatin1String("round"))            pen->setJoinStyle(Qt::RoundJoin);        else if (val == QLatin1String("bevel"))            pen->setJoinStyle(Qt::BevelJoin);    } else if (prop == QLatin1String("stroke-dasharray")) {        if (val == QLatin1String("18,6"))            pen->setStyle(Qt::DashLine);        else if (val == QLatin1String("3"))            pen->setStyle(Qt::DotLine);        else if (val == QLatin1String("9,6,3,6"))            pen->setStyle(Qt::DashDotLine);        else if (val == QLatin1String("9,3,3"))            pen->setStyle(Qt::DashDotDotLine);    } else if (prop == QLatin1String("fill")) {        if (val == QLatin1String("none"))            pt->setBrush(Qt::NoBrush);        else            pt->setBrush(parseColor(val));    } else if (prop == QLatin1String("font-size")) {        font->setPixelSize(qRound(parseLen(val)));    } else if (prop == QLatin1String("font-family")) {        font->setFamily(val);    } else if (prop == QLatin1String("font-style")) {        if (val == QLatin1String("normal"))            font->setItalic(false);        else if (val == QLatin1String("italic"))            font->setItalic(true);        else            qWarning("QSvgDevice::setStyleProperty: unhandled font-style: %s", val.latin1());    } else if (prop == QLatin1String("font-weight")) {        int w = font->weight();        // no exact equivalents so we have to QLatin1String("round") a little bit        if (val == QLatin1String("100") || val == QLatin1String("200"))            w = QFont::Light;        if (val == QLatin1String("300") || val == QLatin1String("400") || val == QLatin1String("normal"))            w = QFont::Normal;        else if (val == QLatin1String("500") || val == QLatin1String("600"))            w = QFont::DemiBold;        else if (val == QLatin1String("700") || val == QLatin1String("bold") || val == QLatin1String("800"))            w = QFont::Bold;        else if (val == QLatin1String("900"))            w = QFont::Black;        font->setWeight(w);    } else if (prop == QLatin1String("text-anchor")) {        if (val == QLatin1String("middle"))            *talign = Qt::AlignHCenter;        else if (val == QLatin1String("end"))            *talign = Qt::AlignRight;        else            *talign = Qt::AlignLeft;    }}void Q3SVGPaintEnginePrivate::drawPath(const QString &data, QPainter *pt){    double x0 = 0, y0 = 0;              // starting point    double x = 0, y = 0;                // current point    QPointF ctrlPt;    QPainterPath path;                  // resulting path    int idx = 0;                        // current data position    int mode = 0, lastMode = 0;         // parser state    bool relative = false;              // e.g. 'h' vs. 'H'    QString commands(QLatin1String("MZLHVCSQTA"));     // recognized commands    int cmdArgs[] = { 2, 0, 2, 1, 1, 6, 4, 4, 2, 7 };                   // no of arguments    QRegExp reg(QString::fromLatin1("\\s*,?\\s*([+-]?\\d*\\.?\\d*)"));  // floating point    // detect next command    while (idx < data.length()) {        QChar ch = data[(int)idx++];        if (ch.isSpace())            continue;        QChar chUp = ch.toUpper();        int cmd = commands.indexOf(chUp);        if (cmd >= 0) {            // switch to new command mode            mode = cmd;            relative = (ch != chUp);                // e.g. 'm' instead of 'M'        } else {            if (mode && !ch.isLetter()) {                cmd = mode;                        // continue in previous mode                idx--;            } else {                qWarning("Q3SVGPaintEngine::drawPath: Unknown command");                return;            }        }        // read in the required number of arguments        const int maxArgs = 7;        double arg[maxArgs];        int numArgs = cmdArgs[cmd];        for (int i = 0; i < numArgs; i++) {            int pos = reg.indexIn(data, idx);            if (pos == -1) {                qWarning("Q3SVGPaintEngine::drawPath: Error parsing arguments");                return;            }            arg[i] = reg.cap(1).toDouble();            idx = pos + reg.matchedLength();        };        // process command        double offsetX = relative ? x : 0;        // correction offsets        double offsetY = relative ? y : 0;        // for relative commands        switch (mode) {        case 0:                                        // 'M' move to            x = x0 = arg[0] + offsetX;            y = y0 = arg[1] + offsetY;            path.moveTo(x0, y0);            mode = 2;                                  // -> 'L'            break;        case 1:                                        // 'Z' close path            x = x0;            y = y0;            path.closeSubpath();            mode = 0;            break;        case 2:                                        // 'L' line to            x = arg[0] + offsetX;            y = arg[1] + offsetY;            path.lineTo(x, y);            break;        case 3:                                        // 'H' horizontal line            x = arg[0] + offsetX;            path.lineTo(x, y);            break;        case 4:                                        // 'V' vertical line            y = arg[0] + offsetY;            path.lineTo(x, y);            break;        case 5: {                                        // 'C' cubic bezier curveto            QPointF c1(arg[0]+offsetX, arg[1]+offsetY);            QPointF c2(arg[2]+offsetX, arg[3]+offsetY);            QPointF e(arg[4]+offsetX, arg[5]+offsetY);            path.cubicTo(c1, c2, e);            ctrlPt = c2;            x = e.x();            y = e.y();            break;        }        case 6: {                                        // 'S' smooth shorthand            QPointF c1;            if (lastMode == 5 || lastMode == 6)                c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());            else                c1 = QPointF(x, y);            QPointF c2(arg[0]+offsetX, arg[1]+offsetY);            QPointF e(arg[2]+offsetX, arg[3]+offsetY);            path.cubicTo(c1, c2, e);            ctrlPt = c2;            x = e.x();            y = e.y();            break;        }        case 7: {                                        // 'Q' quadratic bezier curves            QPointF c(arg[0]+offsetX, arg[1]+offsetY);            QPointF e(arg[2]+offsetX, arg[3]+offsetY);            path.quadTo(c, e);            ctrlPt = c;            x = e.x();            y = e.y();            break;        }        case 8: {                                      // 'T' smooth shorthand            QPointF e(arg[0]+offsetX, arg[1]+offsetY);            QPointF c;            if (lastMode == 7 || lastMode == 8)                c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());            else                c = QPointF(x, y);            path.quadTo(c, e);            ctrlPt = c;            x = e.x();            y = e.y();            break;        }        case 9:                                        // 'A' elliptical arc curve            // ### just a straight line            x = arg[5] + offsetX;            y = arg[6] + offsetY;            path.lineTo(x, y);            break;        };        lastMode = mode;    }    pt->drawPath(path);}/*!    \internal    Parses a CSS2-compatible color specification. Either a keyword or    a numerical RGB specification like #ff00ff or rgb(255,0,50%).*/QColor Q3SVGPaintEnginePrivate::parseColor(const QString &col){    static const struct ColorTable {        const char *name;        const char *rgb;    } coltab[] = {        { "black",   "#000000" },        { "silver",  "#c0c0c0" },        { "gray",    "#808080" },        { "white",   "#ffffff" },        { "maroon",  "#800000" },        { "red",     "#ff0000" },        { "purple",  "#800080" },        { "fuchsia", "#ff00ff" },        { "green",   "#008000" },        { "lime",    "#00ff00" },        { "olive",   "#808000" },        { "yellow",  "#ffff00" },        { "navy",    "#000080" },        { "blue",    "#0000ff" },        { "teal",    "#008080" },        { "aqua",    "#00ffff" },        // ### the latest spec has more        { 0,         0         }    };    // initialize color map on first use    if (!qSvgColMap) {        qSvgColMap = new QMap<QString,QString>;        const struct ColorTable *t = coltab;        while (t->name) {            qSvgColMap->insert(QLatin1String(t->name), QLatin1String(t->rgb));            ++t;        }    }    // a keyword?    if (qSvgColMap->contains(col))        return QColor((*qSvgColMap)[col]);    // in rgb(r,g,b) form ?    QString c = col;    c.replace(QRegExp(QString::fromLatin1("\\s*")), QLatin1String(""));    QRegExp reg(QString::fromLatin1("^rgb\\((\\d+)(%?),(\\d+)(%?),(\\d+)(%?)\\)$"));    if (reg.indexIn(c) >= 0) {        int comp[3];        for (int i = 0; i < 3; i++) {            comp[i] = reg.cap(2*i+1).toInt();            if (!reg.cap(2*i+2).isEmpty())                // percentage ?                comp[i] = int((double(255*comp[i])/100.0));        }        return QColor(comp[0], comp[1], comp[2]);    }    // check for predefined Qt color objects, #RRGGBB and #RGB    return QColor(col);}static QString qt_svg_compose_path(const QPainterPath &path){    QString str, tmp;    for (int i = 0; i < path.elementCount(); ++i) {        const QPainterPath::Element &elm = path.elementAt(i);        switch (elm.type) {        case QPainterPath::LineToElement:            tmp.sprintf("L %f %f ", elm.x, elm.y);            str += tmp;            break;        case QPainterPath::MoveToElement:            tmp.sprintf("M %f %f ", elm.x, elm.y);            str += tmp;            break;        case QPainterPath::CurveToElement:        {            Q_ASSERT(path.elementCount() > i+2);            const QPainterPath::Element cd1 = path.elementAt(i+1);            const QPainterPath::Element cd2 = path.elementAt(i+2);            Q_ASSERT(cd1.type == QPainterPath::CurveToDataElement                     && cd2.type == QPainterPath::CurveToDataElement);            tmp.sprintf("C %f %f %f %f %f %f ", elm.x, elm.y, cd1.x, cd1.y, cd2.x, cd2.y);            str += tmp;            i += 2;            break;        }        default:            break;        }    }    return str;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -