qwt_text.cpp 15.6 KB
Newer Older
pixhawk's avatar
pixhawk committed
1
2
3
4
5
6
7
8
9
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2003   Uwe Rathmann
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

Bryant's avatar
Bryant committed
10
11
12
#include "qwt_text.h"
#include "qwt_painter.h"
#include "qwt_text_engine.h"
pixhawk's avatar
pixhawk committed
13
14
15
16
17
18
19
20
#include <qmap.h>
#include <qfont.h>
#include <qcolor.h>
#include <qpen.h>
#include <qbrush.h>
#include <qpainter.h>
#include <qapplication.h>
#include <qdesktopwidget.h>
Bryant's avatar
Bryant committed
21
#include <qmath.h>
pixhawk's avatar
pixhawk committed
22
23
24
25

class QwtTextEngineDict
{
public:
Bryant's avatar
Bryant committed
26
    static QwtTextEngineDict &dict();
pixhawk's avatar
pixhawk committed
27

Bryant's avatar
Bryant committed
28
29
30
31
32
    void setTextEngine( QwtText::TextFormat, QwtTextEngine * );

    const QwtTextEngine *textEngine( QwtText::TextFormat ) const;
    const QwtTextEngine *textEngine( const QString &,
        QwtText::TextFormat ) const;
pixhawk's avatar
pixhawk committed
33
34

private:
Bryant's avatar
Bryant committed
35
36
37
    QwtTextEngineDict();
    ~QwtTextEngineDict();

pixhawk's avatar
pixhawk committed
38
39
    typedef QMap<int, QwtTextEngine *> EngineMap;

Bryant's avatar
Bryant committed
40
41
    inline const QwtTextEngine *engine( EngineMap::const_iterator &it ) const
    {
pixhawk's avatar
pixhawk committed
42
43
44
45
46
47
        return it.value();
    }

    EngineMap d_map;
};

Bryant's avatar
Bryant committed
48
49
50
51
52
53
QwtTextEngineDict &QwtTextEngineDict::dict()
{
    static QwtTextEngineDict engineDict;
    return engineDict;
}

pixhawk's avatar
pixhawk committed
54
55
QwtTextEngineDict::QwtTextEngineDict()
{
Bryant's avatar
Bryant committed
56
    d_map.insert( QwtText::PlainText, new QwtPlainTextEngine() );
pixhawk's avatar
pixhawk committed
57
#ifndef QT_NO_RICHTEXT
Bryant's avatar
Bryant committed
58
    d_map.insert( QwtText::RichText, new QwtRichTextEngine() );
pixhawk's avatar
pixhawk committed
59
60
61
62
63
#endif
}

QwtTextEngineDict::~QwtTextEngineDict()
{
64
    for ( EngineMap::const_iterator it = d_map.begin();
Bryant's avatar
Bryant committed
65
66
67
        it != d_map.end(); ++it )
    {
        const QwtTextEngine *textEngine = engine( it );
pixhawk's avatar
pixhawk committed
68
69
70
71
        delete textEngine;
    }
}

Bryant's avatar
Bryant committed
72
73
const QwtTextEngine *QwtTextEngineDict::textEngine( const QString& text,
    QwtText::TextFormat format ) const
pixhawk's avatar
pixhawk committed
74
{
Bryant's avatar
Bryant committed
75
76
    if ( format == QwtText::AutoText )
    {
77
        for ( EngineMap::const_iterator it = d_map.begin();
Bryant's avatar
Bryant committed
78
79
80
81
82
83
84
            it != d_map.end(); ++it )
        {
            if ( it.key() != QwtText::PlainText )
            {
                const QwtTextEngine *e = engine( it );
                if ( e && e->mightRender( text ) )
                    return e;
pixhawk's avatar
pixhawk committed
85
86
87
88
            }
        }
    }

Bryant's avatar
Bryant committed
89
90
91
92
    EngineMap::const_iterator it = d_map.find( format );
    if ( it != d_map.end() )
    {
        const QwtTextEngine *e = engine( it );
pixhawk's avatar
pixhawk committed
93
94
95
96
        if ( e )
            return e;
    }

Bryant's avatar
Bryant committed
97
98
    it = d_map.find( QwtText::PlainText );
    return engine( it );
pixhawk's avatar
pixhawk committed
99
100
}

