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

📄 q3paintengine_svg.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
{    QPolygonF poly;    for (int i = 0; i < pointCount; ++i)        poly << points[i];    drawPolygon(poly.constData(), pointCount, mode);}void Q3SVGPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF & /* sr */){    Q_D(Q3SVGPaintEngine);    QDomElement e = d->doc.createElement(QLatin1String("image"));    e.setAttribute(QLatin1String("x"), r.x());    e.setAttribute(QLatin1String("y"), r.y());    e.setAttribute(QLatin1String("width"), r.width());    e.setAttribute(QLatin1String("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(QLatin1String("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(QLatin1String("x"), p.x());    e.setAttribute(QLatin1String("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(QLatin1String("image"));    e.setAttribute(QLatin1String("x"), r.x());    e.setAttribute(QLatin1String("y"), r.y());    e.setAttribute(QLatin1String("width"), r.width());    e.setAttribute(QLatin1String("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(QLatin1String(".svg")) ?                      fileName.left(fileName.length()-4) : fileName;    // now we have the info about name and dimensions available    QDomElement root = d->doc.documentElement();    root.setAttribute(QLatin1String("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(QLatin1String("x"), d->brect.x());    root.setAttribute(QLatin1String("y"), d->brect.y());    root.setAttribute(QLatin1String("width"), d->brect.width() + d->brect.x());    root.setAttribute(QLatin1String("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(QLatin1String("%1_%2.png")).arg(svgName).arg(icount);        (*iit).image.save(href, "PNG");        (*iit).element.setAttribute(QLatin1String("xlink:href"), href);        icount++;    }    PixmapList::Iterator pit = d->pixmaps.begin();    for (; pit != d->pixmaps.end(); ++pit) {        QString href = QString(QLatin1String("%1_%2.png")).arg(svgName).arg(icount);        (*pit).pixmap.save(href, "PNG");        (*pit).element.setAttribute(QLatin1String("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(QLatin1String("g"));            ne.setAttribute(QLatin1String("style"), QString(QLatin1String("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() != QLatin1String("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(QLatin1String("fill:rgb(%1,%2,%3);")).arg(pcol.red()).arg(pcol.green()).arg(pcol.blue());        s += QString(QLatin1String("stroke-width:0;"));        QFont f = cfont;        QFontInfo fi(f);        s += QString(QLatin1String("font-size:%1;")).arg(fi.pointSize());        s += QString(QLatin1String("font-style:%1;")).arg(f.italic() ? QLatin1String("italic") : QLatin1String("normal"));        // not a very scientific distribution        QString fw;        if (f.weight() <= QFont::Light)            fw = QLatin1String("100");        else if (f.weight() <= QFont::Normal)            fw = QLatin1String("400");        else if (f.weight() <= QFont::DemiBold)            fw = QLatin1String("600");        else if (f.weight() <= QFont::Bold)            fw = QLatin1String("700");        else if (f.weight() <= QFont::Black)            fw = QLatin1String("800");        else            fw = QLatin1String("900");        s += QString(QLatin1String("font-weight:%1;")).arg(fw);        s += QString(QLatin1String("font-family:%1;")).arg(f.family());    } else {        s += QString(QLatin1String("stroke:rgb(%1,%2,%3);")).arg(pcol.red()).arg(pcol.green()).arg(pcol.blue());        if (pcol.alpha() != 255)            s += QString(QLatin1String("stroke-opacity:%1;")).arg(pcol.alpha()/255.0);        if (bcol.alpha() != 255)            s += QString(QLatin1String("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(QLatin1String("stroke-width:%1;")).arg(pw);        if (cpen.style() == Qt::DashLine)            s+= QString(QLatin1String("stroke-dasharray:18,6;"));        else if (cpen.style() == Qt::DotLine)            s+= QString(QLatin1String("stroke-dasharray:3;"));        else if (cpen.style() == Qt::DashDotLine)            s+= QString(QLatin1String("stroke-dasharray:9,6,3,6;"));        else if (cpen.style() == Qt::DashDotDotLine)            s+= QString(QLatin1String("stroke-dasharray:9,3,3;"));        if (cbrush.style() == Qt::NoBrush || c == QPicturePrivate::PdcDrawPolyline || c == QPicturePrivate::PdcDrawCubicBezier)            s += QLatin1String("fill:none;"); // Qt polylines use no brush, neither do Beziers        else            s += QString(QLatin1String("fill:rgb(%1,%2,%3);")).arg(bcol.red()).arg(bcol.green()).arg(bcol.blue());    }    e->setAttribute(QLatin1String("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(QLatin1String("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(QLatin1String("scale(%1,%2)")).arg(m.m11()).arg(m.m22());        else            s = QString(QLatin1String("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(QLatin1String("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(QLatin1String("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, QLatin1String("x"));    int y = d->lenToInt(attr, QLatin1String("y"));    d->brect.setX(x);    d->brect.setY(y);    QString wstr = attr.contains(QLatin1String("width"))                   ? attr.namedItem(QLatin1String("width")).nodeValue() : QString(QLatin1String("100%"));    QString hstr = attr.contains(QLatin1String("height"))                   ? attr.namedItem(QLatin1String("height")).nodeValue() : QString(QLatin1String("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(QLatin1String("viewBox"))) {        QRegExp re(QString::fromLatin1("\\s*(\\S+)\\s*,?\\s*(\\S+)\\s*,?"),                                       "\\s*(\\S+)\\s*,?\\s*(\\S+)\\s*");        if (re.indexIn(attr.namedItem(QLatin1String("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    },

⌨️ 快捷键说明

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