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

📄 q3paintengine_svg.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    QDomElement e = d->doc.createElement("image");    e.setAttribute("x", r.x());    e.setAttribute("y", r.y());    e.setAttribute("width", r.width());    e.setAttribute("height", r.height());    QPixElement pe;    pe.element = e;    pe.pixmap = pm;    d->pixmaps.append(pe);    // saving to disk and setting the xlink:href attribute will be    // done later in save() once we now the svg document name.    d->appendChild(e, QPicturePrivate::PdcDrawPixmap);}void Q3SVGPaintEngine::drawTiledPixmap(const QRectF & /* r */, const QPixmap & /* pixmap */,                                      const QPointF & /* s */){}void Q3SVGPaintEngine::drawTextItem(const QPointF &p, const QTextItem &ti){    Q_D(Q3SVGPaintEngine);    QDomElement e = d->doc.createElement("text");//     int x, y;//     const QRect r(p.x(), p.y(), ti.width, ti.ascent + ti.descent);    // horizontal text alignment //    if ((ti.flags & Qt::AlignHCenter) != 0) {//         x = r.x() + r.width() / 2;//         e.setAttribute("text-anchor", "middle");//     } else if ((textflags & Qt::AlignRight) != 0) {//         x = r.right();//         e.setAttribute("text-anchor", "end");//     } else {//         x = r.x();//     }//     // vertical text alignment//     if ((textflags & Qt::AlignVCenter) != 0)//         y = r.y() + (r.height() + ti.ascent) / 2;//     else if ((textflags & Qt::AlignBottom) != 0)//         y = r.bottom();//     else//         y = r.y() + ti.ascent;//     if (x)//         e.setAttribute("x", x);//     if (y)//         e.setAttribute("y", y);    e.setAttribute("x", p.x());    e.setAttribute("y", p.y());    e.appendChild(d->doc.createTextNode(ti.text()));}void Q3SVGPaintEngine::drawImage(const QRectF &r, const QImage &im,                                 const QRectF &, Qt::ImageConversionFlags){    Q_D(Q3SVGPaintEngine);    QDomElement e = d->doc.createElement("image");    e.setAttribute("x", r.x());    e.setAttribute("y", r.y());    e.setAttribute("width", r.width());    e.setAttribute("height", r.height());    QImgElement ie;    ie.element = e;    ie.image = im;    d->images.append(ie);    // saving to disk and setting the xlink:href attribute will be    // done later in save() once we now the svg document name.    d->appendChild(e, QPicturePrivate::PdcDrawImage);}/*!    Returns the SVG as a single string of XML.*/QString Q3SVGPaintEngine::toString() const{    Q_D(const Q3SVGPaintEngine);    if (d->doc.isNull())        return QString();    return d->doc.toString();}/*!    Saves the SVG to \a fileName.*/bool Q3SVGPaintEngine::save(const QString &fileName){    Q_D(Q3SVGPaintEngine);    // guess svg id from fileName    QString svgName = fileName.endsWith(".svg") ?                      fileName.left(fileName.length()-4) : fileName;    // now we have the info about name and dimensions available    QDomElement root = d->doc.documentElement();    root.setAttribute("id", svgName);    // the standard doesn't take respect x and y. But we want a    // proper bounding rect. We make width and height bigger when    // writing out and subtract x and y when reading in.    root.setAttribute("x", d->brect.x());    root.setAttribute("y", d->brect.y());    root.setAttribute("width", d->brect.width() + d->brect.x());    root.setAttribute("height", d->brect.height() + d->brect.y());    // ... and know how to name any image files to be written out    int icount = 0;    ImageList::Iterator iit = d->images.begin();    for (; iit != d->images.end(); ++iit) {        QString href = QString("%1_%2.png").arg(svgName).arg(icount);        (*iit).image.save(href, "PNG");        (*iit).element.setAttribute("xlink:href", href);        icount++;    }    PixmapList::Iterator pit = d->pixmaps.begin();    for (; pit != d->pixmaps.end(); ++pit) {        QString href = QString("%1_%2.png").arg(svgName).arg(icount);        (*pit).pixmap.save(href, "PNG");        (*pit).element.setAttribute("xlink:href", href);        icount++;    }    QFile f(fileName);    if (!f.open (QIODevice::WriteOnly))        return false;    QTextStream s(&f);    s.setEncoding(QTextStream::UnicodeUTF8);    s << d->doc;    return true;}/*!    \overload    \a dev is the device to use for saving.*/bool Q3SVGPaintEngine::save(QIODevice *dev){    Q_D(Q3SVGPaintEngine);#if defined(CHECK_RANGE)    if (!d->images.isEmpty() || !d->pixmaps.isEmpty())        qWarning("Q3SVGPaintEngine::save: skipping external images");#endif    QTextStream s(dev);    s.setEncoding(QTextStream::UnicodeUTF8);    s << d->doc;    return true;}/*!    Sets the bounding rectangle of the SVG to rectangle \a r.*/void Q3SVGPaintEngine::setBoundingRect(const QRect &r){    d_func()->brect = r;}/*!    Returns the SVG's bounding rectangle.*/QRect Q3SVGPaintEngine::boundingRect() const{    return d_func()->brect;}/*!    Loads and parses a SVG from \a dev into the device. Returns true    on success (i.e. loaded and parsed without error); otherwise    returns false.*/bool Q3SVGPaintEngine::load(QIODevice *dev){    return d_func()->doc.setContent(dev);}void Q3SVGPaintEnginePrivate::appendChild(QDomElement &e, QPicturePrivate::PaintCommand c){    if (!e.isNull()) {        current.appendChild(e);        if (c == QPicturePrivate::PdcSave)            current = e;        // ### optimize application of attributes utilizing <g>        if (c == QPicturePrivate::PdcSetClipRegion || c == QPicturePrivate::PdcSetClipPath) {            QDomElement ne;            ne = doc.createElement("g");            ne.setAttribute("style", QString("clip-path:url(#clip%1)").arg(currentClip));            if (dirtyTransform) {                applyTransform(&ne);                dirtyTransform = false;            }            current.appendChild(ne);            current = ne;        } else {            if (dirtyStyle)                // only reset when entering                applyStyle(&e, c);        // or leaving a <g> tag            if (dirtyTransform && e.tagName() != "g") {                // same as above but not for <g> tags                applyTransform(&e);                if (c == QPicturePrivate::PdcSave)                    dirtyTransform = false;            }        }    }}void Q3SVGPaintEnginePrivate::applyStyle(QDomElement *e, QPicturePrivate::PaintCommand c) const{    // ### do not write every attribute each time    QColor pcol = cpen.color();    QColor bcol = cbrush.color();    QString s;    if (c == QPicturePrivate::PdcDrawText2 || c == QPicturePrivate::PdcDrawText2Formatted) {        // QPainter has a reversed understanding of pen/stroke vs.        // brush/fill for text        s += QString("fill:rgb(%1,%2,%3);").arg(pcol.red()).arg(pcol.green()).arg(pcol.blue());        s += QString("stroke-width:0;");        QFont f = cfont;        QFontInfo fi(f);        s += QString("font-size:%1;").arg(fi.pointSize());        s += QString("font-style:%1;").arg(f.italic() ? "italic" : "normal");        // not a very scientific distribution        QString fw;        if (f.weight() <= QFont::Light)            fw = "100";        else if (f.weight() <= QFont::Normal)            fw = "400";        else if (f.weight() <= QFont::DemiBold)            fw = "600";        else if (f.weight() <= QFont::Bold)            fw = "700";        else if (f.weight() <= QFont::Black)            fw = "800";        else            fw = "900";        s += QString("font-weight:%1;").arg(fw);        s += QString("font-family:%1;").arg(f.family());    } else {        s += QString("stroke:rgb(%1,%2,%3);").arg(pcol.red()).arg(pcol.green()).arg(pcol.blue());        if (pcol.alpha() != 255)            s += QString("stroke-opacity:%1;").arg(pcol.alpha()/255.0);        if (bcol.alpha() != 255)            s += QString("fill-opacity:%1;").arg(bcol.alpha()/255.0);        double pw = cpen.width();        if (pw == 0 && cpen.style() != Qt::NoPen)            pw = 0.9;        if (c == QPicturePrivate::PdcDrawLine)            pw /= (qAbs(worldMatrix.m11()) + qAbs(worldMatrix.m22())) / 2.0;        s += QString("stroke-width:%1;").arg(pw);        if (cpen.style() == Qt::DashLine)            s+= QString("stroke-dasharray:18,6;");        else if (cpen.style() == Qt::DotLine)            s+= QString("stroke-dasharray:3;");        else if (cpen.style() == Qt::DashDotLine)            s+= QString("stroke-dasharray:9,6,3,6;");        else if (cpen.style() == Qt::DashDotDotLine)            s+= QString("stroke-dasharray:9,3,3;");        if (cbrush.style() == Qt::NoBrush || c == QPicturePrivate::PdcDrawPolyline || c == QPicturePrivate::PdcDrawCubicBezier)            s += "fill:none;"; // Qt polylines use no brush, neither do Beziers        else            s += QString("fill:rgb(%1,%2,%3);").arg(bcol.red()).arg(bcol.green()).arg(bcol.blue());    }    e->setAttribute("style", s);}void Q3SVGPaintEnginePrivate::applyTransform(QDomElement *e) const{    QMatrix m = worldMatrix;    QString s;    bool rot = (m.m11() != 1.0 || m.m12() != 0.0 ||                 m.m21() != 0.0 || m.m22() != 1.0);    if (!rot && (m.dx() != 0.0 || m.dy() != 0.0)) {        s = QString("translate(%1,%2)").arg(m.dx()).arg(m.dy());    } else if (rot) {        if (m.m12() == 0.0 && m.m21() == 0.0 &&             m.dx() == 0.0 && m.dy() == 0.0)            s = QString("scale(%1,%2)").arg(m.m11()).arg(m.m22());        else            s = QString("matrix(%1,%2,%3,%4,%5,%6)")                .arg(m.m11()).arg(m.m12())                .arg(m.m21()).arg(m.m22())                .arg(m.dx()).arg(m.dy());    } else {        return;    }    e->setAttribute("transform", s);}bool Q3SVGPaintEngine::play(QPainter *pt){    Q_D(Q3SVGPaintEngine);    if (!pt) {        Q_ASSERT(pt);        return false;    }    if (d->dev == 0)        d->dev = pt->device();    d->wwidth = pt->window().width();    d->wheight = pt->window().height();    pt->setPen(Qt::NoPen); // SVG default pen and brush    pt->setBrush(Qt::black);    if (d->doc.isNull()) {        qWarning("Q3SVGPaintEngine::play: No SVG data set.");        return false;    }    QDomNode svg = d->doc.namedItem("svg");    if (svg.isNull() || !svg.isElement()) {        qWarning("Q3SVGPaintEngine::play: Couldn't find any svg element.");        return false;    }    // force transform to be activated in case our sequences    // are replayed later with a transformed painter    pt->setWorldXForm(true);    QDomNamedNodeMap attr = svg.attributes();    int x = d->lenToInt(attr, "x");    int y = d->lenToInt(attr, "y");    d->brect.setX(x);    d->brect.setY(y);    QString wstr = attr.contains("width")                   ? attr.namedItem("width").nodeValue() : QString("100%");    QString hstr = attr.contains("height")                   ? attr.namedItem("height").nodeValue() : QString("100%");    double width = d->parseLen(wstr, 0, true);    double height = d->parseLen(hstr, 0, false);    // SVG doesn't respect x and y. But we want a proper bounding rect.    d->brect.setWidth(int(width) - x);    d->brect.setHeight(int(height) - y);    pt->setClipRect(d->brect);    if (attr.contains("viewBox")) {        QRegExp re(QString::fromLatin1("\\s*(\\S+)\\s*,?\\s*(\\S+)\\s*,?"                                       "\\s*(\\S+)\\s*,?\\s*(\\S+)\\s*"));        if (re.indexIn(attr.namedItem("viewBox").nodeValue()) < 0) {            qWarning("Q3SVGPaintEngine::play: Invalid viewBox attribute.");            return false;        } else {            double x = re.cap(1).toDouble();            double y = re.cap(2).toDouble();            double w = re.cap(3).toDouble();            double h = re.cap(4).toDouble();            if (w < 0 || h < 0) {                qWarning("Q3SVGPaintEngine::play: Invalid viewBox dimension.");                return false;            } else if (w == 0 || h == 0) {                return true;            }            pt->scale(width/w, height/h);            pt->translate(-x, -y);        }    }    const struct ElementTable {        const char *name;        ElementType type;    } etab[] = {        {"a",        AnchorElement  },        {"#comment", CommentElement },        {"circle",   CircleElement  },        {"clipPath", ClipElement    },        {"desc",     DescElement    },        {"ellipse",  EllipseElement },        {"g",        GroupElement   },        {"image",    ImageElement   },        {"line",     LineElement    },        {"polyline", PolylineElement},        {"polygon",  PolygonElement },        {"path",     PathElement    },

⌨️ 快捷键说明

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