Warning, file /office/calligra/libs/flake/KoShapeStroke.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  *
0003  * Copyright (C) 2006-2007 Thomas Zander <zander@kde.org>
0004  * Copyright (C) 2006-2008 Jan Hambrecht <jaham@gmx.net>
0005  * Copyright (C) 2007,2009 Thorsten Zachmann <zachmann@kde.org>
0006  * Copyright (C) 2012      Inge Wallin <inge@lysator.liu.se>
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Library General Public
0010  * License as published by the Free Software Foundation; either
0011  * version 2 of the License, or (at your option) any later version.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Library General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Library General Public License
0019  * along with this library; see the file COPYING.LIB.  If not, write to
0020  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022  */
0023 
0024 // Own
0025 #include "KoShapeStroke.h"
0026 
0027 // Posix
0028 #include <math.h>
0029 
0030 // Qt
0031 #include <QPainterPath>
0032 #include <QPainter>
0033 
0034 // Calligra
0035 #include <KoGenStyles.h>
0036 #include <KoOdfGraphicStyles.h>
0037 
0038 // Flake
0039 #include "KoViewConverter.h"
0040 #include "KoShape.h"
0041 #include "KoShapeSavingContext.h"
0042 #include "KoPathShape.h"
0043 #include "KoMarkerData.h"
0044 
0045 
0046 class Q_DECL_HIDDEN KoShapeStroke::Private
0047 {
0048 public:
0049     void paintBorder(KoShape *shape, QPainter &painter, const QPen &pen) const;
0050     QColor color;
0051     QPen pen;
0052     QBrush brush;
0053 };
0054 
0055 void KoShapeStroke::Private::paintBorder(KoShape *shape, QPainter &painter, const QPen &pen) const
0056 {
0057     if (!pen.isCosmetic() && pen.style() != Qt::NoPen) {
0058         KoPathShape *pathShape = dynamic_cast<KoPathShape *>(shape);
0059         if (pathShape) {
0060             QPainterPath path = pathShape->pathStroke(pen);
0061             painter.fillPath(path, pen.brush());
0062             return;
0063         }
0064         painter.strokePath(shape->outline(), pen);
0065     }
0066 }
0067 
0068 
0069 KoShapeStroke::KoShapeStroke()
0070         : d(new Private())
0071 {
0072     d->color = QColor(Qt::black);
0073     // we are not rendering stroke with zero width anymore
0074     // so lets use a default width of 1.0
0075     d->pen.setWidthF(1.0);
0076 }
0077 
0078 KoShapeStroke::KoShapeStroke(const KoShapeStroke &other)
0079         : KoShapeStrokeModel(), d(new Private())
0080 {
0081     d->color = other.d->color;
0082     d->pen = other.d->pen;
0083     d->brush = other.d->brush;
0084 }
0085 
0086 KoShapeStroke::KoShapeStroke(qreal lineWidth, const QColor &color)
0087         : d(new Private())
0088 {
0089     d->pen.setWidthF(qMax(qreal(0.0), lineWidth));
0090     d->pen.setJoinStyle(Qt::MiterJoin);
0091     d->color = color;
0092 }
0093 
0094 KoShapeStroke::~KoShapeStroke()
0095 {
0096     delete d;
0097 }
0098 
0099 KoShapeStroke &KoShapeStroke::operator = (const KoShapeStroke &rhs)
0100 {
0101     if (this == &rhs)
0102         return *this;
0103 
0104     d->pen = rhs.d->pen;
0105     d->color = rhs.d->color;
0106     d->brush = rhs.d->brush;
0107 
0108     return *this;
0109 }
0110 
0111 void KoShapeStroke::fillStyle(KoGenStyle &style, KoShapeSavingContext &context) const
0112 {
0113     QPen pen = d->pen;
0114     if (d->brush.gradient())
0115         pen.setBrush(d->brush);
0116     else
0117         pen.setColor(d->color);
0118     KoOdfGraphicStyles::saveOdfStrokeStyle(style, context.mainStyles(), pen);
0119 }
0120 
0121 void KoShapeStroke::strokeInsets(const KoShape *shape, KoInsets &insets) const
0122 {
0123     Q_UNUSED(shape);
0124     qreal lineWidth = d->pen.widthF();
0125     if (lineWidth < 0) {
0126         lineWidth = 1;
0127     }
0128     lineWidth *= 0.5; // since we draw a line half inside, and half outside the object.
0129 
0130     // if we have square cap, we need a little more space
0131     // -> sqrt((0.5*penWidth)^2 + (0.5*penWidth)^2)
0132     if (capStyle() == Qt::SquareCap) {
0133         lineWidth *= M_SQRT2;
0134     }
0135 
0136     if (joinStyle() == Qt::MiterJoin) {
0137         lineWidth = qMax(lineWidth, miterLimit());
0138     }
0139 
0140     insets.top = lineWidth;
0141     insets.bottom = lineWidth;
0142     insets.left = lineWidth;
0143     insets.right = lineWidth;
0144 }
0145 
0146 bool KoShapeStroke::hasTransparency() const
0147 {
0148     return d->color.alpha() > 0;
0149 }
0150 
0151 void KoShapeStroke::paint(KoShape *shape, QPainter &painter, const KoViewConverter &converter)
0152 {
0153     KoShape::applyConversion(painter, converter);
0154 
0155     QPen pen = d->pen;
0156 
0157     if (d->brush.gradient())
0158         pen.setBrush(d->brush);
0159     else
0160         pen.setColor(d->color);
0161 
0162     d->paintBorder(shape, painter, pen);
0163 }
0164 
0165 void KoShapeStroke::paint(KoShape *shape, QPainter &painter, const KoViewConverter &converter, const QColor &color)
0166 {
0167     KoShape::applyConversion(painter, converter);
0168 
0169     QPen pen = d->pen;
0170     pen.setColor(color);
0171 
0172     d->paintBorder(shape, painter, pen);
0173 }
0174 
0175 void KoShapeStroke::setCapStyle(Qt::PenCapStyle style)
0176 {
0177     d->pen.setCapStyle(style);
0178 }
0179 
0180 Qt::PenCapStyle KoShapeStroke::capStyle() const
0181 {
0182     return d->pen.capStyle();
0183 }
0184 
0185 void KoShapeStroke::setJoinStyle(Qt::PenJoinStyle style)
0186 {
0187     d->pen.setJoinStyle(style);
0188 }
0189 
0190 Qt::PenJoinStyle KoShapeStroke::joinStyle() const
0191 {
0192     return d->pen.joinStyle();
0193 }
0194 
0195 void KoShapeStroke::setLineWidth(qreal lineWidth)
0196 {
0197     d->pen.setWidthF(qMax(qreal(0.0), lineWidth));
0198 }
0199 
0200 qreal KoShapeStroke::lineWidth() const
0201 {
0202     return d->pen.widthF();
0203 }
0204 
0205 void KoShapeStroke::setMiterLimit(qreal miterLimit)
0206 {
0207     d->pen.setMiterLimit(miterLimit);
0208 }
0209 
0210 qreal KoShapeStroke::miterLimit() const
0211 {
0212     return d->pen.miterLimit();
0213 }
0214 
0215 QColor KoShapeStroke::color() const
0216 {
0217     return d->color;
0218 }
0219 
0220 void KoShapeStroke::setColor(const QColor &color)
0221 {
0222     d->color = color;
0223 }
0224 
0225 void KoShapeStroke::setLineStyle(Qt::PenStyle style, const QVector<qreal> &dashes)
0226 {
0227     if (style < Qt::CustomDashLine)
0228         d->pen.setStyle(style);
0229     else
0230         d->pen.setDashPattern(dashes);
0231 }
0232 
0233 Qt::PenStyle KoShapeStroke::lineStyle() const
0234 {
0235     return d->pen.style();
0236 }
0237 
0238 QVector<qreal> KoShapeStroke::lineDashes() const
0239 {
0240     return d->pen.dashPattern();
0241 }
0242 
0243 void KoShapeStroke::setDashOffset(qreal dashOffset)
0244 {
0245     d->pen.setDashOffset(dashOffset);
0246 }
0247 
0248 qreal KoShapeStroke::dashOffset() const
0249 {
0250     return d->pen.dashOffset();
0251 }
0252 
0253 void KoShapeStroke::setLineBrush(const QBrush &brush)
0254 {
0255     d->brush = brush;
0256 }
0257 
0258 QBrush KoShapeStroke::lineBrush() const
0259 {
0260     return d->brush;
0261 }