Merged in f5soh/librepilot/update_credits (pull request #529)
[librepilot.git] / ground / gcs / src / libs / qwt / src / qwt_text.cpp
blob77a222aa219e140ca06af2eed5eb2a4f5821062b
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
10 #include "qwt_text.h"
11 #include "qwt_painter.h"
12 #include "qwt_text_engine.h"
13 #include <qmap.h>
14 #include <qfont.h>
15 #include <qcolor.h>
16 #include <qpen.h>
17 #include <qbrush.h>
18 #include <qpainter.h>
19 #include <qapplication.h>
20 #include <qdesktopwidget.h>
21 #include <qmath.h>
23 class QwtTextEngineDict
25 public:
26 static QwtTextEngineDict &dict();
28 void setTextEngine( QwtText::TextFormat, QwtTextEngine * );
30 const QwtTextEngine *textEngine( QwtText::TextFormat ) const;
31 const QwtTextEngine *textEngine( const QString &,
32 QwtText::TextFormat ) const;
34 private:
35 QwtTextEngineDict();
36 ~QwtTextEngineDict();
38 typedef QMap<int, QwtTextEngine *> EngineMap;
40 inline const QwtTextEngine *engine( EngineMap::const_iterator &it ) const
42 return it.value();
45 EngineMap d_map;
48 QwtTextEngineDict &QwtTextEngineDict::dict()
50 static QwtTextEngineDict engineDict;
51 return engineDict;
54 QwtTextEngineDict::QwtTextEngineDict()
56 d_map.insert( QwtText::PlainText, new QwtPlainTextEngine() );
57 #ifndef QT_NO_RICHTEXT
58 d_map.insert( QwtText::RichText, new QwtRichTextEngine() );
59 #endif
62 QwtTextEngineDict::~QwtTextEngineDict()
64 for ( EngineMap::const_iterator it = d_map.begin();
65 it != d_map.end(); ++it )
67 const QwtTextEngine *textEngine = engine( it );
68 delete textEngine;
72 const QwtTextEngine *QwtTextEngineDict::textEngine( const QString& text,
73 QwtText::TextFormat format ) const
75 if ( format == QwtText::AutoText )
77 for ( EngineMap::const_iterator it = d_map.begin();
78 it != d_map.end(); ++it )
80 if ( it.key() != QwtText::PlainText )
82 const QwtTextEngine *e = engine( it );
83 if ( e && e->mightRender( text ) )
84 return e;
89 EngineMap::const_iterator it = d_map.find( format );
90 if ( it != d_map.end() )
92 const QwtTextEngine *e = engine( it );
93 if ( e )
94 return e;
97 it = d_map.find( QwtText::PlainText );
98 return engine( it );
101 void QwtTextEngineDict::setTextEngine( QwtText::TextFormat format,
102 QwtTextEngine *engine )
104 if ( format == QwtText::AutoText )
105 return;
107 if ( format == QwtText::PlainText && engine == NULL )
108 return;
110 EngineMap::const_iterator it = d_map.find( format );
111 if ( it != d_map.end() )
113 const QwtTextEngine *e = this->engine( it );
114 if ( e )
115 delete e;
117 d_map.remove( format );
120 if ( engine != NULL )
121 d_map.insert( format, engine );
124 const QwtTextEngine *QwtTextEngineDict::textEngine(
125 QwtText::TextFormat format ) const
127 const QwtTextEngine *e = NULL;
129 EngineMap::const_iterator it = d_map.find( format );
130 if ( it != d_map.end() )
131 e = engine( it );
133 return e;
136 class QwtText::PrivateData
138 public:
139 PrivateData():
140 renderFlags( Qt::AlignCenter ),
141 borderRadius( 0 ),
142 borderPen( Qt::NoPen ),
143 backgroundBrush( Qt::NoBrush ),
144 paintAttributes( 0 ),
145 layoutAttributes( 0 ),
146 textEngine( NULL )
150 int renderFlags;
151 QString text;
152 QFont font;
153 QColor color;
154 double borderRadius;
155 QPen borderPen;
156 QBrush backgroundBrush;
158 QwtText::PaintAttributes paintAttributes;
159 QwtText::LayoutAttributes layoutAttributes;
161 const QwtTextEngine *textEngine;
164 class QwtText::LayoutCache
166 public:
167 void invalidate()
169 textSize = QSizeF();
172 QFont font;
173 QSizeF textSize;
177 Constructor
179 \param text Text content
180 \param textFormat Text format
182 QwtText::QwtText( const QString &text, QwtText::TextFormat textFormat )
184 d_data = new PrivateData;
185 d_data->text = text;
186 d_data->textEngine = textEngine( text, textFormat );
188 d_layoutCache = new LayoutCache;
191 //! Copy constructor
192 QwtText::QwtText( const QwtText &other )
194 d_data = new PrivateData;
195 *d_data = *other.d_data;
197 d_layoutCache = new LayoutCache;
198 *d_layoutCache = *other.d_layoutCache;
201 //! Destructor
202 QwtText::~QwtText()
204 delete d_data;
205 delete d_layoutCache;
208 //! Assignment operator
209 QwtText &QwtText::operator=( const QwtText & other )
211 *d_data = *other.d_data;
212 *d_layoutCache = *other.d_layoutCache;
213 return *this;
216 //! Relational operator
217 bool QwtText::operator==( const QwtText &other ) const
219 return d_data->renderFlags == other.d_data->renderFlags &&
220 d_data->text == other.d_data->text &&
221 d_data->font == other.d_data->font &&
222 d_data->color == other.d_data->color &&
223 d_data->borderRadius == other.d_data->borderRadius &&
224 d_data->borderPen == other.d_data->borderPen &&
225 d_data->backgroundBrush == other.d_data->backgroundBrush &&
226 d_data->paintAttributes == other.d_data->paintAttributes &&
227 d_data->textEngine == other.d_data->textEngine;
230 //! Relational operator
231 bool QwtText::operator!=( const QwtText &other ) const // invalidate
233 return !( other == *this );
237 Assign a new text content
239 \param text Text content
240 \param textFormat Text format
242 \sa text()
244 void QwtText::setText( const QString &text,
245 QwtText::TextFormat textFormat )
247 d_data->text = text;
248 d_data->textEngine = textEngine( text, textFormat );
249 d_layoutCache->invalidate();
253 \return Text as QString.
254 \sa setText()
256 QString QwtText::text() const
258 return d_data->text;
262 \brief Change the render flags
264 The default setting is Qt::AlignCenter
266 \param renderFlags Bitwise OR of the flags used like in QPainter::drawText()
268 \sa renderFlags(), QwtTextEngine::draw()
269 \note Some renderFlags might have no effect, depending on the text format.
271 void QwtText::setRenderFlags( int renderFlags )
273 if ( renderFlags != d_data->renderFlags )
275 d_data->renderFlags = renderFlags;
276 d_layoutCache->invalidate();
281 \return Render flags
282 \sa setRenderFlags()
284 int QwtText::renderFlags() const
286 return d_data->renderFlags;
290 Set the font.
292 \param font Font
293 \note Setting the font might have no effect, when
294 the text contains control sequences for setting fonts.
296 void QwtText::setFont( const QFont &font )
298 d_data->font = font;
299 setPaintAttribute( PaintUsingTextFont );
302 //! Return the font.
303 QFont QwtText::font() const
305 return d_data->font;
309 Return the font of the text, if it has one.
310 Otherwise return defaultFont.
312 \param defaultFont Default font
313 \return Font used for drawing the text
315 \sa setFont(), font(), PaintAttributes
317 QFont QwtText::usedFont( const QFont &defaultFont ) const
319 if ( d_data->paintAttributes & PaintUsingTextFont )
320 return d_data->font;
322 return defaultFont;
326 Set the pen color used for drawing the text.
328 \param color Color
329 \note Setting the color might have no effect, when
330 the text contains control sequences for setting colors.
332 void QwtText::setColor( const QColor &color )
334 d_data->color = color;
335 setPaintAttribute( PaintUsingTextColor );
338 //! Return the pen color, used for painting the text
339 QColor QwtText::color() const
341 return d_data->color;
345 Return the color of the text, if it has one.
346 Otherwise return defaultColor.
348 \param defaultColor Default color
349 \return Color used for drawing the text
351 \sa setColor(), color(), PaintAttributes
353 QColor QwtText::usedColor( const QColor &defaultColor ) const
355 if ( d_data->paintAttributes & PaintUsingTextColor )
356 return d_data->color;
358 return defaultColor;
362 Set the radius for the corners of the border frame
364 \param radius Radius of a rounded corner
365 \sa borderRadius(), setBorderPen(), setBackgroundBrush()
367 void QwtText::setBorderRadius( double radius )
369 d_data->borderRadius = qMax( 0.0, radius );
373 \return Radius for the corners of the border frame
374 \sa setBorderRadius(), borderPen(), backgroundBrush()
376 double QwtText::borderRadius() const
378 return d_data->borderRadius;
382 Set the background pen
384 \param pen Background pen
385 \sa borderPen(), setBackgroundBrush()
387 void QwtText::setBorderPen( const QPen &pen )
389 d_data->borderPen = pen;
390 setPaintAttribute( PaintBackground );
394 \return Background pen
395 \sa setBorderPen(), backgroundBrush()
397 QPen QwtText::borderPen() const
399 return d_data->borderPen;
403 Set the background brush
405 \param brush Background brush
406 \sa backgroundBrush(), setBorderPen()
408 void QwtText::setBackgroundBrush( const QBrush &brush )
410 d_data->backgroundBrush = brush;
411 setPaintAttribute( PaintBackground );
415 \return Background brush
416 \sa setBackgroundBrush(), borderPen()
418 QBrush QwtText::backgroundBrush() const
420 return d_data->backgroundBrush;
424 Change a paint attribute
426 \param attribute Paint attribute
427 \param on On/Off
429 \note Used by setFont(), setColor(),
430 setBorderPen() and setBackgroundBrush()
431 \sa testPaintAttribute()
433 void QwtText::setPaintAttribute( PaintAttribute attribute, bool on )
435 if ( on )
436 d_data->paintAttributes |= attribute;
437 else
438 d_data->paintAttributes &= ~attribute;
442 Test a paint attribute
444 \param attribute Paint attribute
445 \return true, if attribute is enabled
447 \sa setPaintAttribute()
449 bool QwtText::testPaintAttribute( PaintAttribute attribute ) const
451 return d_data->paintAttributes & attribute;
455 Change a layout attribute
457 \param attribute Layout attribute
458 \param on On/Off
459 \sa testLayoutAttribute()
461 void QwtText::setLayoutAttribute( LayoutAttribute attribute, bool on )
463 if ( on )
464 d_data->layoutAttributes |= attribute;
465 else
466 d_data->layoutAttributes &= ~attribute;
470 Test a layout attribute
472 \param attribute Layout attribute
473 \return true, if attribute is enabled
475 \sa setLayoutAttribute()
477 bool QwtText::testLayoutAttribute( LayoutAttribute attribute ) const
479 return d_data->layoutAttributes | attribute;
483 Find the height for a given width
485 \param defaultFont Font, used for the calculation if the text has no font
486 \param width Width
488 \return Calculated height
490 double QwtText::heightForWidth( double width, const QFont &defaultFont ) const
492 // We want to calculate in screen metrics. So
493 // we need a font that uses screen metrics
495 const QFont font( usedFont( defaultFont ), QApplication::desktop() );
497 double h = 0;
499 if ( d_data->layoutAttributes & MinimumLayout )
501 double left, right, top, bottom;
502 d_data->textEngine->textMargins( font, d_data->text,
503 left, right, top, bottom );
505 h = d_data->textEngine->heightForWidth(
506 font, d_data->renderFlags, d_data->text,
507 width + left + right );
509 h -= top + bottom;
511 else
513 h = d_data->textEngine->heightForWidth(
514 font, d_data->renderFlags, d_data->text, width );
517 return h;
521 Find the height for a given width
523 \param defaultFont Font, used for the calculation if the text has no font
525 \return Calculated height
529 Returns the size, that is needed to render text
531 \param defaultFont Font of the text
532 \return Caluclated size
534 QSizeF QwtText::textSize( const QFont &defaultFont ) const
536 // We want to calculate in screen metrics. So
537 // we need a font that uses screen metrics
539 const QFont font( usedFont( defaultFont ), QApplication::desktop() );
541 if ( !d_layoutCache->textSize.isValid()
542 || d_layoutCache->font != font )
544 d_layoutCache->textSize = d_data->textEngine->textSize(
545 font, d_data->renderFlags, d_data->text );
546 d_layoutCache->font = font;
549 QSizeF sz = d_layoutCache->textSize;
551 if ( d_data->layoutAttributes & MinimumLayout )
553 double left, right, top, bottom;
554 d_data->textEngine->textMargins( font, d_data->text,
555 left, right, top, bottom );
556 sz -= QSizeF( left + right, top + bottom );
559 return sz;
563 Draw a text into a rectangle
565 \param painter Painter
566 \param rect Rectangle
568 void QwtText::draw( QPainter *painter, const QRectF &rect ) const
570 if ( d_data->paintAttributes & PaintBackground )
572 if ( d_data->borderPen != Qt::NoPen ||
573 d_data->backgroundBrush != Qt::NoBrush )
575 painter->save();
577 painter->setPen( d_data->borderPen );
578 painter->setBrush( d_data->backgroundBrush );
580 if ( d_data->borderRadius == 0 )
582 QwtPainter::drawRect( painter, rect );
584 else
586 painter->setRenderHint( QPainter::Antialiasing, true );
587 painter->drawRoundedRect( rect,
588 d_data->borderRadius, d_data->borderRadius );
591 painter->restore();
595 painter->save();
597 if ( d_data->paintAttributes & PaintUsingTextFont )
599 painter->setFont( d_data->font );
602 if ( d_data->paintAttributes & PaintUsingTextColor )
604 if ( d_data->color.isValid() )
605 painter->setPen( d_data->color );
608 QRectF expandedRect = rect;
609 if ( d_data->layoutAttributes & MinimumLayout )
611 // We want to calculate in screen metrics. So
612 // we need a font that uses screen metrics
614 const QFont font( painter->font(), QApplication::desktop() );
616 double left, right, top, bottom;
617 d_data->textEngine->textMargins(
618 font, d_data->text, left, right, top, bottom );
620 expandedRect.setTop( rect.top() - top );
621 expandedRect.setBottom( rect.bottom() + bottom );
622 expandedRect.setLeft( rect.left() - left );
623 expandedRect.setRight( rect.right() + right );
626 d_data->textEngine->draw( painter, expandedRect,
627 d_data->renderFlags, d_data->text );
629 painter->restore();
633 Find the text engine for a text format
635 In case of QwtText::AutoText the first text engine
636 (beside QwtPlainTextEngine) is returned, where QwtTextEngine::mightRender
637 returns true. If there is none QwtPlainTextEngine is returned.
639 If no text engine is registered for the format QwtPlainTextEngine
640 is returnd.
642 \param text Text, needed in case of AutoText
643 \param format Text format
645 \return Corresponding text engine
647 const QwtTextEngine *QwtText::textEngine( const QString &text,
648 QwtText::TextFormat format )
650 return QwtTextEngineDict::dict().textEngine( text, format );
654 Assign/Replace a text engine for a text format
656 With setTextEngine it is possible to extend Qwt with
657 other types of text formats.
659 For QwtText::PlainText it is not allowed to assign a engine == NULL.
661 \param format Text format
662 \param engine Text engine
664 \sa QwtMathMLTextEngine
665 \warning Using QwtText::AutoText does nothing.
667 void QwtText::setTextEngine( QwtText::TextFormat format,
668 QwtTextEngine *engine )
670 QwtTextEngineDict::dict().setTextEngine( format, engine );
674 \brief Find the text engine for a text format
676 textEngine can be used to find out if a text format is supported.
678 \param format Text format
679 \return The text engine, or NULL if no engine is available.
681 const QwtTextEngine *QwtText::textEngine( QwtText::TextFormat format )
683 return QwtTextEngineDict::dict().textEngine( format );