KoLineBorder.cpp 5.68 KB
Newer Older
Thomas Zander's avatar
Thomas Zander committed
1
/* This file is part of the KDE project
2
 * Copyright (C) 2006-2007 Thomas Zander <zander@kde.org>
3
 * Copyright (C) 2006-2008 Jan Hambrecht <jaham@gmx.net>
4
 * Copyright (C) 2007,2009 Thorsten Zachmann <zachmann@kde.org>
Thomas Zander's avatar
Thomas Zander committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "KoLineBorder.h"
#include "KoViewConverter.h"
#include "KoShape.h"
Jarosław Staniek's avatar
Jarosław Staniek committed
25
#include "KoShapeSavingContext.h"
Thomas Zander's avatar
Thomas Zander committed
26

Thorsten Zachmann's avatar
Thorsten Zachmann committed
27 28 29
#include "KoPathShape.h"
#include "KoMarkerData.h"

Thomas Zander's avatar
Thomas Zander committed
30 31
#include <QPainterPath>

32
#include <KoGenStyle.h>
33
#include <KoGenStyles.h>
34
#include <KoOdfGraphicStyles.h>
35

36 37
#include <math.h>

38 39
class KoLineBorder::Private
{
40
public:
Thorsten Zachmann's avatar
Thorsten Zachmann committed
41
    void paintBorder(KoShape *shape, QPainter &painter, const QPen &pen) const;
42 43
    QColor color;
    QPen pen;
44
    QBrush brush;
45 46
};

Thorsten Zachmann's avatar
Thorsten Zachmann committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60
void KoLineBorder::Private::paintBorder(KoShape *shape, QPainter &painter, const QPen &pen) const
{
    if (!pen.isCosmetic()) {
        KoPathShape *pathShape = dynamic_cast<KoPathShape *>(shape);
        if (pathShape) {
            QPainterPath path = pathShape->pathStroke(pen);
            painter.fillPath(path, pen.brush());
            return;
        }
        painter.strokePath(shape->outline(), pen);
    }
}


Thomas Zander's avatar
Thomas Zander committed
61
KoLineBorder::KoLineBorder()
62
        : d(new Private())
Thomas Zander's avatar
Thomas Zander committed
63
{
64
    d->color = QColor(Qt::black);
65 66 67
    // we are not rendering stroke with zero width anymore
    // so lets use a default width of 1.0
    d->pen.setWidthF(1.0);
Thomas Zander's avatar
Thomas Zander committed
68 69
}

Thomas Zander's avatar
Thomas Zander committed
70
KoLineBorder::KoLineBorder(const KoLineBorder &other)
71
        : KoShapeStrokeModel(), d(new Private())
72 73 74
{
    d->color = other.d->color;
    d->pen = other.d->pen;
75
    d->brush = other.d->brush;
76 77
}

78
KoLineBorder::KoLineBorder(qreal lineWidth, const QColor &color)
79
        : d(new Private())
Thomas Zander's avatar
Thomas Zander committed
80
{
81
    d->pen.setWidthF(qMax(qreal(0.0), lineWidth));
82
    d->pen.setJoinStyle(Qt::MiterJoin);
83
    d->color = color;
84 85
}

86 87
KoLineBorder::~KoLineBorder()
{
88
    delete d;
Thomas Zander's avatar
Thomas Zander committed
89 90
}

Thomas Zander's avatar
Thomas Zander committed
91
KoLineBorder &KoLineBorder::operator = (const KoLineBorder &rhs)
92
{
93
    if (this == &rhs)
94 95 96 97
        return *this;

    d->pen = rhs.d->pen;
    d->color = rhs.d->color;
98
    d->brush = rhs.d->brush;
99 100 101 102

    return *this;
}

Thomas Zander's avatar
Thomas Zander committed
103
void KoLineBorder::fillStyle(KoGenStyle &style, KoShapeSavingContext &context) const
104
{
105
    QPen pen = d->pen;
106 107 108 109
    if (d->brush.gradient())
        pen.setBrush(d->brush);
    else
        pen.setColor(d->color);
Thomas Zander's avatar
Thomas Zander committed
110
    KoOdfGraphicStyles::saveOdfStrokeStyle(style, context.mainStyles(), pen);
111 112
}

113
void KoLineBorder::strokeInsets(const KoShape *shape, KoInsets &insets) const
114
{
Thomas Zander's avatar
Thomas Zander committed
115
    Q_UNUSED(shape);
116
    qreal lineWidth = d->pen.widthF();
117
    if (lineWidth < 0)
118
        lineWidth = 1;
119
    lineWidth *= 0.5; // since we draw a line half inside, and half outside the object.
120

121
    // if we have square cap, we need a little more space
Thomas Zander's avatar
Thomas Zander committed
122
    // -> sqrt((0.5*penWidth)^2 + (0.5*penWidth)^2)
Thomas Zander's avatar
Thomas Zander committed
123
    if (capStyle() == Qt::SquareCap)
124
        lineWidth *= M_SQRT2;
125

126 127 128 129
    insets.top = lineWidth;
    insets.bottom = lineWidth;
    insets.left = lineWidth;
    insets.right = lineWidth;
Thomas Zander's avatar
Thomas Zander committed
130 131
}

Thomas Zander's avatar
Thomas Zander committed
132
bool KoLineBorder::hasTransparency() const
133
{
134
    return d->color.alpha() > 0;
Thomas Zander's avatar
Thomas Zander committed
135 136
}

Thomas Zander's avatar
Thomas Zander committed
137
void KoLineBorder::paint(KoShape *shape, QPainter &painter, const KoViewConverter &converter)
138
{
139
    KoShape::applyConversion(painter, converter);
Thomas Zander's avatar
Thomas Zander committed
140

141 142
    QPen pen = d->pen;

143 144
    if (d->brush.gradient())
        pen.setBrush(d->brush);
145 146 147
    else
        pen.setColor(d->color);

Thorsten Zachmann's avatar
Thorsten Zachmann committed
148
    d->paintBorder(shape, painter, pen);
149 150
}

Thomas Zander's avatar
Thomas Zander committed
151
void KoLineBorder::paint(KoShape *shape, QPainter &painter, const KoViewConverter &converter, const QColor &color)
152 153 154 155 156 157
{
    KoShape::applyConversion(painter, converter);

    QPen pen = d->pen;
    pen.setColor(color);

Thorsten Zachmann's avatar
Thorsten Zachmann committed
158
    d->paintBorder(shape, painter, pen);
159 160
}

161
void KoLineBorder::setCapStyle(Qt::PenCapStyle style)
162
{
163
    d->pen.setCapStyle(style);
164 165
}

166 167
Qt::PenCapStyle KoLineBorder::capStyle() const
{
168
    return d->pen.capStyle();
169 170
}

171
void KoLineBorder::setJoinStyle(Qt::PenJoinStyle style)
172
{
173
    d->pen.setJoinStyle(style);
174 175
}

176 177
Qt::PenJoinStyle KoLineBorder::joinStyle() const
{
178
    return d->pen.joinStyle();
179 180
}

181
void KoLineBorder::setLineWidth(qreal lineWidth)
182
{
183
    d->pen.setWidthF(qMax(qreal(0.0), lineWidth));
184 185
}

186 187
qreal KoLineBorder::lineWidth() const
{
188
    return d->pen.widthF();
189 190
}

191
void KoLineBorder::setMiterLimit(qreal miterLimit)
192
{
193
    d->pen.setMiterLimit(miterLimit);
194 195
}

196 197
qreal KoLineBorder::miterLimit() const
{
198
    return d->pen.miterLimit();
Thomas Zander's avatar
Thomas Zander committed
199
}
200

Thomas Zander's avatar
Thomas Zander committed
201
QColor KoLineBorder::color() const
202
{
203
    return d->color;
204 205
}

Thomas Zander's avatar
Thomas Zander committed
206
void KoLineBorder::setColor(const QColor &color)
207
{
208
    d->color = color;
209
}
210

211
void KoLineBorder::setLineStyle(Qt::PenStyle style, const QVector<qreal> &dashes)
212
{
213 214
    if (style < Qt::CustomDashLine)
        d->pen.setStyle(style);
215
    else
216
        d->pen.setDashPattern(dashes);
217 218 219 220 221 222 223 224 225 226 227 228
}

Qt::PenStyle KoLineBorder::lineStyle() const
{
    return d->pen.style();
}

QVector<qreal> KoLineBorder::lineDashes() const
{
    return d->pen.dashPattern();
}

229
void KoLineBorder::setDashOffset(qreal dashOffset)
230
{
231
    d->pen.setDashOffset(dashOffset);
232 233
}

234
qreal KoLineBorder::dashOffset() const
235 236 237 238
{
    return d->pen.dashOffset();
}

Thomas Zander's avatar
Thomas Zander committed
239
void KoLineBorder::setLineBrush(const QBrush &brush)
240 241 242 243 244 245 246 247
{
    d->brush = brush;
}

QBrush KoLineBorder::lineBrush() const
{
    return d->brush;
}