Bryant's avatar
Bryant committed
101
102
void QwtTextEngineDict::setTextEngine( QwtText::TextFormat format,
    QwtTextEngine *engine )
pixhawk's avatar
pixhawk committed
103
104
105
106
107
108
109
{
    if ( format == QwtText::AutoText )
        return;

    if ( format == QwtText::PlainText && engine == NULL )
        return;

Bryant's avatar
Bryant committed
110
111
112
113
    EngineMap::const_iterator it = d_map.find( format );
    if ( it != d_map.end() )
    {
        const QwtTextEngine *e = this->engine( it );
pixhawk's avatar
pixhawk committed
114
115
116
        if ( e )
            delete e;

Bryant's avatar
Bryant committed
117
        d_map.remove( format );
pixhawk's avatar
pixhawk committed
118
119
120
    }

    if ( engine != NULL )
Bryant's avatar
Bryant committed
121
        d_map.insert( format, engine );
pixhawk's avatar
pixhawk committed
122
123
124
}

const QwtTextEngine *QwtTextEngineDict::textEngine(
Bryant's avatar
Bryant committed
125
    QwtText::TextFormat format ) const
pixhawk's avatar
pixhawk committed
126
127
128
{
    const QwtTextEngine *e = NULL;

Bryant's avatar
Bryant committed
129
    EngineMap::const_iterator it = d_map.find( format );
pixhawk's avatar
pixhawk committed
130
    if ( it != d_map.end() )
Bryant's avatar
Bryant committed
131
        e = engine( it );
pixhawk's avatar
pixhawk committed
132
133
134
135
136
137
138
139

    return e;
}

class QwtText::PrivateData
{
public:
    PrivateData():
Bryant's avatar
Bryant committed
140
141
142
143
144
145
146
147
        renderFlags( Qt::AlignCenter ),
        borderRadius( 0 ),
        borderPen( Qt::NoPen ),
        backgroundBrush( Qt::NoBrush ),
        paintAttributes( 0 ),
        layoutAttributes( 0 ),
        textEngine( NULL )
    {
pixhawk's avatar
pixhawk committed
148
149
150
151
152
153
    }

    int renderFlags;
    QString text;
    QFont font;
    QColor color;
Bryant's avatar
Bryant committed
154
155
    double borderRadius;
    QPen borderPen;
pixhawk's avatar
pixhawk committed
156
157
    QBrush backgroundBrush;

Bryant's avatar
Bryant committed
158
159
    QwtText::PaintAttributes paintAttributes;
    QwtText::LayoutAttributes layoutAttributes;
pixhawk's avatar
pixhawk committed
160
161
162
163
164
165
166

    const QwtTextEngine *textEngine;
};

class QwtText::LayoutCache
{
public:
Bryant's avatar
Bryant committed
167
168
169
    void invalidate()
    {
        textSize = QSizeF();
pixhawk's avatar
pixhawk committed
170
171
172
    }

    QFont font;
Bryant's avatar
Bryant committed
173
    QSizeF textSize;
pixhawk's avatar
pixhawk committed
174
175
176
177
178
179
180
181
};

/*!
   Constructor

   \param text Text content
   \param textFormat Text format
*/
Bryant's avatar
Bryant committed
182
QwtText::QwtText( const QString &text, QwtText::TextFormat textFormat )
pixhawk's avatar
pixhawk committed
183
184
185
{
    d_data = new PrivateData;
    d_data->text = text;
Bryant's avatar
Bryant committed
186
    d_data->textEngine = textEngine( text, textFormat );
pixhawk's avatar
pixhawk committed
187
188
189
190
191

    d_layoutCache = new LayoutCache;
}

//! Copy constructor
Bryant's avatar
Bryant committed
192
QwtText::QwtText( const QwtText &other )
pixhawk's avatar
pixhawk committed
193
194
195
196
197
198
199
200
201
{
    d_data = new PrivateData;
    *d_data = *other.d_data;

    d_layoutCache = new LayoutCache;
    *d_layoutCache = *other.d_layoutCache;
}

