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

Last change on this file since 10111 was 9383, checked in by stoecker, 4 years ago

update to qwt verion 6.1.1 to fix build with newer Qt5

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