qwt_text.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
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  *****************************************************************************/
9 
10 #include "qwt_text.h"
11 #include "qwt_painter.h"
12 #include "qwt_text_engine.h"
13 #include "qwt_math.h"
14 
15 #include <qmap.h>
16 #include <qfont.h>
17 #include <qcolor.h>
18 #include <qpen.h>
19 #include <qbrush.h>
20 #include <qpainter.h>
21 #include <qapplication.h>
22 #include <qdesktopwidget.h>
23 
24 namespace
25 {
26  class QwtTextEngineDict
27  {
28  public:
29  static QwtTextEngineDict &dict();
30 
31  void setTextEngine( QwtText::TextFormat, QwtTextEngine * );
32 
33  const QwtTextEngine *textEngine( QwtText::TextFormat ) const;
34  const QwtTextEngine *textEngine( const QString &,
35  QwtText::TextFormat ) const;
36 
37  private:
38  QwtTextEngineDict();
39  ~QwtTextEngineDict();
40 
41  typedef QMap<int, QwtTextEngine *> EngineMap;
42 
43  inline const QwtTextEngine *engine( EngineMap::const_iterator &it ) const
44  {
45  return it.value();
46  }
47 
48  EngineMap d_map;
49  };
50 }
51 
52 QwtTextEngineDict &QwtTextEngineDict::dict()
53 {
54  static QwtTextEngineDict engineDict;
55  return engineDict;
56 }
57 
58 QwtTextEngineDict::QwtTextEngineDict()
59 {
60  d_map.insert( QwtText::PlainText, new QwtPlainTextEngine() );
61 #ifndef QT_NO_RICHTEXT
62  d_map.insert( QwtText::RichText, new QwtRichTextEngine() );
63 #endif
64 }
65 
66 QwtTextEngineDict::~QwtTextEngineDict()
67 {
68  for ( EngineMap::const_iterator it = d_map.constBegin();
69  it != d_map.constEnd(); ++it )
70  {
71  const QwtTextEngine *textEngine = engine( it );
72  delete textEngine;
73  }
74 }
75 
76 const QwtTextEngine *QwtTextEngineDict::textEngine( const QString& text,
78 {
79  if ( format == QwtText::AutoText )
80  {
81  for ( EngineMap::const_iterator it = d_map.begin();
82  it != d_map.end(); ++it )
83  {
84  if ( it.key() != QwtText::PlainText )
85  {
86  const QwtTextEngine *e = engine( it );
87  if ( e && e->mightRender( text ) )
88  return e;
89  }
90  }
91  }
92 
93  EngineMap::const_iterator it = d_map.find( format );
94  if ( it != d_map.end() )
95  {
96  const QwtTextEngine *e = engine( it );
97  if ( e )
98  return e;
99  }
100 
101  it = d_map.find( QwtText::PlainText );
102  return engine( it );
103 }
104 
105 void QwtTextEngineDict::setTextEngine( QwtText::TextFormat format,
106  QwtTextEngine *engine )
107 {
108  if ( format == QwtText::AutoText )
109  return;
110 
111  if ( format == QwtText::PlainText && engine == NULL )
112  return;
113 
114  EngineMap::const_iterator it = d_map.constFind( format );
115  if ( it != d_map.constEnd() )
116  {
117  delete this->engine( it );
118  d_map.remove( format );
119  }
120 
121  if ( engine != NULL )
122  d_map.insert( format, engine );
123 }
124 
125 const QwtTextEngine *QwtTextEngineDict::textEngine(
126  QwtText::TextFormat format ) const
127 {
128  const QwtTextEngine *e = NULL;
129 
130  EngineMap::const_iterator it = d_map.find( format );
131  if ( it != d_map.end() )
132  e = engine( it );
133 
134  return e;
135 }
136 
138 {
139 public:
141  renderFlags( Qt::AlignCenter ),
142  borderRadius( 0 ),
143  borderPen( Qt::NoPen ),
144  backgroundBrush( Qt::NoBrush ),
145  textEngine( NULL )
146  {
147  }
148 
150  QString text;
151  QFont font;
152  QColor color;
153  double borderRadius;
154  QPen borderPen;
156 
159 
161 };
162 
164 {
165 public:
166  void invalidate()
167  {
168  textSize = QSizeF();
169  }
170 
171  QFont font;
172  QSizeF textSize;
173 };
174 
179 {
180  d_data = new PrivateData;
181  d_data->textEngine = textEngine( d_data->text, PlainText );
182 
183  d_layoutCache = new LayoutCache;
184 }
185 
192 QwtText::QwtText( const QString &text, QwtText::TextFormat textFormat )
193 {
194  d_data = new PrivateData;
195  d_data->text = text;
196  d_data->textEngine = textEngine( text, textFormat );
197 
198  d_layoutCache = new LayoutCache;
199 }
200 
202 QwtText::QwtText( const QwtText &other )
203 {
204  d_data = new PrivateData;
205  *d_data = *other.d_data;
206 
207  d_layoutCache = new LayoutCache;
208  *d_layoutCache = *other.d_layoutCache;
209 }
210 
213 {
214  delete d_data;
215  delete d_layoutCache;
216 }
217 
220 {
221  *d_data = *other.d_data;
222  *d_layoutCache = *other.d_layoutCache;
223  return *this;
224 }
225 
227 bool QwtText::operator==( const QwtText &other ) const
228 {
229  return d_data->renderFlags == other.d_data->renderFlags &&
230  d_data->text == other.d_data->text &&
231  d_data->font == other.d_data->font &&
232  d_data->color == other.d_data->color &&
233  d_data->borderRadius == other.d_data->borderRadius &&
234  d_data->borderPen == other.d_data->borderPen &&
235  d_data->backgroundBrush == other.d_data->backgroundBrush &&
236  d_data->paintAttributes == other.d_data->paintAttributes &&
237  d_data->textEngine == other.d_data->textEngine;
238 }
239 
241 bool QwtText::operator!=( const QwtText &other ) const // invalidate
242 {
243  return !( other == *this );
244 }
245 
254 void QwtText::setText( const QString &text,
255  QwtText::TextFormat textFormat )
256 {
257  d_data->text = text;
258  d_data->textEngine = textEngine( text, textFormat );
259  d_layoutCache->invalidate();
260 }
261 
266 QString QwtText::text() const
267 {
268  return d_data->text;
269 }
270 
281 void QwtText::setRenderFlags( int renderFlags )
282 {
283  if ( renderFlags != d_data->renderFlags )
284  {
285  d_data->renderFlags = renderFlags;
286  d_layoutCache->invalidate();
287  }
288 }
289 
295 {
296  return d_data->renderFlags;
297 }
298 
306 void QwtText::setFont( const QFont &font )
307 {
308  d_data->font = font;
309  setPaintAttribute( PaintUsingTextFont );
310 }
311 
313 QFont QwtText::font() const
314 {
315  return d_data->font;
316 }
317 
327 QFont QwtText::usedFont( const QFont &defaultFont ) const
328 {
329  if ( d_data->paintAttributes & PaintUsingTextFont )
330  return d_data->font;
331 
332  return defaultFont;
333 }
334 
342 void QwtText::setColor( const QColor &color )
343 {
344  d_data->color = color;
345  setPaintAttribute( PaintUsingTextColor );
346 }
347 
349 QColor QwtText::color() const
350 {
351  return d_data->color;
352 }
353 
363 QColor QwtText::usedColor( const QColor &defaultColor ) const
364 {
365  if ( d_data->paintAttributes & PaintUsingTextColor )
366  return d_data->color;
367 
368  return defaultColor;
369 }
370 
377 void QwtText::setBorderRadius( double radius )
378 {
379  d_data->borderRadius = qwtMaxF( 0.0, radius );
380 }
381 
386 double QwtText::borderRadius() const
387 {
388  return d_data->borderRadius;
389 }
390 
397 void QwtText::setBorderPen( const QPen &pen )
398 {
399  d_data->borderPen = pen;
400  setPaintAttribute( PaintBackground );
401 }
402 
407 QPen QwtText::borderPen() const
408 {
409  return d_data->borderPen;
410 }
411 
418 void QwtText::setBackgroundBrush( const QBrush &brush )
419 {
420  d_data->backgroundBrush = brush;
421  setPaintAttribute( PaintBackground );
422 }
423 
429 {
430  return d_data->backgroundBrush;
431 }
432 
443 void QwtText::setPaintAttribute( PaintAttribute attribute, bool on )
444 {
445  if ( on )
446  d_data->paintAttributes |= attribute;
447  else
448  d_data->paintAttributes &= ~attribute;
449 }
450 
460 {
461  return d_data->paintAttributes & attribute;
462 }
463 
472 {
473  if ( on )
474  d_data->layoutAttributes |= attribute;
475  else
476  d_data->layoutAttributes &= ~attribute;
477 }
478 
488 {
489  return d_data->layoutAttributes | attribute;
490 }
491 
499 double QwtText::heightForWidth( double width ) const
500 {
501  return heightForWidth( width, QFont() );
502 }
503 
512 double QwtText::heightForWidth( double width, const QFont &defaultFont ) const
513 {
514  // We want to calculate in screen metrics. So
515  // we need a font that uses screen metrics
516 
517  const QFont font( usedFont( defaultFont ), QApplication::desktop() );
518 
519  double h = 0;
520 
521  if ( d_data->layoutAttributes & MinimumLayout )
522  {
523  double left, right, top, bottom;
524  d_data->textEngine->textMargins( font, d_data->text,
525  left, right, top, bottom );
526 
527  h = d_data->textEngine->heightForWidth(
528  font, d_data->renderFlags, d_data->text,
529  width + left + right );
530 
531  h -= top + bottom;
532  }
533  else
534  {
535  h = d_data->textEngine->heightForWidth(
536  font, d_data->renderFlags, d_data->text, width );
537  }
538 
539  return h;
540 }
541 
547 QSizeF QwtText::textSize() const
548 {
549  return textSize( QFont() );
550 }
551 
558 QSizeF QwtText::textSize( const QFont &defaultFont ) const
559 {
560  // We want to calculate in screen metrics. So
561  // we need a font that uses screen metrics
562 
563  const QFont font( usedFont( defaultFont ), QApplication::desktop() );
564 
565  if ( !d_layoutCache->textSize.isValid()
566  || d_layoutCache->font != font )
567  {
568  d_layoutCache->textSize = d_data->textEngine->textSize(
569  font, d_data->renderFlags, d_data->text );
570  d_layoutCache->font = font;
571  }
572 
573  QSizeF sz = d_layoutCache->textSize;
574 
575  if ( d_data->layoutAttributes & MinimumLayout )
576  {
577  double left, right, top, bottom;
578  d_data->textEngine->textMargins( font, d_data->text,
579  left, right, top, bottom );
580  sz -= QSizeF( left + right, top + bottom );
581  }
582 
583  return sz;
584 }
585 
592 void QwtText::draw( QPainter *painter, const QRectF &rect ) const
593 {
594  if ( d_data->paintAttributes & PaintBackground )
595  {
596  if ( d_data->borderPen != Qt::NoPen ||
597  d_data->backgroundBrush != Qt::NoBrush )
598  {
599  painter->save();
600 
601  painter->setPen( d_data->borderPen );
602  painter->setBrush( d_data->backgroundBrush );
603 
604  if ( d_data->borderRadius == 0 )
605  {
606  QwtPainter::drawRect( painter, rect );
607  }
608  else
609  {
610  painter->setRenderHint( QPainter::Antialiasing, true );
611  painter->drawRoundedRect( rect,
612  d_data->borderRadius, d_data->borderRadius );
613  }
614 
615  painter->restore();
616  }
617  }
618 
619  painter->save();
620 
621  if ( d_data->paintAttributes & PaintUsingTextFont )
622  {
623  painter->setFont( d_data->font );
624  }
625 
626  if ( d_data->paintAttributes & PaintUsingTextColor )
627  {
628  if ( d_data->color.isValid() )
629  painter->setPen( d_data->color );
630  }
631 
632  QRectF expandedRect = rect;
633  if ( d_data->layoutAttributes & MinimumLayout )
634  {
635  // We want to calculate in screen metrics. So
636  // we need a font that uses screen metrics
637 
638  const QFont font( painter->font(), QApplication::desktop() );
639 
640  double left, right, top, bottom;
641  d_data->textEngine->textMargins(
642  font, d_data->text, left, right, top, bottom );
643 
644  expandedRect.setTop( rect.top() - top );
645  expandedRect.setBottom( rect.bottom() + bottom );
646  expandedRect.setLeft( rect.left() - left );
647  expandedRect.setRight( rect.right() + right );
648  }
649 
650  d_data->textEngine->draw( painter, expandedRect,
651  d_data->renderFlags, d_data->text );
652 
653  painter->restore();
654 }
655 
671 const QwtTextEngine *QwtText::textEngine( const QString &text,
672  QwtText::TextFormat format )
673 {
674  return QwtTextEngineDict::dict().textEngine( text, format );
675 }
676 
691  QwtTextEngine *engine )
692 {
693  QwtTextEngineDict::dict().setTextEngine( format, engine );
694 }
695 
705 {
706  return QwtTextEngineDict::dict().textEngine( format );
707 }
708 
710 bool QwtText::isNull() const
711 {
712  return d_data->text.isNull();
713 }
714 
716 bool QwtText::isEmpty() const
717 {
718  return d_data->text.isEmpty();
719 }
720 
QFlags< LayoutAttribute > LayoutAttributes
Layout attributes.
Definition: qwt_text.h:145
virtual bool mightRender(const QString &text) const =0
FMT_INLINE std::basic_string< Char > format(const S &format_str, Args &&...args)
Definition: core.h:2081
QwtText::PaintAttributes paintAttributes
Definition: qwt_text.cpp:157
void setFont(const QFont &)
Definition: qwt_text.cpp:306
QSizeF textSize() const
Definition: qwt_text.cpp:547
lu_byte right
Definition: lparser.c:1229
int renderFlags() const
Definition: qwt_text.cpp:294
void setRenderFlags(int)
Change the render flags.
Definition: qwt_text.cpp:281
void setText(const QString &, QwtText::TextFormat textFormat=AutoText)
Definition: qwt_text.cpp:254
QWT_CONSTEXPR float qwtMaxF(float a, float b)
Definition: qwt_math.h:123
TextFormat
Text format.
Definition: qwt_text.h:64
void setBorderPen(const QPen &)
Definition: qwt_text.cpp:397
lu_byte left
Definition: lparser.c:1228
static const QwtTextEngine * textEngine(const QString &text, QwtText::TextFormat=AutoText)
Definition: qwt_text.cpp:671
Use the Scribe framework (Qt Rich Text) to render the text.
Definition: qwt_text.h:78
bool operator!=(const QwtText &) const
Relational operator.
Definition: qwt_text.cpp:241
QFlags< PaintAttribute > PaintAttributes
Paint attributes.
Definition: qwt_text.h:127
void draw(QPainter *painter, const QRectF &rect) const
Definition: qwt_text.cpp:592
void setColor(const QColor &)
Definition: qwt_text.cpp:342
bool testLayoutAttribute(LayoutAttribute) const
Definition: qwt_text.cpp:487
static void setTextEngine(QwtText::TextFormat, QwtTextEngine *)
Definition: qwt_text.cpp:690
LayoutCache * d_layoutCache
Definition: qwt_text.h:211
const QwtTextEngine * textEngine
Definition: qwt_text.cpp:160
bool testPaintAttribute(PaintAttribute) const
Definition: qwt_text.cpp:459
double heightForWidth(double width) const
Definition: qwt_text.cpp:499
QwtText::LayoutAttributes layoutAttributes
Definition: qwt_text.cpp:158
PaintAttribute
Paint Attributes.
Definition: qwt_text.h:114
double borderRadius() const
Definition: qwt_text.cpp:386
QFont usedFont(const QFont &) const
Definition: qwt_text.cpp:327
bool isEmpty() const
Definition: qwt_text.cpp:716
void setLayoutAttribute(LayoutAttribute, bool on=true)
Definition: qwt_text.cpp:471
QColor color() const
Return the pen color, used for painting the text.
Definition: qwt_text.cpp:349
A class representing a text.
Definition: qwt_text.h:51
A text engine for Qt rich texts.
Abstract base class for rendering text strings.
QString text() const
Definition: qwt_text.cpp:266
bool operator==(const QwtText &) const
Relational operator.
Definition: qwt_text.cpp:227
void setBackgroundBrush(const QBrush &)
Definition: qwt_text.cpp:418
void setPaintAttribute(PaintAttribute, bool on=true)
Definition: qwt_text.cpp:443
QPen borderPen() const
Definition: qwt_text.cpp:407
int top(lua_State *L)
Definition: sol.hpp:10543
static void drawRect(QPainter *, qreal x, qreal y, qreal w, qreal h)
Wrapper for QPainter::drawRect()
~QwtText()
Destructor.
Definition: qwt_text.cpp:212
LayoutAttribute
Layout Attributes The layout attributes affects some aspects of the layout of the text...
Definition: qwt_text.h:133
PrivateData * d_data
Definition: qwt_text.h:208
void setBorderRadius(double)
Definition: qwt_text.cpp:377
QBrush backgroundBrush() const
Definition: qwt_text.cpp:428
QFont font() const
Return the font.
Definition: qwt_text.cpp:313
bool isNull() const
Definition: qwt_text.cpp:710
QColor usedColor(const QColor &) const
Definition: qwt_text.cpp:363
Draw the text as it is, using a QwtPlainTextEngine.
Definition: qwt_text.h:75
A text engine for plain texts.
QwtText & operator=(const QwtText &)
Assignment operator.
Definition: qwt_text.cpp:219


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10