//! Destructor
202
QwtText::~QwtText()
pixhawk's avatar
pixhawk committed
203
204
205
206
207
{
    delete d_data;
    delete d_layoutCache;
}

Bryant's avatar
Bryant committed
208
209
//! Assignment operator
QwtText &QwtText::operator=( const QwtText & other )
pixhawk's avatar
pixhawk committed
210
211
212
213
214
{
    *d_data = *other.d_data;
    *d_layoutCache = *other.d_layoutCache;
    return *this;
}
215

Bryant's avatar
Bryant committed
216
217
//! Relational operator
bool QwtText::operator==( const QwtText &other ) const
pixhawk's avatar
pixhawk committed
218
219
{
    return d_data->renderFlags == other.d_data->renderFlags &&
Bryant's avatar
Bryant committed
220
221
222
223
224
225
226
227
        d_data->text == other.d_data->text &&
        d_data->font == other.d_data->font &&
        d_data->color == other.d_data->color &&
        d_data->borderRadius == other.d_data->borderRadius &&
        d_data->borderPen == other.d_data->borderPen &&
        d_data->backgroundBrush == other.d_data->backgroundBrush &&
        d_data->paintAttributes == other.d_data->paintAttributes &&
        d_data->textEngine == other.d_data->textEngine;
pixhawk's avatar
pixhawk committed
228
229
}

Bryant's avatar
Bryant committed
230
231
//! Relational operator
bool QwtText::operator!=( const QwtText &other ) const // invalidate
pixhawk's avatar
pixhawk committed
232
{
Bryant's avatar
Bryant committed
233
    return !( other == *this );
pixhawk's avatar
pixhawk committed
234
235
236
237
238
239
240
}

/*!
   Assign a new text content

   \param text Text content
   \param textFormat Text format
Bryant's avatar
Bryant committed
241
242

   \sa text()
pixhawk's avatar
pixhawk committed
243
*/
Bryant's avatar
Bryant committed
244
245
void QwtText::setText( const QString &text,
    QwtText::TextFormat textFormat )
246
247
{
    d_data->text = text;
Bryant's avatar
Bryant committed
248
    d_data->textEngine = textEngine( text, textFormat );
pixhawk's avatar
pixhawk committed
249
250
251
    d_layoutCache->invalidate();
}

252
/*!
Bryant's avatar
Bryant committed
253
254
   \return Text as QString.
   \sa setText()
pixhawk's avatar
pixhawk committed
255
*/
256
257
258
QString QwtText::text() const
{
    return d_data->text;
pixhawk's avatar
pixhawk committed
259
260
261
262
263
264
265
}

/*!
   \brief Change the render flags

   The default setting is Qt::AlignCenter

Bryant's avatar
Bryant committed
266
   \param renderFlags Bitwise OR of the flags used like in QPainter::drawText()
pixhawk's avatar
pixhawk committed
267

Bryant's avatar
Bryant committed
268
   \sa renderFlags(), QwtTextEngine::draw()
pixhawk's avatar
pixhawk committed
269
270
   \note Some renderFlags might have no effect, depending on the text format.
*/
Bryant's avatar
Bryant committed
271
void QwtText::setRenderFlags( int renderFlags )
272
{
Bryant's avatar
Bryant committed
273
274
    if ( renderFlags != d_data->renderFlags )
    {
275
        d_data->renderFlags = renderFlags;
pixhawk's avatar
pixhawk committed
276
277
278
279
280
281
        d_layoutCache->invalidate();
    }
}

/*!
   \return Render flags
Bryant's avatar
Bryant committed
282
   \sa setRenderFlags()
pixhawk's avatar
pixhawk committed
283
*/
284
285
286
int QwtText::renderFlags() const
{
    return d_data->renderFlags;
pixhawk's avatar
pixhawk committed
287
288
}

