From 1b3a7ae14d25f1caa3f6bedad3cfeb7d83b3904e Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 2 Dec 2016 16:16:03 +0100 Subject: Document 3rd party code using new setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7495086a3712ef817380c80d3dea7d49da047ed8 Reviewed-by: Topi Reiniö --- src/svg/XSVG_LICENSE.txt | 22 ++++++++++++++ src/svg/doc/src/qtsvg-index.qdoc | 14 ++++++++- src/svg/doc/src/svglicense.qdoc | 62 ---------------------------------------- src/svg/qt_attribution.json | 12 ++++++++ 4 files changed, 47 insertions(+), 63 deletions(-) create mode 100644 src/svg/XSVG_LICENSE.txt delete mode 100644 src/svg/doc/src/svglicense.qdoc create mode 100644 src/svg/qt_attribution.json (limited to 'src') diff --git a/src/svg/XSVG_LICENSE.txt b/src/svg/XSVG_LICENSE.txt new file mode 100644 index 0000000..9ad4931 --- /dev/null +++ b/src/svg/XSVG_LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2002 USC/Information Sciences Institute + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without +fee, provided that the above copyright notice appear in all copies +and that both that copyright notice and this permission notice +appear in supporting documentation, and that the name of +Information Sciences Institute not be used in advertising or +publicity pertaining to distribution of the software without +specific, written prior permission. Information Sciences Institute +makes no representations about the suitability of this software for +any purpose. It is provided "as is" without express or implied +warranty. + +INFORMATION SCIENCES INSTITUTE DISCLAIMS ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL INFORMATION SCIENCES +INSTITUTE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/src/svg/doc/src/qtsvg-index.qdoc b/src/svg/doc/src/qtsvg-index.qdoc index 957e009..73a319b 100644 --- a/src/svg/doc/src/qtsvg-index.qdoc +++ b/src/svg/doc/src/qtsvg-index.qdoc @@ -47,11 +47,23 @@ \snippet doc_src_qtsvg.pro 1 + \section1 Licenses and Attributions + + Qt SVG is available under commercial licenses from \l{The Qt Company}. + In addition, it is available under the + \l{GNU Lesser General Public License, version 3}, or + the \l{GNU General Public License, version 2}. + See \l{Qt Licensing} for further details. + + Furthermore Qt SVG contains third party + code under following permissive licenses: + + \generatelist{groupsbymodule attributions-qtsvg} + \section1 Articles \list \li \l{Rendering SVG Files} contains information about how to render SVG files - \li \l{Qt SVG License Information}{License Information} \endlist \section1 References diff --git a/src/svg/doc/src/svglicense.qdoc b/src/svg/doc/src/svglicense.qdoc deleted file mode 100644 index 3fcaa4c..0000000 --- a/src/svg/doc/src/svglicense.qdoc +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt SVG module. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page qtsvglicense.html - \title Qt SVG License Information - \ingroup licensing - \brief License information for Qt SVG - - Some code for arc handling in the \l{Qt SVG} module is derived from code - with the following license: - - \legalese - Copyright 2002 USC/Information Sciences Institute - - Permission to use, copy, modify, distribute, and sell this software - and its documentation for any purpose is hereby granted without - fee, provided that the above copyright notice appear in all copies - and that both that copyright notice and this permission notice - appear in supporting documentation, and that the name of - Information Sciences Institute not be used in advertising or - publicity pertaining to distribution of the software without - specific, written prior permission. Information Sciences Institute - makes no representations about the suitability of this software for - any purpose. It is provided "as is" without express or implied - warranty. - - INFORMATION SCIENCES INSTITUTE DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL INFORMATION SCIENCES - INSTITUTE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA - OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - \endlegalese - -*/ diff --git a/src/svg/qt_attribution.json b/src/svg/qt_attribution.json new file mode 100644 index 0000000..515bb38 --- /dev/null +++ b/src/svg/qt_attribution.json @@ -0,0 +1,12 @@ +{ + "Id": "xsvg", + "Name": "XSVG", + "QDocModule": "qtsvg", + "QtUsage": "Used in the Qt SVG library.", + "Files": "qtsvghandler.cpp", + + "Description": "Some code for arc handling is derived from code from the XSVG project.", + "License": "MIT \"Old Style\" License", + "LicenseFile": "XSVG_LICENSE.txt", + "Copyright": "Copyright 2002 USC/Information Sciences Institute" +} -- cgit v1.2.1 From d45fcac787196bcbbe366c997801d5bcebf1a475 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 2 Feb 2017 09:35:43 +0100 Subject: Introduce logging category "qt.svg" It is then possible to suppress warnings by setting for example QT_LOGGING_RULES to qt.svg.warning=false. This will suppress the warnings floods which are currently produced by faulty theme svg icons on KDE 5 systems. Task-number: QTBUG-52079 Change-Id: I50e3c2e3eab610e182293c8938c6188694eabfb7 Reviewed-by: David Faure --- src/svg/qsvghandler.cpp | 33 ++++++++++++++++++--------------- src/svg/qsvghandler_p.h | 3 +++ src/svg/qsvgtinydocument.cpp | 14 +++++++------- 3 files changed, 28 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 3b1cbb8..0b0750b 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -65,6 +65,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcSvgHandler, "qt.svg") + static const char *qt_inherit_text = "inherit"; #define QT_INHERIT QLatin1String(qt_inherit_text) @@ -2692,11 +2694,11 @@ static QSvgNode *createImageNode(QSvgNode *parent, filename = filename.trimmed(); if (filename.isEmpty()) { - qWarning() << "QSvgHandler: Image filename is empty"; + qCWarning(lcSvgHandler) << "QSvgHandler: Image filename is empty"; return 0; } if (nwidth <= 0 || nheight <= 0) { - qWarning() << "QSvgHandler: Width or height for" << filename << "image was not greater than 0"; + qCWarning(lcSvgHandler) << "QSvgHandler: Width or height for" << filename << "image was not greater than 0"; return 0; } @@ -2709,7 +2711,7 @@ static QSvgNode *createImageNode(QSvgNode *parent, QByteArray data = QByteArray::fromBase64(dataStr.toLatin1()); image = QImage::fromData(data); } else { - qDebug()<<"QSvgHandler::createImageNode: Unrecognized inline image format!"; + qCDebug(lcSvgHandler) << "QSvgHandler::createImageNode: Unrecognized inline image format!"; } } else image = QImage(filename); @@ -3166,7 +3168,7 @@ static QSvgNode *createSvgNode(QSvgNode *parent, QString baseProfile = attributes.value(QLatin1String("baseProfile")).toString(); #if 0 if (baseProfile.isEmpty() && baseProfile != QLatin1String("tiny")) { - qWarning("Profile is %s while we only support tiny!", + qCWarning(lcSvgHandler, "Profile is %s while we only support tiny!", qPrintable(baseProfile)); } #endif @@ -3332,7 +3334,7 @@ static QSvgNode *createUseNode(QSvgNode *parent, } } - qWarning("link %s hasn't been detected!", qPrintable(linkId)); + qCWarning(lcSvgHandler, "link %s hasn't been detected!", qPrintable(linkId)); return 0; } @@ -3619,8 +3621,9 @@ bool QSvgHandler::startElement(const QString &localName, } else if (xmlSpace == QLatin1String("default")) { m_whitespaceMode.push(QSvgText::Default); } else { - qWarning() << QString::fromLatin1("\"%1\" is an invalid value for attribute xml:space. " - "Valid values are \"preserve\" and \"default\".").arg(xmlSpace.toString()); + qCWarning(lcSvgHandler).noquote() + << QString::fromLatin1("\"%1\" is an invalid value for attribute xml:space. " + "Valid values are \"preserve\" and \"default\".").arg(xmlSpace.toString()); m_whitespaceMode.push(QSvgText::Default); } @@ -3676,13 +3679,13 @@ bool QSvgHandler::startElement(const QString &localName, if (node->type() == QSvgNode::TSPAN) { static_cast(m_nodes.top())->addTspan(static_cast(node)); } else { - qWarning("\'text\' or \'textArea\' element contains invalid element type."); + qCWarning(lcSvgHandler, "\'text\' or \'textArea\' element contains invalid element type."); delete node; node = 0; } break; default: - qWarning("Could not add child element to parent element because the types are incorrect."); + qCWarning(lcSvgHandler, "Could not add child element to parent element because the types are incorrect."); delete node; node = 0; break; @@ -3704,7 +3707,7 @@ bool QSvgHandler::startElement(const QString &localName, } else if (ParseMethod method = findUtilFactory(localName)) { Q_ASSERT(!m_nodes.isEmpty()); if (!method(m_nodes.top(), attributes, this)) { - qWarning("Problem parsing %s", qPrintable(localName)); + qCWarning(lcSvgHandler, "Problem parsing %s", qPrintable(localName)); } } else if (StyleFactoryMethod method = findStyleFactoryMethod(localName)) { QSvgStyleProperty *prop = method(m_nodes.top(), attributes, this); @@ -3712,16 +3715,16 @@ bool QSvgHandler::startElement(const QString &localName, m_style = prop; m_nodes.top()->appendStyleProperty(prop, someId(attributes)); } else { - qWarning("Could not parse node: %s", qPrintable(localName)); + qCWarning(lcSvgHandler, "Could not parse node: %s", qPrintable(localName)); } } else if (StyleParseMethod method = findStyleUtilFactoryMethod(localName)) { if (m_style) { if (!method(m_style, attributes, this)) { - qWarning("Problem parsing %s", qPrintable(localName)); + qCWarning(lcSvgHandler, "Problem parsing %s", qPrintable(localName)); } } } else { - //qWarning()<<"Skipping unknown element!"<setFillStyle(style); } else { - qWarning("Could not resolve property : %s", qPrintable(id)); + qCWarning(lcSvgHandler, "Could not resolve property : %s", qPrintable(id)); fill->setBrush(Qt::NoBrush); } } @@ -3792,7 +3795,7 @@ void QSvgHandler::resolveGradients(QSvgNode *node) if (style) { stroke->setStyle(style); } else { - qWarning("Could not resolve property : %s", qPrintable(id)); + qCWarning(lcSvgHandler, "Could not resolve property : %s", qPrintable(id)); stroke->setStroke(Qt::NoBrush); } } diff --git a/src/svg/qsvghandler_p.h b/src/svg/qsvghandler_p.h index 32dd059..2c06cb4 100644 --- a/src/svg/qsvghandler_p.h +++ b/src/svg/qsvghandler_p.h @@ -54,6 +54,7 @@ #include "QtCore/qxmlstream.h" #include "QtCore/qhash.h" #include "QtCore/qstack.h" +#include #include "qsvgstyle_p.h" #include "private/qcssparser_p.h" #include "qsvggraphics_p.h" @@ -186,6 +187,8 @@ private: const bool m_ownsReader; }; +Q_DECLARE_LOGGING_CATEGORY(lcSvgHandler) + QT_END_NAMESPACE #endif // QSVGHANDLER_P_H diff --git a/src/svg/qsvgtinydocument.cpp b/src/svg/qsvgtinydocument.cpp index 7bb1f75..15351bd 100644 --- a/src/svg/qsvgtinydocument.cpp +++ b/src/svg/qsvgtinydocument.cpp @@ -104,7 +104,7 @@ QByteArray qt_inflateGZipDataFrom(QIODevice *device) // Adding 16 to the window size gives us gzip decoding if (inflateInit2(&zlibStream, MAX_WBITS + 16) != Z_OK) { - qWarning("Cannot initialize zlib, because: %s", + qCWarning(lcSvgHandler, "Cannot initialize zlib, because: %s", (zlibStream.msg != NULL ? zlibStream.msg : "Unknown error")); return QByteArray(); } @@ -137,7 +137,7 @@ QByteArray qt_inflateGZipDataFrom(QIODevice *device) case Z_STREAM_ERROR: case Z_MEM_ERROR: { inflateEnd(&zlibStream); - qWarning("Error while inflating gzip file: %s", + qCWarning(lcSvgHandler, "Error while inflating gzip file: %s", (zlibStream.msg != NULL ? zlibStream.msg : "Unknown error")); destination.chop(zlibStream.avail_out); return destination; @@ -167,8 +167,8 @@ QSvgTinyDocument * QSvgTinyDocument::load(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::ReadOnly)) { - qWarning("Cannot open file '%s', because: %s", - qPrintable(fileName), qPrintable(file.errorString())); + qCWarning(lcSvgHandler, "Cannot open file '%s', because: %s", + qPrintable(fileName), qPrintable(file.errorString())); return 0; } @@ -185,7 +185,7 @@ QSvgTinyDocument * QSvgTinyDocument::load(const QString &fileName) doc = handler.document(); doc->m_animationDuration = handler.animationDuration(); } else { - qWarning("Cannot read file '%s', because: %s (line %d)", + qCWarning(lcSvgHandler, "Cannot read file '%s', because: %s (line %d)", qPrintable(fileName), qPrintable(handler.errorString()), handler.lineNumber()); } return doc; @@ -261,7 +261,7 @@ void QSvgTinyDocument::draw(QPainter *p, const QString &id, QSvgNode *node = scopeNode(id); if (!node) { - qDebug("Couldn't find node %s. Skipping rendering.", qPrintable(id)); + qCDebug(lcSvgHandler, "Couldn't find node %s. Skipping rendering.", qPrintable(id)); return; } if (m_time.isNull()) { @@ -443,7 +443,7 @@ QMatrix QSvgTinyDocument::matrixForElement(const QString &id) const QSvgNode *node = scopeNode(id); if (!node) { - qDebug("Couldn't find node %s. Skipping rendering.", qPrintable(id)); + qCDebug(lcSvgHandler, "Couldn't find node %s. Skipping rendering.", qPrintable(id)); return QMatrix(); } -- cgit v1.2.1 From bfa9500ae5b9acf24d1b6847003c19a4e49d9749 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 2 Feb 2017 10:07:39 +0100 Subject: Improve the error messages of QSvgHandler Add a function printing file name and location. Could not resolve property : linearGradient4538 becomes /usr/share/icons/breeze/actions/24/document-new.svg:123: Could not resolve property: linearGradient4538 Task-number: QTBUG-52079 Change-Id: I843f65eb4ca517d103031f9921a16090a6ff6720 Reviewed-by: David Faure --- src/svg/qsvghandler.cpp | 61 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 0b0750b..df654e1 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -55,6 +55,7 @@ #include "qvector.h" #include "qfileinfo.h" #include "qfile.h" +#include "qdir.h" #include "qdebug.h" #include "qmath.h" #include "qnumeric.h" @@ -70,6 +71,36 @@ Q_LOGGING_CATEGORY(lcSvgHandler, "qt.svg") static const char *qt_inherit_text = "inherit"; #define QT_INHERIT QLatin1String(qt_inherit_text) +static QByteArray prefixMessage(const QByteArray &msg, const QXmlStreamReader *r) +{ + QByteArray result; + if (r) { + if (const QFile *file = qobject_cast(r->device())) + result.append(QFile::encodeName(QDir::toNativeSeparators(file->fileName()))); + else + result.append(QByteArrayLiteral("")); + result.append(':'); + result.append(QByteArray::number(r->lineNumber())); + if (const qint64 column = r->columnNumber()) { + result.append(':'); + result.append(QByteArray::number(column)); + } + result.append(QByteArrayLiteral(": ")); + } + result.append(msg); + return result; +} + +static inline QByteArray msgProblemParsing(const QString &localName, const QXmlStreamReader *r) +{ + return prefixMessage(QByteArrayLiteral("Problem parsing ") + localName.toLocal8Bit(), r); +} + +static inline QByteArray msgCouldNotResolveProperty(const QString &id, const QXmlStreamReader *r) +{ + return prefixMessage(QByteArrayLiteral("Could not resolve property: ") + id.toLocal8Bit(), r); +} + // ======== duplicated from qcolor_p static inline int qsvg_h2i(char hex) @@ -3621,9 +3652,10 @@ bool QSvgHandler::startElement(const QString &localName, } else if (xmlSpace == QLatin1String("default")) { m_whitespaceMode.push(QSvgText::Default); } else { - qCWarning(lcSvgHandler).noquote() - << QString::fromLatin1("\"%1\" is an invalid value for attribute xml:space. " - "Valid values are \"preserve\" and \"default\".").arg(xmlSpace.toString()); + const QByteArray msg = '"' + xmlSpace.toString().toLocal8Bit() + + "\" is an invalid value for attribute xml:space. " + "Valid values are \"preserve\" and \"default\"."; + qCWarning(lcSvgHandler, "%s", prefixMessage(msg, xml).constData()); m_whitespaceMode.push(QSvgText::Default); } @@ -3679,13 +3711,15 @@ bool QSvgHandler::startElement(const QString &localName, if (node->type() == QSvgNode::TSPAN) { static_cast(m_nodes.top())->addTspan(static_cast(node)); } else { - qCWarning(lcSvgHandler, "\'text\' or \'textArea\' element contains invalid element type."); + const QByteArray msg = QByteArrayLiteral("\'text\' or \'textArea\' element contains invalid element type."); + qCWarning(lcSvgHandler, "%s", prefixMessage(msg, xml).constData()); delete node; node = 0; } break; default: - qCWarning(lcSvgHandler, "Could not add child element to parent element because the types are incorrect."); + const QByteArray msg = QByteArrayLiteral("Could not add child element to parent element because the types are incorrect."); + qCWarning(lcSvgHandler, "%s", prefixMessage(msg, xml).constData()); delete node; node = 0; break; @@ -3706,22 +3740,21 @@ bool QSvgHandler::startElement(const QString &localName, } } else if (ParseMethod method = findUtilFactory(localName)) { Q_ASSERT(!m_nodes.isEmpty()); - if (!method(m_nodes.top(), attributes, this)) { - qCWarning(lcSvgHandler, "Problem parsing %s", qPrintable(localName)); - } + if (!method(m_nodes.top(), attributes, this)) + qCWarning(lcSvgHandler, "%s", msgProblemParsing(localName, xml).constData()); } else if (StyleFactoryMethod method = findStyleFactoryMethod(localName)) { QSvgStyleProperty *prop = method(m_nodes.top(), attributes, this); if (prop) { m_style = prop; m_nodes.top()->appendStyleProperty(prop, someId(attributes)); } else { - qCWarning(lcSvgHandler, "Could not parse node: %s", qPrintable(localName)); + const QByteArray msg = QByteArrayLiteral("Could not parse node: ") + localName.toLocal8Bit(); + qCWarning(lcSvgHandler, "%s", prefixMessage(msg, xml).constData()); } } else if (StyleParseMethod method = findStyleUtilFactoryMethod(localName)) { if (m_style) { - if (!method(m_style, attributes, this)) { - qCWarning(lcSvgHandler, "Problem parsing %s", qPrintable(localName)); - } + if (!method(m_style, attributes, this)) + qCWarning(lcSvgHandler, "%s", msgProblemParsing(localName, xml).constData()); } } else { //qCWarning(lcSvgHandler) <<"Skipping unknown element!"<setFillStyle(style); } else { - qCWarning(lcSvgHandler, "Could not resolve property : %s", qPrintable(id)); + qCWarning(lcSvgHandler, "%s", msgCouldNotResolveProperty(id, xml).constData()); fill->setBrush(Qt::NoBrush); } } @@ -3795,7 +3828,7 @@ void QSvgHandler::resolveGradients(QSvgNode *node) if (style) { stroke->setStyle(style); } else { - qCWarning(lcSvgHandler, "Could not resolve property : %s", qPrintable(id)); + qCWarning(lcSvgHandler, "%s", msgCouldNotResolveProperty(id, xml).constData()); stroke->setStroke(Qt::NoBrush); } } -- cgit v1.2.1 From 8ea914c667e3d021d6618915e694a4d8bed5fe9f Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 8 Feb 2017 17:12:18 +0100 Subject: Fix svg generation for non-normalized rectangles The raster engine accepts and renders non-normalized rectangles. Make the svg paint engine do the same, instead of just ignoring them. Task-number: QTBUG-58145 Change-Id: Ifa82fd580574bc908552efbb1eeace21bde76ed7 Reviewed-by: Joerg Bornemann --- src/svg/qsvggenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index 5829a1a..6af4370 100644 --- a/src/svg/qsvggenerator.cpp +++ b/src/svg/qsvggenerator.cpp @@ -1062,7 +1062,7 @@ void QSvgPaintEngine::drawRects(const QRectF *rects, int rectCount) Q_D(QSvgPaintEngine); for (int i=0; i < rectCount; ++i) { - const QRectF &rect = rects[i]; + const QRectF &rect = rects[i].normalized(); *d->stream << "pen().isCosmetic()) *d->stream << " vector-effect=\"non-scaling-stroke\""; -- cgit v1.2.1 From 914e25bf01e6264dd80b6f27e50b45a578a7fe89 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 13 Feb 2017 12:38:10 +0100 Subject: Add support for pattern brushes to svg generator Pattern brushes was not implemented in the svg generator. Shapes drawn with such brushes would not be included in the svg file. [ChangeLog][][QSvgGenerator] Add support for pattern brushes Task-number: QTBUG-58148 Change-Id: Ib275661c596631fea64cb250c9743a529cd7b834 Reviewed-by: Joerg Bornemann --- src/svg/qsvggenerator.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index 6af4370..de6e8d4 100644 --- a/src/svg/qsvggenerator.cpp +++ b/src/svg/qsvggenerator.cpp @@ -52,6 +52,7 @@ #include "qtextstream.h" #include "qbuffer.h" #include "qmath.h" +#include "qbitmap.h" #include "qdebug.h" @@ -128,6 +129,9 @@ public: QString currentGradientName; int numGradients; + QStringList savedPatternBrushes; + QStringList savedPatternMasks; + struct _attributes { QString document_title; QString document_description; @@ -145,12 +149,13 @@ static inline QPaintEngine::PaintEngineFeatures svgEngineFeatures() { return QPaintEngine::PaintEngineFeatures( QPaintEngine::AllFeatures - & ~QPaintEngine::PatternBrush & ~QPaintEngine::PerspectiveTransform & ~QPaintEngine::ConicalGradientFill & ~QPaintEngine::PorterDuff); } +Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert); + class QSvgPaintEngine : public QPaintEngine { Q_DECLARE_PRIVATE(QSvgPaintEngine) @@ -212,6 +217,41 @@ public: Q_ASSERT(!isActive()); d_func()->resolution = resolution; } + + QString savePatternMask(Qt::BrushStyle style) + { + QString maskId = QString(QStringLiteral("patternmask%1")).arg(style); + if (!d_func()->savedPatternMasks.contains(maskId)) { + QImage img = qt_imageForBrush(style, true); + QRegion reg(QBitmap::fromData(img.size(), img.constBits())); + QString rct(QStringLiteral("")); + QTextStream str(&d_func()->defs, QIODevice::Append); + str << "" << endl; + for (QRect r : reg.rects()) { + str << rct.arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height()) << endl; + } + str << QStringLiteral("") << endl << endl; + d_func()->savedPatternMasks.append(maskId); + } + return maskId; + } + + QString savePatternBrush(const QString &color, const QBrush &brush) + { + QString patternId = QString(QStringLiteral("fillpattern%1_")).arg(brush.style()) + color.midRef(1); + if (!d_func()->savedPatternBrushes.contains(patternId)) { + QString maskId = savePatternMask(brush.style()); + QString geo(QStringLiteral("x=\"0\" y=\"0\" width=\"8\" height=\"8\"")); + QTextStream str(&d_func()->defs, QIODevice::Append); + str << QString(QStringLiteral("")).arg(patternId, geo) << endl; + str << QString(QStringLiteral("")).arg(geo, color, maskId) << endl; + str << QStringLiteral("") << endl << endl; + d_func()->savedPatternBrushes.append(patternId); + } + return patternId; + } + void saveLinearGradientBrush(const QGradient *g) { QTextStream str(&d_func()->defs, QIODevice::Append); @@ -421,6 +461,28 @@ public: d_func()->attributes.fillOpacity = colorOpacity; } break; + case Qt::Dense1Pattern: + case Qt::Dense2Pattern: + case Qt::Dense3Pattern: + case Qt::Dense4Pattern: + case Qt::Dense5Pattern: + case Qt::Dense6Pattern: + case Qt::Dense7Pattern: + case Qt::HorPattern: + case Qt::VerPattern: + case Qt::CrossPattern: + case Qt::BDiagPattern: + case Qt::FDiagPattern: + case Qt::DiagCrossPattern: { + QString color, colorOpacity; + translate_color(sbrush.color(), &color, &colorOpacity); + QString patternId = savePatternBrush(color, sbrush); + QString patternRef = QString(QStringLiteral("url(#%1)")).arg(patternId); + stream() << "fill=\"" << patternRef << "\" fill-opacity=\"" << colorOpacity << "\" "; + d_func()->attributes.fill = patternRef; + d_func()->attributes.fillOpacity = colorOpacity; + break; + } case Qt::LinearGradientPattern: saveLinearGradientBrush(sbrush.gradient()); d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName); -- cgit v1.2.1 From 7cc50e972b7fa546f7cedff2ef19db20af9e36ab Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 14 Feb 2017 12:34:52 +0100 Subject: Fix radial gradient brushes in svg generator The code would generate radial gradiants named with an "xml:id" attribute, in contrast to linear gradients which is named by an "id" attribute. Those two forms should be equivalent according to the spec, but in practice most browsers and viewers only accept the latter. Change-Id: I798387bdbd3a6ea831af8ce103683141b567e940 Reviewed-by: Joerg Bornemann --- src/svg/qsvggenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index de6e8d4..3f4e545 100644 --- a/src/svg/qsvggenerator.cpp +++ b/src/svg/qsvggenerator.cpp @@ -282,7 +282,7 @@ public: << QLatin1String("fx=\"") <focalPoint().x() << QLatin1String("\" ") << QLatin1String("fy=\"") <focalPoint().y() << QLatin1String("\" "); } - str << QLatin1String("xml:id=\"") <generateGradientName()<< QLatin1String("\">\n"); + str << QLatin1String("id=\"") <generateGradientName()<< QLatin1String("\">\n"); saveGradientStops(str, g); str << QLatin1String("") << endl; } -- cgit v1.2.1 From 02ed4c65618b0f27b9ccb6867ab4d633612415c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Sun, 26 Mar 2017 13:55:23 +0200 Subject: QSvgIconEngine: Paint correct size if device pixel ratio is fractional Use method which returns qreal. It is available since Qt 5.6. Task-number: QTBUG-59729 Change-Id: Ifc1a101c8dd837597c35ce14f0314218d2882501 Reviewed-by: Friedemann Kleint --- src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp b/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp index 53e9a57..2644326 100644 --- a/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp +++ b/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp @@ -254,7 +254,7 @@ void QSvgIconEngine::paint(QPainter *painter, const QRect &rect, { QSize pixmapSize = rect.size(); if (painter->device()) - pixmapSize *= painter->device()->devicePixelRatio(); + pixmapSize *= painter->device()->devicePixelRatioF(); painter->drawPixmap(rect, pixmap(pixmapSize, mode, state)); } -- cgit v1.2.1 From e4038c6a3696973aca6db7f5442a8fb00a9b5bab Mon Sep 17 00:00:00 2001 From: Nikita Krupenko Date: Thu, 23 Mar 2017 22:04:50 +0200 Subject: Fix warnings for -no-feature-cssparser Change-Id: Ifdb27c6fed26f95acff30f64259d6905e88c3a6f Reviewed-by: Paul Olav Tvete --- src/svg/qsvghandler.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index df654e1..c40091f 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -322,6 +322,8 @@ QSvgAttributes::QSvgAttributes(const QXmlStreamAttributes &xmlAttributes, QSvgHa } } } +#else + Q_UNUSED(handler); #endif // QT_NO_CSSPARSER for (int i = 0; i < xmlAttributes.count(); ++i) { @@ -430,6 +432,8 @@ QSvgAttributes::QSvgAttributes(const QXmlStreamAttributes &xmlAttributes, QSvgHa } +#ifndef QT_NO_CSSPARSER + static const char * QSvgStyleSelector_nodeString[] = { "svg", "g", @@ -452,8 +456,6 @@ static const char * QSvgStyleSelector_nodeString[] = { "video" }; -#ifndef QT_NO_CSSPARSER - class QSvgStyleSelector : public QCss::StyleSelector { public: -- cgit v1.2.1