1 /* This file is part of the KDE project
2 * Copyright (C) 2008 Jan Hambrecht <jaham@gmx.net>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "KoGradientBackground.h"
21 #include "KoShapeBackground_p.h"
22 #include "KoFlake.h"
23 #include <KoStyleStack.h>
24 #include <KoXmlNS.h>
25 #include <KoOdfLoadingContext.h>
26 #include <KoOdfGraphicStyles.h>
27 #include <KoShapeSavingContext.h>
28
29 #include <FlakeDebug.h>
30
31 #include <QSharedPointer>
32 #include <QBrush>
33 #include <QPainter>
34
35 class KoGradientBackgroundPrivate : public KoShapeBackgroundPrivate
36 {
37 public:
KoGradientBackgroundPrivate()38 KoGradientBackgroundPrivate()
39 : gradient(0)
40 {}
41
42 QGradient *gradient;
43 QTransform matrix;
44 };
45
KoGradientBackground(QGradient * gradient,const QTransform & matrix)46 KoGradientBackground::KoGradientBackground(QGradient * gradient, const QTransform &matrix)
47 : KoShapeBackground(*(new KoGradientBackgroundPrivate()))
48 {
49 Q_D(KoGradientBackground);
50 d->gradient = gradient;
51 d->matrix = matrix;
52 Q_ASSERT(d->gradient);
53 Q_ASSERT(d->gradient->coordinateMode() == QGradient::ObjectBoundingMode);
54 }
55
KoGradientBackground(const QGradient & gradient,const QTransform & matrix)56 KoGradientBackground::KoGradientBackground(const QGradient & gradient, const QTransform &matrix)
57 : KoShapeBackground(*(new KoGradientBackgroundPrivate()))
58 {
59 Q_D(KoGradientBackground);
60 d->gradient = KoFlake::cloneGradient(&gradient);
61 d->matrix = matrix;
62 Q_ASSERT(d->gradient);
63 Q_ASSERT(d->gradient->coordinateMode() == QGradient::ObjectBoundingMode);
64 }
65
~KoGradientBackground()66 KoGradientBackground::~KoGradientBackground()
67 {
68 Q_D(KoGradientBackground);
69 delete d->gradient;
70 }
71
setTransform(const QTransform & matrix)72 void KoGradientBackground::setTransform(const QTransform &matrix)
73 {
74 Q_D(KoGradientBackground);
75 d->matrix = matrix;
76 }
77
transform() const78 QTransform KoGradientBackground::transform() const
79 {
80 Q_D(const KoGradientBackground);
81 return d->matrix;
82 }
83
setGradient(const QGradient & gradient)84 void KoGradientBackground::setGradient(const QGradient &gradient)
85 {
86 Q_D(KoGradientBackground);
87 delete d->gradient;
88
89 d->gradient = KoFlake::cloneGradient(&gradient);
90 Q_ASSERT(d->gradient);
91 Q_ASSERT(d->gradient->coordinateMode() == QGradient::ObjectBoundingMode);
92 }
93
gradient() const94 const QGradient * KoGradientBackground::gradient() const
95 {
96 Q_D(const KoGradientBackground);
97 return d->gradient;
98 }
99
paint(QPainter & painter,const KoViewConverter &,KoShapePaintingContext &,const QPainterPath & fillPath) const100 void KoGradientBackground::paint(QPainter &painter, const KoViewConverter &/*converter*/, KoShapePaintingContext &/*context*/, const QPainterPath &fillPath) const
101 {
102 Q_D(const KoGradientBackground);
103 if (!d->gradient) return;
104 QBrush brush(*d->gradient);
105 brush.setTransform(d->matrix);
106
107 painter.setBrush(brush);
108 painter.drawPath(fillPath);
109 }
110
fillStyle(KoGenStyle & style,KoShapeSavingContext & context)111 void KoGradientBackground::fillStyle(KoGenStyle &style, KoShapeSavingContext &context)
112 {
113 Q_D(KoGradientBackground);
114 if (!d->gradient) return;
115 QBrush brush(*d->gradient);
116 brush.setTransform(d->matrix);
117 KoOdfGraphicStyles::saveOdfFillStyle(style, context.mainStyles(), brush);
118 }
119
loadStyle(KoOdfLoadingContext & context,const QSizeF & shapeSize)120 bool KoGradientBackground::loadStyle(KoOdfLoadingContext &context, const QSizeF &shapeSize)
121 {
122 Q_D(KoGradientBackground);
123 KoStyleStack &styleStack = context.styleStack();
124 if (! styleStack.hasProperty(KoXmlNS::draw, "fill"))
125 return false;
126
127 QString fillStyle = styleStack.property(KoXmlNS::draw, "fill");
128 if (fillStyle == "gradient") {
129 QBrush brush = KoOdfGraphicStyles::loadOdfGradientStyle(styleStack, context.stylesReader(), shapeSize);
130 const QGradient * gradient = brush.gradient();
131 if (gradient) {
132 d->gradient = KoFlake::cloneGradient(gradient);
133 d->matrix = brush.transform();
134
135 //Gopalakrishna Bhat: If the brush has transparency then we ignore the draw:opacity property and use the brush transparency.
136 // Brush will have transparency if the svg:linearGradient stop point has stop-opacity property otherwise it is opaque
137 if (brush.isOpaque() && styleStack.hasProperty(KoXmlNS::draw, "opacity")) {
138 QString opacityPercent = styleStack.property(KoXmlNS::draw, "opacity");
139 if (! opacityPercent.isEmpty() && opacityPercent.right(1) == "%") {
140 float opacity = qMin(opacityPercent.leftRef(opacityPercent.length() - 1).toDouble(), 100.0) / 100;
141 QGradientStops stops;
142 foreach(QGradientStop stop, d->gradient->stops()) {
143 stop.second.setAlphaF(opacity);
144 stops << stop;
145 }
146 d->gradient->setStops(stops);
147 }
148 }
149
150 return true;
151 }
152 }
153 return false;
154 }
155