289
/*!
pixhawk's avatar
pixhawk committed
290
291
292
293
294
295
   Set the font.

   \param font Font
   \note Setting the font might have no effect, when
         the text contains control sequences for setting fonts.
*/
Bryant's avatar
Bryant committed
296
void QwtText::setFont( const QFont &font )
pixhawk's avatar
pixhawk committed
297
{
298
    d_data->font = font;
Bryant's avatar
Bryant committed
299
    setPaintAttribute( PaintUsingTextFont );
pixhawk's avatar
pixhawk committed
300
301
302
}

//! Return the font.
303
304
305
QFont QwtText::font() const
{
    return d_data->font;
pixhawk's avatar
pixhawk committed
306
307
308
}

/*!
Bryant's avatar
Bryant committed
309
310
311
312
313
   Return the font of the text, if it has one.
   Otherwise return defaultFont.

   \param defaultFont Default font
   \return Font used for drawing the text
pixhawk's avatar
pixhawk committed
314

Bryant's avatar
Bryant committed
315
   \sa setFont(), font(), PaintAttributes
pixhawk's avatar
pixhawk committed
316
*/
Bryant's avatar
Bryant committed
317
QFont QwtText::usedFont( const QFont &defaultFont ) const
pixhawk's avatar
pixhawk committed
318
319
320
321
322
323
324
{
    if ( d_data->paintAttributes & PaintUsingTextFont )
        return d_data->font;

    return defaultFont;
}

325
/*!
Bryant's avatar
Bryant committed
326
   Set the pen color used for drawing the text.
pixhawk's avatar
pixhawk committed
327
328
329
330
331

   \param color Color
   \note Setting the color might have no effect, when
         the text contains control sequences for setting colors.
*/
Bryant's avatar
Bryant committed
332
void QwtText::setColor( const QColor &color )
333
334
{
    d_data->color = color;
Bryant's avatar
Bryant committed
335
    setPaintAttribute( PaintUsingTextColor );
pixhawk's avatar
pixhawk committed
336
337
338
}

//! Return the pen color, used for painting the text
339
340
341
QColor QwtText::color() const
{
    return d_data->color;
pixhawk's avatar
pixhawk committed
342
343
344
}

/*!
345
  Return the color of the text, if it has one.
pixhawk's avatar
pixhawk committed
346
347
348
  Otherwise return defaultColor.

  \param defaultColor Default color
Bryant's avatar
Bryant committed
349
350
351
  \return Color used for drawing the text

  \sa setColor(), color(), PaintAttributes
pixhawk's avatar
pixhawk committed
352
*/
Bryant's avatar
Bryant committed
353
QColor QwtText::usedColor( const QColor &defaultColor ) const
pixhawk's avatar
pixhawk committed
354
355
356
357
358
359
360
{
    if ( d_data->paintAttributes & PaintUsingTextColor )
        return d_data->color;

    return defaultColor;
}

Bryant's avatar
Bryant committed
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
/*!
  Set the radius for the corners of the border frame

  \param radius Radius of a rounded corner
  \sa borderRadius(), setBorderPen(), setBackgroundBrush()
*/
void QwtText::setBorderRadius( double radius )
{
    d_data->borderRadius = qMax( 0.0, radius );
}

/*!
  \return Radius for the corners of the border frame
  \sa setBorderRadius(), borderPen(), backgroundBrush()
*/
double QwtText::borderRadius() const
{
    return d_data->borderRadius;
}

pixhawk's avatar
pixhawk committed
381
382
383
384
/*!
   Set the background pen

   \param pen Background pen
Bryant's avatar
Bryant committed
385
   \sa borderPen(), setBackgroundBrush()
pixhawk's avatar
pixhawk committed
386
*/
Bryant's avatar
Bryant committed
387
void QwtText::setBorderPen( const QPen &pen )
388
{
Bryant's avatar
Bryant committed
389
390
    d_data->borderPen = pen;
    setPaintAttribute( PaintBackground );
pixhawk's avatar
pixhawk committed
391
392
}

393
/*!
pixhawk's avatar
pixhawk committed
394
   \return Background pen
Bryant's avatar
Bryant committed
395
   \sa setBorderPen(), backgroundBrush()
pixhawk's avatar
pixhawk committed
396
*/
Bryant's avatar
Bryant committed
397
QPen QwtText::borderPen() const
398
{
Bryant's avatar
Bryant committed
399
    return d_data->borderPen;
pixhawk's avatar
pixhawk committed
400
401
402
403
404
405
}

