svg重编译,支持石化自绘的svg文件转视图
This commit is contained in:
parent
fcce4f565a
commit
235c1d7fff
|
|
@ -161,14 +161,14 @@ private:
|
|||
// 左边界矩形控制点
|
||||
mLeftHandle->topLeft->setParentAnchor(mRect->topLeft);
|
||||
mLeftHandle->bottomRight->setParentAnchor(mRect->topRight);//(mRect->bottomLeft);
|
||||
mLeftHandle->topLeft->setCoords(-5, 5); // 矩形大小
|
||||
mLeftHandle->bottomRight->setCoords(5, -5); // 矩形大小
|
||||
mLeftHandle->topLeft->setCoords(-0.5, 0.5); // 矩形大小
|
||||
mLeftHandle->bottomRight->setCoords(0.5, -0.5); // 矩形大小
|
||||
|
||||
// 右边界矩形控制点
|
||||
mRightHandle->topLeft->setParentAnchor(mRect->bottomLeft);
|
||||
mRightHandle->bottomRight->setParentAnchor(mRect->bottomRight);
|
||||
mRightHandle->topLeft->setCoords(-5, 5); // 矩形大小
|
||||
mRightHandle->bottomRight->setCoords(5, -5); // 矩形大小
|
||||
mRightHandle->topLeft->setCoords(-0.5, 0.5); // 矩形大小
|
||||
mRightHandle->bottomRight->setCoords(0.5, -0.5); // 矩形大小
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,56 @@ public:
|
|||
// mPlot->removeItem(mRightHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DrawSVGNormal(QPainter* painter,QString svgFileName,QRectF borderRect,bool IsWellSectonHorizonLayout)
|
||||
{
|
||||
QString svg=svgFileName;
|
||||
QRectF boundingRect = painter->transform().mapRect(borderRect);
|
||||
painter->save();
|
||||
QTransform transform;
|
||||
transform.reset();
|
||||
if (!IsWellSectonHorizonLayout)
|
||||
{
|
||||
painter->setWorldTransform(transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
QPixmap tiledmap(svg);
|
||||
QRect border(boundingRect.left(),boundingRect.top(),boundingRect.width(),boundingRect.height());
|
||||
painter->drawPixmap(border,tiledmap);
|
||||
painter->restore();
|
||||
}
|
||||
//拉伸
|
||||
void DrawSVGSteched(QPainter* painter,QString svgFileName,QRectF borderRect,bool IsWellSectonHorizonLayout)
|
||||
{
|
||||
QString svg;
|
||||
QSvgRenderer m_SvgRenderer;
|
||||
svg=svgFileName;
|
||||
m_SvgRenderer.load(svg);
|
||||
m_SvgRenderer.render(painter,borderRect);
|
||||
}
|
||||
//平铺
|
||||
void DrawSVGTiled(QPainter* painter,QString svgFileName,QRectF borderRect,bool IsWellSectonHorizonLayout)
|
||||
{
|
||||
QString svg=svgFileName;
|
||||
QRectF boundingRect = painter->transform().mapRect(borderRect);
|
||||
painter->save();
|
||||
QTransform transform;
|
||||
transform.reset();
|
||||
if (!IsWellSectonHorizonLayout)
|
||||
{
|
||||
painter->setWorldTransform(transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
QPixmap tiledmap(svg);
|
||||
painter->drawTiledPixmap(boundingRect,tiledmap);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
//设置最小宽度
|
||||
void setMinWidth(double minWidth){
|
||||
mMinWidth = minWidth;
|
||||
|
|
@ -50,25 +99,54 @@ public:
|
|||
}
|
||||
|
||||
//设置解释结论
|
||||
void setResult(QString result){
|
||||
m_Result = result;
|
||||
void setResult(QString filePath){
|
||||
m_Result = filePath;
|
||||
//
|
||||
QString strLast = result.right(4);
|
||||
QString strLast = filePath.right(4);
|
||||
if(strLast.toLower()==".svg")
|
||||
{
|
||||
QSvgRenderer* svgRender = new QSvgRenderer();
|
||||
svgRender->load(result);
|
||||
//
|
||||
QPixmap* pixmap = new QPixmap(10, 10);
|
||||
pixmap->fill(Qt::transparent);//设置背景透明
|
||||
QPainter p(pixmap);
|
||||
svgRender->render(&p);
|
||||
//
|
||||
mPixmap->setPixmap(*pixmap); // 设置图片
|
||||
QString path,filename;
|
||||
GetWellNameAndPath(filePath, filename, path);
|
||||
QString basename = filename.left(filename.size()-4);
|
||||
|
||||
QString val=filePath;
|
||||
QImage image(320,160,QImage::Format_RGB32);
|
||||
QPainter painter(&image);
|
||||
QRectF fillRect(0,0,320,160);
|
||||
painter.fillRect(fillRect,Qt::white);
|
||||
//拉伸
|
||||
DrawSVGSteched(&painter,filePath,fillRect,0);
|
||||
//平铺
|
||||
//DrawSVGTiled(&painter,filePath,fillRect,0);
|
||||
//正常
|
||||
//DrawSVGNormal(&painter,filePath,fillRect,0);
|
||||
|
||||
val=GetImagePath()+"TempNew";
|
||||
QDir ss;
|
||||
if(!ss.exists(val)) {
|
||||
ss.mkdir(val);
|
||||
}
|
||||
val+=QDir::separator();
|
||||
val+=basename+".png";
|
||||
image.save(val);
|
||||
|
||||
//
|
||||
mPixmap->setPixmap(QPixmap(val)); // 设置图片
|
||||
|
||||
|
||||
// QSvgRenderer* svgRender = new QSvgRenderer();
|
||||
// svgRender->load(result);
|
||||
// //
|
||||
// QPixmap* pixmap = new QPixmap(10, 10);
|
||||
// pixmap->fill(Qt::transparent);//设置背景透明
|
||||
// QPainter p(pixmap);
|
||||
// svgRender->render(&p);
|
||||
// //
|
||||
// mPixmap->setPixmap(*pixmap); // 设置图片
|
||||
}
|
||||
else
|
||||
{
|
||||
mPixmap->setPixmap(QPixmap(result)); // 设置图片
|
||||
mPixmap->setPixmap(QPixmap(filePath)); // 设置图片
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -197,14 +275,14 @@ private:
|
|||
// 左边界矩形控制点
|
||||
mLeftHandle->topLeft->setParentAnchor(mRect->topLeft);
|
||||
mLeftHandle->bottomRight->setParentAnchor(mRect->topRight);//(mRect->bottomLeft);
|
||||
mLeftHandle->topLeft->setCoords(-5, 5); // 矩形大小
|
||||
mLeftHandle->bottomRight->setCoords(5, -5); // 矩形大小
|
||||
mLeftHandle->topLeft->setCoords(-0.5, 0.5); // 矩形大小
|
||||
mLeftHandle->bottomRight->setCoords(0.5, -0.5); // 矩形大小
|
||||
|
||||
// 右边界矩形控制点
|
||||
mRightHandle->topLeft->setParentAnchor(mRect->bottomLeft);
|
||||
mRightHandle->bottomRight->setParentAnchor(mRect->bottomRight);
|
||||
mRightHandle->topLeft->setCoords(-5, 5); // 矩形大小
|
||||
mRightHandle->bottomRight->setCoords(5, -5); // 矩形大小
|
||||
mRightHandle->topLeft->setCoords(-0.5, 0.5); // 矩形大小
|
||||
mRightHandle->bottomRight->setCoords(0.5, -0.5); // 矩形大小
|
||||
|
||||
// if(m_upDraggableResult)
|
||||
// {
|
||||
|
|
|
|||
22
svg/XSVG_LICENSE.txt
Normal file
22
svg/XSVG_LICENSE.txt
Normal file
|
|
@ -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.
|
||||
49
svg/doc/qtsvg.qdocconf
Normal file
49
svg/doc/qtsvg.qdocconf
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
|
||||
|
||||
project = QtSvg
|
||||
description = Qt SVG Reference Documentation
|
||||
version = $QT_VERSION
|
||||
|
||||
qhp.projects = QtSvg
|
||||
|
||||
qhp.QtSvg.file = qtsvg.qhp
|
||||
qhp.QtSvg.namespace = org.qt-project.qtsvg.$QT_VERSION_TAG
|
||||
qhp.QtSvg.virtualFolder = qtsvg
|
||||
qhp.QtSvg.indexTitle = Qt SVG
|
||||
qhp.QtSvg.indexRoot =
|
||||
|
||||
qhp.QtSvg.filterAttributes = qtsvg $QT_VERSION qtrefdoc
|
||||
qhp.QtSvg.customFilters.Qt.name = QtSvg $QT_VERSION
|
||||
qhp.QtSvg.customFilters.Qt.filterAttributes = qtsvg $QT_VERSION
|
||||
qhp.QtSvg.subprojects = classes
|
||||
qhp.QtSvg.subprojects.classes.title = C++ Classes
|
||||
qhp.QtSvg.subprojects.classes.indexTitle = Qt SVG C++ Classes
|
||||
qhp.QtSvg.subprojects.classes.selectors = class fake:headerfile
|
||||
qhp.QtSvg.subprojects.classes.sortPages = true
|
||||
|
||||
depends += qtcore \
|
||||
qtwidgets \
|
||||
qtgui \
|
||||
qtdesigner \
|
||||
qtdoc \
|
||||
qmake
|
||||
|
||||
tagfile = ../../../doc/qtsvg/qtsvg.tags
|
||||
|
||||
headerdirs += .. \
|
||||
../../plugins/imageformats \
|
||||
../../plugins/iconengines
|
||||
|
||||
sourcedirs += .. \
|
||||
../../plugins/imageformats \
|
||||
../../plugins/iconengines
|
||||
|
||||
exampledirs += ../../../examples/svg \
|
||||
snippets/
|
||||
|
||||
examplesinstallpath = svg
|
||||
|
||||
imagedirs += images
|
||||
|
||||
navigation.landingpage = "Qt SVG"
|
||||
navigation.cppclassespage = "Qt SVG C++ Classes"
|
||||
53
svg/doc/snippets/doc_src_qtsvg.cpp
Normal file
53
svg/doc/snippets/doc_src_qtsvg.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//! [0]
|
||||
#include <QtSvg>
|
||||
//! [0]
|
||||
53
svg/doc/snippets/doc_src_qtsvg.pro
Normal file
53
svg/doc/snippets/doc_src_qtsvg.pro
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#! [1]
|
||||
QT += svg
|
||||
#! [1]
|
||||
61
svg/doc/snippets/src_svg_qgraphicssvgitem.cpp
Normal file
61
svg/doc/snippets/src_svg_qgraphicssvgitem.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//! [0]
|
||||
QSvgRenderer *renderer = new QSvgRenderer(QLatin1String("SvgCardDeck.svg"));
|
||||
QGraphicsSvgItem *black = new QGraphicsSvgItem();
|
||||
QGraphicsSvgItem *red = new QGraphicsSvgItem();
|
||||
|
||||
black->setSharedRenderer(renderer);
|
||||
black->setElementId(QLatin1String("black_joker"));
|
||||
|
||||
red->setSharedRenderer(renderer);
|
||||
red->setElementId(QLatin1String("red_joker"));
|
||||
//! [0]
|
||||
80
svg/doc/src/qtsvg-index.qdoc
Normal file
80
svg/doc/src/qtsvg-index.qdoc
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\title Qt SVG
|
||||
\page qtsvg-index.html
|
||||
\brief Qt SVG provides functionality for handling SVG images.
|
||||
|
||||
Scalable Vector Graphics (SVG) is an XML-based language for
|
||||
describing two-dimensional vector graphics. Qt provides classes
|
||||
for rendering and displaying SVG drawings in widgets and on other
|
||||
paint devices.
|
||||
|
||||
\section1 Getting Started
|
||||
|
||||
Qt SVG provides classes for rendering SVG files. To include the definitions
|
||||
of the module's classes, use the following directive:
|
||||
|
||||
\snippet doc_src_qtsvg.cpp 0
|
||||
|
||||
To link against the module, add this line to your \l qmake \c
|
||||
.pro file:
|
||||
|
||||
\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
|
||||
\endlist
|
||||
|
||||
\section1 References
|
||||
\list
|
||||
\li \l{Qt SVG C++ Classes}
|
||||
\endlist
|
||||
|
||||
Qt SVG comes with the following examples:
|
||||
|
||||
\list
|
||||
\li \l{SVG Generator Example}
|
||||
\li \l{SVG Viewer Example}
|
||||
\endlist
|
||||
*/
|
||||
41
svg/doc/src/qtsvg.qdoc
Normal file
41
svg/doc/src/qtsvg.qdoc
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\module QtSvg
|
||||
\title Qt SVG C++ Classes
|
||||
\ingroup modules
|
||||
\qtvariable svg
|
||||
|
||||
\brief The Qt SVG module provides functionality for handling SVG images.
|
||||
|
||||
Scalable Vector Graphics (SVG) is an XML-based language for
|
||||
describing two-dimensional vector graphics. Qt provides classes
|
||||
for rendering and displaying SVG drawings in widgets and on other
|
||||
paint devices. See the class descriptions for further details.
|
||||
|
||||
*/
|
||||
78
svg/doc/src/svgrendering.qdoc
Normal file
78
svg/doc/src/svgrendering.qdoc
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\page svgrendering.html
|
||||
\title Rendering SVG Files
|
||||
\brief Rendering SVG files with the Qt SVG module
|
||||
|
||||
Qt SVG provides classes for rendering SVG files. To include the definitions
|
||||
of the module's classes, use the following directive:
|
||||
|
||||
\snippet doc_src_qtsvg.cpp 0
|
||||
|
||||
To link against the module, add this line to your \l qmake \c
|
||||
.pro file:
|
||||
|
||||
\snippet doc_src_qtsvg.pro 1
|
||||
|
||||
\section1 Rendering SVG Files
|
||||
|
||||
Scalable Vector Graphics (SVG) is a language for describing two-dimensional
|
||||
graphics and graphical applications in XML. SVG 1.1 is a W3C Recommendation
|
||||
and forms the core of the current SVG developments in Qt. SVG 1.2 is the
|
||||
specification currently being developed by the \l{SVG Working Group}, and it
|
||||
is \l{http://www.w3.org/TR/SVG12/}{available in draft form}. The \l{Mobile
|
||||
SVG Profiles} (SVG Basic and SVG Tiny) are aimed at resource-limited devices
|
||||
and are part of the 3GPP platform for third generation mobile phones. You
|
||||
can read more about SVG at \l{About SVG}.
|
||||
|
||||
Qt supports the \l{SVG 1.2 Tiny Static Features}{static features} of
|
||||
\l{http://www.w3.org/TR/SVGMobile12}{SVG 1.2 Tiny}. ECMA scripts and DOM manipulation are currently not
|
||||
supported.
|
||||
|
||||
SVG drawings can be rendered onto any QPaintDevice subclass. This
|
||||
approach gives developers the flexibility to experiment, in order
|
||||
to find the best solution for each application.
|
||||
|
||||
The easiest way to render SVG files is to construct a QSvgWidget and
|
||||
load an SVG file using one of the QSvgWidget::load() functions.
|
||||
|
||||
QSvgRenderer is the class responsible for rendering SVG files for
|
||||
QSvgWidget, and it can be used directly to provide SVG support for
|
||||
custom widgets.
|
||||
To load an SVG file, construct a QSvgRenderer with a file name or the
|
||||
contents of a file, or call QSvgRenderer::load() on an existing
|
||||
renderer. If the SVG file has been loaded successfully the
|
||||
QSvgRenderer::isValid() will return true.
|
||||
|
||||
Once you have loaded the SVG file successfully, you can render it
|
||||
with the QSvgRenderer::render() function. Note that this scheme allows
|
||||
you to render SVG files on all paint devices supported by Qt, including
|
||||
QWidget, QGLWidget, and QImage. See the \l{SVG Viewer Example}{SVG Viewer}
|
||||
example for more details.
|
||||
*/
|
||||
388
svg/qgraphicssvgitem.cpp
Normal file
388
svg/qgraphicssvgitem.cpp
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "qgraphicssvgitem.h"
|
||||
|
||||
#if !defined(QT_NO_GRAPHICSVIEW) && !defined(QT_NO_WIDGETS)
|
||||
|
||||
#include "qpainter.h"
|
||||
#include "qstyleoption.h"
|
||||
#include "qsvgrenderer.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#include "private/qobject_p.h"
|
||||
#include "private/qgraphicsitem_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QGraphicsSvgItemPrivate : public QGraphicsItemPrivate
|
||||
{
|
||||
public:
|
||||
Q_DECLARE_PUBLIC(QGraphicsSvgItem)
|
||||
|
||||
QGraphicsSvgItemPrivate()
|
||||
: renderer(0), shared(false)
|
||||
{
|
||||
}
|
||||
|
||||
void init(QGraphicsItem *parent)
|
||||
{
|
||||
Q_Q(QGraphicsSvgItem);
|
||||
q->setParentItem(parent);
|
||||
renderer = new QSvgRenderer(q);
|
||||
QObject::connect(renderer, SIGNAL(repaintNeeded()),
|
||||
q, SLOT(_q_repaintItem()));
|
||||
q->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
|
||||
q->setMaximumCacheSize(QSize(1024, 768));
|
||||
}
|
||||
|
||||
void _q_repaintItem()
|
||||
{
|
||||
q_func()->update();
|
||||
}
|
||||
|
||||
inline void updateDefaultSize()
|
||||
{
|
||||
QRectF bounds;
|
||||
if (elemId.isEmpty()) {
|
||||
bounds = QRectF(QPointF(0, 0), renderer->defaultSize());
|
||||
} else {
|
||||
bounds = renderer->boundsOnElement(elemId);
|
||||
}
|
||||
if (boundingRect.size() != bounds.size()) {
|
||||
q_func()->prepareGeometryChange();
|
||||
boundingRect.setSize(bounds.size());
|
||||
}
|
||||
}
|
||||
|
||||
QSvgRenderer *renderer;
|
||||
QRectF boundingRect;
|
||||
bool shared;
|
||||
QString elemId;
|
||||
};
|
||||
|
||||
/*!
|
||||
\class QGraphicsSvgItem
|
||||
\inmodule QtSvg
|
||||
\ingroup graphicsview-api
|
||||
\brief The QGraphicsSvgItem class is a QGraphicsItem that can be used to render
|
||||
the contents of SVG files.
|
||||
|
||||
\since 4.2
|
||||
|
||||
QGraphicsSvgItem provides a way of rendering SVG files onto QGraphicsView.
|
||||
QGraphicsSvgItem can be created by passing the SVG file to be rendered to
|
||||
its constructor or by explicit setting a shared QSvgRenderer on it.
|
||||
|
||||
Note that setting QSvgRenderer on a QGraphicsSvgItem doesn't make the item take
|
||||
ownership of the renderer, therefore if using setSharedRenderer() method one has
|
||||
to make sure that the lifetime of the QSvgRenderer object will be at least as long
|
||||
as that of the QGraphicsSvgItem.
|
||||
|
||||
QGraphicsSvgItem provides a way of rendering only parts of the SVG files via
|
||||
the setElementId. If setElementId() method is called, only the SVG element
|
||||
(and its children) with the passed id will be renderer. This provides a convenient
|
||||
way of selectively rendering large SVG files that contain a number of discrete
|
||||
elements. For example the following code renders only jokers from a SVG file
|
||||
containing a whole card deck:
|
||||
|
||||
\snippet src_svg_qgraphicssvgitem.cpp 0
|
||||
|
||||
Size of the item can be set via direct manipulation of the items
|
||||
transformation matrix.
|
||||
|
||||
By default the SVG rendering is cached using QGraphicsItem::DeviceCoordinateCache
|
||||
mode to speedup the display of items. Caching can be disabled by passing
|
||||
QGraphicsItem::NoCache to the QGraphicsItem::setCacheMode() method.
|
||||
|
||||
\sa QSvgWidget, {Qt SVG C++ Classes}, QGraphicsItem, QGraphicsView
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs a new SVG item with the given \a parent.
|
||||
*/
|
||||
QGraphicsSvgItem::QGraphicsSvgItem(QGraphicsItem *parent)
|
||||
: QGraphicsObject(*new QGraphicsSvgItemPrivate(), 0)
|
||||
{
|
||||
Q_D(QGraphicsSvgItem);
|
||||
d->init(parent);
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new item with the given \a parent and loads the contents of the
|
||||
SVG file with the specified \a fileName.
|
||||
*/
|
||||
QGraphicsSvgItem::QGraphicsSvgItem(const QString &fileName, QGraphicsItem *parent)
|
||||
: QGraphicsObject(*new QGraphicsSvgItemPrivate(), 0)
|
||||
{
|
||||
Q_D(QGraphicsSvgItem);
|
||||
d->init(parent);
|
||||
d->renderer->load(fileName);
|
||||
d->updateDefaultSize();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the currently use QSvgRenderer.
|
||||
*/
|
||||
QSvgRenderer *QGraphicsSvgItem::renderer() const
|
||||
{
|
||||
return d_func()->renderer;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Returns the bounding rectangle of this item.
|
||||
*/
|
||||
QRectF QGraphicsSvgItem::boundingRect() const
|
||||
{
|
||||
Q_D(const QGraphicsSvgItem);
|
||||
return d->boundingRect;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
Highlights \a item as selected.
|
||||
|
||||
NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in qgraphicsitem.cpp!
|
||||
*/
|
||||
static void qt_graphicsItem_highlightSelected(
|
||||
QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
|
||||
{
|
||||
const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
|
||||
if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
|
||||
return;
|
||||
|
||||
const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
|
||||
if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
|
||||
return;
|
||||
|
||||
qreal itemPenWidth;
|
||||
switch (item->type()) {
|
||||
case QGraphicsEllipseItem::Type:
|
||||
itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
|
||||
break;
|
||||
case QGraphicsPathItem::Type:
|
||||
itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
|
||||
break;
|
||||
case QGraphicsPolygonItem::Type:
|
||||
itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
|
||||
break;
|
||||
case QGraphicsRectItem::Type:
|
||||
itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
|
||||
break;
|
||||
case QGraphicsSimpleTextItem::Type:
|
||||
itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
|
||||
break;
|
||||
case QGraphicsLineItem::Type:
|
||||
itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
|
||||
break;
|
||||
default:
|
||||
itemPenWidth = 1.0;
|
||||
}
|
||||
const qreal pad = itemPenWidth / 2;
|
||||
|
||||
const qreal penWidth = 0; // cosmetic pen
|
||||
|
||||
const QColor fgcolor = option->palette.windowText().color();
|
||||
const QColor bgcolor( // ensure good contrast against fgcolor
|
||||
fgcolor.red() > 127 ? 0 : 255,
|
||||
fgcolor.green() > 127 ? 0 : 255,
|
||||
fgcolor.blue() > 127 ? 0 : 255);
|
||||
|
||||
painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
|
||||
|
||||
painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QGraphicsSvgItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget)
|
||||
{
|
||||
// Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
Q_D(QGraphicsSvgItem);
|
||||
if (!d->renderer->isValid())
|
||||
return;
|
||||
|
||||
if (d->elemId.isEmpty())
|
||||
d->renderer->render(painter, d->boundingRect);
|
||||
else
|
||||
d->renderer->render(painter, d->elemId, d->boundingRect);
|
||||
|
||||
if (option->state & QStyle::State_Selected)
|
||||
qt_graphicsItem_highlightSelected(this, painter, option);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
int QGraphicsSvgItem::type() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QGraphicsSvgItem::maximumCacheSize
|
||||
\since 4.6
|
||||
|
||||
This property holds the maximum size of the device coordinate cache
|
||||
for this item.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Sets the maximum device coordinate cache size of the item to \a size.
|
||||
If the item is cached using QGraphicsItem::DeviceCoordinateCache mode,
|
||||
caching is bypassed if the extension of the item in device coordinates
|
||||
is larger than \a size.
|
||||
|
||||
The cache corresponds to the QPixmap which is used to cache the
|
||||
results of the rendering.
|
||||
Use QPixmapCache::setCacheLimit() to set limitations on the whole cache
|
||||
and use setMaximumCacheSize() when setting cache size for individual
|
||||
items.
|
||||
|
||||
\sa QGraphicsItem::cacheMode()
|
||||
*/
|
||||
void QGraphicsSvgItem::setMaximumCacheSize(const QSize &size)
|
||||
{
|
||||
QGraphicsItem::d_ptr->setExtra(QGraphicsItemPrivate::ExtraMaxDeviceCoordCacheSize, size);
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the current maximum size of the device coordinate cache for this item.
|
||||
If the item is cached using QGraphicsItem::DeviceCoordinateCache mode,
|
||||
caching is bypassed if the extension of the item in device coordinates
|
||||
is larger than the maximum size.
|
||||
|
||||
The default maximum cache size is 1024x768.
|
||||
QPixmapCache::cacheLimit() gives the
|
||||
cumulative bounds of the whole cache, whereas maximumCacheSize() refers
|
||||
to a maximum cache size for this particular item.
|
||||
|
||||
\sa QGraphicsItem::cacheMode()
|
||||
*/
|
||||
QSize QGraphicsSvgItem::maximumCacheSize() const
|
||||
{
|
||||
return QGraphicsItem::d_ptr->extra(QGraphicsItemPrivate::ExtraMaxDeviceCoordCacheSize).toSize();
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QGraphicsSvgItem::elementId
|
||||
\since 4.6
|
||||
|
||||
This property holds the element's XML ID.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Sets the XML ID of the element to \a id.
|
||||
*/
|
||||
void QGraphicsSvgItem::setElementId(const QString &id)
|
||||
{
|
||||
Q_D(QGraphicsSvgItem);
|
||||
d->elemId = id;
|
||||
d->updateDefaultSize();
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the XML ID the element that is currently
|
||||
being rendered. Returns an empty string if the whole
|
||||
file is being rendered.
|
||||
*/
|
||||
QString QGraphicsSvgItem::elementId() const
|
||||
{
|
||||
Q_D(const QGraphicsSvgItem);
|
||||
return d->elemId;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets \a renderer to be a shared QSvgRenderer on the item. By
|
||||
using this method one can share the same QSvgRenderer on a number
|
||||
of items. This means that the SVG file will be parsed only once.
|
||||
QSvgRenderer passed to this method has to exist for as long as
|
||||
this item is used.
|
||||
*/
|
||||
void QGraphicsSvgItem::setSharedRenderer(QSvgRenderer *renderer)
|
||||
{
|
||||
Q_D(QGraphicsSvgItem);
|
||||
if (!d->shared)
|
||||
delete d->renderer;
|
||||
|
||||
d->renderer = renderer;
|
||||
d->shared = true;
|
||||
|
||||
d->updateDefaultSize();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
\obsolete
|
||||
|
||||
Use QGraphicsItem::setCacheMode() instead. Passing true to this function is equivalent
|
||||
to QGraphicsItem::setCacheMode(QGraphicsItem::DeviceCoordinateCache).
|
||||
*/
|
||||
void QGraphicsSvgItem::setCachingEnabled(bool caching)
|
||||
{
|
||||
setCacheMode(caching ? QGraphicsItem::DeviceCoordinateCache : QGraphicsItem::NoCache);
|
||||
}
|
||||
|
||||
/*!
|
||||
\obsolete
|
||||
|
||||
Use QGraphicsItem::cacheMode() instead.
|
||||
*/
|
||||
bool QGraphicsSvgItem::isCachingEnabled() const
|
||||
{
|
||||
return cacheMode() != QGraphicsItem::NoCache;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_qgraphicssvgitem.cpp"
|
||||
|
||||
#endif // QT_NO_WIDGETS
|
||||
99
svg/qgraphicssvgitem.h
Normal file
99
svg/qgraphicssvgitem.h
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#ifndef QGRAPHICSSVGITEM_H
|
||||
#define QGRAPHICSSVGITEM_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if !defined(QT_NO_GRAPHICSVIEW) && !defined(QT_NO_WIDGETS)
|
||||
|
||||
#include <QtWidgets/qgraphicsitem.h>
|
||||
|
||||
#include <QtSvg/qtsvgglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QSvgRenderer;
|
||||
class QGraphicsSvgItemPrivate;
|
||||
|
||||
class Q_SVG_EXPORT QGraphicsSvgItem : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QGraphicsItem)
|
||||
Q_PROPERTY(QString elementId READ elementId WRITE setElementId)
|
||||
Q_PROPERTY(QSize maximumCacheSize READ maximumCacheSize WRITE setMaximumCacheSize)
|
||||
|
||||
public:
|
||||
QGraphicsSvgItem(QGraphicsItem *parentItem = nullptr);
|
||||
QGraphicsSvgItem(const QString &fileName, QGraphicsItem *parentItem = nullptr);
|
||||
|
||||
void setSharedRenderer(QSvgRenderer *renderer);
|
||||
QSvgRenderer *renderer() const;
|
||||
|
||||
void setElementId(const QString &id);
|
||||
QString elementId() const;
|
||||
|
||||
void setCachingEnabled(bool);
|
||||
bool isCachingEnabled() const;
|
||||
|
||||
void setMaximumCacheSize(const QSize &size);
|
||||
QSize maximumCacheSize() const;
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
|
||||
void paint(QPainter *painter,
|
||||
const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget = nullptr) override;
|
||||
|
||||
enum { Type = 13 };
|
||||
int type() const override;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QGraphicsSvgItem)
|
||||
Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsSvgItem)
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_repaintItem())
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_GRAPHICSVIEW or QT_NO_WIDGETS
|
||||
|
||||
#endif // QGRAPHICSSVGITEM_H
|
||||
136
svg/qsvgfont.cpp
Normal file
136
svg/qsvgfont.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsvgfont_p.h"
|
||||
|
||||
#include "qpainter.h"
|
||||
#include "qpen.h"
|
||||
#include "qdebug.h"
|
||||
#include "qpicture.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QSvgGlyph::QSvgGlyph(QChar unicode, const QPainterPath &path, qreal horizAdvX)
|
||||
: m_unicode(unicode), m_path(path), m_horizAdvX(horizAdvX)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
QSvgFont::QSvgFont(qreal horizAdvX)
|
||||
: m_horizAdvX(horizAdvX)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QString QSvgFont::familyName() const
|
||||
{
|
||||
return m_familyName;
|
||||
}
|
||||
|
||||
|
||||
void QSvgFont::addGlyph(QChar unicode, const QPainterPath &path, qreal horizAdvX )
|
||||
{
|
||||
m_glyphs.insert(unicode, QSvgGlyph(unicode, path,
|
||||
(horizAdvX==-1)?m_horizAdvX:horizAdvX));
|
||||
}
|
||||
|
||||
|
||||
void QSvgFont::draw(QPainter *p, const QPointF &point, const QString &str, qreal pixelSize, Qt::Alignment alignment) const
|
||||
{
|
||||
p->save();
|
||||
p->translate(point);
|
||||
p->scale(pixelSize / m_unitsPerEm, -pixelSize / m_unitsPerEm);
|
||||
|
||||
// Calculate the text width to be used for alignment
|
||||
int textWidth = 0;
|
||||
QString::const_iterator itr = str.constBegin();
|
||||
for ( ; itr != str.constEnd(); ++itr) {
|
||||
QChar unicode = *itr;
|
||||
if (!m_glyphs.contains(*itr)) {
|
||||
unicode = 0;
|
||||
if (!m_glyphs.contains(unicode))
|
||||
continue;
|
||||
}
|
||||
textWidth += static_cast<int>(m_glyphs[unicode].m_horizAdvX);
|
||||
}
|
||||
|
||||
QPoint alignmentOffset(0, 0);
|
||||
if (alignment == Qt::AlignHCenter) {
|
||||
alignmentOffset.setX(-textWidth / 2);
|
||||
} else if (alignment == Qt::AlignRight) {
|
||||
alignmentOffset.setX(-textWidth);
|
||||
}
|
||||
|
||||
p->translate(alignmentOffset);
|
||||
|
||||
// since in SVG the embedded font ain't really a path
|
||||
// the outline has got to stay untransformed...
|
||||
qreal penWidth = p->pen().widthF();
|
||||
penWidth /= (pixelSize/m_unitsPerEm);
|
||||
QPen pen = p->pen();
|
||||
pen.setWidthF(penWidth);
|
||||
p->setPen(pen);
|
||||
|
||||
itr = str.constBegin();
|
||||
for ( ; itr != str.constEnd(); ++itr) {
|
||||
QChar unicode = *itr;
|
||||
if (!m_glyphs.contains(*itr)) {
|
||||
unicode = 0;
|
||||
if (!m_glyphs.contains(unicode))
|
||||
continue;
|
||||
}
|
||||
p->drawPath(m_glyphs[unicode].m_path);
|
||||
p->translate(m_glyphs[unicode].m_horizAdvX, 0);
|
||||
}
|
||||
|
||||
p->restore();
|
||||
}
|
||||
|
||||
void QSvgFont::setFamilyName(const QString &name)
|
||||
{
|
||||
m_familyName = name;
|
||||
}
|
||||
|
||||
void QSvgFont::setUnitsPerEm(qreal upem)
|
||||
{
|
||||
m_unitsPerEm = upem;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
98
svg/qsvgfont_p.h
Normal file
98
svg/qsvgfont_p.h
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGFONT_P_H
|
||||
#define QSVGFONT_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qpainterpath.h"
|
||||
#include "qhash.h"
|
||||
#include "qstring.h"
|
||||
#include "qsvgstyle_p.h"
|
||||
#include "qtsvgglobal_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgGlyph
|
||||
{
|
||||
public:
|
||||
QSvgGlyph(QChar unicode, const QPainterPath &path, qreal horizAdvX);
|
||||
QSvgGlyph() : m_unicode(0), m_horizAdvX(0) {}
|
||||
|
||||
QChar m_unicode;
|
||||
QPainterPath m_path;
|
||||
qreal m_horizAdvX;
|
||||
};
|
||||
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgFont : public QSvgRefCounted
|
||||
{
|
||||
public:
|
||||
QSvgFont(qreal horizAdvX);
|
||||
|
||||
void setFamilyName(const QString &name);
|
||||
QString familyName() const;
|
||||
|
||||
void setUnitsPerEm(qreal upem);
|
||||
|
||||
void addGlyph(QChar unicode, const QPainterPath &path, qreal horizAdvX = -1);
|
||||
|
||||
void draw(QPainter *p, const QPointF &point, const QString &str, qreal pixelSize, Qt::Alignment alignment) const;
|
||||
public:
|
||||
QString m_familyName;
|
||||
qreal m_unitsPerEm;
|
||||
qreal m_ascent;
|
||||
qreal m_descent;
|
||||
qreal m_horizAdvX;
|
||||
QHash<QChar, QSvgGlyph> m_glyphs;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSVGFONT_P_H
|
||||
1163
svg/qsvggenerator.cpp
Normal file
1163
svg/qsvggenerator.cpp
Normal file
File diff suppressed because it is too large
Load Diff
106
svg/qsvggenerator.h
Normal file
106
svg/qsvggenerator.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGGENERATOR_H
|
||||
#define QSVGGENERATOR_H
|
||||
|
||||
#include <QtGui/qpaintdevice.h>
|
||||
|
||||
#ifndef QT_NO_SVGGENERATOR
|
||||
|
||||
#include <QtCore/qnamespace.h>
|
||||
#include <QtCore/qiodevice.h>
|
||||
#include <QtCore/qobjectdefs.h>
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
#include <QtSvg/qtsvgglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QSvgGeneratorPrivate;
|
||||
|
||||
class Q_SVG_EXPORT QSvgGenerator : public QPaintDevice
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QSvgGenerator)
|
||||
|
||||
Q_PROPERTY(QSize size READ size WRITE setSize)
|
||||
Q_PROPERTY(QRectF viewBox READ viewBoxF WRITE setViewBox)
|
||||
Q_PROPERTY(QString title READ title WRITE setTitle)
|
||||
Q_PROPERTY(QString description READ description WRITE setDescription)
|
||||
Q_PROPERTY(QString fileName READ fileName WRITE setFileName)
|
||||
Q_PROPERTY(QIODevice* outputDevice READ outputDevice WRITE setOutputDevice)
|
||||
Q_PROPERTY(int resolution READ resolution WRITE setResolution)
|
||||
public:
|
||||
QSvgGenerator();
|
||||
~QSvgGenerator();
|
||||
|
||||
QString title() const;
|
||||
void setTitle(const QString &title);
|
||||
|
||||
QString description() const;
|
||||
void setDescription(const QString &description);
|
||||
|
||||
QSize size() const;
|
||||
void setSize(const QSize &size);
|
||||
|
||||
QRect viewBox() const;
|
||||
QRectF viewBoxF() const;
|
||||
void setViewBox(const QRect &viewBox);
|
||||
void setViewBox(const QRectF &viewBox);
|
||||
|
||||
QString fileName() const;
|
||||
void setFileName(const QString &fileName);
|
||||
|
||||
QIODevice *outputDevice() const;
|
||||
void setOutputDevice(QIODevice *outputDevice);
|
||||
|
||||
void setResolution(int dpi);
|
||||
int resolution() const;
|
||||
protected:
|
||||
QPaintEngine *paintEngine() const override;
|
||||
int metric(QPaintDevice::PaintDeviceMetric metric) const override;
|
||||
|
||||
private:
|
||||
QScopedPointer<QSvgGeneratorPrivate> d_ptr;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_SVGGENERATOR
|
||||
#endif // QSVGGENERATOR_H
|
||||
1035
svg/qsvggraphics.cpp
Normal file
1035
svg/qsvggraphics.cpp
Normal file
File diff suppressed because it is too large
Load Diff
274
svg/qsvggraphics_p.h
Normal file
274
svg/qsvggraphics_p.h
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGGRAPHICS_P_H
|
||||
#define QSVGGRAPHICS_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qsvgnode_p.h"
|
||||
#include "qtsvgglobal_p.h"
|
||||
|
||||
#include "QtGui/qpainterpath.h"
|
||||
#include "QtGui/qimage.h"
|
||||
#include "QtGui/qtextlayout.h"
|
||||
#include "QtGui/qtextoption.h"
|
||||
#include "QtCore/qstack.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTextCharFormat;
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgAnimation : public QSvgNode
|
||||
{
|
||||
public:
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgArc : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgArc(QSvgNode *parent, const QPainterPath &path);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
private:
|
||||
QPainterPath m_path;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgEllipse : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgEllipse(QSvgNode *parent, const QRectF &rect);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
private:
|
||||
QRectF m_bounds;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgCircle : public QSvgEllipse
|
||||
{
|
||||
public:
|
||||
QSvgCircle(QSvgNode *parent, const QRectF &rect) : QSvgEllipse(parent, rect) { }
|
||||
Type type() const override;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgImage : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgImage(QSvgNode *parent, const QImage &image,
|
||||
const QRectF &bounds);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
private:
|
||||
QImage m_image;
|
||||
QRectF m_bounds;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgLine : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgLine(QSvgNode *parent, const QLineF &line);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
private:
|
||||
QLineF m_line;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgPath : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgPath(QSvgNode *parent, const QPainterPath &qpath);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
|
||||
QPainterPath *qpath() {
|
||||
return &m_path;
|
||||
}
|
||||
private:
|
||||
QPainterPath m_path;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgPolygon : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgPolygon(QSvgNode *parent, const QPolygonF &poly);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
private:
|
||||
QPolygonF m_poly;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgPolyline : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgPolyline(QSvgNode *parent, const QPolygonF &poly);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
private:
|
||||
QPolygonF m_poly;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgRect : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgRect(QSvgNode *paren, const QRectF &rect, int rx=0, int ry=0);
|
||||
Type type() const override;
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
void SetRect(QRectF rect);
|
||||
QRectF &rect();
|
||||
private:
|
||||
QRectF m_rect;
|
||||
int m_rx, m_ry;
|
||||
};
|
||||
|
||||
class QSvgTspan;
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgText : public QSvgNode
|
||||
{
|
||||
public:
|
||||
enum WhitespaceMode
|
||||
{
|
||||
Default,
|
||||
Preserve
|
||||
};
|
||||
|
||||
QSvgText(QSvgNode *parent, const QPointF &coord);
|
||||
~QSvgText();
|
||||
void setTextArea(const QSizeF &size);
|
||||
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
|
||||
void addTspan(QSvgTspan *tspan) {m_tspans.append(tspan);}
|
||||
void addText(const QString &text);
|
||||
void addLineBreak() {m_tspans.append(LINEBREAK);}
|
||||
void setWhitespaceMode(WhitespaceMode mode) {m_mode = mode;}
|
||||
|
||||
//QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
private:
|
||||
static QSvgTspan * const LINEBREAK;
|
||||
|
||||
QPointF m_coord;
|
||||
|
||||
// 'm_tspans' is also used to store characters outside tspans and line breaks.
|
||||
// If a 'm_tspan' item is null, it indicates a line break.
|
||||
QVector<QSvgTspan *> m_tspans;
|
||||
|
||||
Type m_type;
|
||||
QSizeF m_size;
|
||||
WhitespaceMode m_mode;
|
||||
public:
|
||||
void draw(QPainter *p, QSvgExtraStates &states,QRectF bounds,QTransform &oldTransform,QRectF &sourceRect,QMatrix &b);
|
||||
QVector<QSvgTspan *>&Tspans()
|
||||
{
|
||||
return m_tspans;
|
||||
}
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgTspan : public QSvgNode
|
||||
{
|
||||
public:
|
||||
// tspans are also used to store normal text, so the 'isProperTspan' is used to separate text from tspan.
|
||||
QSvgTspan(QSvgNode *parent, bool isProperTspan = true)
|
||||
: QSvgNode(parent), m_mode(QSvgText::Default), m_isTspan(isProperTspan)
|
||||
{
|
||||
}
|
||||
~QSvgTspan() { };
|
||||
Type type() const override { return TSPAN; }
|
||||
void draw(QPainter *, QSvgExtraStates &) override { Q_ASSERT(!"Tspans should be drawn through QSvgText::draw()."); }
|
||||
void addText(const QString &text) {m_text += text;}
|
||||
const QString &text() const {return m_text;}
|
||||
bool isTspan() const {return m_isTspan;}
|
||||
void setWhitespaceMode(QSvgText::WhitespaceMode mode) {m_mode = mode;}
|
||||
QSvgText::WhitespaceMode whitespaceMode() const {return m_mode;}
|
||||
private:
|
||||
QString m_text;
|
||||
QSvgText::WhitespaceMode m_mode;
|
||||
bool m_isTspan;
|
||||
};
|
||||
|
||||
class QSvgUse : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgUse(const QPointF &start, QSvgNode *parent, QSvgNode *link);
|
||||
QSvgUse(const QPointF &start, QSvgNode *parent, const QString &linkId)
|
||||
: QSvgUse(start, parent, nullptr)
|
||||
{ m_linkId = linkId; }
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
bool isResolved() const { return m_link != nullptr; }
|
||||
QString linkId() const { return m_linkId; }
|
||||
void setLink(QSvgNode *link) { m_link = link; }
|
||||
|
||||
private:
|
||||
QSvgNode *m_link;
|
||||
QPointF m_start;
|
||||
QString m_linkId;
|
||||
mutable bool m_recursing;
|
||||
};
|
||||
|
||||
class QSvgVideo : public QSvgNode
|
||||
{
|
||||
public:
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSVGGRAPHICS_P_H
|
||||
4120
svg/qsvghandler.cpp
Normal file
4120
svg/qsvghandler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
196
svg/qsvghandler_p.h
Normal file
196
svg/qsvghandler_p.h
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGHANDLER_P_H
|
||||
#define QSVGHANDLER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "QtCore/qxmlstream.h"
|
||||
#include "QtCore/qhash.h"
|
||||
#include "QtCore/qstack.h"
|
||||
#include <QtCore/QLoggingCategory>
|
||||
#include "qsvgstyle_p.h"
|
||||
#include "private/qcssparser_p.h"
|
||||
#include "qsvggraphics_p.h"
|
||||
#include "qtsvgglobal_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSvgNode;
|
||||
class QSvgTinyDocument;
|
||||
class QSvgHandler;
|
||||
class QColor;
|
||||
class QSvgStyleSelector;
|
||||
class QXmlStreamReader;
|
||||
|
||||
#ifndef QT_NO_CSSPARSER
|
||||
|
||||
struct QSvgCssAttribute
|
||||
{
|
||||
QXmlStreamStringRef name;
|
||||
QXmlStreamStringRef value;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgHandler
|
||||
{
|
||||
public:
|
||||
enum LengthType {
|
||||
LT_PERCENT,
|
||||
LT_PX,
|
||||
LT_PC,
|
||||
LT_PT,
|
||||
LT_MM,
|
||||
LT_CM,
|
||||
LT_IN,
|
||||
LT_OTHER
|
||||
};
|
||||
|
||||
public:
|
||||
QSvgHandler(QIODevice *device);
|
||||
QSvgHandler(const QByteArray &data);
|
||||
QSvgHandler(QXmlStreamReader *const data);
|
||||
~QSvgHandler();
|
||||
|
||||
QIODevice *device() const;
|
||||
QSvgTinyDocument *document() const;
|
||||
|
||||
inline bool ok() const {
|
||||
return document() != 0 && !xml->hasError();
|
||||
}
|
||||
|
||||
inline QString errorString() const { return xml->errorString(); }
|
||||
inline int lineNumber() const { return xml->lineNumber(); }
|
||||
|
||||
void setDefaultCoordinateSystem(LengthType type);
|
||||
LengthType defaultCoordinateSystem() const;
|
||||
|
||||
void pushColor(const QColor &color);
|
||||
void pushColorCopy();
|
||||
void popColor();
|
||||
QColor currentColor() const;
|
||||
|
||||
#ifndef QT_NO_CSSPARSER
|
||||
void setInStyle(bool b);
|
||||
bool inStyle() const;
|
||||
|
||||
QSvgStyleSelector *selector() const;
|
||||
#endif
|
||||
|
||||
void setAnimPeriod(int start, int end);
|
||||
int animationDuration() const;
|
||||
|
||||
#ifndef QT_NO_CSSPARSER
|
||||
void parseCSStoXMLAttrs(QString css, QVector<QSvgCssAttribute> *attributes);
|
||||
#endif
|
||||
|
||||
inline QPen defaultPen() const
|
||||
{ return m_defaultPen; }
|
||||
|
||||
public:
|
||||
bool startElement(const QString &localName, const QXmlStreamAttributes &attributes);
|
||||
bool endElement(const QStringRef &localName);
|
||||
bool characters(const QStringRef &str);
|
||||
bool processingInstruction(const QString &target, const QString &data);
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
QSvgTinyDocument *m_doc;
|
||||
QStack<QSvgNode*> m_nodes;
|
||||
|
||||
QList<QSvgNode*> m_resolveNodes;
|
||||
|
||||
enum CurrentNode
|
||||
{
|
||||
Unknown,
|
||||
Graphics,
|
||||
Style
|
||||
};
|
||||
QStack<CurrentNode> m_skipNodes;
|
||||
|
||||
/*!
|
||||
Follows the depths of elements. The top is current xml:space
|
||||
value that applies for a given element.
|
||||
*/
|
||||
QStack<QSvgText::WhitespaceMode> m_whitespaceMode;
|
||||
|
||||
QSvgRefCounter<QSvgStyleProperty> m_style;
|
||||
|
||||
LengthType m_defaultCoords;
|
||||
|
||||
QStack<QColor> m_colorStack;
|
||||
QStack<int> m_colorTagCount;
|
||||
|
||||
int m_animEnd;
|
||||
|
||||
QXmlStreamReader *const xml;
|
||||
#ifndef QT_NO_CSSPARSER
|
||||
bool m_inStyle;
|
||||
QSvgStyleSelector *m_selector;
|
||||
QCss::Parser m_cssParser;
|
||||
#endif
|
||||
void parse();
|
||||
void resolveGradients(QSvgNode *node);
|
||||
void resolveNodes();
|
||||
|
||||
QPen m_defaultPen;
|
||||
/**
|
||||
* Whether we own the variable xml, and hence whether
|
||||
* we need to delete it.
|
||||
*/
|
||||
const bool m_ownsReader;
|
||||
};
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcSvgHandler)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSVGHANDLER_P_H
|
||||
350
svg/qsvgnode.cpp
Normal file
350
svg/qsvgnode.cpp
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsvgnode_p.h"
|
||||
#include "qsvgtinydocument_p.h"
|
||||
|
||||
#include "qdebug.h"
|
||||
#include "qstack.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QSvgNode::QSvgNode(QSvgNode *parent)
|
||||
: m_parent(parent),
|
||||
m_visible(true),
|
||||
m_displayMode(BlockMode)
|
||||
{
|
||||
}
|
||||
|
||||
QSvgNode::~QSvgNode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool QSvgNode::isDescendantOf(const QSvgNode *parent) const
|
||||
{
|
||||
const QSvgNode *n = this;
|
||||
while (n) {
|
||||
if (n == parent)
|
||||
return true;
|
||||
n = n->m_parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void QSvgNode::appendStyleProperty(QSvgStyleProperty *prop, const QString &id)
|
||||
{
|
||||
//qDebug()<<"appending "<<prop->type()<< " ("<< id <<") "<<"to "<<this<<this->type();
|
||||
QSvgTinyDocument *doc;
|
||||
switch (prop->type()) {
|
||||
case QSvgStyleProperty::QUALITY:
|
||||
m_style.quality = static_cast<QSvgQualityStyle*>(prop);
|
||||
break;
|
||||
case QSvgStyleProperty::FILL:
|
||||
m_style.fill = static_cast<QSvgFillStyle*>(prop);
|
||||
break;
|
||||
case QSvgStyleProperty::VIEWPORT_FILL:
|
||||
m_style.viewportFill = static_cast<QSvgViewportFillStyle*>(prop);
|
||||
break;
|
||||
case QSvgStyleProperty::FONT:
|
||||
m_style.font = static_cast<QSvgFontStyle*>(prop);
|
||||
break;
|
||||
case QSvgStyleProperty::STROKE:
|
||||
m_style.stroke = static_cast<QSvgStrokeStyle*>(prop);
|
||||
break;
|
||||
case QSvgStyleProperty::SOLID_COLOR:
|
||||
m_style.solidColor = static_cast<QSvgSolidColorStyle*>(prop);
|
||||
doc = document();
|
||||
if (doc && !id.isEmpty())
|
||||
doc->addNamedStyle(id, m_style.solidColor);
|
||||
break;
|
||||
case QSvgStyleProperty::GRADIENT:
|
||||
m_style.gradient = static_cast<QSvgGradientStyle*>(prop);
|
||||
doc = document();
|
||||
if (doc && !id.isEmpty())
|
||||
doc->addNamedStyle(id, m_style.gradient);
|
||||
break;
|
||||
case QSvgStyleProperty::TRANSFORM:
|
||||
m_style.transform = static_cast<QSvgTransformStyle*>(prop);
|
||||
break;
|
||||
case QSvgStyleProperty::ANIMATE_COLOR:
|
||||
m_style.animateColor = static_cast<QSvgAnimateColor*>(prop);
|
||||
break;
|
||||
case QSvgStyleProperty::ANIMATE_TRANSFORM:
|
||||
m_style.animateTransforms.append(
|
||||
static_cast<QSvgAnimateTransform*>(prop));
|
||||
break;
|
||||
case QSvgStyleProperty::OPACITY:
|
||||
m_style.opacity = static_cast<QSvgOpacityStyle*>(prop);
|
||||
break;
|
||||
case QSvgStyleProperty::COMP_OP:
|
||||
m_style.compop = static_cast<QSvgCompOpStyle*>(prop);
|
||||
break;
|
||||
default:
|
||||
qDebug("QSvgNode: Trying to append unknown property!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QSvgNode::applyStyle(QPainter *p, QSvgExtraStates &states) const
|
||||
{
|
||||
m_style.apply(p, this, states);
|
||||
}
|
||||
|
||||
void QSvgNode::revertStyle(QPainter *p, QSvgExtraStates &states) const
|
||||
{
|
||||
m_style.revert(p, states);
|
||||
}
|
||||
|
||||
QSvgStyleProperty * QSvgNode::styleProperty(QSvgStyleProperty::Type type) const
|
||||
{
|
||||
const QSvgNode *node = this;
|
||||
while (node) {
|
||||
switch (type) {
|
||||
case QSvgStyleProperty::QUALITY:
|
||||
if (node->m_style.quality)
|
||||
return node->m_style.quality;
|
||||
break;
|
||||
case QSvgStyleProperty::FILL:
|
||||
if (node->m_style.fill)
|
||||
return node->m_style.fill;
|
||||
break;
|
||||
case QSvgStyleProperty::VIEWPORT_FILL:
|
||||
if (m_style.viewportFill)
|
||||
return node->m_style.viewportFill;
|
||||
break;
|
||||
case QSvgStyleProperty::FONT:
|
||||
if (node->m_style.font)
|
||||
return node->m_style.font;
|
||||
break;
|
||||
case QSvgStyleProperty::STROKE:
|
||||
if (node->m_style.stroke)
|
||||
return node->m_style.stroke;
|
||||
break;
|
||||
case QSvgStyleProperty::SOLID_COLOR:
|
||||
if (node->m_style.solidColor)
|
||||
return node->m_style.solidColor;
|
||||
break;
|
||||
case QSvgStyleProperty::GRADIENT:
|
||||
if (node->m_style.gradient)
|
||||
return node->m_style.gradient;
|
||||
break;
|
||||
case QSvgStyleProperty::TRANSFORM:
|
||||
if (node->m_style.transform)
|
||||
return node->m_style.transform;
|
||||
break;
|
||||
case QSvgStyleProperty::ANIMATE_COLOR:
|
||||
if (node->m_style.animateColor)
|
||||
return node->m_style.animateColor;
|
||||
break;
|
||||
case QSvgStyleProperty::ANIMATE_TRANSFORM:
|
||||
if (!node->m_style.animateTransforms.isEmpty())
|
||||
return node->m_style.animateTransforms.first();
|
||||
break;
|
||||
case QSvgStyleProperty::OPACITY:
|
||||
if (node->m_style.opacity)
|
||||
return node->m_style.opacity;
|
||||
break;
|
||||
case QSvgStyleProperty::COMP_OP:
|
||||
if (node->m_style.compop)
|
||||
return node->m_style.compop;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
node = node->parent();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QSvgFillStyleProperty * QSvgNode::styleProperty(const QString &id) const
|
||||
{
|
||||
QString rid = id;
|
||||
if (rid.startsWith(QLatin1Char('#')))
|
||||
rid.remove(0, 1);
|
||||
QSvgTinyDocument *doc = document();
|
||||
return doc ? doc->namedStyle(rid) : 0;
|
||||
}
|
||||
|
||||
QRectF QSvgNode::bounds(QPainter *, QSvgExtraStates &) const
|
||||
{
|
||||
return QRectF(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
QRectF QSvgNode::transformedBounds() const
|
||||
{
|
||||
if (!m_cachedBounds.isEmpty())
|
||||
return m_cachedBounds;
|
||||
|
||||
QImage dummy(1, 1, QImage::Format_RGB32);
|
||||
QPainter p(&dummy);
|
||||
QSvgExtraStates states;
|
||||
|
||||
QPen pen(Qt::NoBrush, 1, Qt::SolidLine, Qt::FlatCap, Qt::SvgMiterJoin);
|
||||
pen.setMiterLimit(4);
|
||||
p.setPen(pen);
|
||||
|
||||
QStack<QSvgNode*> parentApplyStack;
|
||||
QSvgNode *parent = m_parent;
|
||||
while (parent) {
|
||||
parentApplyStack.push(parent);
|
||||
parent = parent->parent();
|
||||
}
|
||||
|
||||
for (int i = parentApplyStack.size() - 1; i >= 0; --i)
|
||||
parentApplyStack[i]->applyStyle(&p, states);
|
||||
|
||||
p.setWorldTransform(QTransform());
|
||||
|
||||
m_cachedBounds = transformedBounds(&p, states);
|
||||
return m_cachedBounds;
|
||||
}
|
||||
|
||||
QSvgTinyDocument * QSvgNode::document() const
|
||||
{
|
||||
QSvgTinyDocument *doc = 0;
|
||||
QSvgNode *node = const_cast<QSvgNode*>(this);
|
||||
while (node && node->type() != QSvgNode::DOC) {
|
||||
node = node->parent();
|
||||
}
|
||||
doc = static_cast<QSvgTinyDocument*>(node);
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
void QSvgNode::setRequiredFeatures(const QStringList &lst)
|
||||
{
|
||||
m_requiredFeatures = lst;
|
||||
}
|
||||
|
||||
const QStringList & QSvgNode::requiredFeatures() const
|
||||
{
|
||||
return m_requiredFeatures;
|
||||
}
|
||||
|
||||
void QSvgNode::setRequiredExtensions(const QStringList &lst)
|
||||
{
|
||||
m_requiredExtensions = lst;
|
||||
}
|
||||
|
||||
const QStringList & QSvgNode::requiredExtensions() const
|
||||
{
|
||||
return m_requiredExtensions;
|
||||
}
|
||||
|
||||
void QSvgNode::setRequiredLanguages(const QStringList &lst)
|
||||
{
|
||||
m_requiredLanguages = lst;
|
||||
}
|
||||
|
||||
const QStringList & QSvgNode::requiredLanguages() const
|
||||
{
|
||||
return m_requiredLanguages;
|
||||
}
|
||||
|
||||
void QSvgNode::setRequiredFormats(const QStringList &lst)
|
||||
{
|
||||
m_requiredFormats = lst;
|
||||
}
|
||||
|
||||
const QStringList & QSvgNode::requiredFormats() const
|
||||
{
|
||||
return m_requiredFormats;
|
||||
}
|
||||
|
||||
void QSvgNode::setRequiredFonts(const QStringList &lst)
|
||||
{
|
||||
m_requiredFonts = lst;
|
||||
}
|
||||
|
||||
const QStringList & QSvgNode::requiredFonts() const
|
||||
{
|
||||
return m_requiredFonts;
|
||||
}
|
||||
|
||||
void QSvgNode::setVisible(bool visible)
|
||||
{
|
||||
//propagate visibility change of true to the parent
|
||||
//not propagating false is just a small performance
|
||||
//degradation since we'll iterate over children without
|
||||
//drawing any of them
|
||||
if (m_parent && visible && !m_parent->isVisible())
|
||||
m_parent->setVisible(true);
|
||||
|
||||
m_visible = visible;
|
||||
}
|
||||
|
||||
QRectF QSvgNode::transformedBounds(QPainter *p, QSvgExtraStates &states) const
|
||||
{
|
||||
applyStyle(p, states);
|
||||
QRectF rect = bounds(p, states);
|
||||
revertStyle(p, states);
|
||||
return rect;
|
||||
}
|
||||
|
||||
void QSvgNode::setNodeId(const QString &i)
|
||||
{
|
||||
m_id = i;
|
||||
}
|
||||
|
||||
void QSvgNode::setXmlClass(const QString &str)
|
||||
{
|
||||
m_class = str;
|
||||
}
|
||||
|
||||
void QSvgNode::setDisplayMode(DisplayMode mode)
|
||||
{
|
||||
m_displayMode = mode;
|
||||
}
|
||||
|
||||
QSvgNode::DisplayMode QSvgNode::displayMode() const
|
||||
{
|
||||
return m_displayMode;
|
||||
}
|
||||
|
||||
qreal QSvgNode::strokeWidth(QPainter *p)
|
||||
{
|
||||
QPen pen = p->pen();
|
||||
if (pen.style() == Qt::NoPen || pen.brush().style() == Qt::NoBrush || pen.isCosmetic())
|
||||
return 0;
|
||||
return pen.widthF();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
203
svg/qsvgnode_p.h
Normal file
203
svg/qsvgnode_p.h
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGNODE_P_H
|
||||
#define QSVGNODE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qsvgstyle_p.h"
|
||||
#include "qtsvgglobal_p.h"
|
||||
|
||||
#include "QtCore/qstring.h"
|
||||
#include "QtCore/qhash.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPainter;
|
||||
class QSvgTinyDocument;
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgNode
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
DOC,
|
||||
G,
|
||||
DEFS,
|
||||
SWITCH,
|
||||
ANIMATION,
|
||||
ARC,
|
||||
CIRCLE,
|
||||
ELLIPSE,
|
||||
IMAGE,
|
||||
LINE,
|
||||
PATH,
|
||||
POLYGON,
|
||||
POLYLINE,
|
||||
RECT,
|
||||
TEXT,
|
||||
TEXTAREA,
|
||||
TSPAN,
|
||||
USE,
|
||||
VIDEO
|
||||
};
|
||||
enum DisplayMode {
|
||||
InlineMode,
|
||||
BlockMode,
|
||||
ListItemMode,
|
||||
RunInMode,
|
||||
CompactMode,
|
||||
MarkerMode,
|
||||
TableMode,
|
||||
InlineTableMode,
|
||||
TableRowGroupMode,
|
||||
TableHeaderGroupMode,
|
||||
TableFooterGroupMode,
|
||||
TableRowMode,
|
||||
TableColumnGroupMode,
|
||||
TableColumnMode,
|
||||
TableCellMode,
|
||||
TableCaptionMode,
|
||||
NoneMode,
|
||||
InheritMode
|
||||
};
|
||||
public:
|
||||
QSvgNode(QSvgNode *parent=0);
|
||||
virtual ~QSvgNode();
|
||||
virtual void draw(QPainter *p, QSvgExtraStates &states) =0;
|
||||
|
||||
QSvgNode *parent() const;
|
||||
bool isDescendantOf(const QSvgNode *parent) const;
|
||||
|
||||
void appendStyleProperty(QSvgStyleProperty *prop, const QString &id);
|
||||
void applyStyle(QPainter *p, QSvgExtraStates &states) const;
|
||||
void revertStyle(QPainter *p, QSvgExtraStates &states) const;
|
||||
QSvgStyleProperty *styleProperty(QSvgStyleProperty::Type type) const;
|
||||
QSvgFillStyleProperty *styleProperty(const QString &id) const;
|
||||
|
||||
QSvgTinyDocument *document() const;
|
||||
|
||||
virtual Type type() const =0;
|
||||
virtual QRectF bounds(QPainter *p, QSvgExtraStates &states) const;
|
||||
virtual QRectF transformedBounds(QPainter *p, QSvgExtraStates &states) const;
|
||||
QRectF transformedBounds() const;
|
||||
|
||||
void setRequiredFeatures(const QStringList &lst);
|
||||
const QStringList & requiredFeatures() const;
|
||||
|
||||
void setRequiredExtensions(const QStringList &lst);
|
||||
const QStringList & requiredExtensions() const;
|
||||
|
||||
void setRequiredLanguages(const QStringList &lst);
|
||||
const QStringList & requiredLanguages() const;
|
||||
|
||||
void setRequiredFormats(const QStringList &lst);
|
||||
const QStringList & requiredFormats() const;
|
||||
|
||||
void setRequiredFonts(const QStringList &lst);
|
||||
const QStringList & requiredFonts() const;
|
||||
|
||||
void setVisible(bool visible);
|
||||
bool isVisible() const;
|
||||
|
||||
void setDisplayMode(DisplayMode display);
|
||||
DisplayMode displayMode() const;
|
||||
|
||||
QString nodeId() const;
|
||||
void setNodeId(const QString &i);
|
||||
|
||||
QString xmlClass() const;
|
||||
void setXmlClass(const QString &str);
|
||||
protected:
|
||||
mutable QSvgStyle m_style;
|
||||
|
||||
static qreal strokeWidth(QPainter *p);
|
||||
private:
|
||||
QSvgNode *m_parent;
|
||||
|
||||
QStringList m_requiredFeatures;
|
||||
QStringList m_requiredExtensions;
|
||||
QStringList m_requiredLanguages;
|
||||
QStringList m_requiredFormats;
|
||||
QStringList m_requiredFonts;
|
||||
|
||||
bool m_visible;
|
||||
|
||||
QString m_id;
|
||||
QString m_class;
|
||||
|
||||
DisplayMode m_displayMode;
|
||||
mutable QRectF m_cachedBounds;
|
||||
|
||||
friend class QSvgTinyDocument;
|
||||
};
|
||||
|
||||
inline QSvgNode *QSvgNode::parent() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
inline bool QSvgNode::isVisible() const
|
||||
{
|
||||
return m_visible;
|
||||
}
|
||||
|
||||
inline QString QSvgNode::nodeId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
inline QString QSvgNode::xmlClass() const
|
||||
{
|
||||
return m_class;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSVGNODE_P_H
|
||||
500
svg/qsvgrenderer.cpp
Normal file
500
svg/qsvgrenderer.cpp
Normal file
|
|
@ -0,0 +1,500 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsvgrenderer.h"
|
||||
|
||||
#ifndef QT_NO_SVGRENDERER
|
||||
|
||||
#include "qsvgtinydocument_p.h"
|
||||
|
||||
#include "qbytearray.h"
|
||||
#include "qtimer.h"
|
||||
#include "qdebug.h"
|
||||
#include "private/qobject_p.h"
|
||||
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QSvgRenderer
|
||||
\inmodule QtSvg
|
||||
\ingroup painting
|
||||
|
||||
\brief The QSvgRenderer class is used to draw the contents of SVG files onto paint devices.
|
||||
\since 4.1
|
||||
\reentrant
|
||||
|
||||
Using QSvgRenderer, Scalable Vector Graphics (SVG) can be rendered onto any QPaintDevice
|
||||
subclass, including QWidget, QImage, and QGLWidget.
|
||||
|
||||
QSvgRenderer provides an API that supports basic features of SVG rendering, such as loading
|
||||
and rendering of static drawings, and more interactive features like animation. Since the
|
||||
rendering is performed using QPainter, SVG drawings can be rendered on any subclass of
|
||||
QPaintDevice.
|
||||
|
||||
SVG drawings are either loaded when an QSvgRenderer is constructed, or loaded later
|
||||
using the load() functions. Data is either supplied directly as serialized XML, or
|
||||
indirectly using a file name. If a valid file has been loaded, either when the renderer
|
||||
is constructed or at some later time, isValid() returns true; otherwise it returns false.
|
||||
QSvgRenderer provides the render() slot to render the current document, or the current
|
||||
frame of an animated document, using a given painter.
|
||||
|
||||
The defaultSize() function provides information about the amount of space that is required
|
||||
to render the currently loaded SVG file. This is useful for paint devices, such as QWidget,
|
||||
that often need to supply a size hint to their parent layout.
|
||||
The default size of a drawing may differ from its visible area, found using the \l viewBox
|
||||
property.
|
||||
|
||||
Animated SVG drawings are supported, and can be controlled with a simple collection of
|
||||
functions and properties:
|
||||
|
||||
\list
|
||||
\li The animated() function indicates whether a drawing contains animation information.
|
||||
\omit
|
||||
\li The animationDuration() function provides the duration in milliseconds of the
|
||||
animation, without taking any looping into account.
|
||||
\li The \l currentFrame property contains the current frame of the animation.
|
||||
\endomit
|
||||
\li The \l framesPerSecond property contains the rate at which the animation plays.
|
||||
\endlist
|
||||
|
||||
Finally, the QSvgRenderer class provides the repaintNeeded() signal which is emitted
|
||||
whenever the rendering of the document needs to be updated.
|
||||
|
||||
\sa QSvgWidget, {Qt SVG C++ Classes}, {SVG Viewer Example}, QPicture
|
||||
*/
|
||||
|
||||
class QSvgRendererPrivate : public QObjectPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QSvgRenderer)
|
||||
public:
|
||||
explicit QSvgRendererPrivate()
|
||||
: QObjectPrivate(),
|
||||
render(0), timer(0),
|
||||
fps(30)
|
||||
{}
|
||||
~QSvgRendererPrivate()
|
||||
{
|
||||
delete render;
|
||||
}
|
||||
|
||||
static void callRepaintNeeded(QSvgRenderer *const q);
|
||||
|
||||
QSvgTinyDocument *render;
|
||||
QTimer *timer;
|
||||
int fps;
|
||||
};
|
||||
|
||||
/*!
|
||||
Constructs a new renderer with the given \a parent.
|
||||
*/
|
||||
QSvgRenderer::QSvgRenderer(QObject *parent)
|
||||
: QObject(*(new QSvgRendererPrivate), parent)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new renderer with the given \a parent and loads the contents of the
|
||||
SVG file with the specified \a filename.
|
||||
*/
|
||||
QSvgRenderer::QSvgRenderer(const QString &filename, QObject *parent)
|
||||
: QObject(*new QSvgRendererPrivate, parent)
|
||||
{
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new renderer with the given \a parent and loads the SVG data
|
||||
from the byte array specified by \a contents.
|
||||
*/
|
||||
QSvgRenderer::QSvgRenderer(const QByteArray &contents, QObject *parent)
|
||||
: QObject(*new QSvgRendererPrivate, parent)
|
||||
{
|
||||
load(contents);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.5
|
||||
|
||||
Constructs a new renderer with the given \a parent and loads the SVG data
|
||||
using the stream reader specified by \a contents.
|
||||
*/
|
||||
QSvgRenderer::QSvgRenderer(QXmlStreamReader *contents, QObject *parent)
|
||||
: QObject(*new QSvgRendererPrivate, parent)
|
||||
{
|
||||
load(contents);
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the renderer.
|
||||
*/
|
||||
QSvgRenderer::~QSvgRenderer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if there is a valid current document; otherwise returns false.
|
||||
*/
|
||||
bool QSvgRenderer::isValid() const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
return d->render;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the default size of the document contents.
|
||||
*/
|
||||
QSize QSvgRenderer::defaultSize() const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
if (d->render)
|
||||
return d->render->size();
|
||||
else
|
||||
return QSize();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns viewBoxF().toRect().
|
||||
|
||||
\sa viewBoxF()
|
||||
*/
|
||||
QRect QSvgRenderer::viewBox() const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
if (d->render)
|
||||
return d->render->viewBox().toRect();
|
||||
else
|
||||
return QRect();
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QSvgRenderer::viewBox
|
||||
\brief the rectangle specifying the visible area of the document in logical coordinates
|
||||
\since 4.2
|
||||
*/
|
||||
void QSvgRenderer::setViewBox(const QRect &viewbox)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
if (d->render)
|
||||
d->render->setViewBox(viewbox);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the current document contains animated elements; otherwise
|
||||
returns false.
|
||||
|
||||
\sa framesPerSecond()
|
||||
*/
|
||||
bool QSvgRenderer::animated() const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
if (d->render)
|
||||
return d->render->animated();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QSvgRenderer::framesPerSecond
|
||||
\brief the number of frames per second to be shown
|
||||
|
||||
The number of frames per second is 0 if the current document is not animated.
|
||||
|
||||
\sa animated()
|
||||
*/
|
||||
int QSvgRenderer::framesPerSecond() const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
return d->fps;
|
||||
}
|
||||
|
||||
void QSvgRenderer::setFramesPerSecond(int num)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
if (num < 0) {
|
||||
qWarning("QSvgRenderer::setFramesPerSecond: Cannot set negative value %d", num);
|
||||
return;
|
||||
}
|
||||
d->fps = num;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QSvgRenderer::currentFrame
|
||||
\brief the current frame of the document's animation, or 0 if the document is not animated
|
||||
\internal
|
||||
|
||||
\sa animationDuration(), framesPerSecond, animated()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
int QSvgRenderer::currentFrame() const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
return d->render->currentFrame();
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
void QSvgRenderer::setCurrentFrame(int frame)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
d->render->setCurrentFrame(frame);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
Returns the number of frames in the animation, or 0 if the current document is not
|
||||
animated.
|
||||
|
||||
\sa animated(), framesPerSecond
|
||||
*/
|
||||
int QSvgRenderer::animationDuration() const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
return d->render->animationDuration();
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
\since 4.5
|
||||
|
||||
We can't have template functions, that's loadDocument(), as friends, for this
|
||||
code, so we let this function be a friend of QSvgRenderer instead.
|
||||
*/
|
||||
void QSvgRendererPrivate::callRepaintNeeded(QSvgRenderer *const q)
|
||||
{
|
||||
emit q->repaintNeeded();
|
||||
}
|
||||
|
||||
template<typename TInputType>
|
||||
static bool loadDocument(QSvgRenderer *const q,
|
||||
QSvgRendererPrivate *const d,
|
||||
const TInputType &in)
|
||||
{
|
||||
delete d->render;
|
||||
d->render = QSvgTinyDocument::load(in);
|
||||
if (d->render && d->render->animated() && d->fps > 0) {
|
||||
if (!d->timer)
|
||||
d->timer = new QTimer(q);
|
||||
else
|
||||
d->timer->stop();
|
||||
q->connect(d->timer, SIGNAL(timeout()),
|
||||
q, SIGNAL(repaintNeeded()));
|
||||
d->timer->start(1000/d->fps);
|
||||
} else if (d->timer) {
|
||||
d->timer->stop();
|
||||
}
|
||||
|
||||
//force first update
|
||||
QSvgRendererPrivate::callRepaintNeeded(q);
|
||||
|
||||
return d->render;
|
||||
}
|
||||
|
||||
/*!
|
||||
Loads the SVG file specified by \a filename, returning true if the content
|
||||
was successfully parsed; otherwise returns false.
|
||||
*/
|
||||
bool QSvgRenderer::load(const QString &filename)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
return loadDocument(this, d, filename);
|
||||
}
|
||||
|
||||
/*!
|
||||
Loads the specified SVG format \a contents, returning true if the content
|
||||
was successfully parsed; otherwise returns false.
|
||||
*/
|
||||
bool QSvgRenderer::load(const QByteArray &contents)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
return loadDocument(this, d, contents);
|
||||
}
|
||||
|
||||
/*!
|
||||
Loads the specified SVG in \a contents, returning true if the content
|
||||
was successfully parsed; otherwise returns false.
|
||||
|
||||
The reader will be used from where it currently is positioned. If \a contents
|
||||
is \c null, behavior is undefined.
|
||||
|
||||
\since 4.5
|
||||
*/
|
||||
bool QSvgRenderer::load(QXmlStreamReader *contents)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
return loadDocument(this, d, contents);
|
||||
}
|
||||
|
||||
/*!
|
||||
Renders the current document, or the current frame of an animated
|
||||
document, using the given \a painter.
|
||||
*/
|
||||
void QSvgRenderer::render(QPainter *painter)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
if (d->render) {
|
||||
d->render->draw(painter);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void QSvgRenderer::repaintNeeded()
|
||||
|
||||
This signal is emitted whenever the rendering of the document
|
||||
needs to be updated, usually for the purposes of animation.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Renders the given element with \a elementId using the given \a painter
|
||||
on the specified \a bounds. If the bounding rectangle is not specified
|
||||
the SVG element is mapped to the whole paint device.
|
||||
*/
|
||||
void QSvgRenderer::render(QPainter *painter, const QString &elementId,
|
||||
const QRectF &bounds)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
if (d->render) {
|
||||
d->render->draw(painter, elementId, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Renders the current document, or the current frame of an animated
|
||||
document, using the given \a painter on the specified \a bounds within
|
||||
the painter. If the bounding rectangle is not specified
|
||||
the SVG file is mapped to the whole paint device.
|
||||
*/
|
||||
void QSvgRenderer::render(QPainter *painter, const QRectF &bounds)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
if (d->render) {
|
||||
d->render->draw(painter, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
QRectF QSvgRenderer::viewBoxF() const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
if (d->render)
|
||||
return d->render->viewBox();
|
||||
else
|
||||
return QRect();
|
||||
}
|
||||
|
||||
void QSvgRenderer::setViewBox(const QRectF &viewbox)
|
||||
{
|
||||
Q_D(QSvgRenderer);
|
||||
if (d->render)
|
||||
d->render->setViewBox(viewbox);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.2
|
||||
|
||||
Returns bounding rectangle of the item with the given \a id.
|
||||
The transformation matrix of parent elements is not affecting
|
||||
the bounds of the element.
|
||||
|
||||
\sa matrixForElement()
|
||||
*/
|
||||
QRectF QSvgRenderer::boundsOnElement(const QString &id) const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
QRectF bounds;
|
||||
if (d->render)
|
||||
bounds = d->render->boundsOnElement(id);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\since 4.2
|
||||
|
||||
Returns true if the element with the given \a id exists
|
||||
in the currently parsed SVG file and is a renderable
|
||||
element.
|
||||
|
||||
Note: this method returns true only for elements that
|
||||
can be rendered. Which implies that elements that are considered
|
||||
part of the fill/stroke style properties, e.g. radialGradients
|
||||
even tough marked with "id" attributes will not be found by this
|
||||
method.
|
||||
*/
|
||||
bool QSvgRenderer::elementExists(const QString &id) const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
bool exists = false;
|
||||
if (d->render)
|
||||
exists = d->render->elementExists(id);
|
||||
return exists;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.2
|
||||
|
||||
Returns the transformation matrix for the element
|
||||
with the given \a id. The matrix is a product of
|
||||
the transformation of the element's parents. The transformation of
|
||||
the element itself is not included.
|
||||
|
||||
To find the bounding rectangle of the element in logical coordinates,
|
||||
you can apply the matrix on the rectangle returned from boundsOnElement().
|
||||
|
||||
\sa boundsOnElement()
|
||||
*/
|
||||
QMatrix QSvgRenderer::matrixForElement(const QString &id) const
|
||||
{
|
||||
Q_D(const QSvgRenderer);
|
||||
QMatrix mat;
|
||||
if (d->render)
|
||||
mat = d->render->matrixForElement(id);
|
||||
return mat;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_qsvgrenderer.cpp"
|
||||
|
||||
#endif // QT_NO_SVGRENDERER
|
||||
114
svg/qsvgrenderer.h
Normal file
114
svg/qsvgrenderer.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGRENDERER_H
|
||||
#define QSVGRENDERER_H
|
||||
|
||||
#include <QtGui/qmatrix.h>
|
||||
|
||||
#ifndef QT_NO_SVGRENDERER
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qsize.h>
|
||||
#include <QtCore/qrect.h>
|
||||
#include <QtCore/qxmlstream.h>
|
||||
#include <QtSvg/qtsvgglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QSvgRendererPrivate;
|
||||
class QPainter;
|
||||
class QByteArray;
|
||||
|
||||
class Q_SVG_EXPORT QSvgRenderer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QRectF viewBox READ viewBoxF WRITE setViewBox)
|
||||
Q_PROPERTY(int framesPerSecond READ framesPerSecond WRITE setFramesPerSecond)
|
||||
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame)
|
||||
public:
|
||||
QSvgRenderer(QObject *parent = nullptr);
|
||||
QSvgRenderer(const QString &filename, QObject *parent = nullptr);
|
||||
QSvgRenderer(const QByteArray &contents, QObject *parent = nullptr);
|
||||
QSvgRenderer(QXmlStreamReader *contents, QObject *parent = nullptr);
|
||||
~QSvgRenderer();
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
QSize defaultSize() const;
|
||||
|
||||
QRect viewBox() const;
|
||||
QRectF viewBoxF() const;
|
||||
void setViewBox(const QRect &viewbox);
|
||||
void setViewBox(const QRectF &viewbox);
|
||||
|
||||
bool animated() const;
|
||||
int framesPerSecond() const;
|
||||
void setFramesPerSecond(int num);
|
||||
int currentFrame() const;
|
||||
void setCurrentFrame(int);
|
||||
int animationDuration() const;//in seconds
|
||||
|
||||
QRectF boundsOnElement(const QString &id) const;
|
||||
bool elementExists(const QString &id) const;
|
||||
QMatrix matrixForElement(const QString &id) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
bool load(const QString &filename);
|
||||
bool load(const QByteArray &contents);
|
||||
bool load(QXmlStreamReader *contents);
|
||||
void render(QPainter *p);
|
||||
void render(QPainter *p, const QRectF &bounds);
|
||||
|
||||
void render(QPainter *p, const QString &elementId,
|
||||
const QRectF &bounds=QRectF());
|
||||
|
||||
Q_SIGNALS:
|
||||
void repaintNeeded();
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QSvgRenderer)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_SVGRENDERER
|
||||
#endif // QSVGRENDERER_H
|
||||
377
svg/qsvgstructure.cpp
Normal file
377
svg/qsvgstructure.cpp
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsvgstructure_p.h"
|
||||
|
||||
#include "qsvgnode_p.h"
|
||||
#include "qsvgstyle_p.h"
|
||||
#include "qsvgtinydocument_p.h"
|
||||
|
||||
#include "qpainter.h"
|
||||
#include "qlocale.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QSvgG::QSvgG(QSvgNode *parent)
|
||||
: QSvgStructureNode(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QSvgStructureNode::~QSvgStructureNode()
|
||||
{
|
||||
qDeleteAll(m_renderers);
|
||||
}
|
||||
|
||||
void QSvgG::draw(QPainter *p, QSvgExtraStates &states)
|
||||
{
|
||||
QList<QSvgNode*>::iterator itr = m_renderers.begin();
|
||||
applyStyle(p, states);
|
||||
|
||||
while (itr != m_renderers.end()) {
|
||||
QSvgNode *node = *itr;
|
||||
if ((node->isVisible()) && (node->displayMode() != QSvgNode::NoneMode))
|
||||
node->draw(p, states);
|
||||
++itr;
|
||||
}
|
||||
revertStyle(p, states);
|
||||
}
|
||||
|
||||
QSvgNode::Type QSvgG::type() const
|
||||
{
|
||||
return G;
|
||||
}
|
||||
|
||||
QSvgStructureNode::QSvgStructureNode(QSvgNode *parent)
|
||||
:QSvgNode(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QSvgNode * QSvgStructureNode::scopeNode(const QString &id) const
|
||||
{
|
||||
QSvgTinyDocument *doc = document();
|
||||
return doc ? doc->namedNode(id) : 0;
|
||||
}
|
||||
|
||||
void QSvgStructureNode::addChild(QSvgNode *child, const QString &id)
|
||||
{
|
||||
m_renderers.append(child);
|
||||
|
||||
if (id.isEmpty())
|
||||
return; //we can't add it to scope without id
|
||||
|
||||
QSvgTinyDocument *doc = document();
|
||||
if (doc)
|
||||
doc->addNamedNode(id, child);
|
||||
}
|
||||
|
||||
QSvgDefs::QSvgDefs(QSvgNode *parent)
|
||||
: QSvgStructureNode(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void QSvgDefs::draw(QPainter *, QSvgExtraStates &)
|
||||
{
|
||||
//noop
|
||||
}
|
||||
|
||||
QSvgNode::Type QSvgDefs::type() const
|
||||
{
|
||||
return DEFS;
|
||||
}
|
||||
|
||||
/*
|
||||
Below is a lookup function based on the gperf output using the following set:
|
||||
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#SVG
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#SVG-static
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#CoreAttribute
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#Structure
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessing
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessingAttribute
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#Image
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#Prefetch
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#Shape
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#Text
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#PaintAttribute
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#OpacityAttribute
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#GraphicsAttribute
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#Gradient
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#SolidColor
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#XlinkAttribute
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#ExternalResourcesRequiredAttribute
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#Font
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#Hyperlinking
|
||||
http://www.w3.org/Graphics/SVG/feature/1.2/#Extensibility
|
||||
*/
|
||||
|
||||
// ----- begin of generated code -----
|
||||
|
||||
/* C code produced by gperf version 3.0.2 */
|
||||
/* Command-line: gperf -c -L c svg */
|
||||
/* Computed positions: -k'45-46' */
|
||||
|
||||
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
||||
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
||||
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
||||
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
||||
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
||||
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
||||
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
||||
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
||||
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
||||
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
||||
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
||||
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
||||
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
||||
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
||||
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
||||
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
||||
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
||||
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
||||
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
||||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
|
||||
/* The character set is not based on ISO-646. */
|
||||
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
|
||||
#endif
|
||||
|
||||
enum {
|
||||
TOTAL_KEYWORDS = 20,
|
||||
MIN_WORD_LENGTH = 47,
|
||||
MAX_WORD_LENGTH = 78,
|
||||
MIN_HASH_VALUE = 48,
|
||||
MAX_HASH_VALUE = 88
|
||||
};
|
||||
/* maximum key range = 41, duplicates = 0 */
|
||||
|
||||
inline static bool isSupportedSvgFeature(const QString &str)
|
||||
{
|
||||
static const unsigned char asso_values[] = {
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 0, 89, 5,
|
||||
15, 5, 0, 10, 89, 89, 89, 89, 89, 0,
|
||||
15, 89, 89, 0, 0, 89, 5, 89, 0, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 0, 89, 89,
|
||||
89, 0, 89, 89, 0, 89, 89, 89, 0, 5,
|
||||
89, 0, 0, 89, 5, 89, 0, 89, 89, 89,
|
||||
5, 0, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
|
||||
89, 89, 89, 89, 89, 89
|
||||
};
|
||||
|
||||
static const char * wordlist[] = {
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"", "", "",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#Text",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#Shape",
|
||||
"", "",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#SVG",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#Structure",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#SolidColor",
|
||||
"",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#Hyperlinking",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#CoreAttribute",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#XlinkAttribute",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#SVG-static",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#OpacityAttribute",
|
||||
"",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#Gradient",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#Font",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#Image",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessing",
|
||||
"",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#Extensibility",
|
||||
"", "", "",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#GraphicsAttribute",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#Prefetch",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#PaintAttribute",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessingAttribute",
|
||||
"", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "",
|
||||
"http://www.w3.org/Graphics/SVG/feature/1.2/#ExternalResourcesRequiredAttribute"
|
||||
};
|
||||
|
||||
if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
|
||||
const int key = str.length()
|
||||
+ asso_values[str.at(45).unicode()]
|
||||
+ asso_values[str.at(44).unicode()];
|
||||
if (key <= MAX_HASH_VALUE && key >= 0)
|
||||
return str == QLatin1String(wordlist[key]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----- end of generated code -----
|
||||
|
||||
static inline bool isSupportedSvgExtension(const QString &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QSvgSwitch::QSvgSwitch(QSvgNode *parent)
|
||||
: QSvgStructureNode(parent)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void QSvgSwitch::draw(QPainter *p, QSvgExtraStates &states)
|
||||
{
|
||||
QList<QSvgNode*>::iterator itr = m_renderers.begin();
|
||||
applyStyle(p, states);
|
||||
|
||||
while (itr != m_renderers.end()) {
|
||||
QSvgNode *node = *itr;
|
||||
if (node->isVisible() && (node->displayMode() != QSvgNode::NoneMode)) {
|
||||
const QStringList &features = node->requiredFeatures();
|
||||
const QStringList &extensions = node->requiredExtensions();
|
||||
const QStringList &languages = node->requiredLanguages();
|
||||
const QStringList &formats = node->requiredFormats();
|
||||
const QStringList &fonts = node->requiredFonts();
|
||||
|
||||
bool okToRender = true;
|
||||
if (!features.isEmpty()) {
|
||||
QStringList::const_iterator sitr = features.constBegin();
|
||||
for (; sitr != features.constEnd(); ++sitr) {
|
||||
if (!isSupportedSvgFeature(*sitr)) {
|
||||
okToRender = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (okToRender && !extensions.isEmpty()) {
|
||||
QStringList::const_iterator sitr = extensions.constBegin();
|
||||
for (; sitr != extensions.constEnd(); ++sitr) {
|
||||
if (!isSupportedSvgExtension(*sitr)) {
|
||||
okToRender = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (okToRender && !languages.isEmpty()) {
|
||||
QStringList::const_iterator sitr = languages.constBegin();
|
||||
okToRender = false;
|
||||
for (; sitr != languages.constEnd(); ++sitr) {
|
||||
if ((*sitr).startsWith(m_systemLanguagePrefix)) {
|
||||
okToRender = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (okToRender && !formats.isEmpty()) {
|
||||
okToRender = false;
|
||||
}
|
||||
|
||||
if (okToRender && !fonts.isEmpty()) {
|
||||
okToRender = false;
|
||||
}
|
||||
|
||||
if (okToRender) {
|
||||
node->draw(p, states);
|
||||
break;
|
||||
}
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
revertStyle(p, states);
|
||||
}
|
||||
|
||||
QSvgNode::Type QSvgSwitch::type() const
|
||||
{
|
||||
return SWITCH;
|
||||
}
|
||||
|
||||
void QSvgSwitch::init()
|
||||
{
|
||||
QLocale locale;
|
||||
m_systemLanguage = locale.name().replace(QLatin1Char('_'), QLatin1Char('-'));
|
||||
int idx = m_systemLanguage.indexOf(QLatin1Char('-'));
|
||||
m_systemLanguagePrefix = m_systemLanguage.mid(0, idx);
|
||||
}
|
||||
|
||||
QRectF QSvgStructureNode::bounds(QPainter *p, QSvgExtraStates &states) const
|
||||
{
|
||||
QRectF bounds;
|
||||
for (QSvgNode *node : qAsConst(m_renderers))
|
||||
bounds |= node->transformedBounds(p, states);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
QSvgNode * QSvgStructureNode::previousSiblingNode(QSvgNode *n) const
|
||||
{
|
||||
QSvgNode *prev = 0;
|
||||
QList<QSvgNode*>::const_iterator itr = m_renderers.constBegin();
|
||||
for (; itr != m_renderers.constEnd(); ++itr) {
|
||||
QSvgNode *node = *itr;
|
||||
if (node == n)
|
||||
return prev;
|
||||
prev = node;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
114
svg/qsvgstructure_p.h
Normal file
114
svg/qsvgstructure_p.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGSTRUCTURE_P_H
|
||||
#define QSVGSTRUCTURE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qsvgnode_p.h"
|
||||
#include "qtsvgglobal_p.h"
|
||||
|
||||
#include "QtCore/qlist.h"
|
||||
#include "QtCore/qhash.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSvgTinyDocument;
|
||||
class QSvgNode;
|
||||
class QPainter;
|
||||
class QSvgDefs;
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgStructureNode : public QSvgNode
|
||||
{
|
||||
public:
|
||||
QSvgStructureNode(QSvgNode *parent);
|
||||
~QSvgStructureNode();
|
||||
QSvgNode *scopeNode(const QString &id) const;
|
||||
void addChild(QSvgNode *child, const QString &id);
|
||||
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
|
||||
QSvgNode *previousSiblingNode(QSvgNode *n) const;
|
||||
QList<QSvgNode*> renderers() const { return m_renderers; }
|
||||
protected:
|
||||
QList<QSvgNode*> m_renderers;
|
||||
QHash<QString, QSvgNode*> m_scope;
|
||||
QList<QSvgStructureNode*> m_linkedScopes;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgG : public QSvgStructureNode
|
||||
{
|
||||
public:
|
||||
QSvgG(QSvgNode *parent);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgDefs : public QSvgStructureNode
|
||||
{
|
||||
public:
|
||||
QSvgDefs(QSvgNode *parent);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgSwitch : public QSvgStructureNode
|
||||
{
|
||||
public:
|
||||
QSvgSwitch(QSvgNode *parent);
|
||||
void draw(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
private:
|
||||
void init();
|
||||
private:
|
||||
QString m_systemLanguage;
|
||||
QString m_systemLanguagePrefix;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSVGSTRUCTURE_P_H
|
||||
969
svg/qsvgstyle.cpp
Normal file
969
svg/qsvgstyle.cpp
Normal file
|
|
@ -0,0 +1,969 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsvgstyle_p.h"
|
||||
|
||||
#include "qsvgfont_p.h"
|
||||
#include "qsvggraphics_p.h"
|
||||
#include "qsvgnode_p.h"
|
||||
#include "qsvgtinydocument_p.h"
|
||||
|
||||
#include "qpainter.h"
|
||||
#include "qpair.h"
|
||||
#include "qcolor.h"
|
||||
#include "qdebug.h"
|
||||
#include "qmath.h"
|
||||
#include "qnumeric.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QSvgExtraStates::QSvgExtraStates()
|
||||
: fillOpacity(1.0)
|
||||
, strokeOpacity(1.0)
|
||||
, svgFont(0)
|
||||
, textAnchor(Qt::AlignLeft)
|
||||
, fontWeight(400)
|
||||
, fillRule(Qt::WindingFill)
|
||||
, strokeDashOffset(0)
|
||||
, vectorEffect(false)
|
||||
{
|
||||
}
|
||||
|
||||
QSvgStyleProperty::~QSvgStyleProperty()
|
||||
{
|
||||
}
|
||||
|
||||
void QSvgFillStyleProperty::apply(QPainter *, const QSvgNode *, QSvgExtraStates &)
|
||||
{
|
||||
Q_ASSERT(!"This should not be called!");
|
||||
}
|
||||
|
||||
void QSvgFillStyleProperty::revert(QPainter *, QSvgExtraStates &)
|
||||
{
|
||||
Q_ASSERT(!"This should not be called!");
|
||||
}
|
||||
|
||||
|
||||
QSvgQualityStyle::QSvgQualityStyle(int color)
|
||||
{
|
||||
Q_UNUSED(color);
|
||||
}
|
||||
void QSvgQualityStyle::apply(QPainter *, const QSvgNode *, QSvgExtraStates &)
|
||||
{
|
||||
|
||||
}
|
||||
void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QSvgFillStyle::QSvgFillStyle()
|
||||
: m_style(0)
|
||||
, m_fillRule(Qt::WindingFill)
|
||||
, m_oldFillRule(Qt::WindingFill)
|
||||
, m_fillOpacity(1.0)
|
||||
, m_oldFillOpacity(0)
|
||||
, m_gradientResolved(1)
|
||||
, m_fillRuleSet(0)
|
||||
, m_fillOpacitySet(0)
|
||||
, m_fillSet(0)
|
||||
{
|
||||
}
|
||||
|
||||
void QSvgFillStyle::setFillRule(Qt::FillRule f)
|
||||
{
|
||||
m_fillRuleSet = 1;
|
||||
m_fillRule = f;
|
||||
}
|
||||
|
||||
void QSvgFillStyle::setFillOpacity(qreal opacity)
|
||||
{
|
||||
m_fillOpacitySet = 1;
|
||||
m_fillOpacity = opacity;
|
||||
}
|
||||
|
||||
void QSvgFillStyle::setFillStyle(QSvgFillStyleProperty* style)
|
||||
{
|
||||
m_style = style;
|
||||
m_fillSet = 1;
|
||||
}
|
||||
|
||||
void QSvgFillStyle::setBrush(QBrush brush)
|
||||
{
|
||||
m_fill = brush;
|
||||
m_style = 0;
|
||||
m_fillSet = 1;
|
||||
}
|
||||
|
||||
void QSvgFillStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &states)
|
||||
{
|
||||
m_oldFill = p->brush();
|
||||
m_oldFillRule = states.fillRule;
|
||||
m_oldFillOpacity = states.fillOpacity;
|
||||
|
||||
if (m_fillRuleSet)
|
||||
states.fillRule = m_fillRule;
|
||||
if (m_fillSet) {
|
||||
if (m_style)
|
||||
p->setBrush(m_style->brush(p, states));
|
||||
else
|
||||
p->setBrush(m_fill);
|
||||
}
|
||||
if (m_fillOpacitySet)
|
||||
states.fillOpacity = m_fillOpacity;
|
||||
}
|
||||
|
||||
void QSvgFillStyle::revert(QPainter *p, QSvgExtraStates &states)
|
||||
{
|
||||
if (m_fillOpacitySet)
|
||||
states.fillOpacity = m_oldFillOpacity;
|
||||
if (m_fillSet)
|
||||
p->setBrush(m_oldFill);
|
||||
if (m_fillRuleSet)
|
||||
states.fillRule = m_oldFillRule;
|
||||
}
|
||||
|
||||
QSvgViewportFillStyle::QSvgViewportFillStyle(const QBrush &brush)
|
||||
: m_viewportFill(brush)
|
||||
{
|
||||
}
|
||||
|
||||
void QSvgViewportFillStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &)
|
||||
{
|
||||
m_oldFill = p->brush();
|
||||
p->setBrush(m_viewportFill);
|
||||
}
|
||||
|
||||
void QSvgViewportFillStyle::revert(QPainter *p, QSvgExtraStates &)
|
||||
{
|
||||
p->setBrush(m_oldFill);
|
||||
}
|
||||
|
||||
QSvgFontStyle::QSvgFontStyle(QSvgFont *font, QSvgTinyDocument *doc)
|
||||
: m_svgFont(font)
|
||||
, m_doc(doc)
|
||||
, m_familySet(0)
|
||||
, m_sizeSet(0)
|
||||
, m_styleSet(0)
|
||||
, m_variantSet(0)
|
||||
, m_weightSet(0)
|
||||
, m_textAnchorSet(0)
|
||||
{
|
||||
}
|
||||
|
||||
QSvgFontStyle::QSvgFontStyle()
|
||||
: m_svgFont(0)
|
||||
, m_doc(0)
|
||||
, m_familySet(0)
|
||||
, m_sizeSet(0)
|
||||
, m_styleSet(0)
|
||||
, m_variantSet(0)
|
||||
, m_weightSet(0)
|
||||
, m_textAnchorSet(0)
|
||||
{
|
||||
}
|
||||
|
||||
int QSvgFontStyle::SVGToQtWeight(int weight) {
|
||||
switch (weight) {
|
||||
case 100:
|
||||
case 200:
|
||||
return QFont::Light;
|
||||
case 300:
|
||||
case 400:
|
||||
return QFont::Normal;
|
||||
case 500:
|
||||
case 600:
|
||||
return QFont::DemiBold;
|
||||
case 700:
|
||||
case 800:
|
||||
return QFont::Bold;
|
||||
case 900:
|
||||
return QFont::Black;
|
||||
}
|
||||
return QFont::Normal;
|
||||
}
|
||||
|
||||
void QSvgFontStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &states)
|
||||
{
|
||||
m_oldQFont = p->font();
|
||||
m_oldSvgFont = states.svgFont;
|
||||
m_oldTextAnchor = states.textAnchor;
|
||||
m_oldWeight = states.fontWeight;
|
||||
|
||||
if (m_textAnchorSet)
|
||||
states.textAnchor = m_textAnchor;
|
||||
|
||||
QFont font = m_oldQFont;
|
||||
if (m_familySet) {
|
||||
states.svgFont = m_svgFont;
|
||||
font.setFamily(m_qfont.family());
|
||||
}
|
||||
|
||||
if (m_sizeSet)
|
||||
font.setPointSizeF(m_qfont.pointSizeF());
|
||||
|
||||
if (m_styleSet)
|
||||
font.setStyle(m_qfont.style());
|
||||
|
||||
if (m_variantSet)
|
||||
font.setCapitalization(m_qfont.capitalization());
|
||||
|
||||
if (m_weightSet) {
|
||||
if (m_weight == BOLDER) {
|
||||
states.fontWeight = qMin(states.fontWeight + 100, 900);
|
||||
} else if (m_weight == LIGHTER) {
|
||||
states.fontWeight = qMax(states.fontWeight - 100, 100);
|
||||
} else {
|
||||
states.fontWeight = m_weight;
|
||||
}
|
||||
font.setWeight(SVGToQtWeight(states.fontWeight));
|
||||
}
|
||||
|
||||
p->setFont(font);
|
||||
}
|
||||
|
||||
void QSvgFontStyle::revert(QPainter *p, QSvgExtraStates &states)
|
||||
{
|
||||
p->setFont(m_oldQFont);
|
||||
states.svgFont = m_oldSvgFont;
|
||||
states.textAnchor = m_oldTextAnchor;
|
||||
states.fontWeight = m_oldWeight;
|
||||
}
|
||||
|
||||
QSvgStrokeStyle::QSvgStrokeStyle()
|
||||
: m_strokeOpacity(1.0)
|
||||
, m_oldStrokeOpacity(0.0)
|
||||
, m_strokeDashOffset(0)
|
||||
, m_oldStrokeDashOffset(0)
|
||||
, m_style(0)
|
||||
, m_gradientResolved(1)
|
||||
, m_vectorEffect(0)
|
||||
, m_oldVectorEffect(0)
|
||||
, m_strokeSet(0)
|
||||
, m_strokeDashArraySet(0)
|
||||
, m_strokeDashOffsetSet(0)
|
||||
, m_strokeLineCapSet(0)
|
||||
, m_strokeLineJoinSet(0)
|
||||
, m_strokeMiterLimitSet(0)
|
||||
, m_strokeOpacitySet(0)
|
||||
, m_strokeWidthSet(0)
|
||||
, m_vectorEffectSet(0)
|
||||
{
|
||||
}
|
||||
|
||||
void QSvgStrokeStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &states)
|
||||
{
|
||||
m_oldStroke = p->pen();
|
||||
m_oldStrokeOpacity = states.strokeOpacity;
|
||||
m_oldStrokeDashOffset = states.strokeDashOffset;
|
||||
m_oldVectorEffect = states.vectorEffect;
|
||||
|
||||
QPen pen = p->pen();
|
||||
|
||||
qreal oldWidth = pen.widthF();
|
||||
qreal width = m_stroke.widthF();
|
||||
if (oldWidth == 0)
|
||||
oldWidth = 1;
|
||||
if (width == 0)
|
||||
width = 1;
|
||||
qreal scale = oldWidth / width;
|
||||
|
||||
if (m_strokeOpacitySet)
|
||||
states.strokeOpacity = m_strokeOpacity;
|
||||
|
||||
if (m_vectorEffectSet)
|
||||
states.vectorEffect = m_vectorEffect;
|
||||
|
||||
if (m_strokeSet) {
|
||||
if (m_style)
|
||||
pen.setBrush(m_style->brush(p, states));
|
||||
else
|
||||
pen.setBrush(m_stroke.brush());
|
||||
}
|
||||
|
||||
if (m_strokeWidthSet)
|
||||
pen.setWidthF(m_stroke.widthF());
|
||||
|
||||
bool setDashOffsetNeeded = false;
|
||||
|
||||
if (m_strokeDashOffsetSet) {
|
||||
states.strokeDashOffset = m_strokeDashOffset;
|
||||
setDashOffsetNeeded = true;
|
||||
}
|
||||
|
||||
if (m_strokeDashArraySet) {
|
||||
if (m_stroke.style() == Qt::SolidLine) {
|
||||
pen.setStyle(Qt::SolidLine);
|
||||
} else if (m_strokeWidthSet || oldWidth == 1) {
|
||||
// If both width and dash array was set, the dash array is already scaled correctly.
|
||||
pen.setDashPattern(m_stroke.dashPattern());
|
||||
setDashOffsetNeeded = true;
|
||||
} else {
|
||||
// If dash array was set, but not the width, the dash array has to be scaled with respect to the old width.
|
||||
QVector<qreal> dashes = m_stroke.dashPattern();
|
||||
for (int i = 0; i < dashes.size(); ++i)
|
||||
dashes[i] /= oldWidth;
|
||||
pen.setDashPattern(dashes);
|
||||
setDashOffsetNeeded = true;
|
||||
}
|
||||
} else if (m_strokeWidthSet && pen.style() != Qt::SolidLine && scale != 1) {
|
||||
// If the width was set, but not the dash array, the old dash array must be scaled with respect to the new width.
|
||||
QVector<qreal> dashes = pen.dashPattern();
|
||||
for (int i = 0; i < dashes.size(); ++i)
|
||||
dashes[i] *= scale;
|
||||
pen.setDashPattern(dashes);
|
||||
setDashOffsetNeeded = true;
|
||||
}
|
||||
|
||||
if (m_strokeLineCapSet)
|
||||
pen.setCapStyle(m_stroke.capStyle());
|
||||
if (m_strokeLineJoinSet)
|
||||
pen.setJoinStyle(m_stroke.joinStyle());
|
||||
if (m_strokeMiterLimitSet)
|
||||
pen.setMiterLimit(m_stroke.miterLimit());
|
||||
|
||||
// You can have dash offset on solid strokes in SVG files, but not in Qt.
|
||||
// QPen::setDashOffset() will set the pen style to Qt::CustomDashLine,
|
||||
// so don't call the method if the pen is solid.
|
||||
if (setDashOffsetNeeded && pen.style() != Qt::SolidLine) {
|
||||
qreal currentWidth = pen.widthF();
|
||||
if (currentWidth == 0)
|
||||
currentWidth = 1;
|
||||
pen.setDashOffset(states.strokeDashOffset / currentWidth);
|
||||
}
|
||||
|
||||
pen.setCosmetic(states.vectorEffect);
|
||||
|
||||
p->setPen(pen);
|
||||
}
|
||||
|
||||
void QSvgStrokeStyle::revert(QPainter *p, QSvgExtraStates &states)
|
||||
{
|
||||
p->setPen(m_oldStroke);
|
||||
states.strokeOpacity = m_oldStrokeOpacity;
|
||||
states.strokeDashOffset = m_oldStrokeDashOffset;
|
||||
states.vectorEffect = m_oldVectorEffect;
|
||||
}
|
||||
|
||||
void QSvgStrokeStyle::setDashArray(const QVector<qreal> &dashes)
|
||||
{
|
||||
if (m_strokeWidthSet) {
|
||||
QVector<qreal> d = dashes;
|
||||
qreal w = m_stroke.widthF();
|
||||
if (w != 0 && w != 1) {
|
||||
for (int i = 0; i < d.size(); ++i)
|
||||
d[i] /= w;
|
||||
}
|
||||
m_stroke.setDashPattern(d);
|
||||
} else {
|
||||
m_stroke.setDashPattern(dashes);
|
||||
}
|
||||
m_strokeDashArraySet = 1;
|
||||
}
|
||||
|
||||
QSvgSolidColorStyle::QSvgSolidColorStyle(const QColor &color)
|
||||
: m_solidColor(color)
|
||||
{
|
||||
}
|
||||
|
||||
QSvgGradientStyle::QSvgGradientStyle(QGradient *grad)
|
||||
: m_gradient(grad), m_gradientStopsSet(false)
|
||||
{
|
||||
}
|
||||
|
||||
QBrush QSvgGradientStyle::brush(QPainter *, QSvgExtraStates &)
|
||||
{
|
||||
if (!m_link.isEmpty()) {
|
||||
resolveStops();
|
||||
}
|
||||
|
||||
// If the gradient is marked as empty, insert transparent black
|
||||
if (!m_gradientStopsSet) {
|
||||
m_gradient->setStops(QGradientStops() << QGradientStop(0.0, QColor(0, 0, 0, 0)));
|
||||
m_gradientStopsSet = true;
|
||||
}
|
||||
|
||||
QBrush b(*m_gradient);
|
||||
|
||||
if (!m_matrix.isIdentity())
|
||||
b.setMatrix(m_matrix);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
void QSvgGradientStyle::setMatrix(const QMatrix &mat)
|
||||
{
|
||||
m_matrix = mat;
|
||||
}
|
||||
|
||||
QSvgTransformStyle::QSvgTransformStyle(const QTransform &trans)
|
||||
: m_transform(trans)
|
||||
{
|
||||
}
|
||||
|
||||
void QSvgTransformStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &)
|
||||
{
|
||||
m_oldWorldTransform = p->worldTransform();
|
||||
p->setWorldTransform(m_transform, true);
|
||||
}
|
||||
|
||||
void QSvgTransformStyle::revert(QPainter *p, QSvgExtraStates &)
|
||||
{
|
||||
p->setWorldTransform(m_oldWorldTransform, false /* don't combine */);
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgQualityStyle::type() const
|
||||
{
|
||||
return QUALITY;
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgFillStyle::type() const
|
||||
{
|
||||
return FILL;
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgViewportFillStyle::type() const
|
||||
{
|
||||
return VIEWPORT_FILL;
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgFontStyle::type() const
|
||||
{
|
||||
return FONT;
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgStrokeStyle::type() const
|
||||
{
|
||||
return STROKE;
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgSolidColorStyle::type() const
|
||||
{
|
||||
return SOLID_COLOR;
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgGradientStyle::type() const
|
||||
{
|
||||
return GRADIENT;
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgTransformStyle::type() const
|
||||
{
|
||||
return TRANSFORM;
|
||||
}
|
||||
|
||||
|
||||
QSvgCompOpStyle::QSvgCompOpStyle(QPainter::CompositionMode mode)
|
||||
: m_mode(mode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QSvgCompOpStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &)
|
||||
{
|
||||
m_oldMode = p->compositionMode();
|
||||
p->setCompositionMode(m_mode);
|
||||
}
|
||||
|
||||
void QSvgCompOpStyle::revert(QPainter *p, QSvgExtraStates &)
|
||||
{
|
||||
p->setCompositionMode(m_oldMode);
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgCompOpStyle::type() const
|
||||
{
|
||||
return COMP_OP;
|
||||
}
|
||||
|
||||
QSvgStyle::~QSvgStyle()
|
||||
{
|
||||
}
|
||||
|
||||
void QSvgStyle::apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states)
|
||||
{
|
||||
if (quality) {
|
||||
quality->apply(p, node, states);
|
||||
}
|
||||
|
||||
if (fill) {
|
||||
fill->apply(p, node, states);
|
||||
}
|
||||
|
||||
if (viewportFill) {
|
||||
viewportFill->apply(p, node, states);
|
||||
}
|
||||
|
||||
if (font) {
|
||||
font->apply(p, node, states);
|
||||
}
|
||||
|
||||
if (stroke) {
|
||||
stroke->apply(p, node, states);
|
||||
}
|
||||
|
||||
if (transform) {
|
||||
transform->apply(p, node, states);
|
||||
}
|
||||
|
||||
if (animateColor) {
|
||||
animateColor->apply(p, node, states);
|
||||
}
|
||||
|
||||
//animated transforms have to be applied
|
||||
//_after_ the original object transformations
|
||||
if (!animateTransforms.isEmpty()) {
|
||||
qreal totalTimeElapsed = node->document()->currentElapsed();
|
||||
// Find the last animateTransform with additive="replace", since this will override all
|
||||
// previous animateTransforms.
|
||||
QList<QSvgRefCounter<QSvgAnimateTransform> >::const_iterator itr = animateTransforms.constEnd();
|
||||
do {
|
||||
--itr;
|
||||
if ((*itr)->animActive(totalTimeElapsed)
|
||||
&& (*itr)->additiveType() == QSvgAnimateTransform::Replace) {
|
||||
// An animateTransform with additive="replace" will replace the transform attribute.
|
||||
if (transform)
|
||||
transform->revert(p, states);
|
||||
break;
|
||||
}
|
||||
} while (itr != animateTransforms.constBegin());
|
||||
|
||||
// Apply the animateTransforms after and including the last one with additive="replace".
|
||||
for (; itr != animateTransforms.constEnd(); ++itr) {
|
||||
if ((*itr)->animActive(totalTimeElapsed))
|
||||
(*itr)->apply(p, node, states);
|
||||
}
|
||||
}
|
||||
|
||||
if (opacity) {
|
||||
opacity->apply(p, node, states);
|
||||
}
|
||||
|
||||
if (compop) {
|
||||
compop->apply(p, node, states);
|
||||
}
|
||||
}
|
||||
|
||||
void QSvgStyle::revert(QPainter *p, QSvgExtraStates &states)
|
||||
{
|
||||
if (quality) {
|
||||
quality->revert(p, states);
|
||||
}
|
||||
|
||||
if (fill) {
|
||||
fill->revert(p, states);
|
||||
}
|
||||
|
||||
if (viewportFill) {
|
||||
viewportFill->revert(p, states);
|
||||
}
|
||||
|
||||
if (font) {
|
||||
font->revert(p, states);
|
||||
}
|
||||
|
||||
if (stroke) {
|
||||
stroke->revert(p, states);
|
||||
}
|
||||
|
||||
//animated transforms need to be reverted _before_
|
||||
//the native transforms
|
||||
if (!animateTransforms.isEmpty()) {
|
||||
QList<QSvgRefCounter<QSvgAnimateTransform> >::const_iterator itr = animateTransforms.constBegin();
|
||||
for (; itr != animateTransforms.constEnd(); ++itr) {
|
||||
if ((*itr)->transformApplied()) {
|
||||
(*itr)->revert(p, states);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; itr != animateTransforms.constEnd(); ++itr)
|
||||
(*itr)->clearTransformApplied();
|
||||
}
|
||||
|
||||
if (transform) {
|
||||
transform->revert(p, states);
|
||||
}
|
||||
|
||||
if (animateColor) {
|
||||
animateColor->revert(p, states);
|
||||
}
|
||||
|
||||
if (opacity) {
|
||||
opacity->revert(p, states);
|
||||
}
|
||||
|
||||
if (compop) {
|
||||
compop->revert(p, states);
|
||||
}
|
||||
}
|
||||
|
||||
QSvgAnimateTransform::QSvgAnimateTransform(int startMs, int endMs, int byMs )
|
||||
: QSvgStyleProperty(),
|
||||
m_from(startMs),
|
||||
m_totalRunningTime(endMs - startMs),
|
||||
m_type(Empty),
|
||||
m_additive(Replace),
|
||||
m_count(0),
|
||||
m_finished(false),
|
||||
m_freeze(false),
|
||||
m_repeatCount(-1.),
|
||||
m_transformApplied(false)
|
||||
{
|
||||
Q_UNUSED(byMs);
|
||||
}
|
||||
|
||||
void QSvgAnimateTransform::setArgs(TransformType type, Additive additive, const QVector<qreal> &args)
|
||||
{
|
||||
m_type = type;
|
||||
m_args = args;
|
||||
m_additive = additive;
|
||||
Q_ASSERT(!(args.count()%3));
|
||||
m_count = args.count() / 3;
|
||||
}
|
||||
|
||||
void QSvgAnimateTransform::apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &)
|
||||
{
|
||||
m_oldWorldTransform = p->worldTransform();
|
||||
resolveMatrix(node);
|
||||
p->setWorldTransform(m_transform, true);
|
||||
m_transformApplied = true;
|
||||
}
|
||||
|
||||
void QSvgAnimateTransform::revert(QPainter *p, QSvgExtraStates &)
|
||||
{
|
||||
p->setWorldTransform(m_oldWorldTransform, false /* don't combine */);
|
||||
m_transformApplied = false;
|
||||
}
|
||||
|
||||
void QSvgAnimateTransform::resolveMatrix(const QSvgNode *node)
|
||||
{
|
||||
static const qreal deg2rad = qreal(0.017453292519943295769);
|
||||
qreal totalTimeElapsed = node->document()->currentElapsed();
|
||||
if (totalTimeElapsed < m_from || m_finished)
|
||||
return;
|
||||
|
||||
qreal animationFrame = 0;
|
||||
if (m_totalRunningTime != 0) {
|
||||
animationFrame = (totalTimeElapsed - m_from) / m_totalRunningTime;
|
||||
|
||||
if (m_repeatCount >= 0 && m_repeatCount < animationFrame) {
|
||||
m_finished = true;
|
||||
animationFrame = m_repeatCount;
|
||||
}
|
||||
}
|
||||
|
||||
qreal percentOfAnimation = animationFrame;
|
||||
if (percentOfAnimation > 1) {
|
||||
percentOfAnimation -= ((int)percentOfAnimation);
|
||||
}
|
||||
|
||||
qreal currentPosition = percentOfAnimation * (m_count - 1);
|
||||
int endElem = qCeil(currentPosition);
|
||||
int startElem = qMax(endElem - 1, 0);
|
||||
|
||||
switch(m_type)
|
||||
{
|
||||
case Translate: {
|
||||
startElem *= 3;
|
||||
endElem *= 3;
|
||||
qreal from1, from2;
|
||||
qreal to1, to2;
|
||||
from1 = m_args[startElem++];
|
||||
from2 = m_args[startElem++];
|
||||
to1 = m_args[endElem++];
|
||||
to2 = m_args[endElem++];
|
||||
|
||||
qreal transXDiff = (to1-from1) * percentOfAnimation;
|
||||
qreal transX = from1 + transXDiff;
|
||||
qreal transYDiff = (to2-from2) * percentOfAnimation;
|
||||
qreal transY = from2 + transYDiff;
|
||||
m_transform = QTransform();
|
||||
m_transform.translate(transX, transY);
|
||||
break;
|
||||
}
|
||||
case Scale: {
|
||||
startElem *= 3;
|
||||
endElem *= 3;
|
||||
qreal from1, from2;
|
||||
qreal to1, to2;
|
||||
from1 = m_args[startElem++];
|
||||
from2 = m_args[startElem++];
|
||||
to1 = m_args[endElem++];
|
||||
to2 = m_args[endElem++];
|
||||
|
||||
qreal transXDiff = (to1-from1) * percentOfAnimation;
|
||||
qreal transX = from1 + transXDiff;
|
||||
qreal transYDiff = (to2-from2) * percentOfAnimation;
|
||||
qreal transY = from2 + transYDiff;
|
||||
if (transY == 0)
|
||||
transY = transX;
|
||||
m_transform = QTransform();
|
||||
m_transform.scale(transX, transY);
|
||||
break;
|
||||
}
|
||||
case Rotate: {
|
||||
startElem *= 3;
|
||||
endElem *= 3;
|
||||
qreal from1, from2, from3;
|
||||
qreal to1, to2, to3;
|
||||
from1 = m_args[startElem++];
|
||||
from2 = m_args[startElem++];
|
||||
from3 = m_args[startElem++];
|
||||
to1 = m_args[endElem++];
|
||||
to2 = m_args[endElem++];
|
||||
to3 = m_args[endElem++];
|
||||
|
||||
qreal rotationDiff = (to1 - from1) * percentOfAnimation;
|
||||
//qreal rotation = from1 + rotationDiff;
|
||||
|
||||
qreal transXDiff = (to2-from2) * percentOfAnimation;
|
||||
qreal transX = from2 + transXDiff;
|
||||
qreal transYDiff = (to3-from3) * percentOfAnimation;
|
||||
qreal transY = from3 + transYDiff;
|
||||
m_transform = QTransform();
|
||||
m_transform.translate(transX, transY);
|
||||
m_transform.rotate(rotationDiff);
|
||||
m_transform.translate(-transX, -transY);
|
||||
break;
|
||||
}
|
||||
case SkewX: {
|
||||
startElem *= 3;
|
||||
endElem *= 3;
|
||||
qreal from1;
|
||||
qreal to1;
|
||||
from1 = m_args[startElem++];
|
||||
to1 = m_args[endElem++];
|
||||
|
||||
qreal transXDiff = (to1-from1) * percentOfAnimation;
|
||||
qreal transX = from1 + transXDiff;
|
||||
m_transform = QTransform();
|
||||
m_transform.shear(qTan(transX * deg2rad), 0);
|
||||
break;
|
||||
}
|
||||
case SkewY: {
|
||||
startElem *= 3;
|
||||
endElem *= 3;
|
||||
qreal from1;
|
||||
qreal to1;
|
||||
from1 = m_args[startElem++];
|
||||
to1 = m_args[endElem++];
|
||||
|
||||
|
||||
qreal transYDiff = (to1 - from1) * percentOfAnimation;
|
||||
qreal transY = from1 + transYDiff;
|
||||
m_transform = QTransform();
|
||||
m_transform.shear(0, qTan(transY * deg2rad));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgAnimateTransform::type() const
|
||||
{
|
||||
return ANIMATE_TRANSFORM;
|
||||
}
|
||||
|
||||
void QSvgAnimateTransform::setFreeze(bool freeze)
|
||||
{
|
||||
m_freeze = freeze;
|
||||
}
|
||||
|
||||
void QSvgAnimateTransform::setRepeatCount(qreal repeatCount)
|
||||
{
|
||||
m_repeatCount = repeatCount;
|
||||
}
|
||||
|
||||
QSvgAnimateColor::QSvgAnimateColor(int startMs, int endMs, int byMs)
|
||||
: QSvgStyleProperty(),
|
||||
m_from(startMs),
|
||||
m_totalRunningTime(endMs - startMs),
|
||||
m_fill(false),
|
||||
m_finished(false),
|
||||
m_freeze(false),
|
||||
m_repeatCount(-1.)
|
||||
{
|
||||
Q_UNUSED(byMs);
|
||||
}
|
||||
|
||||
void QSvgAnimateColor::setArgs(bool fill,
|
||||
const QList<QColor> &colors)
|
||||
{
|
||||
m_fill = fill;
|
||||
m_colors = colors;
|
||||
}
|
||||
|
||||
void QSvgAnimateColor::setFreeze(bool freeze)
|
||||
{
|
||||
m_freeze = freeze;
|
||||
}
|
||||
|
||||
void QSvgAnimateColor::setRepeatCount(qreal repeatCount)
|
||||
{
|
||||
m_repeatCount = repeatCount;
|
||||
}
|
||||
|
||||
void QSvgAnimateColor::apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &)
|
||||
{
|
||||
qreal totalTimeElapsed = node->document()->currentElapsed();
|
||||
if (totalTimeElapsed < m_from || m_finished)
|
||||
return;
|
||||
|
||||
qreal animationFrame = 0;
|
||||
if (m_totalRunningTime != 0)
|
||||
animationFrame = (totalTimeElapsed - m_from) / m_totalRunningTime;
|
||||
|
||||
if (m_repeatCount >= 0 && m_repeatCount < animationFrame) {
|
||||
m_finished = true;
|
||||
animationFrame = m_repeatCount;
|
||||
}
|
||||
|
||||
qreal percentOfAnimation = animationFrame;
|
||||
if (percentOfAnimation > 1) {
|
||||
percentOfAnimation -= ((int)percentOfAnimation);
|
||||
}
|
||||
|
||||
qreal currentPosition = percentOfAnimation * (m_colors.count() - 1);
|
||||
|
||||
int startElem = qFloor(currentPosition);
|
||||
int endElem = qCeil(currentPosition);
|
||||
QColor start = m_colors[startElem];
|
||||
QColor end = m_colors[endElem];
|
||||
|
||||
qreal percentOfColorMorph = currentPosition;
|
||||
if (percentOfColorMorph > 1) {
|
||||
percentOfColorMorph -= ((int)percentOfColorMorph);
|
||||
}
|
||||
|
||||
// Interpolate between the two fixed colors start and end
|
||||
qreal aDiff = (end.alpha() - start.alpha()) * percentOfColorMorph;
|
||||
qreal rDiff = (end.red() - start.red()) * percentOfColorMorph;
|
||||
qreal gDiff = (end.green() - start.green()) * percentOfColorMorph;
|
||||
qreal bDiff = (end.blue() - start.blue()) * percentOfColorMorph;
|
||||
|
||||
int alpha = int(start.alpha() + aDiff);
|
||||
int red = int(start.red() + rDiff);
|
||||
int green = int(start.green() + gDiff);
|
||||
int blue = int(start.blue() + bDiff);
|
||||
|
||||
QColor color(red, green, blue, alpha);
|
||||
|
||||
if (m_fill) {
|
||||
QBrush b = p->brush();
|
||||
m_oldBrush = b;
|
||||
b.setColor(color);
|
||||
p->setBrush(b);
|
||||
} else {
|
||||
QPen pen = p->pen();
|
||||
m_oldPen = pen;
|
||||
pen.setColor(color);
|
||||
p->setPen(pen);
|
||||
}
|
||||
}
|
||||
|
||||
void QSvgAnimateColor::revert(QPainter *p, QSvgExtraStates &)
|
||||
{
|
||||
if (m_fill) {
|
||||
p->setBrush(m_oldBrush);
|
||||
} else {
|
||||
p->setPen(m_oldPen);
|
||||
}
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgAnimateColor::type() const
|
||||
{
|
||||
return ANIMATE_COLOR;
|
||||
}
|
||||
|
||||
QSvgOpacityStyle::QSvgOpacityStyle(qreal opacity)
|
||||
: m_opacity(opacity), m_oldOpacity(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QSvgOpacityStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &)
|
||||
{
|
||||
m_oldOpacity = p->opacity();
|
||||
p->setOpacity(m_opacity * m_oldOpacity);
|
||||
}
|
||||
|
||||
void QSvgOpacityStyle::revert(QPainter *p, QSvgExtraStates &)
|
||||
{
|
||||
p->setOpacity(m_oldOpacity);
|
||||
}
|
||||
|
||||
QSvgStyleProperty::Type QSvgOpacityStyle::type() const
|
||||
{
|
||||
return OPACITY;
|
||||
}
|
||||
|
||||
void QSvgGradientStyle::setStopLink(const QString &link, QSvgTinyDocument *doc)
|
||||
{
|
||||
m_link = link;
|
||||
m_doc = doc;
|
||||
}
|
||||
|
||||
void QSvgGradientStyle::resolveStops()
|
||||
{
|
||||
QStringList visited;
|
||||
resolveStops_helper(&visited);
|
||||
}
|
||||
|
||||
void QSvgGradientStyle::resolveStops_helper(QStringList *visited)
|
||||
{
|
||||
if (!m_link.isEmpty() && m_doc) {
|
||||
QSvgStyleProperty *prop = m_doc->styleProperty(m_link);
|
||||
if (prop && !visited->contains(m_link)) {
|
||||
visited->append(m_link);
|
||||
if (prop->type() == QSvgStyleProperty::GRADIENT) {
|
||||
QSvgGradientStyle *st =
|
||||
static_cast<QSvgGradientStyle*>(prop);
|
||||
st->resolveStops_helper(visited);
|
||||
m_gradient->setStops(st->qgradient()->stops());
|
||||
m_gradientStopsSet = st->gradientStopsSet();
|
||||
}
|
||||
} else {
|
||||
qWarning("Could not resolve property : %s", qPrintable(m_link));
|
||||
}
|
||||
m_link = QString();
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
822
svg/qsvgstyle_p.h
Normal file
822
svg/qsvgstyle_p.h
Normal file
|
|
@ -0,0 +1,822 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGSTYLE_P_H
|
||||
#define QSVGSTYLE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "QtGui/qpainter.h"
|
||||
#include "QtGui/qpen.h"
|
||||
#include "QtGui/qbrush.h"
|
||||
#include "QtGui/qmatrix.h"
|
||||
#include "QtGui/qcolor.h"
|
||||
#include "QtGui/qfont.h"
|
||||
#include <qdebug.h>
|
||||
#include "qtsvgglobal_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPainter;
|
||||
class QSvgNode;
|
||||
class QSvgFont;
|
||||
class QSvgTinyDocument;
|
||||
|
||||
template <class T> class QSvgRefCounter
|
||||
{
|
||||
public:
|
||||
QSvgRefCounter() { t = 0; }
|
||||
QSvgRefCounter(T *_t)
|
||||
{
|
||||
t = _t;
|
||||
if (t)
|
||||
t->ref();
|
||||
}
|
||||
QSvgRefCounter(const QSvgRefCounter &other)
|
||||
{
|
||||
t = other.t;
|
||||
if (t)
|
||||
t->ref();
|
||||
}
|
||||
QSvgRefCounter &operator =(T *_t)
|
||||
{
|
||||
if(_t)
|
||||
_t->ref();
|
||||
if (t)
|
||||
t->deref();
|
||||
t = _t;
|
||||
return *this;
|
||||
}
|
||||
QSvgRefCounter &operator =(const QSvgRefCounter &other)
|
||||
{
|
||||
if(other.t)
|
||||
other.t->ref();
|
||||
if (t)
|
||||
t->deref();
|
||||
t = other.t;
|
||||
return *this;
|
||||
}
|
||||
~QSvgRefCounter()
|
||||
{
|
||||
if (t)
|
||||
t->deref();
|
||||
}
|
||||
|
||||
inline T *operator->() const { return t; }
|
||||
inline operator T*() const { return t; }
|
||||
|
||||
private:
|
||||
T *t;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgRefCounted
|
||||
{
|
||||
public:
|
||||
QSvgRefCounted() { _ref = 0; }
|
||||
virtual ~QSvgRefCounted() {}
|
||||
void ref() {
|
||||
++_ref;
|
||||
// qDebug() << this << ": adding ref, now " << _ref;
|
||||
}
|
||||
void deref() {
|
||||
// qDebug() << this << ": removing ref, now " << _ref;
|
||||
if(!--_ref) {
|
||||
// qDebug(" deleting");
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
private:
|
||||
int _ref;
|
||||
};
|
||||
|
||||
struct Q_SVG_PRIVATE_EXPORT QSvgExtraStates
|
||||
{
|
||||
QSvgExtraStates();
|
||||
|
||||
qreal fillOpacity;
|
||||
qreal strokeOpacity;
|
||||
QSvgFont *svgFont;
|
||||
Qt::Alignment textAnchor;
|
||||
int fontWeight;
|
||||
Qt::FillRule fillRule;
|
||||
qreal strokeDashOffset;
|
||||
bool vectorEffect; // true if pen is cosmetic
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgStyleProperty : public QSvgRefCounted
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
QUALITY,
|
||||
FILL,
|
||||
VIEWPORT_FILL,
|
||||
FONT,
|
||||
STROKE,
|
||||
SOLID_COLOR,
|
||||
GRADIENT,
|
||||
TRANSFORM,
|
||||
ANIMATE_TRANSFORM,
|
||||
ANIMATE_COLOR,
|
||||
OPACITY,
|
||||
COMP_OP
|
||||
};
|
||||
public:
|
||||
virtual ~QSvgStyleProperty();
|
||||
virtual void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) = 0;
|
||||
virtual void revert(QPainter *p, QSvgExtraStates &states) =0;
|
||||
virtual Type type() const=0;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgFillStyleProperty : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
virtual QBrush brush(QPainter *p, QSvgExtraStates &states) = 0;
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgQualityStyle : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgQualityStyle(int color);
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
private:
|
||||
// color-render ing v v 'auto' | 'optimizeSpeed' |
|
||||
// 'optimizeQuality' | 'inherit'
|
||||
//int m_colorRendering;
|
||||
|
||||
// shape-rendering v v 'auto' | 'optimizeSpeed' | 'crispEdges' |
|
||||
// 'geometricPrecision' | 'inherit'
|
||||
//QSvgShapeRendering m_shapeRendering;
|
||||
|
||||
|
||||
// text-rendering v v 'auto' | 'optimizeSpeed' | 'optimizeLegibility'
|
||||
// | 'geometricPrecision' | 'inherit'
|
||||
//QSvgTextRendering m_textRendering;
|
||||
|
||||
|
||||
// vector-effect v x 'default' | 'non-scaling-stroke' | 'inherit'
|
||||
//QSvgVectorEffect m_vectorEffect;
|
||||
|
||||
// image-rendering v v 'auto' | 'optimizeSpeed' | 'optimizeQuality' |
|
||||
// 'inherit'
|
||||
//QSvgImageRendering m_imageRendering;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgOpacityStyle : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgOpacityStyle(qreal opacity);
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
private:
|
||||
qreal m_opacity;
|
||||
qreal m_oldOpacity;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgFillStyle : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgFillStyle();
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
|
||||
void setFillRule(Qt::FillRule f);
|
||||
void setFillOpacity(qreal opacity);
|
||||
void setFillStyle(QSvgFillStyleProperty* style);
|
||||
void setBrush(QBrush brush);
|
||||
|
||||
const QBrush & qbrush() const
|
||||
{
|
||||
return m_fill;
|
||||
}
|
||||
|
||||
qreal fillOpacity() const
|
||||
{
|
||||
return m_fillOpacity;
|
||||
}
|
||||
|
||||
Qt::FillRule fillRule() const
|
||||
{
|
||||
return m_fillRule;
|
||||
}
|
||||
|
||||
QSvgFillStyleProperty* style() const
|
||||
{
|
||||
return m_style;
|
||||
}
|
||||
|
||||
void setGradientId(const QString &Id)
|
||||
{
|
||||
m_gradientId = Id;
|
||||
}
|
||||
|
||||
QString gradientId() const
|
||||
{
|
||||
return m_gradientId;
|
||||
}
|
||||
|
||||
void setGradientResolved(bool resolved)
|
||||
{
|
||||
m_gradientResolved = resolved;
|
||||
}
|
||||
|
||||
bool isGradientResolved() const
|
||||
{
|
||||
return m_gradientResolved;
|
||||
}
|
||||
|
||||
private:
|
||||
// fill v v 'inherit' | <Paint.datatype>
|
||||
// fill-opacity v v 'inherit' | <OpacityValue.datatype>
|
||||
QBrush m_fill;
|
||||
QBrush m_oldFill;
|
||||
QSvgFillStyleProperty *m_style;
|
||||
|
||||
Qt::FillRule m_fillRule;
|
||||
Qt::FillRule m_oldFillRule;
|
||||
qreal m_fillOpacity;
|
||||
qreal m_oldFillOpacity;
|
||||
|
||||
QString m_gradientId;
|
||||
uint m_gradientResolved : 1;
|
||||
|
||||
uint m_fillRuleSet : 1;
|
||||
uint m_fillOpacitySet : 1;
|
||||
uint m_fillSet : 1;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgViewportFillStyle : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgViewportFillStyle(const QBrush &brush);
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
|
||||
const QBrush & qbrush() const
|
||||
{
|
||||
return m_viewportFill;
|
||||
}
|
||||
private:
|
||||
// viewport-fill v x 'inherit' | <Paint.datatype>
|
||||
// viewport-fill-opacity v x 'inherit' | <OpacityValue.datatype>
|
||||
QBrush m_viewportFill;
|
||||
|
||||
QBrush m_oldFill;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgFontStyle : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
static const int LIGHTER = -1;
|
||||
static const int BOLDER = 1;
|
||||
|
||||
QSvgFontStyle(QSvgFont *font, QSvgTinyDocument *doc);
|
||||
QSvgFontStyle();
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
|
||||
void setSize(qreal size)
|
||||
{
|
||||
// Store the _pixel_ size in the font. Since QFont::setPixelSize() only takes an int, call
|
||||
// QFont::SetPointSize() instead. Set proper font size just before rendering.
|
||||
m_qfont.setPointSizeF(size);
|
||||
m_sizeSet = 1;
|
||||
}
|
||||
|
||||
void setTextAnchor(Qt::Alignment anchor)
|
||||
{
|
||||
m_textAnchor = anchor;
|
||||
m_textAnchorSet = 1;
|
||||
}
|
||||
|
||||
void setFamily(const QString &family)
|
||||
{
|
||||
m_qfont.setFamily(family);
|
||||
m_familySet = 1;
|
||||
}
|
||||
|
||||
void setStyle(QFont::Style fontStyle) {
|
||||
m_qfont.setStyle(fontStyle);
|
||||
m_styleSet = 1;
|
||||
}
|
||||
|
||||
void setVariant(QFont::Capitalization fontVariant)
|
||||
{
|
||||
m_qfont.setCapitalization(fontVariant);
|
||||
m_variantSet = 1;
|
||||
}
|
||||
|
||||
static int SVGToQtWeight(int weight);
|
||||
|
||||
void setWeight(int weight)
|
||||
{
|
||||
m_weight = weight;
|
||||
m_weightSet = 1;
|
||||
}
|
||||
|
||||
QSvgFont * svgFont() const
|
||||
{
|
||||
return m_svgFont;
|
||||
}
|
||||
|
||||
const QFont &qfont() const
|
||||
{
|
||||
return m_qfont;
|
||||
}
|
||||
|
||||
QSvgTinyDocument *doc() const {return m_doc;}
|
||||
|
||||
private:
|
||||
QSvgFont *m_svgFont;
|
||||
QSvgTinyDocument *m_doc;
|
||||
QFont m_qfont;
|
||||
|
||||
int m_weight;
|
||||
Qt::Alignment m_textAnchor;
|
||||
|
||||
QSvgFont *m_oldSvgFont;
|
||||
QFont m_oldQFont;
|
||||
Qt::Alignment m_oldTextAnchor;
|
||||
int m_oldWeight;
|
||||
|
||||
uint m_familySet : 1;
|
||||
uint m_sizeSet : 1;
|
||||
uint m_styleSet : 1;
|
||||
uint m_variantSet : 1;
|
||||
uint m_weightSet : 1;
|
||||
uint m_textAnchorSet : 1;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgStrokeStyle : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgStrokeStyle();
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
|
||||
void setStroke(QBrush brush)
|
||||
{
|
||||
m_stroke.setBrush(brush);
|
||||
m_style = 0;
|
||||
m_strokeSet = 1;
|
||||
}
|
||||
|
||||
void setStyle(QSvgFillStyleProperty *style)
|
||||
{
|
||||
m_style = style;
|
||||
m_strokeSet = 1;
|
||||
}
|
||||
|
||||
void setDashArray(const QVector<qreal> &dashes);
|
||||
|
||||
void setDashArrayNone()
|
||||
{
|
||||
m_stroke.setStyle(Qt::SolidLine);
|
||||
m_strokeDashArraySet = 1;
|
||||
}
|
||||
|
||||
void setDashOffset(qreal offset)
|
||||
{
|
||||
m_strokeDashOffset = offset;
|
||||
m_strokeDashOffsetSet = 1;
|
||||
}
|
||||
|
||||
void setLineCap(Qt::PenCapStyle cap)
|
||||
{
|
||||
m_stroke.setCapStyle(cap);
|
||||
m_strokeLineCapSet = 1;
|
||||
}
|
||||
|
||||
void setLineJoin(Qt::PenJoinStyle join)
|
||||
{
|
||||
m_stroke.setJoinStyle(join);
|
||||
m_strokeLineJoinSet = 1;
|
||||
}
|
||||
|
||||
void setMiterLimit(qreal limit)
|
||||
{
|
||||
m_stroke.setMiterLimit(limit);
|
||||
m_strokeMiterLimitSet = 1;
|
||||
}
|
||||
|
||||
void setOpacity(qreal opacity)
|
||||
{
|
||||
m_strokeOpacity = opacity;
|
||||
m_strokeOpacitySet = 1;
|
||||
}
|
||||
|
||||
void setWidth(qreal width)
|
||||
{
|
||||
m_stroke.setWidthF(width);
|
||||
m_strokeWidthSet = 1;
|
||||
Q_ASSERT(!m_strokeDashArraySet); // set width before dash array.
|
||||
}
|
||||
|
||||
qreal width()
|
||||
{
|
||||
return m_stroke.widthF();
|
||||
}
|
||||
|
||||
void setVectorEffect(bool nonScalingStroke)
|
||||
{
|
||||
m_vectorEffect = nonScalingStroke;
|
||||
m_vectorEffectSet = 1;
|
||||
}
|
||||
|
||||
QSvgFillStyleProperty* style() const
|
||||
{
|
||||
return m_style;
|
||||
}
|
||||
|
||||
void setGradientId(const QString &Id)
|
||||
{
|
||||
m_gradientId = Id;
|
||||
}
|
||||
|
||||
QString gradientId() const
|
||||
{
|
||||
return m_gradientId;
|
||||
}
|
||||
|
||||
void setGradientResolved(bool resolved)
|
||||
{
|
||||
m_gradientResolved = resolved;
|
||||
}
|
||||
|
||||
bool isGradientResolved() const
|
||||
{
|
||||
return m_gradientResolved;
|
||||
}
|
||||
|
||||
QPen stroke() const
|
||||
{
|
||||
return m_stroke;
|
||||
}
|
||||
|
||||
private:
|
||||
// stroke v v 'inherit' | <Paint.datatype>
|
||||
// stroke-dasharray v v 'inherit' | <StrokeDashArrayValue.datatype>
|
||||
// stroke-dashoffset v v 'inherit' | <StrokeDashOffsetValue.datatype>
|
||||
// stroke-linecap v v 'butt' | 'round' | 'square' | 'inherit'
|
||||
// stroke-linejoin v v 'miter' | 'round' | 'bevel' | 'inherit'
|
||||
// stroke-miterlimit v v 'inherit' | <StrokeMiterLimitValue.datatype>
|
||||
// stroke-opacity v v 'inherit' | <OpacityValue.datatype>
|
||||
// stroke-width v v 'inherit' | <StrokeWidthValue.datatype>
|
||||
QPen m_stroke;
|
||||
QPen m_oldStroke;
|
||||
qreal m_strokeOpacity;
|
||||
qreal m_oldStrokeOpacity;
|
||||
qreal m_strokeDashOffset;
|
||||
qreal m_oldStrokeDashOffset;
|
||||
|
||||
QSvgFillStyleProperty *m_style;
|
||||
QString m_gradientId;
|
||||
uint m_gradientResolved : 1;
|
||||
uint m_vectorEffect : 1;
|
||||
uint m_oldVectorEffect : 1;
|
||||
|
||||
uint m_strokeSet : 1;
|
||||
uint m_strokeDashArraySet : 1;
|
||||
uint m_strokeDashOffsetSet : 1;
|
||||
uint m_strokeLineCapSet : 1;
|
||||
uint m_strokeLineJoinSet : 1;
|
||||
uint m_strokeMiterLimitSet : 1;
|
||||
uint m_strokeOpacitySet : 1;
|
||||
uint m_strokeWidthSet : 1;
|
||||
uint m_vectorEffectSet : 1;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgSolidColorStyle : public QSvgFillStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgSolidColorStyle(const QColor &color);
|
||||
Type type() const override;
|
||||
|
||||
const QColor & qcolor() const
|
||||
{
|
||||
return m_solidColor;
|
||||
}
|
||||
|
||||
QBrush brush(QPainter *, QSvgExtraStates &) override
|
||||
{
|
||||
return m_solidColor;
|
||||
}
|
||||
|
||||
private:
|
||||
// solid-color v x 'inherit' | <SVGColor.datatype>
|
||||
// solid-opacity v x 'inherit' | <OpacityValue.datatype>
|
||||
QColor m_solidColor;
|
||||
|
||||
QBrush m_oldFill;
|
||||
QPen m_oldStroke;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgGradientStyle : public QSvgFillStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgGradientStyle(QGradient *grad);
|
||||
~QSvgGradientStyle() { delete m_gradient; }
|
||||
Type type() const override;
|
||||
|
||||
void setStopLink(const QString &link, QSvgTinyDocument *doc);
|
||||
QString stopLink() const { return m_link; }
|
||||
void resolveStops();
|
||||
void resolveStops_helper(QStringList *visited);
|
||||
|
||||
void setMatrix(const QMatrix &matrix);
|
||||
QMatrix qmatrix() const
|
||||
{
|
||||
return m_matrix;
|
||||
}
|
||||
|
||||
QGradient *qgradient() const
|
||||
{
|
||||
return m_gradient;
|
||||
}
|
||||
|
||||
bool gradientStopsSet() const
|
||||
{
|
||||
return m_gradientStopsSet;
|
||||
}
|
||||
|
||||
void setGradientStopsSet(bool set)
|
||||
{
|
||||
m_gradientStopsSet = set;
|
||||
}
|
||||
|
||||
QBrush brush(QPainter *, QSvgExtraStates &) override;
|
||||
private:
|
||||
QGradient *m_gradient;
|
||||
QMatrix m_matrix;
|
||||
|
||||
QSvgTinyDocument *m_doc;
|
||||
QString m_link;
|
||||
bool m_gradientStopsSet;
|
||||
};
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgTransformStyle : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgTransformStyle(const QTransform &transform);
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
|
||||
const QTransform & qtransform() const
|
||||
{
|
||||
return m_transform;
|
||||
}
|
||||
private:
|
||||
//7.6 The transform attribute
|
||||
QTransform m_transform;
|
||||
QTransform m_oldWorldTransform;
|
||||
};
|
||||
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgAnimateTransform : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
enum TransformType
|
||||
{
|
||||
Empty,
|
||||
Translate,
|
||||
Scale,
|
||||
Rotate,
|
||||
SkewX,
|
||||
SkewY
|
||||
};
|
||||
enum Additive
|
||||
{
|
||||
Sum,
|
||||
Replace
|
||||
};
|
||||
public:
|
||||
QSvgAnimateTransform(int startMs, int endMs, int by = 0);
|
||||
void setArgs(TransformType type, Additive additive, const QVector<qreal> &args);
|
||||
void setFreeze(bool freeze);
|
||||
void setRepeatCount(qreal repeatCount);
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
QSvgAnimateTransform::Additive additiveType() const
|
||||
{
|
||||
return m_additive;
|
||||
}
|
||||
|
||||
bool animActive(qreal totalTimeElapsed)
|
||||
{
|
||||
if (totalTimeElapsed < m_from)
|
||||
return false;
|
||||
if (m_freeze || m_repeatCount < 0) // fill="freeze" or repeat="indefinite"
|
||||
return true;
|
||||
if (m_totalRunningTime == 0)
|
||||
return false;
|
||||
qreal animationFrame = (totalTimeElapsed - m_from) / m_totalRunningTime;
|
||||
if (animationFrame > m_repeatCount)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool transformApplied() const
|
||||
{
|
||||
return m_transformApplied;
|
||||
}
|
||||
|
||||
// Call this instead of revert if you know that revert is unnecessary.
|
||||
void clearTransformApplied()
|
||||
{
|
||||
m_transformApplied = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
void resolveMatrix(const QSvgNode *node);
|
||||
private:
|
||||
qreal m_from;
|
||||
qreal m_totalRunningTime;
|
||||
TransformType m_type;
|
||||
Additive m_additive;
|
||||
QVector<qreal> m_args;
|
||||
int m_count;
|
||||
QTransform m_transform;
|
||||
QTransform m_oldWorldTransform;
|
||||
bool m_finished;
|
||||
bool m_freeze;
|
||||
qreal m_repeatCount;
|
||||
bool m_transformApplied;
|
||||
};
|
||||
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgAnimateColor : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgAnimateColor(int startMs, int endMs, int by = 0);
|
||||
void setArgs(bool fill, const QList<QColor> &colors);
|
||||
void setFreeze(bool freeze);
|
||||
void setRepeatCount(qreal repeatCount);
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
private:
|
||||
qreal m_from;
|
||||
qreal m_totalRunningTime;
|
||||
QList<QColor> m_colors;
|
||||
QBrush m_oldBrush;
|
||||
QPen m_oldPen;
|
||||
bool m_fill;
|
||||
bool m_finished;
|
||||
bool m_freeze;
|
||||
qreal m_repeatCount;
|
||||
};
|
||||
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgCompOpStyle : public QSvgStyleProperty
|
||||
{
|
||||
public:
|
||||
QSvgCompOpStyle(QPainter::CompositionMode mode);
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
|
||||
void revert(QPainter *p, QSvgExtraStates &states) override;
|
||||
Type type() const override;
|
||||
|
||||
const QPainter::CompositionMode & compOp() const
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
private:
|
||||
//comp-op attribute
|
||||
QPainter::CompositionMode m_mode;
|
||||
|
||||
QPainter::CompositionMode m_oldMode;
|
||||
};
|
||||
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgStyle
|
||||
{
|
||||
public:
|
||||
QSvgStyle()
|
||||
: quality(0),
|
||||
fill(0),
|
||||
viewportFill(0),
|
||||
font(0),
|
||||
stroke(0),
|
||||
solidColor(0),
|
||||
gradient(0),
|
||||
transform(0),
|
||||
animateColor(0),
|
||||
opacity(0),
|
||||
compop(0)
|
||||
{}
|
||||
~QSvgStyle();
|
||||
|
||||
void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states);
|
||||
void revert(QPainter *p, QSvgExtraStates &states);
|
||||
QSvgRefCounter<QSvgQualityStyle> quality;
|
||||
QSvgRefCounter<QSvgFillStyle> fill;
|
||||
QSvgRefCounter<QSvgViewportFillStyle> viewportFill;
|
||||
QSvgRefCounter<QSvgFontStyle> font;
|
||||
QSvgRefCounter<QSvgStrokeStyle> stroke;
|
||||
QSvgRefCounter<QSvgSolidColorStyle> solidColor;
|
||||
QSvgRefCounter<QSvgGradientStyle> gradient;
|
||||
QSvgRefCounter<QSvgTransformStyle> transform;
|
||||
QSvgRefCounter<QSvgAnimateColor> animateColor;
|
||||
QList<QSvgRefCounter<QSvgAnimateTransform> > animateTransforms;
|
||||
QSvgRefCounter<QSvgOpacityStyle> opacity;
|
||||
QSvgRefCounter<QSvgCompOpStyle> compop;
|
||||
};
|
||||
|
||||
/********************************************************/
|
||||
// NOT implemented:
|
||||
|
||||
// color v v 'inherit' | <Color.datatype>
|
||||
//QColor m_color;
|
||||
|
||||
// display v x 'inline' | 'block' | 'list-item'
|
||||
// | 'run-in' | 'compact' | 'marker' |
|
||||
// 'table' | 'inline-table' |
|
||||
// 'table-row-group' | 'table-header-group' |
|
||||
// 'table-footer-group' | 'table-row' |
|
||||
// 'table-column-group' | 'table-column' |
|
||||
// 'table-cell' | 'table-caption' |
|
||||
// 'none' | 'inherit'
|
||||
//QSvgDisplayStyle m_display;
|
||||
|
||||
// display-align v v 'auto' | 'before' | 'center' | 'after' | 'inherit'
|
||||
//QSvgDisplayAlign m_displayAlign;
|
||||
|
||||
// line-increment v v 'auto' | 'inherit' | <Number.datatype>
|
||||
//int m_lineIncrement;
|
||||
|
||||
// text-anchor v v 'start' | 'middle' | 'end' | 'inherit'
|
||||
//QSvgTextAnchor m_textAnchor;
|
||||
|
||||
// visibility v v 'visible' | 'hidden' | 'inherit'
|
||||
//QSvgVisibility m_visibility;
|
||||
|
||||
/******************************************************/
|
||||
// the following do not make sense for us
|
||||
|
||||
// pointer-events v v 'visiblePainted' | 'visibleFill' | 'visibleStroke' |
|
||||
// 'visible' | 'painted' | 'fill' | 'stroke' | 'all' |
|
||||
// 'none' | 'inherit'
|
||||
//QSvgPointEvents m_pointerEvents;
|
||||
|
||||
// audio-level v x 'inherit' | <Number.datatype>
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSVGSTYLE_P_H
|
||||
557
svg/qsvgtinydocument.cpp
Normal file
557
svg/qsvgtinydocument.cpp
Normal file
|
|
@ -0,0 +1,557 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsvgtinydocument_p.h"
|
||||
|
||||
#include "qsvghandler_p.h"
|
||||
#include "qsvgfont_p.h"
|
||||
|
||||
#include "qpainter.h"
|
||||
#include "qfile.h"
|
||||
#include "qbuffer.h"
|
||||
#include "qbytearray.h"
|
||||
#include "qqueue.h"
|
||||
#include "qstack.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QSvgTinyDocument::QSvgTinyDocument()
|
||||
: QSvgStructureNode(0)
|
||||
, m_widthPercent(false)
|
||||
, m_heightPercent(false)
|
||||
, m_animated(false)
|
||||
, m_animationDuration(0)
|
||||
, m_fps(30)
|
||||
{
|
||||
}
|
||||
|
||||
QSvgTinyDocument::~QSvgTinyDocument()
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
# ifdef QT_BUILD_INTERNAL
|
||||
Q_AUTOTEST_EXPORT QByteArray qt_inflateGZipDataFrom(QIODevice *device);
|
||||
# else
|
||||
static QByteArray qt_inflateGZipDataFrom(QIODevice *device);
|
||||
# endif
|
||||
|
||||
QByteArray qt_inflateGZipDataFrom(QIODevice *device)
|
||||
{
|
||||
if (!device)
|
||||
return QByteArray();
|
||||
|
||||
if (!device->isOpen())
|
||||
device->open(QIODevice::ReadOnly);
|
||||
|
||||
Q_ASSERT(device->isOpen() && device->isReadable());
|
||||
|
||||
static const int CHUNK_SIZE = 4096;
|
||||
int zlibResult = Z_OK;
|
||||
|
||||
QByteArray source;
|
||||
QByteArray destination;
|
||||
|
||||
// Initialize zlib stream struct
|
||||
z_stream zlibStream;
|
||||
zlibStream.next_in = Z_NULL;
|
||||
zlibStream.avail_in = 0;
|
||||
zlibStream.avail_out = 0;
|
||||
zlibStream.zalloc = Z_NULL;
|
||||
zlibStream.zfree = Z_NULL;
|
||||
zlibStream.opaque = Z_NULL;
|
||||
|
||||
// Adding 16 to the window size gives us gzip decoding
|
||||
if (inflateInit2(&zlibStream, MAX_WBITS + 16) != Z_OK) {
|
||||
qCWarning(lcSvgHandler, "Cannot initialize zlib, because: %s",
|
||||
(zlibStream.msg != NULL ? zlibStream.msg : "Unknown error"));
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
bool stillMoreWorkToDo = true;
|
||||
while (stillMoreWorkToDo) {
|
||||
|
||||
if (!zlibStream.avail_in) {
|
||||
source = device->read(CHUNK_SIZE);
|
||||
|
||||
if (source.isEmpty())
|
||||
break;
|
||||
|
||||
zlibStream.avail_in = source.size();
|
||||
zlibStream.next_in = reinterpret_cast<Bytef*>(source.data());
|
||||
}
|
||||
|
||||
do {
|
||||
// Prepare the destination buffer
|
||||
int oldSize = destination.size();
|
||||
destination.resize(oldSize + CHUNK_SIZE);
|
||||
zlibStream.next_out = reinterpret_cast<Bytef*>(
|
||||
destination.data() + oldSize - zlibStream.avail_out);
|
||||
zlibStream.avail_out += CHUNK_SIZE;
|
||||
|
||||
zlibResult = inflate(&zlibStream, Z_NO_FLUSH);
|
||||
switch (zlibResult) {
|
||||
case Z_NEED_DICT:
|
||||
case Z_DATA_ERROR:
|
||||
case Z_STREAM_ERROR:
|
||||
case Z_MEM_ERROR: {
|
||||
inflateEnd(&zlibStream);
|
||||
qCWarning(lcSvgHandler, "Error while inflating gzip file: %s",
|
||||
(zlibStream.msg != NULL ? zlibStream.msg : "Unknown error"));
|
||||
destination.chop(zlibStream.avail_out);
|
||||
return destination;
|
||||
}
|
||||
}
|
||||
|
||||
// If the output buffer still has more room after calling inflate
|
||||
// it means we have to provide more data, so exit the loop here
|
||||
} while (!zlibStream.avail_out);
|
||||
|
||||
if (zlibResult == Z_STREAM_END) {
|
||||
// Make sure there are no more members to process before exiting
|
||||
if (!(zlibStream.avail_in && inflateReset(&zlibStream) == Z_OK))
|
||||
stillMoreWorkToDo = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Chop off trailing space in the buffer
|
||||
destination.chop(zlibStream.avail_out);
|
||||
|
||||
inflateEnd(&zlibStream);
|
||||
return destination;
|
||||
}
|
||||
#endif
|
||||
|
||||
QSvgTinyDocument * QSvgTinyDocument::load(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
qCWarning(lcSvgHandler, "Cannot open file '%s', because: %s",
|
||||
qPrintable(fileName), qPrintable(file.errorString()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_COMPRESS
|
||||
if (fileName.endsWith(QLatin1String(".svgz"), Qt::CaseInsensitive)
|
||||
|| fileName.endsWith(QLatin1String(".svg.gz"), Qt::CaseInsensitive)) {
|
||||
return load(qt_inflateGZipDataFrom(&file));
|
||||
}
|
||||
#endif
|
||||
|
||||
QSvgTinyDocument *doc = 0;
|
||||
QSvgHandler handler(&file);
|
||||
if (handler.ok()) {
|
||||
doc = handler.document();
|
||||
doc->m_animationDuration = handler.animationDuration();
|
||||
} else {
|
||||
qCWarning(lcSvgHandler, "Cannot read file '%s', because: %s (line %d)",
|
||||
qPrintable(fileName), qPrintable(handler.errorString()), handler.lineNumber());
|
||||
delete handler.document();
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
QSvgTinyDocument * QSvgTinyDocument::load(const QByteArray &contents)
|
||||
{
|
||||
#ifndef QT_NO_COMPRESS
|
||||
// Check for gzip magic number and inflate if appropriate
|
||||
if (contents.startsWith("\x1f\x8b")) {
|
||||
QBuffer buffer(const_cast<QByteArray *>(&contents));
|
||||
return load(qt_inflateGZipDataFrom(&buffer));
|
||||
}
|
||||
#endif
|
||||
|
||||
QSvgHandler handler(contents);
|
||||
|
||||
QSvgTinyDocument *doc = 0;
|
||||
if (handler.ok()) {
|
||||
doc = handler.document();
|
||||
doc->m_animationDuration = handler.animationDuration();
|
||||
} else {
|
||||
delete handler.document();
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
QSvgTinyDocument * QSvgTinyDocument::load(QXmlStreamReader *contents)
|
||||
{
|
||||
QSvgHandler handler(contents);
|
||||
|
||||
QSvgTinyDocument *doc = 0;
|
||||
if (handler.ok()) {
|
||||
doc = handler.document();
|
||||
doc->m_animationDuration = handler.animationDuration();
|
||||
} else {
|
||||
delete handler.document();
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::draw(QPainter *p, const QRectF &bounds)
|
||||
{
|
||||
if (m_time.isNull()) {
|
||||
m_time.start();
|
||||
}
|
||||
|
||||
if (displayMode() == QSvgNode::NoneMode)
|
||||
return;
|
||||
|
||||
p->save();
|
||||
//sets default style on the painter
|
||||
//### not the most optimal way
|
||||
QTransform oldTransform = p->worldTransform();
|
||||
mapSourceToTarget(p, bounds);
|
||||
QPen pen(Qt::NoBrush, 1, Qt::SolidLine, Qt::FlatCap, Qt::SvgMiterJoin);
|
||||
pen.setMiterLimit(4);
|
||||
p->setPen(pen);
|
||||
p->setBrush(Qt::black);
|
||||
p->setRenderHint(QPainter::Antialiasing);
|
||||
p->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
QList<QSvgNode*>::iterator itr = m_renderers.begin();
|
||||
applyStyle(p, m_states);
|
||||
while (itr != m_renderers.end()) {
|
||||
QSvgNode *node = *itr;
|
||||
if ((node->isVisible()) && (node->displayMode() != QSvgNode::NoneMode)) {
|
||||
QSvgText *a = dynamic_cast<QSvgText*>(node);
|
||||
if(a) {
|
||||
QVector<QSvgTspan *> &ts=a->Tspans();
|
||||
int s=0;
|
||||
if(ts.size()){
|
||||
QString st=ts[0]->text();
|
||||
if(st.indexOf('$')>=0) {
|
||||
s=1;
|
||||
}
|
||||
}
|
||||
/*if(!s) {
|
||||
a->draw(p,m_states);
|
||||
}
|
||||
else*/
|
||||
{
|
||||
p->save();
|
||||
QRectF source = viewBox();
|
||||
QMatrix b=matrixForElement(a);
|
||||
a->draw(p,m_states,bounds,oldTransform,source,b);
|
||||
p->restore();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QSvgRect *a = dynamic_cast<QSvgRect*>(node);
|
||||
if(a) {
|
||||
QRectF source = viewBox();
|
||||
QRectF rect=a->rect();
|
||||
qreal sx=rect.width()/source.width();
|
||||
qreal sy=rect.height()/source.height();
|
||||
qreal x0=(rect.x()-source.x())/source.width();
|
||||
qreal y0=(rect.y()-source.y())/source.height();
|
||||
QRectF mRect(bounds.x()+x0*bounds.width(),bounds.y()+y0*bounds.height(),bounds.width()*sx,bounds.height()*sy);
|
||||
p->save();
|
||||
p->setWorldTransform(oldTransform);
|
||||
QRectF trect=p->transform().mapRect(mRect);
|
||||
p->setWorldTransform(QTransform());//临时切回像素坐标系
|
||||
a->SetRect(trect);
|
||||
node->draw(p,m_states);
|
||||
p->restore();
|
||||
}
|
||||
else
|
||||
node->draw(p, m_states);
|
||||
}
|
||||
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
revertStyle(p, m_states);
|
||||
p->restore();
|
||||
}
|
||||
|
||||
|
||||
void QSvgTinyDocument::draw(QPainter *p, const QString &id,
|
||||
const QRectF &bounds)
|
||||
{
|
||||
QSvgNode *node = scopeNode(id);
|
||||
|
||||
if (!node) {
|
||||
qCDebug(lcSvgHandler, "Couldn't find node %s. Skipping rendering.", qPrintable(id));
|
||||
return;
|
||||
}
|
||||
if (m_time.isNull()) {
|
||||
m_time.start();
|
||||
}
|
||||
|
||||
if (node->displayMode() == QSvgNode::NoneMode)
|
||||
return;
|
||||
|
||||
p->save();
|
||||
|
||||
const QRectF elementBounds = node->transformedBounds();
|
||||
|
||||
mapSourceToTarget(p, bounds, elementBounds);
|
||||
QTransform originalTransform = p->worldTransform();
|
||||
|
||||
//XXX set default style on the painter
|
||||
QPen pen(Qt::NoBrush, 1, Qt::SolidLine, Qt::FlatCap, Qt::SvgMiterJoin);
|
||||
pen.setMiterLimit(4);
|
||||
p->setPen(pen);
|
||||
p->setBrush(Qt::black);
|
||||
p->setRenderHint(QPainter::Antialiasing);
|
||||
p->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
QStack<QSvgNode*> parentApplyStack;
|
||||
QSvgNode *parent = node->parent();
|
||||
while (parent) {
|
||||
parentApplyStack.push(parent);
|
||||
parent = parent->parent();
|
||||
}
|
||||
|
||||
for (int i = parentApplyStack.size() - 1; i >= 0; --i)
|
||||
parentApplyStack[i]->applyStyle(p, m_states);
|
||||
|
||||
// Reset the world transform so that our parents don't affect
|
||||
// the position
|
||||
QTransform currentTransform = p->worldTransform();
|
||||
p->setWorldTransform(originalTransform);
|
||||
|
||||
node->draw(p, m_states);
|
||||
|
||||
p->setWorldTransform(currentTransform);
|
||||
|
||||
for (int i = 0; i < parentApplyStack.size(); ++i)
|
||||
parentApplyStack[i]->revertStyle(p, m_states);
|
||||
|
||||
//p->fillRect(bounds.adjusted(-5, -5, 5, 5), QColor(0, 0, 255, 100));
|
||||
|
||||
p->restore();
|
||||
}
|
||||
|
||||
|
||||
QSvgNode::Type QSvgTinyDocument::type() const
|
||||
{
|
||||
return DOC;
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::setWidth(int len, bool percent)
|
||||
{
|
||||
m_size.setWidth(len);
|
||||
m_widthPercent = percent;
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::setHeight(int len, bool percent)
|
||||
{
|
||||
m_size.setHeight(len);
|
||||
m_heightPercent = percent;
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::setViewBox(const QRectF &rect)
|
||||
{
|
||||
m_viewBox = rect;
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::addSvgFont(QSvgFont *font)
|
||||
{
|
||||
m_fonts.insert(font->familyName(), font);
|
||||
}
|
||||
|
||||
QSvgFont * QSvgTinyDocument::svgFont(const QString &family) const
|
||||
{
|
||||
return m_fonts[family];
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::addNamedNode(const QString &id, QSvgNode *node)
|
||||
{
|
||||
m_namedNodes.insert(id, node);
|
||||
}
|
||||
|
||||
QSvgNode *QSvgTinyDocument::namedNode(const QString &id) const
|
||||
{
|
||||
return m_namedNodes.value(id);
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::addNamedStyle(const QString &id, QSvgFillStyleProperty *style)
|
||||
{
|
||||
if (!m_namedStyles.contains(id))
|
||||
m_namedStyles.insert(id, style);
|
||||
else
|
||||
qCWarning(lcSvgHandler) << "Duplicate unique style id:" << id;
|
||||
}
|
||||
|
||||
QSvgFillStyleProperty *QSvgTinyDocument::namedStyle(const QString &id) const
|
||||
{
|
||||
return m_namedStyles.value(id);
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::restartAnimation()
|
||||
{
|
||||
m_time.restart();
|
||||
}
|
||||
|
||||
bool QSvgTinyDocument::animated() const
|
||||
{
|
||||
return m_animated;
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::setAnimated(bool a)
|
||||
{
|
||||
m_animated = a;
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::draw(QPainter *p)
|
||||
{
|
||||
draw(p, QRectF());
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::draw(QPainter *p, QSvgExtraStates &)
|
||||
{
|
||||
draw(p);
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect)
|
||||
{
|
||||
QRectF target = targetRect;
|
||||
if (target.isNull()) {
|
||||
QPaintDevice *dev = p->device();
|
||||
QRectF deviceRect(0, 0, dev->width(), dev->height());
|
||||
if (deviceRect.isNull()) {
|
||||
if (sourceRect.isNull())
|
||||
target = QRectF(QPointF(0, 0), size());
|
||||
else
|
||||
target = QRectF(QPointF(0, 0), sourceRect.size());
|
||||
} else {
|
||||
target = deviceRect;
|
||||
}
|
||||
}
|
||||
|
||||
QRectF source = sourceRect;
|
||||
if (source.isNull())
|
||||
source = viewBox();
|
||||
|
||||
if (source != target && !source.isNull()) {
|
||||
QTransform transform;
|
||||
transform.scale(target.width() / source.width(),
|
||||
target.height() / source.height());
|
||||
QRectF c2 = transform.mapRect(source);
|
||||
float x1=target.x();
|
||||
float y1=target.y();
|
||||
float x2=c2.x();
|
||||
float y2=c2.y();
|
||||
p->translate(target.x() - c2.x(),
|
||||
target.y() - c2.y());
|
||||
p->scale(target.width() / source.width(),
|
||||
target.height() / source.height());
|
||||
}
|
||||
}
|
||||
|
||||
QRectF QSvgTinyDocument::boundsOnElement(const QString &id) const
|
||||
{
|
||||
const QSvgNode *node = scopeNode(id);
|
||||
if (!node)
|
||||
node = this;
|
||||
return node->transformedBounds();
|
||||
}
|
||||
|
||||
bool QSvgTinyDocument::elementExists(const QString &id) const
|
||||
{
|
||||
QSvgNode *node = scopeNode(id);
|
||||
|
||||
return (node!=0);
|
||||
}
|
||||
|
||||
QMatrix QSvgTinyDocument::matrixForElement(const QString &id) const
|
||||
{
|
||||
QSvgNode *node = scopeNode(id);
|
||||
|
||||
if (!node) {
|
||||
qCDebug(lcSvgHandler, "Couldn't find node %s. Skipping rendering.", qPrintable(id));
|
||||
return QMatrix();
|
||||
}
|
||||
|
||||
QTransform t;
|
||||
|
||||
node = node->parent();
|
||||
while (node) {
|
||||
if (node->m_style.transform)
|
||||
t *= node->m_style.transform->qtransform();
|
||||
node = node->parent();
|
||||
}
|
||||
|
||||
return t.toAffine();
|
||||
}
|
||||
QMatrix QSvgTinyDocument::matrixForElement(QSvgNode *node) const
|
||||
{
|
||||
if (!node) {
|
||||
qDebug("Couldn't find node %s. Skipping rendering.", "node");
|
||||
return QMatrix();
|
||||
}
|
||||
|
||||
QTransform t;
|
||||
if (node->m_style.transform)
|
||||
t = node->m_style.transform->qtransform();
|
||||
|
||||
return t.toAffine();
|
||||
}
|
||||
|
||||
int QSvgTinyDocument::currentFrame() const
|
||||
{
|
||||
double runningPercentage = qMin(m_time.elapsed()/double(m_animationDuration), 1.);
|
||||
|
||||
int totalFrames = m_fps * m_animationDuration;
|
||||
|
||||
return int(runningPercentage * totalFrames);
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::setCurrentFrame(int frame)
|
||||
{
|
||||
int totalFrames = m_fps * m_animationDuration;
|
||||
double framePercentage = frame/double(totalFrames);
|
||||
double timeForFrame = m_animationDuration * framePercentage; //in S
|
||||
timeForFrame *= 1000; //in ms
|
||||
int timeToAdd = int(timeForFrame - m_time.elapsed());
|
||||
m_time = m_time.addMSecs(timeToAdd);
|
||||
}
|
||||
|
||||
void QSvgTinyDocument::setFramesPerSecond(int num)
|
||||
{
|
||||
m_fps = num;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
201
svg/qsvgtinydocument_p.h
Normal file
201
svg/qsvgtinydocument_p.h
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGTINYDOCUMENT_P_H
|
||||
#define QSVGTINYDOCUMENT_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qsvgstructure_p.h"
|
||||
#include "qtsvgglobal_p.h"
|
||||
|
||||
#include "QtCore/qrect.h"
|
||||
#include "QtCore/qlist.h"
|
||||
#include "QtCore/qhash.h"
|
||||
#include "QtCore/qdatetime.h"
|
||||
#include "QtCore/qxmlstream.h"
|
||||
#include "qsvgstyle_p.h"
|
||||
#include "qsvgfont_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPainter;
|
||||
class QByteArray;
|
||||
class QSvgFont;
|
||||
|
||||
class Q_SVG_PRIVATE_EXPORT QSvgTinyDocument : public QSvgStructureNode
|
||||
{
|
||||
public:
|
||||
static QSvgTinyDocument * load(const QString &file);
|
||||
static QSvgTinyDocument * load(const QByteArray &contents);
|
||||
static QSvgTinyDocument * load(QXmlStreamReader *contents);
|
||||
public:
|
||||
QSvgTinyDocument();
|
||||
~QSvgTinyDocument();
|
||||
Type type() const override;
|
||||
|
||||
QSize size() const;
|
||||
void setWidth(int len, bool percent);
|
||||
void setHeight(int len, bool percent);
|
||||
int width() const;
|
||||
int height() const;
|
||||
bool widthPercent() const;
|
||||
bool heightPercent() const;
|
||||
|
||||
bool preserveAspectRatio() const;
|
||||
|
||||
QRectF viewBox() const;
|
||||
void setViewBox(const QRectF &rect);
|
||||
|
||||
void draw(QPainter *p, QSvgExtraStates &) override; //from the QSvgNode
|
||||
|
||||
void draw(QPainter *p);
|
||||
void draw(QPainter *p, const QRectF &bounds);
|
||||
void draw(QPainter *p, const QString &id,
|
||||
const QRectF &bounds=QRectF());
|
||||
|
||||
QMatrix matrixForElement(const QString &id) const;
|
||||
QRectF boundsOnElement(const QString &id) const;
|
||||
bool elementExists(const QString &id) const;
|
||||
|
||||
void addSvgFont(QSvgFont *);
|
||||
QSvgFont *svgFont(const QString &family) const;
|
||||
void addNamedNode(const QString &id, QSvgNode *node);
|
||||
QSvgNode *namedNode(const QString &id) const;
|
||||
void addNamedStyle(const QString &id, QSvgFillStyleProperty *style);
|
||||
QSvgFillStyleProperty *namedStyle(const QString &id) const;
|
||||
|
||||
void restartAnimation();
|
||||
int currentElapsed() const;
|
||||
bool animated() const;
|
||||
void setAnimated(bool a);
|
||||
int animationDuration() const;
|
||||
int currentFrame() const;
|
||||
void setCurrentFrame(int);
|
||||
void setFramesPerSecond(int num);
|
||||
private:
|
||||
void mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect = QRectF());
|
||||
private:
|
||||
QSize m_size;
|
||||
bool m_widthPercent;
|
||||
bool m_heightPercent;
|
||||
|
||||
mutable QRectF m_viewBox;
|
||||
|
||||
QHash<QString, QSvgRefCounter<QSvgFont> > m_fonts;
|
||||
QHash<QString, QSvgNode *> m_namedNodes;
|
||||
QHash<QString, QSvgRefCounter<QSvgFillStyleProperty> > m_namedStyles;
|
||||
|
||||
QTime m_time;
|
||||
bool m_animated;
|
||||
int m_animationDuration;
|
||||
int m_fps;
|
||||
|
||||
QSvgExtraStates m_states;
|
||||
public:
|
||||
QMatrix matrixForElement(QSvgNode *node) const;
|
||||
};
|
||||
|
||||
inline QSize QSvgTinyDocument::size() const
|
||||
{
|
||||
if (m_size.isEmpty())
|
||||
return viewBox().size().toSize();
|
||||
if (m_widthPercent || m_heightPercent) {
|
||||
const int width = m_widthPercent ? qRound(0.01 * m_size.width() * viewBox().size().width()) : m_size.width();
|
||||
const int height = m_heightPercent ? qRound(0.01 * m_size.height() * viewBox().size().height()) : m_size.height();
|
||||
return QSize(width, height);
|
||||
}
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline int QSvgTinyDocument::width() const
|
||||
{
|
||||
return size().width();
|
||||
}
|
||||
|
||||
inline int QSvgTinyDocument::height() const
|
||||
{
|
||||
return size().height();
|
||||
}
|
||||
|
||||
inline bool QSvgTinyDocument::widthPercent() const
|
||||
{
|
||||
return m_widthPercent;
|
||||
}
|
||||
|
||||
inline bool QSvgTinyDocument::heightPercent() const
|
||||
{
|
||||
return m_heightPercent;
|
||||
}
|
||||
|
||||
inline QRectF QSvgTinyDocument::viewBox() const
|
||||
{
|
||||
if (m_viewBox.isNull())
|
||||
m_viewBox = transformedBounds();
|
||||
|
||||
return m_viewBox;
|
||||
}
|
||||
|
||||
inline bool QSvgTinyDocument::preserveAspectRatio() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inline int QSvgTinyDocument::currentElapsed() const
|
||||
{
|
||||
return m_time.elapsed();
|
||||
}
|
||||
|
||||
inline int QSvgTinyDocument::animationDuration() const
|
||||
{
|
||||
return m_animationDuration;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSVGTINYDOCUMENT_P_H
|
||||
176
svg/qsvgwidget.cpp
Normal file
176
svg/qsvgwidget.cpp
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsvgwidget.h"
|
||||
|
||||
#ifndef QT_NO_WIDGETS
|
||||
|
||||
#include "qsvgrenderer.h"
|
||||
|
||||
#include "qstyleoption.h"
|
||||
#include "qpainter.h"
|
||||
#include "private/qwidget_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QSvgWidget
|
||||
\inmodule QtSvg
|
||||
\ingroup painting
|
||||
|
||||
\brief The QSvgWidget class provides a widget that is used to display the contents of
|
||||
Scalable Vector Graphics (SVG) files.
|
||||
\since 4.1
|
||||
|
||||
This class enables developers to display SVG drawings alongside standard widgets, and
|
||||
is used in much the same way as QLabel is used for displaying text and bitmap images.
|
||||
|
||||
Since QSvgWidget is a subclass of QWidget, SVG drawings are rendered using the properties
|
||||
of the display. More control can be exercised over the rendering process with the
|
||||
QSvgRenderer class, as this can be used to paint onto other paint devices, such as QImage
|
||||
and QGLWidget. The renderer used by the widget can be obtained with the renderer()
|
||||
function.
|
||||
|
||||
Each QSvgWidget can be constructed with the file name of a SVG file, or they can be
|
||||
constructed without a specific file to render and one can be supplied later. The load()
|
||||
functions provide two different ways to load an SVG file: they accept either the file name
|
||||
of an SVG file or a QByteArray containing the serialized XML representation of an SVG file.
|
||||
|
||||
By default, the widget provides a size hint to reflect the size of the drawing that it
|
||||
displays. If no data has been loaded, the widget provides the default QWidget size hint.
|
||||
Subclass this class and reimplement sizeHint() if you need to customize this behavior.
|
||||
|
||||
\sa QSvgRenderer, {Qt SVG C++ Classes}, QPicture
|
||||
*/
|
||||
|
||||
class QSvgWidgetPrivate : public QWidgetPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QSvgWidget)
|
||||
public:
|
||||
QSvgRenderer *renderer;
|
||||
};
|
||||
|
||||
/*!
|
||||
Constructs a new SVG display widget with the given \a parent.
|
||||
*/
|
||||
QSvgWidget::QSvgWidget(QWidget *parent)
|
||||
: QWidget(*new QSvgWidgetPrivate, parent, 0)
|
||||
{
|
||||
d_func()->renderer = new QSvgRenderer(this);
|
||||
QObject::connect(d_func()->renderer, SIGNAL(repaintNeeded()),
|
||||
this, SLOT(update()));
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new SVG display widget with the given \a parent and loads the contents
|
||||
of the specified \a file.
|
||||
*/
|
||||
QSvgWidget::QSvgWidget(const QString &file, QWidget *parent)
|
||||
: QWidget(*new QSvgWidgetPrivate, parent, 0)
|
||||
{
|
||||
d_func()->renderer = new QSvgRenderer(file, this);
|
||||
QObject::connect(d_func()->renderer, SIGNAL(repaintNeeded()),
|
||||
this, SLOT(update()));
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the widget.
|
||||
*/
|
||||
QSvgWidget::~QSvgWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the renderer used to display the contents of the widget.
|
||||
*/
|
||||
QSvgRenderer * QSvgWidget::renderer() const
|
||||
{
|
||||
Q_D(const QSvgWidget);
|
||||
return d->renderer;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QSize QSvgWidget::sizeHint() const
|
||||
{
|
||||
Q_D(const QSvgWidget);
|
||||
if (d->renderer->isValid())
|
||||
return d->renderer->defaultSize();
|
||||
else
|
||||
return QSize(128, 64);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QSvgWidget::paintEvent(QPaintEvent *)
|
||||
{
|
||||
Q_D(QSvgWidget);
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
d->renderer->render(&p);
|
||||
}
|
||||
|
||||
/*!
|
||||
Loads the contents of the specified SVG \a file and updates the widget.
|
||||
*/
|
||||
void QSvgWidget::load(const QString &file)
|
||||
{
|
||||
Q_D(const QSvgWidget);
|
||||
d->renderer->load(file);
|
||||
}
|
||||
|
||||
/*!
|
||||
Loads the specified SVG format \a contents and updates the widget.
|
||||
*/
|
||||
void QSvgWidget::load(const QByteArray &contents)
|
||||
{
|
||||
Q_D(const QSvgWidget);
|
||||
d->renderer->load(contents);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_WIDGETS
|
||||
83
svg/qsvgwidget.h
Normal file
83
svg/qsvgwidget.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSVGWIDGET_H
|
||||
#define QSVGWIDGET_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef QT_NO_WIDGETS
|
||||
|
||||
#include <QtWidgets/qwidget.h>
|
||||
|
||||
#include <QtSvg/qtsvgglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QSvgWidgetPrivate;
|
||||
class QPaintEvent;
|
||||
class QSvgRenderer;
|
||||
|
||||
class Q_SVG_EXPORT QSvgWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QSvgWidget(QWidget *parent = nullptr);
|
||||
QSvgWidget(const QString &file, QWidget *parent = nullptr);
|
||||
~QSvgWidget();
|
||||
|
||||
QSvgRenderer *renderer() const;
|
||||
|
||||
QSize sizeHint() const override;
|
||||
public Q_SLOTS:
|
||||
void load(const QString &file);
|
||||
void load(const QByteArray &contents);
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
private:
|
||||
Q_DISABLE_COPY(QSvgWidget)
|
||||
Q_DECLARE_PRIVATE(QSvgWidget)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_WIDGETS
|
||||
|
||||
#endif // QSVGWIDGET_H
|
||||
12
svg/qt_attribution.json
Normal file
12
svg/qt_attribution.json
Normal file
|
|
@ -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"
|
||||
}
|
||||
61
svg/qtsvgglobal.h
Normal file
61
svg/qtsvgglobal.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 Intel Corporation.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTSVGGLOBAL_H
|
||||
#define QTSVGGLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef Q_SVG_EXPORT
|
||||
# ifndef QT_STATIC
|
||||
# if defined(QT_BUILD_SVG_LIB)
|
||||
# define Q_SVG_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define Q_SVG_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# else
|
||||
# define Q_SVG_EXPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
58
svg/qtsvgglobal_p.h
Normal file
58
svg/qtsvgglobal_p.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt SVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTSVGGLOBAL_P_H
|
||||
#define QTSVGGLOBAL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qtsvgglobal.h"
|
||||
|
||||
#define Q_SVG_PRIVATE_EXPORT Q_SVG_EXPORT
|
||||
|
||||
#endif // QTSVGGLOBAL_P_H
|
||||
52
svg/svg.pro
Normal file
52
svg/svg.pro
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
TARGET = QtSvg
|
||||
QT = core-private gui-private
|
||||
qtHaveModule(widgets): QT += widgets-private
|
||||
|
||||
DEFINES += QT_NO_USING_NAMESPACE
|
||||
msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x66000000
|
||||
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
|
||||
|
||||
QMAKE_DOCS = $$PWD/doc/qtsvg.qdocconf
|
||||
|
||||
HEADERS += \
|
||||
qsvggraphics_p.h \
|
||||
qsvghandler_p.h \
|
||||
qsvgnode_p.h \
|
||||
qsvgstructure_p.h \
|
||||
qsvgstyle_p.h \
|
||||
qsvgfont_p.h \
|
||||
qsvgtinydocument_p.h \
|
||||
qsvgrenderer.h \
|
||||
qsvgwidget.h \
|
||||
qgraphicssvgitem.h \
|
||||
qsvggenerator.h \
|
||||
qtsvgglobal.h
|
||||
|
||||
|
||||
SOURCES += \
|
||||
qsvggraphics.cpp \
|
||||
qsvghandler.cpp \
|
||||
qsvgnode.cpp \
|
||||
qsvgstructure.cpp \
|
||||
qsvgstyle.cpp \
|
||||
qsvgfont.cpp \
|
||||
qsvgtinydocument.cpp \
|
||||
qsvgrenderer.cpp \
|
||||
qsvgwidget.cpp \
|
||||
qgraphicssvgitem.cpp \
|
||||
qsvggenerator.cpp
|
||||
|
||||
qtConfig(system-zlib): \
|
||||
QMAKE_USE_PRIVATE += zlib
|
||||
else: \
|
||||
QT_PRIVATE += zlib-private
|
||||
|
||||
load(qt_module)
|
||||
|
||||
CONFIG(debug, debug|release){
|
||||
DESTDIR = ../Bin
|
||||
TARGET = $$join(TARGET,,,) #为debug版本生成的文件增加d的后缀
|
||||
} else {
|
||||
DESTDIR = ../Bin
|
||||
TARGET = $$join(TARGET,,,)
|
||||
}
|
||||
337
svg/svg.pro.user
Normal file
337
svg/svg.pro.user
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.9.1, 2025-12-10T14:25:22. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{04219d0a-2df9-4f31-921d-c25f7a4fa4e5}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey">
|
||||
<value type="QString">-fno-delayed-template-parsing</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.13.0 MSVC2017 64bit</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.13.0 MSVC2017 64bit</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5130.win64_msvc2017_64_kit</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Qt/Qt5.13.0/5.13.0/Src/qtsvg/src/build-svg-Desktop_Qt_5_13_0_MSVC2017_64bit-Debug</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Qt/Qt5.13.0/5.13.0/Src/qtsvg/src/build-svg-Desktop_Qt_5_13_0_MSVC2017_64bit-Release</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Qt/Qt5.13.0/5.13.0/Src/qtsvg/src/build-svg-Desktop_Qt_5_13_0_MSVC2017_64bit-Profile</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
|
||||
<value type="QString">cpu-cycles</value>
|
||||
</valuelist>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
|
||||
<value type="int" key="Analyzer.Perf.Frequency">250</value>
|
||||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
|
||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Executable</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||
<value type="QString" key="RunConfiguration.Arguments"></value>
|
||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">21</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">21</value>
|
||||
</data>
|
||||
</qtcreator>
|
||||
Loading…
Reference in New Issue
Block a user