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

📄 qsvggenerator.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtSVG module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qsvggenerator.h"#include "qpainterpath.h"#include "private/qpaintengine_p.h"#include "private/qtextengine_p.h"#include "qfile.h"#include "qtextstream.h"#include "qbuffer.h"#include "qdebug.h"static void translate_color(const QColor &color, QString *color_string,                            QString *opacity_string){    Q_ASSERT(color_string);    Q_ASSERT(opacity_string);    *color_string =        QString::fromLatin1("#%1%2%3")        .arg(color.red(), 2, 16, QLatin1Char('0'))        .arg(color.green(), 2, 16, QLatin1Char('0'))        .arg(color.blue(), 2, 16, QLatin1Char('0'));    *opacity_string = QString::number(color.alphaF());}static void translate_dashPattern(QVector<qreal> pattern, const qreal& width, QString *pattern_string){    Q_ASSERT(pattern_string);    // Note that SVG operates in absolute lengths, whereas Qt uses a length/width ratio.    foreach (qreal entry, pattern)        *pattern_string += QString::fromLatin1("%1,").arg(entry * width);    pattern_string->chop(1);}class QSvgPaintEnginePrivate : public QPaintEnginePrivate{public:    QSvgPaintEnginePrivate()    {        size = QSize(100, 100);        outputDevice = 0;        resolution = 72;        attributes.document_title = QLatin1String("Qt Svg Document");        attributes.document_description = QLatin1String("Generated with Qt");        attributes.font_family = QLatin1String("serif");        attributes.font_size = QLatin1String("10pt");        attributes.font_style = QLatin1String("normal");        attributes.font_weight = QLatin1String("normal");        afterFirstUpdate = false;        numGradients = 0;    }    QSize size;    QIODevice *outputDevice;    QTextStream *stream;    int resolution;    QString header;    QString defs;    QString body;    bool    afterFirstUpdate;    QBrush brush;    QPen pen;    QMatrix matrix;    QFont font;    QString generateGradientName() {        ++numGradients;        currentGradientName = QString::fromLatin1("gradient%1").arg(numGradients);        return currentGradientName;    }    QString currentGradientName;    int numGradients;    struct _attributes {        QString document_title;        QString document_description;        QString font_weight;        QString font_size;        QString font_family;        QString font_style;        QString stroke, strokeOpacity;        QString dashPattern, dashOffset;        QString fill, fillOpacity;    } attributes;};static inline QPaintEngine::PaintEngineFeatures svgEngineFeatures(){    return QPaintEngine::PaintEngineFeatures(        QPaintEngine::AllFeatures        & ~QPaintEngine::PatternBrush        & ~QPaintEngine::PerspectiveTransform        & ~QPaintEngine::ConicalGradientFill        & ~QPaintEngine::PorterDuff);}class QSvgPaintEngine : public QPaintEngine{    Q_DECLARE_PRIVATE(QSvgPaintEngine)public:    QSvgPaintEngine()        : QPaintEngine(*new QSvgPaintEnginePrivate,                       svgEngineFeatures())    {    }    bool begin(QPaintDevice *device);    bool end();    void updateState(const QPaintEngineState &state);    void popGroup();    void drawPath(const QPainterPath &path);    void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);    void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);    void drawTextItem(const QPointF &pt, const QTextItem &item);    void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,                   Qt::ImageConversionFlag = Qt::AutoColor);    QPaintEngine::Type type() const { return QPaintEngine::SVG; }    QSize size() const { return d_func()->size; }    void setSize(const QSize &size) {        Q_ASSERT(!isActive());        d_func()->size = size;    }    QIODevice *outputDevice() const { return d_func()->outputDevice; }    void setOutputDevice(QIODevice *device) {        Q_ASSERT(!isActive());        d_func()->outputDevice = device;    }    int resolution() { return d_func()->resolution; }    void setResolution(int resolution) {        Q_ASSERT(!isActive());        d_func()->resolution = resolution;    }    void saveLinearGradientBrush(const QGradient *g)    {        QTextStream str(&d_func()->defs, QIODevice::Append);        const QLinearGradient *grad = static_cast<const QLinearGradient*>(g);        str << QLatin1String("<linearGradient ");        saveGradientUnits(str, g);        if (grad) {            str << QLatin1String("x1=\"") <<grad->start().x()<< QLatin1String("\" ")                << QLatin1String("y1=\"") <<grad->start().y()<< QLatin1String("\" ")                << QLatin1String("x2=\"") <<grad->finalStop().x() << QLatin1String("\" ")                << QLatin1String("y2=\"") <<grad->finalStop().y() << QLatin1String("\" ");        }        str << QLatin1String("id=\"") << d_func()->generateGradientName() << QLatin1String("\">\n");        saveGradientStops(str, g);        str << QLatin1String("</linearGradient>") <<endl;    }    void saveRadialGradientBrush(const QGradient *g)    {        QTextStream str(&d_func()->defs, QIODevice::Append);        const QRadialGradient *grad = static_cast<const QRadialGradient*>(g);        str << QLatin1String("<radialGradient ");        saveGradientUnits(str, g);        if (grad) {            str << QLatin1String("cx=\"") <<grad->center().x()<< QLatin1String("\" ")                << QLatin1String("cy=\"") <<grad->center().y()<< QLatin1String("\" ")                << QLatin1String("r=\"") <<grad->radius() << QLatin1String("\" ")                << QLatin1String("fx=\"") <<grad->focalPoint().x() << QLatin1String("\" ")                << QLatin1String("fy=\"") <<grad->focalPoint().y() << QLatin1String("\" ");        }        str << QLatin1String("xml:id=\"") <<d_func()->generateGradientName()<< QLatin1String("\">\n");        saveGradientStops(str, g);        str << QLatin1String("</radialGradient>") << endl;    }    void saveConicalGradientBrush(const QGradient *)    {        qWarning("svg's don't support conical gradients!");    }    void saveGradientStops(QTextStream &str, const QGradient *g) {        QGradientStops stops = g->stops();        foreach(QGradientStop stop, stops) {            QString color =                QString::fromLatin1("#%1%2%3")                .arg(stop.second.red(), 2, 16, QLatin1Char('0'))                .arg(stop.second.green(), 2, 16, QLatin1Char('0'))                .arg(stop.second.blue(), 2, 16, QLatin1Char('0'));            str << QLatin1String("    <stop offset=\"")<< stop.first << QLatin1String("\" ")                << QLatin1String("stop-color=\"") << color << QLatin1String("\" ")                << QLatin1String("stop-opacity=\"") << stop.second.alphaF() <<QLatin1String("\" />\n");        }    }    void saveGradientUnits(QTextStream &str, const QGradient *gradient)    {        str << QLatin1String("gradientUnits=\"");        if (gradient && gradient->coordinateMode() == QGradient::ObjectBoundingMode)            str << QLatin1String("objectBoundingBox");        else            str << QLatin1String("userSpaceOnUse");        str << QLatin1String("\" ");    }    void generateQtDefaults()    {        *d_func()->stream << QLatin1String("fill=\"none\" ");        *d_func()->stream << QLatin1String("stroke=\"black\" ");        *d_func()->stream << QLatin1String("vector-effect=\"non-scaling-stroke\" ");        *d_func()->stream << QLatin1String("stroke-width=\"1\" ");        *d_func()->stream << QLatin1String("fill-rule=\"evenodd\" ");        *d_func()->stream << QLatin1String("stroke-linecap=\"square\" ");        *d_func()->stream << QLatin1String("stroke-linejoin=\"bevel\" ");        *d_func()->stream << QLatin1String(">\n");    }    inline QTextStream &stream()    {        return *d_func()->stream;    }    void qpenToSvg(const QPen &spen)    {        QString width;        d_func()->pen = spen;        switch (spen.style()) {        case Qt::NoPen:            stream() << QLatin1String("stroke=\"none\" ");            d_func()->attributes.stroke = QLatin1String("none");            d_func()->attributes.strokeOpacity = QString();            return;            break;        case Qt::SolidLine: {            QString color, colorOpacity;            translate_color(spen.color(), &color,                            &colorOpacity);            d_func()->attributes.stroke = color;            d_func()->attributes.strokeOpacity = colorOpacity;            stream() << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");            stream() << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");        }            break;        case Qt::DashLine:        case Qt::DotLine:        case Qt::DashDotLine:        case Qt::DashDotDotLine:        case Qt::CustomDashLine: {            QString color, colorOpacity, dashPattern, dashOffset;            qreal penWidth = spen.width() == 0 ? qreal(1) : spen.widthF();            translate_color(spen.color(), &color, &colorOpacity);            translate_dashPattern(spen.dashPattern(), penWidth, &dashPattern);            // SVG uses absolute offset            dashOffset = QString::fromLatin1("%1").arg(spen.dashOffset() * penWidth);            d_func()->attributes.stroke = color;            d_func()->attributes.strokeOpacity = colorOpacity;            d_func()->attributes.dashPattern = dashPattern;            d_func()->attributes.dashOffset = dashOffset;            stream() << QLatin1String("stroke=\"")<<color<< QLatin1String("\" ");            stream() << QLatin1String("stroke-opacity=\"")<<colorOpacity<< QLatin1String("\" ");            stream() << QLatin1String("stroke-dasharray=\"")<<dashPattern<< QLatin1String("\" ");            stream() << QLatin1String("stroke-dashoffset=\"")<<dashOffset<< QLatin1String("\" ");            break;        }        default:            qWarning("Unsupported pen style");            break;        }        if (spen.widthF() == 0) {            width = QLatin1String("1");            stream() << "vector-effect=\"non-scaling-stroke\" ";        }        else            width = QString::number(spen.widthF());        stream() <<"stroke-width=\""<<width<<"\" ";        switch (spen.capStyle()) {        case Qt::FlatCap:            stream() << "stroke-linecap=\"butt\" ";            break;        case Qt::SquareCap:            stream() << "stroke-linecap=\"square\" ";            break;        case Qt::RoundCap:            stream() << "stroke-linecap=\"round\" ";            break;        default:            qWarning("Unhandled cap style");        }        switch (spen.joinStyle()) {        case Qt::MiterJoin:            stream() << "stroke-linejoin=\"miter\" ";            stream() << "stroke-miterlimit=\""<<spen.miterLimit()<<"\" ";            break;        case Qt::BevelJoin:            stream() << "stroke-linejoin=\"bevel\" ";            break;        case Qt::RoundJoin:            stream() << "stroke-linejoin=\"round\" ";            break;        case Qt::SvgMiterJoin:            stream() << "stroke-linejoin=\"miter\" ";            stream() << "stroke-miterlimit=\""<<spen.miterLimit()<<"\" ";            break;        default:            qWarning("Unhandled join style");        }    }    void qbrushToSvg(const QBrush &sbrush)    {        d_func()->brush = sbrush;        switch (sbrush.style()) {        case Qt::SolidPattern: {            QString color, colorOpacity;            translate_color(sbrush.color(), &color, &colorOpacity);            stream() << "fill=\"" << color << "\" ";            stream() << "fill-opacity=\""                     << colorOpacity << "\" ";            d_func()->attributes.fill = color;            d_func()->attributes.fillOpacity = colorOpacity;        }            break;        case Qt::LinearGradientPattern:            saveLinearGradientBrush(sbrush.gradient());            d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName);            d_func()->attributes.fillOpacity = QString();            stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");            break;        case Qt::RadialGradientPattern:            saveRadialGradientBrush(sbrush.gradient());            d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName);            d_func()->attributes.fillOpacity = QString();            stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");            break;        case Qt::ConicalGradientPattern:            saveConicalGradientBrush(sbrush.gradient());            d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName);            d_func()->attributes.fillOpacity = QString();            stream() << QLatin1String("fill=\"url(#") << d_func()->currentGradientName << QLatin1String(")\" ");            break;        case Qt::NoBrush:            stream() << QLatin1String("fill=\"none\" ");            d_func()->attributes.fill = QLatin1String("none");            d_func()->attributes.fillOpacity = QString();            return;            break;        default:           break;        }    }    void qfontToSvg(const QFont &sfont)    {        Q_D(QSvgPaintEngine);        d->font = sfont;        d->attributes.font_size = QString::number(d->font.pointSize()) + QLatin1String("pt");        int svgWeight = d->font.weight();        switch (svgWeight) {        case QFont::Light:            svgWeight = 100;            break;        case QFont::Normal:            svgWeight = 400;            break;        case QFont::Bold:            svgWeight = 700;            break;        default:            svgWeight *= 10;        }        d->attributes.font_weight = QString::number(svgWeight);        d->attributes.font_family = d->font.family();        d->attributes.font_style = d->font.italic() ? QLatin1String("italic") : QLatin1String("normal");        *d->stream << "font-family=\"" << d->attributes.font_family << "\" "                   << "font-size=\"" << d->attributes.font_size << "\" "                   << "font-weight=\"" << d->attributes.font_weight << "\" "                   << "font-style=\"" << d->attributes.font_style << "\" "                   << endl;    }};class QSvgGeneratorPrivate{public:    QSvgPaintEngine *engine;    uint owns_iodevice : 1;

⌨️ 快捷键说明

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