/*!
   Set the background brush

   \param brush Background brush
Bryant's avatar
Bryant committed
406
   \sa backgroundBrush(), setBorderPen()
pixhawk's avatar
pixhawk committed
407
*/
Bryant's avatar
Bryant committed
408
void QwtText::setBackgroundBrush( const QBrush &brush )
409
410
{
    d_data->backgroundBrush = brush;
Bryant's avatar
Bryant committed
411
    setPaintAttribute( PaintBackground );
pixhawk's avatar
pixhawk committed
412
413
}

414
/*!
pixhawk's avatar
pixhawk committed
415
   \return Background brush
Bryant's avatar
Bryant committed
416
   \sa setBackgroundBrush(), borderPen()
pixhawk's avatar
pixhawk committed
417
*/
418
419
420
QBrush QwtText::backgroundBrush() const
{
    return d_data->backgroundBrush;
pixhawk's avatar
pixhawk committed
421
422
423
424
425
426
427
428
}

/*!
   Change a paint attribute

   \param attribute Paint attribute
   \param on On/Off

Bryant's avatar
Bryant committed
429
430
431
   \note Used by setFont(), setColor(),
         setBorderPen() and setBackgroundBrush()
   \sa testPaintAttribute()
pixhawk's avatar
pixhawk committed
432
*/
Bryant's avatar
Bryant committed
433
void QwtText::setPaintAttribute( PaintAttribute attribute, bool on )
pixhawk's avatar
pixhawk committed
434
435
436
437
438
439
440
441
442
443
444
445
446
{
    if ( on )
        d_data->paintAttributes |= attribute;
    else
        d_data->paintAttributes &= ~attribute;
}

/*!
   Test a paint attribute

   \param attribute Paint attribute
   \return true, if attribute is enabled

Bryant's avatar
Bryant committed
447
   \sa setPaintAttribute()
pixhawk's avatar
pixhawk committed
448
*/
Bryant's avatar
Bryant committed
449
bool QwtText::testPaintAttribute( PaintAttribute attribute ) const
pixhawk's avatar
pixhawk committed
450
451
452
453
454
455
456
457
458
{
    return d_data->paintAttributes & attribute;
}

/*!
   Change a layout attribute

   \param attribute Layout attribute
   \param on On/Off
Bryant's avatar
Bryant committed
459
   \sa testLayoutAttribute()
460
*/
Bryant's avatar
Bryant committed
461
void QwtText::setLayoutAttribute( LayoutAttribute attribute, bool on )
pixhawk's avatar
pixhawk committed
462
463
464
465
466
467
468
469
470
471
472
473
474
{
    if ( on )
        d_data->layoutAttributes |= attribute;
    else
        d_data->layoutAttributes &= ~attribute;
}

/*!
   Test a layout attribute

   \param attribute Layout attribute
   \return true, if attribute is enabled

Bryant's avatar
Bryant committed
475
   \sa setLayoutAttribute()
pixhawk's avatar
pixhawk committed
476
*/
Bryant's avatar
Bryant committed
477
bool QwtText::testLayoutAttribute( LayoutAttribute attribute ) const
pixhawk's avatar
pixhawk committed
478
479
480
481
482
483
484
485
486
487
488
489
{
    return d_data->layoutAttributes | attribute;
}

