Warning, file /office/calligra/libs/text/KoTextBlockBorderData.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 * Copyright (C) 2006 Thomas Zander <zander@kde.org> 0003 * Copyright (C) 2011 Stuart Dickson <stuart@furkinfantastic.net> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KoTextBlockBorderData.h" 0022 0023 #include <QPainter> 0024 0025 #include "TextDebug.h" 0026 0027 struct Edge { 0028 Edge() : distance(0.0) { innerPen.setWidthF(0.); outerPen.setWidthF(0.); } 0029 QPen innerPen; 0030 QPen outerPen; 0031 qreal distance; 0032 }; 0033 0034 class Q_DECL_HIDDEN KoTextBlockBorderData::Private 0035 { 0036 public: 0037 Private() : refCount(0), mergeWithNext(true) {} 0038 Edge edges[4]; 0039 0040 QAtomicInt refCount; 0041 bool mergeWithNext; 0042 }; 0043 0044 KoTextBlockBorderData::KoTextBlockBorderData(const QRectF ¶gRect) 0045 : d(new Private()) 0046 { 0047 ///TODO Remove parameter paragRect and update references to this constructor. 0048 Q_UNUSED(paragRect); 0049 } 0050 0051 KoTextBlockBorderData::~KoTextBlockBorderData() 0052 { 0053 delete d; 0054 } 0055 0056 KoTextBlockBorderData::KoTextBlockBorderData(const KoTextBlockBorderData &other) 0057 : d(new Private()) 0058 { 0059 d->mergeWithNext = other.d->mergeWithNext; 0060 0061 for (int i = Top; i <= Right; i++) 0062 d->edges[i] = other.d->edges[i]; 0063 } 0064 0065 void KoTextBlockBorderData::setMergeWithNext(bool merge) 0066 { 0067 d->mergeWithNext = merge; 0068 } 0069 0070 bool KoTextBlockBorderData::hasBorders() const 0071 { 0072 for (int i = Top; i <= Right; i++) 0073 if (d->edges[i].outerPen.widthF() > 0.0) 0074 return true; 0075 return false; 0076 } 0077 0078 bool KoTextBlockBorderData::operator==(const KoTextBlockBorderData &border) const 0079 { 0080 return equals(border); 0081 } 0082 bool KoTextBlockBorderData::equals(const KoTextBlockBorderData &border) const 0083 { 0084 if (!d->mergeWithNext) { 0085 return false; 0086 } 0087 for (int i = Top; i <= Right; i++) { 0088 if (d->edges[i].outerPen != border.d->edges[i].outerPen) 0089 return false; 0090 if (d->edges[i].innerPen != border.d->edges[i].innerPen) 0091 return false; 0092 if (qAbs(d->edges[i].distance - border.d->edges[i].distance) > 1E-10) 0093 return false; 0094 } 0095 return true; 0096 } 0097 0098 void KoTextBlockBorderData::paint(QPainter &painter, const QRectF &bounds) const 0099 { 0100 QRectF innerBounds = bounds; 0101 if (d->edges[Top].outerPen.widthF() > 0) { 0102 QPen pen = d->edges[Top].outerPen; 0103 painter.setPen(pen); 0104 const qreal t = bounds.top() + pen.widthF() / 2.0; 0105 painter.drawLine(QLineF(bounds.left(), t, bounds.right(), t)); 0106 innerBounds.setTop(bounds.top() + d->edges[Top].distance + pen.widthF()); 0107 } 0108 if (d->edges[Bottom].outerPen.widthF() > 0) { 0109 QPen pen = d->edges[Bottom].outerPen; 0110 painter.setPen(pen); 0111 const qreal b = bounds.bottom() - pen.widthF() / 2.0; 0112 innerBounds.setBottom(bounds.bottom() - d->edges[Bottom].distance - pen.widthF()); 0113 painter.drawLine(QLineF(bounds.left(), b, bounds.right(), b)); 0114 } 0115 if (d->edges[Left].outerPen.widthF() > 0) { 0116 QPen pen = d->edges[Left].outerPen; 0117 painter.setPen(pen); 0118 const qreal l = bounds.left() + pen.widthF() / 2.0; 0119 innerBounds.setLeft(bounds.left() + d->edges[Left].distance + pen.widthF()); 0120 painter.drawLine(QLineF(l, bounds.top(), l, bounds.bottom())); 0121 } 0122 if (d->edges[Right].outerPen.widthF() > 0) { 0123 QPen pen = d->edges[Right].outerPen; 0124 painter.setPen(pen); 0125 const qreal r = bounds.right() - pen.widthF() / 2.0; 0126 innerBounds.setRight(bounds.right() - d->edges[Right].distance - pen.widthF()); 0127 painter.drawLine(QLineF(r, bounds.top(), r, bounds.bottom())); 0128 } 0129 // inner lines 0130 if (d->edges[Top].innerPen.widthF() > 0) { 0131 QPen pen = d->edges[Top].innerPen; 0132 painter.setPen(pen); 0133 const qreal t = innerBounds.top() + pen.widthF() / 2.0; 0134 painter.drawLine(QLineF(innerBounds.left(), t, innerBounds.right(), t)); 0135 } 0136 if (d->edges[Bottom].innerPen.widthF() > 0) { 0137 QPen pen = d->edges[Bottom].innerPen; 0138 painter.setPen(pen); 0139 const qreal b = innerBounds.bottom() - pen.widthF() / 2.0; 0140 painter.drawLine(QLineF(innerBounds.left(), b, innerBounds.right(), b)); 0141 } 0142 if (d->edges[Left].innerPen.widthF() > 0) { 0143 QPen pen = d->edges[Left].innerPen; 0144 painter.setPen(pen); 0145 const qreal l = innerBounds.left() + pen.widthF() / 2.0; 0146 painter.drawLine(QLineF(l, innerBounds.top(), l, innerBounds.bottom())); 0147 } 0148 if (d->edges[Right].innerPen.widthF() > 0) { 0149 QPen pen = d->edges[Right].innerPen; 0150 painter.setPen(pen); 0151 const qreal r = innerBounds.right() - pen.widthF() / 2.0; 0152 painter.drawLine(QLineF(r, innerBounds.top(), r, innerBounds.bottom())); 0153 } 0154 } 0155 0156 qreal KoTextBlockBorderData::inset(Side side) const 0157 { 0158 return d->edges[side].outerPen.widthF() + d->edges[side].distance + d->edges[side].innerPen.widthF(); 0159 } 0160 0161 void KoTextBlockBorderData::setEdge(Side side, const QTextBlockFormat &bf, 0162 KoParagraphStyle::Property style, KoParagraphStyle::Property width, 0163 KoParagraphStyle::Property color, KoParagraphStyle::Property space, 0164 KoParagraphStyle::Property innerWidth) 0165 { 0166 0167 Edge edge; 0168 KoBorder::BorderStyle borderStyle; 0169 borderStyle = static_cast<KoBorder::BorderStyle>(bf.intProperty(style)); 0170 switch (borderStyle) { 0171 case KoBorder::BorderDotted: edge.innerPen.setStyle(Qt::DotLine); break; 0172 case KoBorder::BorderDashed: edge.innerPen.setStyle(Qt::DashLine); break; 0173 case KoBorder::BorderDashDot: edge.innerPen.setStyle(Qt::DashDotLine); break; 0174 case KoBorder::BorderDashDotDot: edge.innerPen.setStyle(Qt::DashDotDotLine); break; 0175 case KoBorder::BorderGroove: /* TODO */ break; 0176 case KoBorder::BorderRidge: /* TODO */ break; 0177 case KoBorder::BorderInset: /* TODO */ break; 0178 case KoBorder::BorderOutset: /* TODO */ break; 0179 default: 0180 edge.innerPen.setStyle(Qt::SolidLine); 0181 } 0182 edge.innerPen.setColor(bf.colorProperty(color)); 0183 edge.innerPen.setJoinStyle(Qt::MiterJoin); 0184 edge.innerPen.setCapStyle(Qt::FlatCap); 0185 edge.outerPen = edge.innerPen; 0186 edge.outerPen.setWidthF(bf.doubleProperty(width)); // TODO check if this does not need any conversion 0187 0188 edge.distance = bf.doubleProperty(space); 0189 edge.innerPen.setWidthF(bf.doubleProperty(innerWidth)); 0190 0191 d->edges[side] = edge; 0192 } 0193 0194 bool KoTextBlockBorderData::ref() 0195 { 0196 return d->refCount.ref(); 0197 } 0198 0199 bool KoTextBlockBorderData::deref() 0200 { 0201 return d->refCount.deref(); 0202 } 0203 0204 int KoTextBlockBorderData::useCount() const 0205 { 0206 return d->refCount; 0207 }