📄 qsvgstyle.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtSVG module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "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 <math.h>QSvgStyleProperty::~QSvgStyleProperty(){}QSvgQualityStyle::QSvgQualityStyle(int color) : m_colorRendering(color){}void QSvgQualityStyle::apply(QPainter *, const QRectF &, QSvgNode *){}void QSvgQualityStyle::revert(QPainter *){}QSvgFillStyle::QSvgFillStyle(const QBrush &brush, bool fromColor) : m_fill(brush), m_fromColor(fromColor), m_fillRuleSet(false){}void QSvgFillStyle::setFillRule(Qt::FillRule f){ m_fillRuleSet = true; m_fillRule = f;}static void recursivelySetFill(QSvgNode *node, Qt::FillRule f){ if (node->type() == QSvgNode::PATH) { QSvgPath *path = static_cast<QSvgPath*>(node); path->qpath()->setFillRule(f); } else if (node->type() == QSvgNode::G) { QList<QSvgNode*> renderers = static_cast<QSvgG*>(node)->renderers(); foreach(QSvgNode *n, renderers) { recursivelySetFill(n, f); } }}void QSvgFillStyle::apply(QPainter *p, const QRectF &, QSvgNode *node){ m_oldFill = p->brush(); if (m_fillRuleSet) { recursivelySetFill(node, m_fillRule); m_fillRuleSet = false;//set it only on the first run } p->setBrush(m_fill);}void QSvgFillStyle::revert(QPainter *p){ p->setBrush(m_oldFill);}QSvgViewportFillStyle::QSvgViewportFillStyle(const QBrush &brush) : m_viewportFill(brush){}void QSvgViewportFillStyle::apply(QPainter *p, const QRectF &, QSvgNode *){ m_oldFill = p->brush(); p->setBrush(m_viewportFill);}void QSvgViewportFillStyle::revert(QPainter *p){ p->setBrush(m_oldFill);}QSvgFontStyle::QSvgFontStyle(QSvgFont *font, QSvgTinyDocument *doc) : m_font(font), m_pointSize(24), m_doc(doc){}QSvgFontStyle::QSvgFontStyle(const QFont &font, QSvgTinyDocument *doc) : m_font(0), m_pointSize(24), m_doc(doc), m_qfont(font){}void QSvgFontStyle::setPointSize(qreal size){ m_pointSize = size;}qreal QSvgFontStyle::pointSize() const{ return m_pointSize;}void QSvgFontStyle::apply(QPainter *p, const QRectF &, QSvgNode *){ if (!m_font) { m_oldFont = p->font(); p->setFont(m_qfont); }}void QSvgFontStyle::revert(QPainter *p){ if (!m_font) { p->setFont(m_oldFont); }}QSvgStrokeStyle::QSvgStrokeStyle(const QPen &pen) : m_stroke(pen){}void QSvgStrokeStyle::apply(QPainter *p, const QRectF &, QSvgNode *){ m_oldStroke = p->pen(); p->setPen(m_stroke);}void QSvgStrokeStyle::revert(QPainter *p){ p->setPen(m_oldStroke);}QSvgSolidColorStyle::QSvgSolidColorStyle(const QColor &color) : m_solidColor(color){}void QSvgSolidColorStyle::apply(QPainter *p, const QRectF &, QSvgNode *){ m_oldFill = p->brush(); m_oldStroke = p->pen(); QBrush b = m_oldFill; b.setColor(m_solidColor); p->setBrush(b); QPen pen = m_oldStroke; pen.setColor(m_solidColor); p->setPen(pen);}void QSvgSolidColorStyle::revert(QPainter *p){ p->setBrush(m_oldFill); p->setPen(m_oldStroke);}QSvgGradientStyle::QSvgGradientStyle(QGradient *grad, bool resolveBounds) : m_gradient(grad), m_resolveBounds(resolveBounds){}void QSvgGradientStyle::apply(QPainter *p, const QRectF &rect, QSvgNode *){ if (!m_link.isEmpty()) { resolveStops(); } m_oldFill = p->brush(); //resolving stop colors if (!m_resolvePoints.isEmpty()) { QColor color = p->brush().color(); if (!color.isValid()) color = p->pen().color(); QList<qreal>::const_iterator itr = m_resolvePoints.constBegin(); for (; itr != m_resolvePoints.constEnd(); ++itr) { //qDebug()<<"resolving "<<(*itr)<<" to "<<color; m_gradient->setColorAt(*itr, color); } } QBrush brush; //we need to resolve boundaries //the code is funky i'll have to verify it //(testcases right now are bugs/resolve_radial.svg // and bugs/resolve_linear.svg) if (m_resolveBounds) { if (m_gradient->type() == QGradient::LinearGradient) { QLinearGradient *grad = (QLinearGradient*)(m_gradient); qreal xs, ys, xf, yf; xs = rect.x() + rect.width() * grad->start().x(); ys = rect.y() + rect.height() * grad->start().y(); xf = rect.x() + rect.width() * grad->finalStop().x(); yf = rect.y() + rect.height() * grad->finalStop().y(); QLinearGradient gradient(xs, ys, xf, yf); gradient.setStops(m_gradient->stops()); gradient.setSpread(m_gradient->spread()); brush = QBrush(gradient); } else { QRadialGradient *grad = (QRadialGradient*)m_gradient; qreal cx, cy, r, fx, fy; cx = rect.width() * grad->center().x(); cy = rect.height() * grad->center().y(); //### the radius is wrong. it has to be transformed // so that the horizontal on is rect.width() * grad->radius(); // and vertical rect.height() * grad->radius(). it's a simple // transformation but we don't support exclusive fill // transformations at the moment r = rect.width() * grad->radius(); fx = rect.width() * grad->focalPoint().x(); fy = rect.width() * grad->focalPoint().y(); //qDebug()<<cx << cy << r << fx << fy; QRadialGradient gradient(cx, cy, r, fx, fy); gradient.setStops(m_gradient->stops()); gradient.setSpread(m_gradient->spread()); brush = QBrush(gradient); } } else { brush = QBrush(*m_gradient); } if (!m_matrix.isIdentity()) brush.setMatrix(m_matrix); p->setBrush(brush);}void QSvgGradientStyle::revert(QPainter *p){ p->setBrush(m_oldFill);}void QSvgGradientStyle::setMatrix(const QMatrix &mat){ m_matrix = mat;}void QSvgGradientStyle::addResolve(qreal offset){ m_resolvePoints.append(offset);}QSvgTransformStyle::QSvgTransformStyle(const QMatrix &trans) : m_transform(trans){}void QSvgTransformStyle::apply(QPainter *p, const QRectF &, QSvgNode *){ m_oldWorldMatrix = p->matrix(); p->setMatrix(m_transform, true);}void QSvgTransformStyle::revert(QPainter *p){ p->setMatrix(m_oldWorldMatrix, 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 QRectF &, QSvgNode *){ m_oldMode = p->compositionMode(); p->setCompositionMode(m_mode);}void QSvgCompOpStyle::revert(QPainter *p){ p->setCompositionMode(m_oldMode);}QSvgStyleProperty::Type QSvgCompOpStyle::type() const{ return COMP_OP;}QSvgStyle::~QSvgStyle(){}void QSvgStyle::apply(QPainter *p, const QRectF &rect, QSvgNode *node){ if (quality) { quality->apply(p, rect, node); } if (fill) { fill->apply(p, rect, node); } if (viewportFill) { viewportFill->apply(p, rect, node); } if (font) { font->apply(p, rect, node); } if (stroke) { stroke->apply(p, rect, node); } if (solidColor) { solidColor->apply(p, rect, node); } if (gradient) { gradient->apply(p, rect, node); } if (transform) { transform->apply(p, rect, node); } if (animateColor) { animateColor->apply(p, rect, node); } //animated transforms have to be applied //_after_ the original object transformations if (!animateTransforms.isEmpty()) { QList<QSvgRefCounter<QSvgAnimateTransform> >::const_iterator itr; for (itr = animateTransforms.constBegin(); itr != animateTransforms.constEnd(); ++itr) { (*itr)->apply(p, rect, node); } } if (opacity) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -