1 /*
2 * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3 *
4 * This file is part of the KD Chart library.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "KChartTextAttributes.h"
21
22 #include <KChartCartesianCoordinatePlane.h>
23 #include <KChartCartesianCoordinatePlane_p.h>
24 #include "KChartMath_p.h"
25
26 #include <QFont>
27 #include <QPen>
28 #include <qglobal.h>
29 #include <QApplication>
30 #include <QSharedPointer>
31 #include <QTextDocument>
32
33 #define d d_func()
34
35 using namespace KChart;
36
37 class Q_DECL_HIDDEN TextAttributes::Private
38 {
39 friend class TextAttributes;
40 public:
41 Private();
42 private:
43 bool visible;
44 QFont font;
45 mutable QFont cachedFont;
46 mutable qreal cachedFontSize;
47 Measure fontSize;
48 Measure minimalFontSize;
49 bool autoRotate;
50 bool autoShrink;
51 bool hasRotation;
52 int rotation;
53 QPen pen;
54 QSharedPointer<QTextDocument> document;
55 };
56
Private()57 TextAttributes::Private::Private()
58 : visible( true ),
59 font( QApplication::font() ),
60 cachedFontSize( -1.0 ),
61 autoRotate( false ),
62 autoShrink( false ),
63 hasRotation( false ),
64 rotation( 0 ),
65 pen( Qt::black )
66 {
67 }
68
TextAttributes()69 TextAttributes::TextAttributes()
70 : _d( new Private() )
71 {
72 }
73
TextAttributes(const TextAttributes & r)74 TextAttributes::TextAttributes( const TextAttributes& r )
75 : _d( new Private( *r.d ) )
76 {
77
78 }
79
operator =(const TextAttributes & r)80 TextAttributes & TextAttributes::operator=( const TextAttributes& r )
81 {
82 if ( this == &r )
83 return *this;
84
85 *d = *r.d;
86
87 return *this;
88 }
89
~TextAttributes()90 TextAttributes::~TextAttributes()
91 {
92 delete _d; _d = nullptr;
93 }
94
95
operator ==(const TextAttributes & r) const96 bool TextAttributes::operator==( const TextAttributes& r ) const
97 {
98 // the following works around a bug in gcc 4.3.2
99 // causing StyleHint to be set to Zero when copying a QFont
100 const QFont myFont( font() );
101 QFont r_font( r.font() );
102 r_font.setStyleHint( myFont.styleHint(), myFont.styleStrategy() );
103 return ( isVisible() == r.isVisible() &&
104 myFont == r_font &&
105 fontSize() == r.fontSize() &&
106 minimalFontSize() == r.minimalFontSize() &&
107 autoRotate() == r.autoRotate() &&
108 autoShrink() == r.autoShrink() &&
109 rotation() == r.rotation() &&
110 pen() == r.pen() &&
111 textDocument() == r.textDocument() );
112 }
113
114
setVisible(bool visible)115 void TextAttributes::setVisible( bool visible )
116 {
117 d->visible = visible;
118 }
119
isVisible() const120 bool TextAttributes::isVisible() const
121 {
122 return d->visible;
123 }
124
setFont(const QFont & font)125 void TextAttributes::setFont( const QFont& font )
126 {
127 d->font = font;
128 d->cachedFont = font; // note: we do not set the font's size here, but in calculatedFont()
129 d->cachedFontSize = -1.0;
130 }
131
font() const132 QFont TextAttributes::font() const
133 {
134 return d->font;
135 }
136
setFontSize(const Measure & measure)137 void TextAttributes::setFontSize( const Measure & measure )
138 {
139 d->fontSize = measure;
140 }
141
fontSize() const142 Measure TextAttributes::fontSize() const
143 {
144 return d->fontSize;
145 }
146
setMinimalFontSize(const Measure & measure)147 void TextAttributes::setMinimalFontSize( const Measure & measure )
148 {
149 d->minimalFontSize = measure;
150 }
151
minimalFontSize() const152 Measure TextAttributes::minimalFontSize() const
153 {
154 return d->minimalFontSize;
155 }
156
hasAbsoluteFontSize() const157 bool TextAttributes::hasAbsoluteFontSize() const
158 {
159 return d->fontSize.calculationMode() == KChartEnums::MeasureCalculationModeAbsolute
160 && d->minimalFontSize.calculationMode() == KChartEnums::MeasureCalculationModeAbsolute;
161 }
162
calculatedFontSize(const QSizeF & referenceSize,KChartEnums::MeasureOrientation autoReferenceOrientation) const163 qreal TextAttributes::calculatedFontSize( const QSizeF &referenceSize,
164 KChartEnums::MeasureOrientation autoReferenceOrientation ) const
165 {
166 const qreal normalSize = fontSize().calculatedValue( referenceSize, autoReferenceOrientation );
167 const qreal minimalSize = minimalFontSize().calculatedValue( referenceSize, autoReferenceOrientation );
168 return qMax( normalSize, minimalSize );
169 }
170
171 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
172 const
173 #endif
calculatedFontSize(const QObject * autoReferenceArea,KChartEnums::MeasureOrientation autoReferenceOrientation) const174 qreal TextAttributes::calculatedFontSize( const QObject* autoReferenceArea,
175 KChartEnums::MeasureOrientation autoReferenceOrientation ) const
176 {
177 const qreal normalSize = fontSize().calculatedValue( autoReferenceArea, autoReferenceOrientation );
178 const qreal minimalSize = minimalFontSize().calculatedValue( autoReferenceArea, autoReferenceOrientation );
179 return qMax( normalSize, minimalSize );
180 }
181
calculatedFont(const QObject * autoReferenceArea,KChartEnums::MeasureOrientation autoReferenceOrientation) const182 const QFont TextAttributes::calculatedFont( const QObject* autoReferenceArea,
183 KChartEnums::MeasureOrientation autoReferenceOrientation ) const
184 {
185 qreal size = NaN;
186
187 const CartesianCoordinatePlane* plane = qobject_cast< const CartesianCoordinatePlane* >( autoReferenceArea );
188 if ( plane && plane->hasFixedDataCoordinateSpaceRelation() ) {
189 // HACK
190 // if hasFixedDataCoordinateSpaceRelation, we use a zoom trick to keep the diagram at a constant size
191 // even when the plane size changes. calculatedFontSize() usually uses the plane size, not the diagram
192 // size, to determine the font size. here we need to give it the diagram size in order to make the font
193 // size constant, too. see KDCHDEV-219.
194 CartesianCoordinatePlane::Private *priv
195 = CartesianCoordinatePlane::Private::get( const_cast< CartesianCoordinatePlane * >( plane ) );
196 size = calculatedFontSize( priv->fixedDataCoordinateSpaceRelationPinnedSize,
197 autoReferenceOrientation );
198 } else {
199 size = calculatedFontSize( autoReferenceArea, autoReferenceOrientation );
200 }
201
202 if ( size > 0.0 && d->cachedFontSize != size ) {
203 d->cachedFontSize = size;
204 d->cachedFont.setPointSizeF( d->cachedFontSize );
205 }
206
207 return d->cachedFont;
208 }
209
210
setAutoRotate(bool autoRotate)211 void TextAttributes::setAutoRotate( bool autoRotate )
212 {
213 d->autoRotate = autoRotate;
214 }
215
autoRotate() const216 bool TextAttributes::autoRotate() const
217 {
218 return d->autoRotate;
219 }
220
setAutoShrink(bool autoShrink)221 void TextAttributes::setAutoShrink( bool autoShrink )
222 {
223 d->autoShrink = autoShrink;
224 }
225
autoShrink() const226 bool TextAttributes::autoShrink() const
227 {
228 return d->autoShrink;
229 }
230
setRotation(int rotation)231 void TextAttributes::setRotation( int rotation )
232 {
233 d->hasRotation = true;
234 d->rotation = rotation;
235 }
236
rotation() const237 int TextAttributes::rotation() const
238 {
239 return d->rotation;
240 }
241
resetRotation()242 void TextAttributes::resetRotation()
243 {
244 d->hasRotation = false;
245 d->rotation = 0;
246 }
247
hasRotation() const248 bool TextAttributes::hasRotation() const
249 {
250 return d->hasRotation;
251 }
252
setPen(const QPen & pen)253 void TextAttributes::setPen( const QPen& pen )
254 {
255 d->pen = pen;
256 }
257
pen() const258 QPen TextAttributes::pen() const
259 {
260 return d->pen;
261 }
262
textDocument() const263 QTextDocument* TextAttributes::textDocument() const
264 {
265 return d->document.data();
266 }
267
setTextDocument(QTextDocument * document)268 void TextAttributes::setTextDocument(QTextDocument* document)
269 {
270 d->document = QSharedPointer<QTextDocument>(document);
271 }
272
273 #if !defined(QT_NO_DEBUG_STREAM)
operator <<(QDebug dbg,const KChart::TextAttributes & ta)274 QDebug operator<<(QDebug dbg, const KChart::TextAttributes& ta)
275 {
276 dbg << "KChart::TextAttributes("
277 << "visible=" << ta.isVisible()
278 << "font=" << ta.font().toString() /* What? No QDebug for QFont? */
279 << "fontsize=" << ta.fontSize()
280 << "minimalfontsize=" << ta.minimalFontSize()
281 << "autorotate=" << ta.autoRotate()
282 << "autoshrink=" << ta.autoShrink()
283 << "rotation=" << ta.rotation()
284 << "pen=" << ta.pen()
285 << ")";
286 return dbg;
287 }
288 #endif /* QT_NO_DEBUG_STREAM */
289