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
}