source: ntrip/trunk/GnssCenter/qwt/qwt_text_engine.cpp@ 5290

Last change on this file since 5290 was 4839, checked in by mervart, 12 years ago
File size: 8.5 KB
Line 
1/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2003 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_math.h"
12#include "qwt_painter.h"
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
22static 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( QString::fromLatin1( "<div align=\"justify\">" ) );
30 richText.append( QString::fromLatin1( "</div>" ) );
31 }
32 else if ( flags & Qt::AlignRight )
33 {
34 richText.prepend( QString::fromLatin1( "<div align=\"right\">" ) );
35 richText.append( QString::fromLatin1( "</div>" ) );
36 }
37 else if ( flags & Qt::AlignHCenter )
38 {
39 richText.prepend( QString::fromLatin1( "<div align=\"center\">" ) );
40 richText.append( QString::fromLatin1( "</div>" ) );
41 }
42
43 return richText;
44}
45
46class QwtRichTextDocument: public QTextDocument
47{
48public:
49 QwtRichTextDocument( const QString &text, int flags, const QFont &font )
50 {
51 setUndoRedoEnabled( false );
52 setDefaultFont( font );
53 setHtml( text );
54
55 // make sure we have a document layout
56 ( void )documentLayout();
57
58 QTextOption option = defaultTextOption();
59 if ( flags & Qt::TextWordWrap )
60 option.setWrapMode( QTextOption::WordWrap );
61 else
62 option.setWrapMode( QTextOption::NoWrap );
63
64 option.setAlignment( ( Qt::Alignment ) flags );
65 setDefaultTextOption( option );
66
67 QTextFrame *root = rootFrame();
68 QTextFrameFormat fm = root->frameFormat();
69 fm.setBorder( 0 );
70 fm.setMargin( 0 );
71 fm.setPadding( 0 );
72 fm.setBottomMargin( 0 );
73 fm.setLeftMargin( 0 );
74 root->setFrameFormat( fm );
75
76 adjustSize();
77 }
78};
79
80class QwtPlainTextEngine::PrivateData
81{
82public:
83 int effectiveAscent( const QFont &font ) const
84 {
85 const QString fontKey = font.key();
86
87 QMap<QString, int>::const_iterator it =
88 d_ascentCache.find( fontKey );
89 if ( it == d_ascentCache.end() )
90 {
91 int ascent = findAscent( font );
92 it = d_ascentCache.insert( fontKey, ascent );
93 }
94
95 return ( *it );
96 }
97
98private:
99 int findAscent( const QFont &font ) const
100 {
101 static const QString dummy( "E" );
102 static const QColor white( Qt::white );
103
104 const QFontMetrics fm( font );
105 QPixmap pm( fm.width( dummy ), fm.height() );
106 pm.fill( white );
107
108 QPainter p( &pm );
109 p.setFont( font );
110 p.drawText( 0, 0, pm.width(), pm.height(), 0, dummy );
111 p.end();
112
113 const QImage img = pm.toImage();
114
115 int row = 0;
116 for ( row = 0; row < img.height(); row++ )
117 {
118 const QRgb *line = ( const QRgb * )img.scanLine( row );
119
120 const int w = pm.width();
121 for ( int col = 0; col < w; col++ )
122 {
123 if ( line[col] != white.rgb() )
124 return fm.ascent() - row + 1;
125 }
126 }
127
128 return fm.ascent();
129 }
130
131 mutable QMap<QString, int> d_ascentCache;
132};
133
134//! Constructor
135QwtTextEngine::QwtTextEngine()
136{
137}
138
139//! Destructor
140QwtTextEngine::~QwtTextEngine()
141{
142}
143
144//! Constructor
145QwtPlainTextEngine::QwtPlainTextEngine()
146{
147 d_data = new PrivateData;
148}
149
150//! Destructor
151QwtPlainTextEngine::~QwtPlainTextEngine()
152{
153 delete d_data;
154}
155
156/*!
157 Find the height for a given width
158
159 \param font Font of the text
160 \param flags Bitwise OR of the flags used like in QPainter::drawText
161 \param text Text to be rendered
162 \param width Width
163
164 \return Calculated height
165*/
166double QwtPlainTextEngine::heightForWidth( const QFont& font, int flags,
167 const QString& text, double width ) const
168{
169 const QFontMetricsF fm( font );
170 const QRectF rect = fm.boundingRect(
171 QRectF( 0, 0, width, QWIDGETSIZE_MAX ), flags, text );
172
173 return rect.height();
174}
175
176/*!
177 Returns the size, that is needed to render text
178
179 \param font Font of the text
180 \param flags Bitwise OR of the flags used like in QPainter::drawText
181 \param text Text to be rendered
182
183 \return Caluclated size
184*/
185QSizeF QwtPlainTextEngine::textSize( const QFont &font,
186 int flags, const QString& text ) const
187{
188 const QFontMetricsF fm( font );
189 const QRectF rect = fm.boundingRect(
190 QRectF( 0, 0, QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ), flags, text );
191
192 return rect.size();
193}
194
195/*!
196 Return margins around the texts
197
198 \param font Font of the text
199 \param left Return 0
200 \param right Return 0
201 \param top Return value for the top margin
202 \param bottom Return value for the bottom margin
203*/
204void QwtPlainTextEngine::textMargins( const QFont &font, const QString &,
205 double &left, double &right, double &top, double &bottom ) const
206{
207 left = right = top = 0;
208
209 const QFontMetricsF fm( font );
210 top = fm.ascent() - d_data->effectiveAscent( font );
211 bottom = fm.descent();
212}
213
214/*!
215 \brief Draw the text in a clipping rectangle
216
217 A wrapper for QPainter::drawText.
218
219 \param painter Painter
220 \param rect Clipping rectangle
221 \param flags Bitwise OR of the flags used like in QPainter::drawText
222 \param text Text to be rendered
223*/
224void QwtPlainTextEngine::draw( QPainter *painter, const QRectF &rect,
225 int flags, const QString& text ) const
226{
227 QwtPainter::drawText( painter, rect, flags, text );
228}
229
230/*!
231 Test if a string can be rendered by this text engine.
232 \return Always true. All texts can be rendered by QwtPlainTextEngine
233*/
234bool QwtPlainTextEngine::mightRender( const QString & ) const
235{
236 return true;
237}
238
239#ifndef QT_NO_RICHTEXT
240
241//! Constructor
242QwtRichTextEngine::QwtRichTextEngine()
243{
244}
245
246/*!
247 Find the height for a given width
248
249 \param font Font of the text
250 \param flags Bitwise OR of the flags used like in QPainter::drawText
251 \param text Text to be rendered
252 \param width Width
253
254 \return Calculated height
255*/
256double QwtRichTextEngine::heightForWidth( const QFont& font, int flags,
257 const QString& text, double width ) const
258{
259 QwtRichTextDocument doc( text, flags, font );
260
261 doc.setPageSize( QSizeF( width, QWIDGETSIZE_MAX ) );
262 return doc.documentLayout()->documentSize().height();
263}
264
265/*!
266 Returns the size, that is needed to render text
267
268 \param font Font of the text
269 \param flags Bitwise OR of the flags used like in QPainter::drawText
270 \param text Text to be rendered
271
272 \return Caluclated size
273*/
274
275QSizeF QwtRichTextEngine::textSize( const QFont &font,
276 int flags, const QString& text ) const
277{
278 QwtRichTextDocument doc( text, flags, font );
279
280 QTextOption option = doc.defaultTextOption();
281 if ( option.wrapMode() != QTextOption::NoWrap )
282 {
283 option.setWrapMode( QTextOption::NoWrap );
284 doc.setDefaultTextOption( option );
285 doc.adjustSize();
286 }
287
288 return doc.size();
289}
290
291/*!
292 Draw the text in a clipping rectangle
293
294 \param painter Painter
295 \param rect Clipping rectangle
296 \param flags Bitwise OR of the flags like in for QPainter::drawText
297 \param text Text to be rendered
298*/
299void QwtRichTextEngine::draw( QPainter *painter, const QRectF &rect,
300 int flags, const QString& text ) const
301{
302 QwtRichTextDocument doc( text, flags, painter->font() );
303 QwtPainter::drawSimpleRichText( painter, rect, flags, doc );
304}
305
306/*!
307 Wrap text into <div align=...> </div> tags according flags
308
309 \param text Text
310 \param flags Bitwise OR of the flags like in for QPainter::drawText
311
312 \return Tagged text
313*/
314QString QwtRichTextEngine::taggedText( const QString &text, int flags ) const
315{
316 return taggedRichText( text, flags );
317}
318
319/*!
320 Test if a string can be rendered by this text engine
321
322 \param text Text to be tested
323 \return QStyleSheet::mightBeRichText(text);
324*/
325bool QwtRichTextEngine::mightRender( const QString &text ) const
326{
327 return Qt::mightBeRichText( text );
328}
329
330/*!
331 Return margins around the texts
332
333 \param left Return 0
334 \param right Return 0
335 \param top Return 0
336 \param bottom Return 0
337*/
338void QwtRichTextEngine::textMargins( const QFont &, const QString &,
339 double &left, double &right, double &top, double &bottom ) const
340{
341 left = right = top = bottom = 0;
342}
343
344#endif // !QT_NO_RICHTEXT
Note: See TracBrowser for help on using the repository browser.