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 #ifndef KCHARTTEXTLABELCACHE_H
21 #define KCHARTTEXTLABELCACHE_H
22 
23 #include <QPixmap>
24 #include <QFont>
25 #include <QBrush>
26 #include <QPen>
27 
28 #include "KChartEnums.h"
29 
30 /**
31   * @brief  base class for prerendered elements like labels, pixmaps, markers, etc.
32   */
33 class PrerenderedElement {
34 public:
35     PrerenderedElement();
~PrerenderedElement()36     virtual ~PrerenderedElement() {}
37 
38     /** Returns the rendered element.
39         If any of the properties have change, the element will be
40         regenerated. */
41     virtual const QPixmap& pixmap() const = 0;
42 
43     /** Return the location of the reference point relatively to the
44         pixmap's origin. */
45     virtual QPointF referencePointLocation( KChartEnums::PositionValue ) const = 0;
46 
47     /** Set the position of the element. */
48     void setPosition( const QPointF& position );
49     /** Get the position of the element. */
50     const QPointF& position() const;
51 
52     /** Set the reference point of the element.
53         Every element has nine possible reference points (all compass
54         directions, plus the center.
55      */
56     void setReferencePoint( KChartEnums::PositionValue );
57     /** Get the reference point of the element. */
58     KChartEnums::PositionValue referencePoint() const;
59 
60 protected:
61     /** invalidate() needs to be called if any of the properties that
62         determine the visual appearance of the prerendered element
63         change.
64         It can be called for a const object, as objects may need to
65         force recalculation of the pixmap.
66     */
67     virtual void invalidate() const = 0;
68 
69 private:
70     QPointF m_position;
71     KChartEnums::PositionValue m_referencePoint;
72 };
73 
74 /**
75     @brief PrerenderedLabel is an internal KChart class that simplifies creation
76     and caching of cached text labels.
77 
78     It provides referenze points to anchor the text to other
79     elements. Reference points use the positions defined in
80     KChartEnums.
81 
82     Usage:
83     <pre>
84     qreal angle = 90.0;
85     CachedLabel label;
86     label.paint( font, tr("Label"), angle );
87     </pre>
88 */
89 
90 // FIXME this is merely a prototype
91 // FIXME caching could be done by a second layer that can be used to,
92 // e.g., query for a prerendered element by id or name, or by changing
93 // the pixmap() method to do lazy evaluation.
94 class PrerenderedLabel : public PrerenderedElement
95 {
96 public:
97     PrerenderedLabel();
98     ~PrerenderedLabel();
99 
100 
101     /**
102       * Sets the label's font to \a font.
103       */
104     void setFont( const QFont& font );
105 
106     /**
107       * @return the label's font.
108       */
109     const QFont& font() const;
110 
111 
112     /**
113       * Sets the label's text to \a text
114       */
115     void setText( const QString& text );
116 
117     /**
118       * @return the label's text
119       */
120     const QString& text() const;
121 
122 
123     /**
124       * Sets the label's brush to \a brush
125       */
126     void setBrush( const QBrush& brush );
127 
128     /**
129       * @return the label's brush
130       */
131     const QBrush& brush() const;
132 
133     void setPen( const QPen& );
134     const QPen& pen() const;
135 
136 
137     /**
138       * Sets the angle of the label to \a angle degrees
139       */
140     void setAngle( qreal angle );
141 
142     /**
143       * @return the label's angle in degrees
144       */
145     qreal angle() const;
146 
147     // reimpl PrerenderedElement:
148     const QPixmap& pixmap() const override;
149     QPointF referencePointLocation( KChartEnums::PositionValue position ) const override;
150     // overload: return location of referencePoint():
151     QPointF referencePointLocation() const;
152 
153 protected:
154 
155     /**
156       * Invalidates the preredendered data, forces re-rendering.
157       */
158     void invalidate() const override;
159 
160 private:
161     /** Create a label with the given text and the given rotation
162         angle. Needs to be const, otherwise the pixmap() method cannot
163         update when needed. */
164     void paint() const;
165 
166     // store the settings (these are used for the painting):
167     mutable bool m_dirty;
168     QFont m_font;
169     QString m_text;
170     QBrush m_brush;
171     QPen m_pen;
172     qreal m_angle;
173 
174     // these are valid once the label has been rendered:
175     mutable QPixmap m_pixmap;
176     mutable QPointF m_referenceBottomLeft;
177     mutable QPointF m_textBaseLineVector;
178     mutable QPointF m_textAscendVector;
179 };
180 
181 #endif
182