Newer
Older
/* -*- 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
*****************************************************************************/
#include "qwt_text.h"
#include "qwt_painter.h"
#include "qwt_text_engine.h"
#include <qmap.h>
#include <qfont.h>
#include <qcolor.h>
#include <qpen.h>
#include <qbrush.h>
#include <qpainter.h>
#include <qapplication.h>
#include <qdesktopwidget.h>
void setTextEngine( QwtText::TextFormat, QwtTextEngine * );
const QwtTextEngine *textEngine( QwtText::TextFormat ) const;
const QwtTextEngine *textEngine( const QString &,
QwtText::TextFormat ) const;
inline const QwtTextEngine *engine( EngineMap::const_iterator &it ) const
{
QwtTextEngineDict &QwtTextEngineDict::dict()
{
static QwtTextEngineDict engineDict;
return engineDict;
}
d_map.insert( QwtText::PlainText, new QwtPlainTextEngine() );
for ( EngineMap::const_iterator it = d_map.begin();
it != d_map.end(); ++it )
{
const QwtTextEngine *textEngine = engine( it );
const QwtTextEngine *QwtTextEngineDict::textEngine( const QString& text,
QwtText::TextFormat format ) const
for ( EngineMap::const_iterator it = d_map.begin();
it != d_map.end(); ++it )
{
if ( it.key() != QwtText::PlainText )
{
const QwtTextEngine *e = engine( it );
if ( e && e->mightRender( text ) )
return e;
EngineMap::const_iterator it = d_map.find( format );
if ( it != d_map.end() )
{
const QwtTextEngine *e = engine( it );
it = d_map.find( QwtText::PlainText );
return engine( it );
void QwtTextEngineDict::setTextEngine( QwtText::TextFormat format,
QwtTextEngine *engine )
{
if ( format == QwtText::AutoText )
return;
if ( format == QwtText::PlainText && engine == NULL )
return;
EngineMap::const_iterator it = d_map.find( format );
if ( it != d_map.end() )
{
const QwtTextEngine *e = this->engine( it );
return e;
}
class QwtText::PrivateData
{
public:
PrivateData():
renderFlags( Qt::AlignCenter ),
borderRadius( 0 ),
borderPen( Qt::NoPen ),
backgroundBrush( Qt::NoBrush ),
paintAttributes( 0 ),
layoutAttributes( 0 ),
textEngine( NULL )
{
}
int renderFlags;
QString text;
QFont font;
QColor color;
QwtText::PaintAttributes paintAttributes;
QwtText::LayoutAttributes layoutAttributes;
const QwtTextEngine *textEngine;
};
class QwtText::LayoutCache
{
public:
};
/*!
Constructor
\param text Text content
\param textFormat Text format
*/
QwtText::QwtText( const QString &text, QwtText::TextFormat textFormat )
d_layoutCache = new LayoutCache;
}
//! Copy constructor
{
d_data = new PrivateData;
*d_data = *other.d_data;
d_layoutCache = new LayoutCache;
*d_layoutCache = *other.d_layoutCache;
}
//! Destructor
//! Assignment operator
QwtText &QwtText::operator=( const QwtText & other )
{
*d_data = *other.d_data;
*d_layoutCache = *other.d_layoutCache;
return *this;
}
//! Relational operator
bool QwtText::operator==( const QwtText &other ) const
{
return d_data->renderFlags == other.d_data->renderFlags &&
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;
//! Relational operator
bool QwtText::operator!=( const QwtText &other ) const // invalidate
}
/*!
Assign a new text content
\param text Text content
\param textFormat Text format
void QwtText::setText( const QString &text,
QwtText::TextFormat textFormat )
QString QwtText::text() const
{
return d_data->text;
}
/*!
\brief Change the render flags
The default setting is Qt::AlignCenter
\param renderFlags Bitwise OR of the flags used like in QPainter::drawText()
\note Some renderFlags might have no effect, depending on the text format.
*/
d_data->renderFlags = renderFlags;
d_layoutCache->invalidate();
}
}
/*!
\return Render flags
int QwtText::renderFlags() const
{
return d_data->renderFlags;
Set the font.
\param font Font
\note Setting the font might have no effect, when
the text contains control sequences for setting fonts.
*/
QFont QwtText::font() const
{
return d_data->font;
Return the font of the text, if it has one.
Otherwise return defaultFont.
\param defaultFont Default font
\return Font used for drawing the text
{
if ( d_data->paintAttributes & PaintUsingTextFont )
return d_data->font;
return defaultFont;
}
\param color Color
\note Setting the color might have no effect, when
the text contains control sequences for setting colors.
*/
QColor QwtText::color() const
{
return d_data->color;
Return the color of the text, if it has one.
Otherwise return defaultColor.
\param defaultColor Default color
\return Color used for drawing the text
\sa setColor(), color(), PaintAttributes
QColor QwtText::usedColor( const QColor &defaultColor ) const
{
if ( d_data->paintAttributes & PaintUsingTextColor )
return d_data->color;
return defaultColor;
}
/*!
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;
}
/*!
Set the background pen
\param pen Background pen
d_data->borderPen = pen;
setPaintAttribute( PaintBackground );
}
/*!
Set the background brush
\param brush Background brush
{
d_data->backgroundBrush = brush;
QBrush QwtText::backgroundBrush() const
{
return d_data->backgroundBrush;
}
/*!
Change a paint attribute
\param attribute Paint attribute
\param on On/Off
\note Used by setFont(), setColor(),
setBorderPen() and setBackgroundBrush()
\sa testPaintAttribute()
void QwtText::setPaintAttribute( PaintAttribute attribute, bool on )
{
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
bool QwtText::testPaintAttribute( PaintAttribute attribute ) const
{
return d_data->paintAttributes & attribute;
}
/*!
Change a layout attribute
\param attribute Layout attribute
\param on On/Off
void QwtText::setLayoutAttribute( LayoutAttribute attribute, bool on )
{
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
bool QwtText::testLayoutAttribute( LayoutAttribute attribute ) const
{
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
*/
double QwtText::heightForWidth( double width, const QFont &defaultFont ) const
{
// We want to calculate in screen metrics. So
// we need a font that uses screen metrics
const QFont font( usedFont( defaultFont ), QApplication::desktop() );
if ( d_data->layoutAttributes & MinimumLayout )
{
double left, right, top, bottom;
d_data->textEngine->textMargins( font, d_data->text,
left, right, top, bottom );
font, d_data->renderFlags, d_data->text,
width + left + right );
}
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
*/
{
// We want to calculate in screen metrics. So
// we need a font that uses screen metrics
const QFont font( usedFont( defaultFont ), QApplication::desktop() );
if ( !d_layoutCache->textSize.isValid()
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 );
}
return sz;
}
/*!
Draw a text into a rectangle
\param painter Painter
\param rect Rectangle
*/
void QwtText::draw( QPainter *painter, const QRectF &rect ) const
if ( d_data->paintAttributes & PaintBackground )
{
if ( d_data->borderPen != Qt::NoPen ||
d_data->backgroundBrush != Qt::NoBrush )
{
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 );
}
if ( d_data->paintAttributes & PaintUsingTextFont )
{
painter->setFont( d_data->font );
QRectF expandedRect = rect;
if ( d_data->layoutAttributes & MinimumLayout )
{
// We want to calculate in screen metrics. So
// we need a font that uses screen metrics
const QFont font( painter->font(), QApplication::desktop() );
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 );
d_data->textEngine->draw( painter, expandedRect,
d_data->renderFlags, d_data->text );
painter->restore();
}
/*!
Find the text engine for a text format
In case of QwtText::AutoText the first text engine
(beside QwtPlainTextEngine) is returned, where QwtTextEngine::mightRender
returns true. If there is none QwtPlainTextEngine is returned.
If no text engine is registered for the format QwtPlainTextEngine
is returnd.
\param text Text, needed in case of AutoText
\param format Text format
\return Corresponding text engine
*/
const QwtTextEngine *QwtText::textEngine( const QString &text,
QwtText::TextFormat format )
{
return QwtTextEngineDict::dict().textEngine( text, format );
}
/*!
Assign/Replace a text engine for a text format
With setTextEngine it is possible to extend Qwt with
For QwtText::PlainText it is not allowed to assign a engine == NULL.
\param format Text format
\param engine Text engine
\sa QwtMathMLTextEngine
\warning Using QwtText::AutoText does nothing.
*/
void QwtText::setTextEngine( QwtText::TextFormat format,
QwtTextEngine *engine )
}
/*!
\brief Find the text engine for a text format
textEngine can be used to find out if a text format is supported.
\param format Text format
\return The text engine, or NULL if no engine is available.
*/
const QwtTextEngine *QwtText::textEngine( QwtText::TextFormat format )