source: ntrip/trunk/BNC/qwt/qwt_text_engine.cpp@ 8474

Last change on this file since 8474 was 8127, checked in by stoecker, 8 years ago

update qwt and qwtpolar, many QT5 fixes (unfinished)

File size: 8.6 KB
Line 
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_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( static_cast<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 = reinterpret_cast<const QRgb *>(
119 img.scanLine( row ) );
120
121 const int w = pm.width();
122 for ( int col = 0; col < w; col++ )
123 {
124 if ( line[col] != white.rgb() )
125 return fm.ascent() - row + 1;
126 }
127 }
128
129 return fm.ascent();
130 }
131
132 mutable QMap<QString, int> d_ascentCache;
133};
134
135//! Constructor
136QwtTextEngine::QwtTextEngine()
137{
138}
139
140//! Destructor
141QwtTextEngine::~QwtTextEngine()
142{
143}
144
145//! Constructor
146QwtPlainTextEngine::QwtPlainTextEngine()
147{
148 d_data = new PrivateData;
149}
150
151//! Destructor
152QwtPlainTextEngine::~QwtPlainTextEngine()
153{
154 delete d_data;
155}
156
157/*!
158 Find the height for a given width
159
160 \param font Font of the text
161 \param flags Bitwise OR of the flags used like in QPainter::drawText
162 \param text Text to be rendered
163 \param width Width
164
165 \return Calculated height
166*/
167double QwtPlainTextEngine::heightForWidth( const QFont& font, int flags,
168 const QString& text, double width ) const
169{
170 const QFontMetricsF fm( font );
171 const QRectF rect = fm.boundingRect(
172 QRectF( 0, 0, width, QWIDGETSIZE_MAX ), flags, text );
173
174 return rect.height();
175}
176
177/*!
178 Returns the size, that is needed to render text
179
180 \param font Font of the text
181 \param flags Bitwise OR of the flags used like in QPainter::drawText
182 \param text Text to be rendered
183
184 \return Calculated size
185*/
186QSizeF QwtPlainTextEngine::textSize( const QFont &font,
187 int flags, const QString& text ) const
188{
189 const QFontMetricsF fm( font );
190 const QRectF rect = fm.boundingRect(
191 QRectF( 0, 0, QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ), flags, text );
192
193 return rect.size();
194}
195
196/*!
197 Return margins around the texts
198
199 \param font Font of the text
200 \param left Return 0
201 \param right Return 0
202 \param top Return value for the top margin
203 \param bottom Return value for the bottom margin
204*/
205void QwtPlainTextEngine::textMargins( const QFont &font, const QString &,
206 double &left, double &right, double &top, double &bottom ) const
207{
208 left = right = top = 0;
209
210 const QFontMetricsF fm( font );
211 top = fm.ascent() - d_data->effectiveAscent( font );
212 bottom = fm.descent();
213}
214
215/*!
216 \brief Draw the text in a clipping rectangle
217
218 A wrapper for QPainter::drawText.
219
220 \param painter Painter
221 \param rect Clipping rectangle
222 \param flags Bitwise OR of the flags used like in QPainter::drawText
223 \param text Text to be rendered
224*/
225void QwtPlainTextEngine::draw( QPainter *painter, const QRectF &rect,
226 int flags, const QString& text ) const
227{
228 QwtPainter::drawText( painter, rect, flags, text );
229}
230
231/*!
232 Test if a string can be rendered by this text engine.
233 \return Always true. All texts can be rendered by QwtPlainTextEngine
234*/
235bool QwtPlainTextEngine::mightRender( const QString & ) const
236{
237 return true;
238}
239
240#ifndef QT_NO_RICHTEXT
241
242//! Constructor
243QwtRichTextEngine::QwtRichTextEngine()
244{
245}
246
247/*!
248 Find the height for a given width
249
250 \param font Font of the text
251 \param flags Bitwise OR of the flags used like in QPainter::drawText()
252 \param text Text to be rendered
253 \param width Width
254
255 \return Calculated height
256*/
257double QwtRichTextEngine::heightForWidth( const QFont& font, int flags,
258 const QString& text, double width ) const
259{
260 QwtRichTextDocument doc( text, flags, font );
261
262 doc.setPageSize( QSizeF( width, QWIDGETSIZE_MAX ) );
263 return doc.documentLayout()->documentSize().height();
264}
265
266/*!
267 Returns the size, that is needed to render text
268
269 \param font Font of the text
270 \param flags Bitwise OR of the flags used like in QPainter::drawText()
271 \param text Text to be rendered
272
273 \return Calculated size
274*/
275
276QSizeF QwtRichTextEngine::textSize( const QFont &font,
277 int flags, const QString& text ) const
278{
279 QwtRichTextDocument doc( text, flags, font );
280
281 QTextOption option = doc.defaultTextOption();
282 if ( option.wrapMode() != QTextOption::NoWrap )
283 {
284 option.setWrapMode( QTextOption::NoWrap );
285 doc.setDefaultTextOption( option );
286 doc.adjustSize();
287 }
288
289 return doc.size();
290}
291
292/*!
293 Draw the text in a clipping rectangle
294
295 \param painter Painter
296 \param rect Clipping rectangle
297 \param flags Bitwise OR of the flags like in for QPainter::drawText()
298 \param text Text to be rendered
299*/
300void QwtRichTextEngine::draw( QPainter *painter, const QRectF &rect,
301 int flags, const QString& text ) const
302{
303 QwtRichTextDocument doc( text, flags, painter->font() );
304 QwtPainter::drawSimpleRichText( painter, rect, flags, doc );
305}
306
307/*!
308 Wrap text into <div align=...> </div> tags according flags
309
310 \param text Text
311 \param flags Bitwise OR of the flags like in for QPainter::drawText()
312
313 \return Tagged text
314*/
315QString QwtRichTextEngine::taggedText( const QString &text, int flags ) const
316{
317 return taggedRichText( text, flags );
318}
319
320/*!
321 Test if a string can be rendered by this text engine
322
323 \param text Text to be tested
324 \return Qt::mightBeRichText(text);
325*/
326bool QwtRichTextEngine::mightRender( const QString &text ) const
327{
328 return Qt::mightBeRichText( text );
329}
330
331/*!
332 Return margins around the texts
333
334 \param left Return 0
335 \param right Return 0
336 \param top Return 0
337 \param bottom Return 0
338*/
339void QwtRichTextEngine::textMargins( const QFont &, const QString &,
340 double &left, double &right, double &top, double &bottom ) const
341{
342 left = right = top = bottom = 0;
343}
344
345#endif // !QT_NO_RICHTEXT
Note: See TracBrowser for help on using the repository browser.