File indexing completed on 2024-05-12 15:54:19

0001 /*
0002  * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB.  All rights reserved.
0003  *
0004  * This file is part of the KD Chart library.
0005  *
0006  * This program is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU General Public License as
0008  * published by the Free Software Foundation; either version 2 of
0009  * the License, or (at your option) any later version.
0010  *
0011  * This program is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  * GNU General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU General Public License
0017  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
0018  */
0019 
0020 #include "KChartTextAttributes.h"
0021 
0022 #include <KChartCartesianCoordinatePlane.h>
0023 #include <KChartCartesianCoordinatePlane_p.h>
0024 #include "KChartMath_p.h"
0025 
0026 #include <QFont>
0027 #include <QPen>
0028 #include <qglobal.h>
0029 #include <QApplication>
0030 #include <QSharedPointer>
0031 #include <QTextDocument>
0032 
0033 #define d d_func()
0034 
0035 using namespace KChart;
0036 
0037 class Q_DECL_HIDDEN TextAttributes::Private
0038 {
0039     friend class TextAttributes;
0040 public:
0041      Private();
0042 private:
0043     bool visible;
0044     QFont font;
0045     mutable QFont cachedFont;
0046     mutable qreal cachedFontSize;
0047     Measure fontSize;
0048     Measure minimalFontSize;
0049     bool autoRotate;
0050     bool autoShrink;
0051     bool hasRotation;
0052     int rotation;
0053     QPen pen;
0054     QSharedPointer<QTextDocument> document;
0055 };
0056 
0057 TextAttributes::Private::Private()
0058     : visible( true ),
0059       font( QApplication::font() ),
0060       cachedFontSize( -1.0 ),
0061       autoRotate( false ),
0062       autoShrink( false ),
0063       hasRotation( false ),
0064       rotation( 0 ),
0065       pen( Qt::black )
0066 {
0067 }
0068 
0069 TextAttributes::TextAttributes()
0070     : _d( new Private() )
0071 {
0072 }
0073 
0074 TextAttributes::TextAttributes( const TextAttributes& r )
0075     : _d( new Private( *r.d ) )
0076 {
0077 
0078 }
0079 
0080 TextAttributes & TextAttributes::operator=( const TextAttributes& r )
0081 {
0082     if ( this == &r )
0083         return *this;
0084 
0085     *d = *r.d;
0086 
0087     return *this;
0088 }
0089 
0090 TextAttributes::~TextAttributes()
0091 {
0092     delete _d; _d = nullptr;
0093 }
0094 
0095 
0096 bool TextAttributes::operator==( const TextAttributes& r ) const
0097 {
0098     // the following works around a bug in gcc 4.3.2
0099     // causing StyleHint to be set to Zero when copying a QFont
0100     const QFont myFont( font() );
0101     QFont r_font( r.font() );
0102     r_font.setStyleHint( myFont.styleHint(), myFont.styleStrategy() );
0103     return ( isVisible() == r.isVisible() &&
0104              myFont == r_font &&
0105              fontSize() == r.fontSize() &&
0106              minimalFontSize() == r.minimalFontSize() &&
0107              autoRotate() == r.autoRotate() &&
0108              autoShrink() == r.autoShrink() &&
0109              rotation() == r.rotation() &&
0110              pen() == r.pen() &&
0111              textDocument() == r.textDocument() );
0112 }
0113 
0114 
0115 void TextAttributes::setVisible( bool visible )
0116 {
0117     d->visible = visible;
0118 }
0119 
0120 bool TextAttributes::isVisible() const
0121 {
0122     return d->visible;
0123 }
0124 
0125 void TextAttributes::setFont( const QFont& font )
0126 {
0127     d->font       = font;
0128     d->cachedFont = font; // note: we do not set the font's size here, but in calculatedFont()
0129     d->cachedFontSize = -1.0;
0130 }
0131 
0132 QFont TextAttributes::font() const
0133 {
0134     return d->font;
0135 }
0136 
0137 void TextAttributes::setFontSize( const Measure & measure )
0138 {
0139     d->fontSize = measure;
0140 }
0141 
0142 Measure TextAttributes::fontSize() const
0143 {
0144     return d->fontSize;
0145 }
0146 
0147 void TextAttributes::setMinimalFontSize( const Measure & measure )
0148 {
0149     d->minimalFontSize = measure;
0150 }
0151 
0152 Measure TextAttributes::minimalFontSize() const
0153 {
0154     return d->minimalFontSize;
0155 }
0156 
0157 bool TextAttributes::hasAbsoluteFontSize() const
0158 {
0159     return d->fontSize.calculationMode() == KChartEnums::MeasureCalculationModeAbsolute
0160         && d->minimalFontSize.calculationMode() == KChartEnums::MeasureCalculationModeAbsolute;
0161 }
0162 
0163 qreal TextAttributes::calculatedFontSize( const QSizeF &referenceSize,
0164                                           KChartEnums::MeasureOrientation autoReferenceOrientation ) const
0165 {
0166     const qreal normalSize  = fontSize().calculatedValue( referenceSize, autoReferenceOrientation );
0167     const qreal minimalSize = minimalFontSize().calculatedValue( referenceSize, autoReferenceOrientation );
0168     return qMax( normalSize, minimalSize );
0169 }
0170 
0171 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
0172 const
0173 #endif
0174 qreal TextAttributes::calculatedFontSize( const QObject* autoReferenceArea,
0175                                           KChartEnums::MeasureOrientation autoReferenceOrientation ) const
0176 {
0177     const qreal normalSize  = fontSize().calculatedValue( autoReferenceArea, autoReferenceOrientation );
0178     const qreal minimalSize = minimalFontSize().calculatedValue( autoReferenceArea, autoReferenceOrientation );
0179     return qMax( normalSize, minimalSize );
0180 }
0181 
0182 const QFont TextAttributes::calculatedFont( const QObject* autoReferenceArea,
0183                                             KChartEnums::MeasureOrientation autoReferenceOrientation ) const
0184 {
0185     qreal size = NaN;
0186 
0187     const CartesianCoordinatePlane* plane = qobject_cast< const CartesianCoordinatePlane* >( autoReferenceArea );
0188     if ( plane  && plane->hasFixedDataCoordinateSpaceRelation() ) {
0189         // HACK
0190         // if hasFixedDataCoordinateSpaceRelation, we use a zoom trick to keep the diagram at a constant size
0191         // even when the plane size changes. calculatedFontSize() usually uses the plane size, not the diagram
0192         // size, to determine the font size. here we need to give it the diagram size in order to make the font
0193         // size constant, too. see KDCHDEV-219.
0194         CartesianCoordinatePlane::Private *priv
0195             = CartesianCoordinatePlane::Private::get( const_cast< CartesianCoordinatePlane * >( plane ) );
0196         size = calculatedFontSize( priv->fixedDataCoordinateSpaceRelationPinnedSize,
0197                                    autoReferenceOrientation );
0198     } else {
0199         size = calculatedFontSize( autoReferenceArea, autoReferenceOrientation );
0200     }
0201 
0202     if ( size > 0.0 && d->cachedFontSize != size ) {
0203         d->cachedFontSize = size;
0204         d->cachedFont.setPointSizeF( d->cachedFontSize );
0205     }
0206 
0207     return d->cachedFont;
0208 }
0209 
0210 
0211 void TextAttributes::setAutoRotate( bool autoRotate )
0212 {
0213     d->autoRotate = autoRotate;
0214 }
0215 
0216 bool TextAttributes::autoRotate() const
0217 {
0218     return d->autoRotate;
0219 }
0220 
0221 void TextAttributes::setAutoShrink( bool autoShrink )
0222 {
0223     d->autoShrink = autoShrink;
0224 }
0225 
0226 bool TextAttributes::autoShrink() const
0227 {
0228     return d->autoShrink;
0229 }
0230 
0231 void TextAttributes::setRotation( int rotation )
0232 {
0233     d->hasRotation = true;
0234     d->rotation = rotation;
0235 }
0236 
0237 int TextAttributes::rotation() const
0238 {
0239     return d->rotation;
0240 }
0241 
0242 void TextAttributes::resetRotation()
0243 {
0244     d->hasRotation = false;
0245     d->rotation = 0;
0246 }
0247 
0248 bool TextAttributes::hasRotation() const
0249 {
0250     return d->hasRotation;
0251 }
0252 
0253 void TextAttributes::setPen( const QPen& pen )
0254 {
0255     d->pen = pen;
0256 }
0257 
0258 QPen TextAttributes::pen() const
0259 {
0260     return d->pen;
0261 }
0262 
0263 QTextDocument* TextAttributes::textDocument() const
0264 {
0265     return d->document.data();
0266 }
0267 
0268 void TextAttributes::setTextDocument(QTextDocument* document)
0269 {
0270     d->document = QSharedPointer<QTextDocument>(document);
0271 }
0272 
0273 #if !defined(QT_NO_DEBUG_STREAM)
0274 QDebug operator<<(QDebug dbg, const KChart::TextAttributes& ta)
0275 {
0276     dbg << "KChart::TextAttributes("
0277     << "visible=" << ta.isVisible()
0278     << "font=" << ta.font().toString() /* What? No QDebug for QFont? */
0279     << "fontsize=" << ta.fontSize()
0280     << "minimalfontsize=" << ta.minimalFontSize()
0281     << "autorotate=" << ta.autoRotate()
0282     << "autoshrink=" << ta.autoShrink()
0283     << "rotation=" << ta.rotation()
0284     << "pen=" << ta.pen()
0285     << ")";
0286     return dbg;
0287 }
0288 #endif /* QT_NO_DEBUG_STREAM */