/*!
   Find the height for a given width

   \param defaultFont Font, used for the calculation if the text has no font
   \param width Width

   \return Calculated height
*/
Bryant's avatar
Bryant committed
490
double QwtText::heightForWidth( double width, const QFont &defaultFont ) const
pixhawk's avatar
pixhawk committed
491
492
493
494
{
    // We want to calculate in screen metrics. So
    // we need a font that uses screen metrics

Bryant's avatar
Bryant committed
495
    const QFont font( usedFont( defaultFont ), QApplication::desktop() );
pixhawk's avatar
pixhawk committed
496

Bryant's avatar
Bryant committed
497
    double h = 0;
pixhawk's avatar
pixhawk committed
498

Bryant's avatar
Bryant committed
499
500
501
502
503
    if ( d_data->layoutAttributes & MinimumLayout )
    {
        double left, right, top, bottom;
        d_data->textEngine->textMargins( font, d_data->text,
            left, right, top, bottom );
pixhawk's avatar
pixhawk committed
504
505

        h = d_data->textEngine->heightForWidth(
Bryant's avatar
Bryant committed
506
507
            font, d_data->renderFlags, d_data->text,
            width + left + right );
pixhawk's avatar
pixhawk committed
508
509

        h -= top + bottom;
Bryant's avatar
Bryant committed
510
511
512
    }
    else
    {
pixhawk's avatar
pixhawk committed
513
        h = d_data->textEngine->heightForWidth(
Bryant's avatar
Bryant committed
514
            font, d_data->renderFlags, d_data->text, width );
pixhawk's avatar
pixhawk committed
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
    }

    return h;
}

/*!
   Find the height for a given width

   \param defaultFont Font, used for the calculation if the text has no font

   \return Calculated height
*/

/*!
   Returns the size, that is needed to render text

   \param defaultFont Font of the text
   \return Caluclated size
*/
Bryant's avatar
Bryant committed
534
QSizeF QwtText::textSize( const QFont &defaultFont ) const
pixhawk's avatar
pixhawk committed
535
536
537
538
{
    // We want to calculate in screen metrics. So
    // we need a font that uses screen metrics

Bryant's avatar
Bryant committed
539
    const QFont font( usedFont( defaultFont ), QApplication::desktop() );
pixhawk's avatar
pixhawk committed
540

541
    if ( !d_layoutCache->textSize.isValid()
Bryant's avatar
Bryant committed
542
543
        || d_layoutCache->font != font )
    {
pixhawk's avatar
pixhawk committed
544
        d_layoutCache->textSize = d_data->textEngine->textSize(
Bryant's avatar
Bryant committed
545
            font, d_data->renderFlags, d_data->text );
pixhawk's avatar
pixhawk committed
546
547
548
        d_layoutCache->font = font;
    }

Bryant's avatar
Bryant committed
549
    QSizeF sz = d_layoutCache->textSize;
pixhawk's avatar
pixhawk committed
550

Bryant's avatar
Bryant committed
551
552
553
554
555
556
    if ( d_data->layoutAttributes & MinimumLayout )
    {
        double left, right, top, bottom;
        d_data->textEngine->textMargins( font, d_data->text,
            left, right, top, bottom );
        sz -= QSizeF( left + right, top + bottom );
pixhawk's avatar
pixhawk committed
557
558
559
560
561
562
563
564
565
566
567
    }

    return sz;
}

