/src/svg/qsvgnode.cpp
https://bitbucket.org/ultra_iter/qt-vtl · C++ · 345 lines · 257 code · 43 blank · 45 comment · 34 complexity · 6dd075b28afe410f2dd41f4a56818320 MD5 · raw file
- /****************************************************************************
- **
- ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
- ** All rights reserved.
- ** Contact: Nokia Corporation (qt-info@nokia.com)
- **
- ** This file is part of the QtSvg module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
- ** GNU Lesser General Public License Usage
- ** This file may be used under the terms of the GNU Lesser General Public
- ** License version 2.1 as published by the Free Software Foundation and
- ** appearing in the file LICENSE.LGPL included in the packaging of this
- ** file. Please review the following information to ensure the GNU Lesser
- ** General Public License version 2.1 requirements will be met:
- ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- **
- ** In addition, as a special exception, Nokia gives you certain additional
- ** rights. These rights are described in the Nokia Qt LGPL Exception
- ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- **
- ** GNU General Public License Usage
- ** Alternatively, this file may be used under the terms of the GNU General
- ** Public License version 3.0 as published by the Free Software Foundation
- ** and appearing in the file LICENSE.GPL included in the packaging of this
- ** file. Please review the following information to ensure the GNU General
- ** Public License version 3.0 requirements will be met:
- ** http://www.gnu.org/copyleft/gpl.html.
- **
- ** Other Usage
- ** Alternatively, this file may be used in accordance with the terms and
- ** conditions contained in a signed written agreement between you and Nokia.
- **
- **
- **
- **
- **
- ** $QT_END_LICENSE$
- **
- ****************************************************************************/
- #include "qsvgnode_p.h"
- #include "qsvgtinydocument_p.h"
- #ifndef QT_NO_SVG
- #include "qdebug.h"
- #include "qstack.h"
- QT_BEGIN_NAMESPACE
- QSvgNode::QSvgNode(QSvgNode *parent)
- : m_parent(parent),
- m_visible(true),
- m_displayMode(BlockMode)
- {
- }
- QSvgNode::~QSvgNode()
- {
- }
- 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::MiterJoin);
- 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
- #endif // QT_NO_SVG