Qwt User's Guide: qwt_text_engine.cpp Source File

Qwt User's Guide 6.2.0

qwt_text_engine.cpp
1 /******************************************************************************
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_engine.h"
11 #include "qwt_painter.h"
12
13 #include <qpainter.h>
14 #include <qpixmap.h>
15 #include <qimage.h>
16 #include <qmap.h>
17 #include <qwidget.h>
18 #include <qtextobject.h>
19 #include <qtextdocument.h>
20 #include <qabstracttextdocumentlayout.h>
21
22 static QString taggedRichText( const QString& text, int flags )
23 {
24 QString richText = text;
25
26 // By default QSimpleRichText is Qt::AlignLeft
27 if ( flags & Qt::AlignJustify )
28 {
29 richText.prepend( QLatin1String( "<div align=\"justify\">" ) );
30 richText.append( QLatin1String ( "</div>" ) );
31 }
32 else if ( flags & Qt::AlignRight )
33 {
34 richText.prepend( QLatin1String ( "<div align=\"right\">" ) );
35 richText.append( QLatin1String ( "</div>" ) );
36 }
37 else if ( flags & Qt::AlignHCenter )
38 {
39 richText.prepend( QLatin1String ( "<div align=\"center\">" ) );
40 richText.append( QLatin1String ( "</div>" ) );
41 }
42
43 return richText;
44 }
45
46 namespace
47 {
48 class QwtRichTextDocument : public QTextDocument
49 {
50 public:
51 QwtRichTextDocument( const QString& text, int flags, const QFont& font )
52 {
53 setUndoRedoEnabled( false );
54 setDefaultFont( font );
55 setHtml( text );
56
57 // make sure we have a document layout
58 ( void )documentLayout();
59
60 QTextOption option = defaultTextOption();
61 if ( flags & Qt::TextWordWrap )
62 option.setWrapMode( QTextOption::WordWrap );
63 else
64 option.setWrapMode( QTextOption::NoWrap );
65
66 option.setAlignment( static_cast< Qt::Alignment >( flags ) );
67 setDefaultTextOption( option );
68
69 QTextFrame* root = rootFrame();
70 QTextFrameFormat fm = root->frameFormat();
71 fm.setBorder( 0 );
72 fm.setMargin( 0 );
73 fm.setPadding( 0 );
74 fm.setBottomMargin( 0 );
75 fm.setLeftMargin( 0 );
76 root->setFrameFormat( fm );
77
78 adjustSize();
79 }
80 };
81 }
82
83 class QwtPlainTextEngine::PrivateData
84 {
85 public:
86 int effectiveAscent( const QFont& font ) const
87 {
88 const QString fontKey = font.key();
89
90 QMap< QString, int >::const_iterator it =
91 m_ascentCache.constFind( fontKey );
92
93 if ( it != m_ascentCache.constEnd() )
94 return *it;
95
96 const int ascent = findAscent( font );
97 m_ascentCache.insert( fontKey, ascent );
98
99 return ascent;
100 }
101
102 private:
103 static int findAscent( const QFont& font )
104 {
105 static const QString dummy( "E" );
106 static const QColor white( Qt::white );
107
108 const QFontMetrics fm( font );
109
110 QPixmap pm( QwtPainter::horizontalAdvance( fm, dummy ), fm.height() );
111 pm.fill( white );
112
113 QPainter p( &pm );
114 p.setFont( font );
115 p.drawText( 0, 0, pm.width(), pm.height(), 0, dummy );
116 p.end();
117
118 const QImage img = pm.toImage();
119
120 int row = 0;
121 for ( row = 0; row < img.height(); row++ )
122 {
123 const QRgb* line = reinterpret_cast< const QRgb* >(
124 img.scanLine( row ) );
125
126 const int w = pm.width();
127 for ( int col = 0; col < w; col++ )
128 {
129 if ( line[col] != white.rgb() )
130 return fm.ascent() - row + 1;
131 }
132 }
133
134 return fm.ascent();
135 }
136
137 mutable QMap< QString, int > m_ascentCache;
138 };
139
141 QwtTextEngine::QwtTextEngine()
142 {
143 }
144
146 QwtTextEngine::~QwtTextEngine()
147 {
148 }
149
151 QwtPlainTextEngine::QwtPlainTextEngine()
152 {
153 m_data = new PrivateData;
154 }
155
157 QwtPlainTextEngine::~QwtPlainTextEngine()
158 {
159 delete m_data;
160 }
161
172 double QwtPlainTextEngine::heightForWidth( const QFont& font, int flags,
173 const QString& text, double width ) const
174 {
175 const QFontMetricsF fm( font );
176 const QRectF rect = fm.boundingRect(
177 QRectF( 0, 0, width, QWIDGETSIZE_MAX ), flags, text );
178
179 return rect.height();
180 }
181
191 QSizeF QwtPlainTextEngine::textSize( const QFont& font,
192 int flags, const QString& text ) const
193 {
194 const QFontMetricsF fm( font );
195 const QRectF rect = fm.boundingRect(
196 QRectF( 0, 0, QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ), flags, text );
197
198 return rect.size();
199 }
200
210 void QwtPlainTextEngine::textMargins( const QFont& font, const QString&,
211 double& left, double& right, double& top, double& bottom ) const
212 {
213 left = right = top = 0;
214
215 const QFontMetricsF fm( font );
216 top = fm.ascent() - m_data->effectiveAscent( font );
217 bottom = fm.descent();
218 }
219
230 void QwtPlainTextEngine::draw( QPainter* painter, const QRectF& rect,
231 int flags, const QString& text ) const
232 {
233 QwtPainter::drawText( painter, rect, flags, text );
234 }
235
240 bool QwtPlainTextEngine::mightRender( const QString& ) const
241 {
242 return true;
243 }
244
245 #ifndef QT_NO_RICHTEXT
246
248 QwtRichTextEngine::QwtRichTextEngine()
249 {
250 }
251
262 double QwtRichTextEngine::heightForWidth( const QFont& font, int flags,
263 const QString& text, double width ) const
264 {
265 QwtRichTextDocument doc( text, flags, font );
266
267 doc.setPageSize( QSizeF( width, QWIDGETSIZE_MAX ) );
268 return doc.documentLayout()->documentSize().height();
269 }
270
281 QSizeF QwtRichTextEngine::textSize( const QFont& font,
282 int flags, const QString& text ) const
283 {
284 QwtRichTextDocument doc( text, flags, font );
285
286 QTextOption option = doc.defaultTextOption();
287 if ( option.wrapMode() != QTextOption::NoWrap )
288 {
289 option.setWrapMode( QTextOption::NoWrap );
290 doc.setDefaultTextOption( option );
291 doc.adjustSize();
292 }
293
294 return doc.size();
295 }
296
305 void QwtRichTextEngine::draw( QPainter* painter, const QRectF& rect,
306 int flags, const QString& text ) const
307 {
308 QwtRichTextDocument doc( text, flags, painter->font() );
309 QwtPainter::drawSimpleRichText( painter, rect, flags, doc );
310 }
311
320 QString QwtRichTextEngine::taggedText( const QString& text, int flags ) const
321 {
322 return taggedRichText( text, flags );
323 }
324
331 bool QwtRichTextEngine::mightRender( const QString& text ) const
332 {
333 return Qt::mightBeRichText( text );
334 }
335
344 void QwtRichTextEngine::textMargins( const QFont&, const QString&,
345 double& left, double& right, double& top, double& bottom ) const
346 {
347 left = right = top = bottom = 0;
348 }
349
350 #endif // !QT_NO_RICHTEXT
QMap
Definition: qwt_compass.h:19
QwtPainter::drawSimpleRichText
static void drawSimpleRichText(QPainter *, const QRectF &, int flags, const QTextDocument &)
Definition: qwt_painter.cpp:489
QwtPainter::drawText
static void drawText(QPainter *, qreal x, qreal y, const QString &)
Wrapper for QPainter::drawText()
Definition: qwt_painter.cpp:438
QwtPainter::horizontalAdvance
static int horizontalAdvance(const QFontMetrics &, const QString &)
Definition: qwt_painter.cpp:1379
QwtPlainTextEngine::heightForWidth
virtual double heightForWidth(const QFont &font, int flags, const QString &text, double width) const override
Definition: qwt_text_engine.cpp:172
QwtPlainTextEngine::QwtPlainTextEngine
QwtPlainTextEngine()
Constructor.
Definition: qwt_text_engine.cpp:151
QwtPlainTextEngine::~QwtPlainTextEngine
virtual ~QwtPlainTextEngine()
Destructor.
Definition: qwt_text_engine.cpp:157
QwtPlainTextEngine::textMargins
virtual void textMargins(const QFont &, const QString &, double &left, double &right, double &top, double &bottom) const override
Definition: qwt_text_engine.cpp:210
QwtPlainTextEngine::textSize
virtual QSizeF textSize(const QFont &font, int flags, const QString &text) const override
Definition: qwt_text_engine.cpp:191
QwtPlainTextEngine::draw
virtual void draw(QPainter *, const QRectF &rect, int flags, const QString &text) const override
Draw the text in a clipping rectangle.
Definition: qwt_text_engine.cpp:230
QwtPlainTextEngine::mightRender
virtual bool mightRender(const QString &) const override
Definition: qwt_text_engine.cpp:240
QwtRichTextEngine::textSize
virtual QSizeF textSize(const QFont &font, int flags, const QString &text) const override
Definition: qwt_text_engine.cpp:281
QwtRichTextEngine::textMargins
virtual void textMargins(const QFont &, const QString &, double &left, double &right, double &top, double &bottom) const override
Definition: qwt_text_engine.cpp:344
QwtRichTextEngine::mightRender
virtual bool mightRender(const QString &) const override
Definition: qwt_text_engine.cpp:331
QwtRichTextEngine::heightForWidth
virtual double heightForWidth(const QFont &font, int flags, const QString &text, double width) const override
Definition: qwt_text_engine.cpp:262
QwtRichTextEngine::QwtRichTextEngine
QwtRichTextEngine()
Constructor.
Definition: qwt_text_engine.cpp:248
QwtRichTextEngine::draw
virtual void draw(QPainter *, const QRectF &rect, int flags, const QString &text) const override
Definition: qwt_text_engine.cpp:305
QwtTextEngine::QwtTextEngine
QwtTextEngine()
Constructor.
Definition: qwt_text_engine.cpp:141
QwtTextEngine::~QwtTextEngine
virtual ~QwtTextEngine()
Destructor.
Definition: qwt_text_engine.cpp:146