libs/flake

KoShapeShadow.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  * Copyright (C) 2008-2009 Jan Hambrecht <jaham@gmx.net>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this library; see the file COPYING.LIB.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  */
00019 
00020 #include "KoShapeShadow.h"
00021 #include "KoShapeSavingContext.h"
00022 #include "KoShapeBorderModel.h"
00023 #include "KoShape.h"
00024 #include "KoInsets.h"
00025 #include "KoPathShape.h"
00026 #include <KoGenStyle.h>
00027 #include <KoViewConverter.h>
00028 #include <QtGui/QPainter>
00029 #include <QtCore/QAtomicInt>
00030 
00031 class KoShapeShadow::Private
00032 {
00033 public:
00034     Private()
00035             : offset(10, 10), color(Qt::black), visible(true), refCount(0) {
00036     }
00037     QPointF offset;
00038     QColor color;
00039     bool visible;
00040     QAtomicInt refCount;
00041 };
00042 
00043 KoShapeShadow::KoShapeShadow()
00044         : d(new Private())
00045 {
00046 }
00047 
00048 KoShapeShadow::~KoShapeShadow()
00049 {
00050     delete d;
00051 }
00052 
00053 void KoShapeShadow::fillStyle(KoGenStyle &style, KoShapeSavingContext &context)
00054 {
00055     Q_UNUSED(context);
00056 
00057     style.addProperty("draw:shadow", d->visible ? "visible" : "hidden");
00058     style.addProperty("draw:shadow-color", d->color.name());
00059     if (d->color.alphaF() != 1.0)
00060         style.addProperty("draw:shadow-opacity", QString("%1%").arg(d->color.alphaF() * 100.0));
00061     style.addProperty("draw:shadow-offset-x", QString("%1pt").arg(d->offset.x()));
00062     style.addProperty("draw:shadow-offset-y", QString("%1pt").arg(d->offset.y()));
00063 }
00064 
00065 void KoShapeShadow::paint(KoShape *shape, QPainter &painter, const KoViewConverter &converter)
00066 {
00067     if (! d->visible)
00068         return;
00069 
00070     // calculate the shadow offset independent of shape transformation
00071     QMatrix tm;
00072     tm.translate(d->offset.x(), d->offset.y());
00073     QMatrix tr = shape->absoluteTransformation(&converter);
00074     QMatrix offsetMatrix = tr * tm * tr.inverted();
00075 
00076     if (shape->background()) {
00077         painter.save();
00078 
00079         KoShape::applyConversion(painter, converter);
00080 
00081         // the shadow direction is independent of the shapes transformation
00082         // please only change if you know what you are doing
00083         painter.setMatrix(offsetMatrix * painter.matrix());
00084         painter.setBrush(QBrush(d->color));
00085 
00086         QPainterPath path(shape->outline());
00087         KoPathShape * pathShape = dynamic_cast<KoPathShape*>(shape);
00088         if (pathShape)
00089             path.setFillRule(pathShape->fillRule());
00090         painter.drawPath(path);
00091         painter.restore();
00092     }
00093 
00094     if (shape->border()) {
00095         QMatrix oldPainterMatrix = painter.matrix();
00096         KoShape::applyConversion(painter, converter);
00097         QMatrix newPainterMatrix = painter.matrix();
00098 
00099         // the shadow direction is independent of the shapes transformation
00100         // please only change if you know what you are doing
00101         painter.setMatrix(offsetMatrix * painter.matrix());
00102 
00103         // compensate applyConversion call in paintBorder
00104         QMatrix scaleMatrix = newPainterMatrix * oldPainterMatrix.inverted();
00105         painter.setMatrix(scaleMatrix.inverted() * painter.matrix());
00106 
00107         shape->border()->paintBorder(shape, painter, converter, d->color);
00108     }
00109 }
00110 
00111 void KoShapeShadow::setOffset(const QPointF & offset)
00112 {
00113     d->offset = offset;
00114 }
00115 
00116 QPointF KoShapeShadow::offset() const
00117 {
00118     return d->offset;
00119 }
00120 
00121 void KoShapeShadow::setColor(const QColor &color)
00122 {
00123     d->color = color;
00124 }
00125 
00126 QColor KoShapeShadow::color() const
00127 {
00128     return d->color;
00129 }
00130 
00131 void KoShapeShadow::setVisibility(bool visible)
00132 {
00133     d->visible = visible;
00134 }
00135 
00136 bool KoShapeShadow::isVisible() const
00137 {
00138     return d->visible;
00139 }
00140 
00141 void KoShapeShadow::insets(const KoShape *shape, KoInsets &insets)
00142 {
00143     if (! d->visible)
00144         return;
00145 
00146     Q_UNUSED(shape);
00147 
00148     insets.left = (d->offset.x() < 0.0) ? qAbs(d->offset.x()) : 0.0;
00149     insets.top = (d->offset.y() < 0.0) ? qAbs(d->offset.y()) : 0.0;
00150     insets.right = (d->offset.x() > 0.0) ? d->offset.x() : 0.0;
00151     insets.bottom = (d->offset.y() > 0.0) ? d->offset.y() : 0.0;
00152 }
00153 
00154 void KoShapeShadow::addUser()
00155 {
00156     d->refCount.ref();
00157 }
00158 
00159 bool KoShapeShadow::removeUser()
00160 {
00161     return d->refCount.deref();
00162 }
00163 
00164 int KoShapeShadow::useCount() const
00165 {
00166     return d->refCount;
00167 }