/*!
   Draw a text into a rectangle

   \param painter Painter
   \param rect Rectangle
*/
Bryant's avatar
Bryant committed
568
void QwtText::draw( QPainter *painter, const QRectF &rect ) const
pixhawk's avatar
pixhawk committed
569
{
Bryant's avatar
Bryant committed
570
571
572
573
574
    if ( d_data->paintAttributes & PaintBackground )
    {
        if ( d_data->borderPen != Qt::NoPen ||
            d_data->backgroundBrush != Qt::NoBrush )
        {
pixhawk's avatar
pixhawk committed
575
            painter->save();
Bryant's avatar
Bryant committed
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590

            painter->setPen( d_data->borderPen );
            painter->setBrush( d_data->backgroundBrush );

            if ( d_data->borderRadius == 0 )
            {
                QwtPainter::drawRect( painter, rect );
            }
            else
            {
                painter->setRenderHint( QPainter::Antialiasing, true );
                painter->drawRoundedRect( rect,
                    d_data->borderRadius, d_data->borderRadius );
            }

pixhawk's avatar
pixhawk committed
591
592
593
594
595
596
            painter->restore();
        }
    }

    painter->save();

Bryant's avatar
Bryant committed
597
598
599
    if ( d_data->paintAttributes & PaintUsingTextFont )
    {
        painter->setFont( d_data->font );
pixhawk's avatar
pixhawk committed
600
601
    }

Bryant's avatar
Bryant committed
602
603
    if ( d_data->paintAttributes & PaintUsingTextColor )
    {
pixhawk's avatar
pixhawk committed
604
        if ( d_data->color.isValid() )
Bryant's avatar
Bryant committed
605
            painter->setPen( d_data->color );
pixhawk's avatar
pixhawk committed
606
607
    }

Bryant's avatar
Bryant committed
608
609
610
    QRectF expandedRect = rect;
    if ( d_data->layoutAttributes & MinimumLayout )
    {
pixhawk's avatar
pixhawk committed
611
612
613
        // We want to calculate in screen metrics. So
        // we need a font that uses screen metrics

Bryant's avatar
Bryant committed
614
        const QFont font( painter->font(), QApplication::desktop() );
pixhawk's avatar
pixhawk committed
615

Bryant's avatar
Bryant committed
616
        double left, right, top, bottom;
pixhawk's avatar
pixhawk committed
617
        d_data->textEngine->textMargins(
Bryant's avatar
Bryant committed
618
619
620
621
622
623
            font, d_data->text, left, right, top, bottom );

        expandedRect.setTop( rect.top() - top );
        expandedRect.setBottom( rect.bottom() + bottom );
        expandedRect.setLeft( rect.left() - left );
        expandedRect.setRight( rect.right() + right );
pixhawk's avatar
pixhawk committed
624
625
    }

Bryant's avatar
Bryant committed
626
627
    d_data->textEngine->draw( painter, expandedRect,
        d_data->renderFlags, d_data->text );
pixhawk's avatar
pixhawk committed
628
629
630
631
632
633
634

    painter->restore();
}

/*!
   Find the text engine for a text format

635
   In case of QwtText::AutoText the first text engine
pixhawk's avatar
pixhawk committed
636
   (beside QwtPlainTextEngine) is returned, where QwtTextEngine::mightRender
Bryant's avatar
Bryant committed
637
   returns true. If there is none QwtPlainTextEngine is returned.
pixhawk's avatar
pixhawk committed
638

639
   If no text engine is registered for the format QwtPlainTextEngine
pixhawk's avatar
pixhawk committed
640
641
642
643
644
   is returnd.

   \param text Text, needed in case of AutoText
   \param format Text format

Bryant's avatar
Bryant committed
645
646
647
648
649
650
   \return Corresponding text engine
*/
const QwtTextEngine *QwtText::textEngine( const QString &text,
    QwtText::TextFormat format )
{
    return QwtTextEngineDict::dict().textEngine( text, format );
pixhawk's avatar
pixhawk committed
651
652
653
654
655
656
}

/*!
   Assign/Replace a text engine for a text format

   With setTextEngine it is possible to extend Qwt with
657
   other types of text formats.
pixhawk's avatar
pixhawk committed
658
659

   For QwtText::PlainText it is not allowed to assign a engine == NULL.
660

pixhawk's avatar
pixhawk committed
661
662
663
664
665
666
   \param format Text format
   \param engine Text engine

   \sa QwtMathMLTextEngine
   \warning Using QwtText::AutoText does nothing.
*/
Bryant's avatar
Bryant committed
667
668
void QwtText::setTextEngine( QwtText::TextFormat format,
    QwtTextEngine *engine )
pixhawk's avatar
pixhawk committed
669
{
Bryant's avatar
Bryant committed
670
    QwtTextEngineDict::dict().setTextEngine( format, engine );
pixhawk's avatar
pixhawk committed
671
672
673
674
675
}

/*!
   \brief Find the text engine for a text format

676
   textEngine can be used to find out if a text format is supported.
pixhawk's avatar
pixhawk committed
677
678
679
680

   \param format Text format
   \return The text engine, or NULL if no engine is available.
*/
Bryant's avatar
Bryant committed
681
const QwtTextEngine *QwtText::textEngine( QwtText::TextFormat format )
pixhawk's avatar
pixhawk committed
682
{
Bryant's avatar
Bryant committed
683
    return  QwtTextEngineDict::dict().textEngine( format );
pixhawk's avatar
pixhawk committed
684
}