Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

qwt_text.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2003   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 // vim: expandtab
00011 
00012 #include <qfont.h>
00013 #include <qcolor.h>
00014 #include <qpen.h>
00015 #include <qbrush.h>
00016 #include <qpainter.h>
00017 #include "qwt_painter.h"
00018 #include "qwt_text_engine.h"
00019 #include "qwt_text.h"
00020 #if QT_VERSION >= 0x040000
00021 #include <qapplication.h>
00022 #include <qdesktopwidget.h>
00023 #endif
00024 class QwtText::PrivateData
00025 {
00026 public:
00027     PrivateData():
00028         flags(Qt::AlignCenter),
00029         backgroundPen(Qt::NoPen),
00030         backgroundBrush(Qt::NoBrush),
00031         paintAttributes(QwtText::PaintUsingPainter),
00032         layoutAttributes(QwtText::DefaultLayout),
00033         textEngine(NULL)
00034     {
00035     }
00036 
00037     int flags;
00038     QString text;
00039     QFont font;
00040     QColor color;
00041     QPen backgroundPen;
00042     QBrush backgroundBrush;
00043 
00044     int paintAttributes;
00045     int layoutAttributes;
00046 
00047     QwtTextEngine *textEngine;
00048 };
00049 
00050 class QwtText::LayoutCache
00051 {
00052 public:
00053     void invalidate()
00054     {
00055         textSize = QSize();
00056     }
00057 
00058     QFont font;
00059     QSize textSize;
00060 };
00061 
00062 QwtText::QwtText(const QString &text, QwtText::TextFormat textFormat)
00063 {
00064     d_data = new PrivateData;
00065     d_data->text = text;
00066     d_data->textEngine = textEngine(text, textFormat);
00067 
00068     d_layoutCache = new LayoutCache;
00069 }
00070 
00071 QwtText::QwtText(const QwtText &other)
00072 {
00073     d_data = new PrivateData;
00074     *d_data = *other.d_data;
00075 
00076     d_layoutCache = new LayoutCache;
00077     *d_layoutCache = *other.d_layoutCache;
00078 }
00079 
00081 QwtText::~QwtText() 
00082 {
00083     delete d_data;
00084     delete d_layoutCache;
00085 }
00086 
00087 QwtText &QwtText::operator=(const QwtText &other)
00088 {
00089     *d_data = *other.d_data;
00090     *d_layoutCache = *other.d_layoutCache;
00091     return *this;
00092 }
00093     
00094 int QwtText::operator==(const QwtText &other) const
00095 {
00096     return d_data->flags == other.d_data->flags &&
00097         d_data->text == other.d_data->text &&
00098         d_data->font == other.d_data->font &&
00099         d_data->color == other.d_data->color &&
00100         d_data->backgroundPen == other.d_data->backgroundPen &&
00101         d_data->backgroundBrush == other.d_data->backgroundBrush &&
00102         d_data->paintAttributes == other.d_data->paintAttributes &&
00103         d_data->textEngine == other.d_data->textEngine;
00104 }
00105 
00106 int QwtText::operator!=(const QwtText &other) const // invalidate
00107 {
00108    return !(other == *this);
00109 }
00110 
00111 void QwtText::setText(const QString &text, 
00112     QwtText::TextFormat textFormat) 
00113 { 
00114     d_data->text = text; 
00115     d_data->textEngine = textEngine(text, textFormat);
00116     d_layoutCache->invalidate();
00117 }
00118 
00120 QString QwtText::text() const 
00121 { 
00122     return d_data->text; 
00123 }
00124 
00125 void QwtText::setFlags(int flags) 
00126 { 
00127     if ( flags != d_data->flags )
00128     {
00129         d_data->flags = flags; 
00130 #if 1
00131         d_layoutCache->invalidate();
00132 #endif
00133     }
00134 }
00135 
00136 int QwtText::flags() const 
00137 { 
00138     return d_data->flags; 
00139 }
00140 
00142 void QwtText::setFont(const QFont &font) 
00143 {
00144     d_data->font = font; 
00145     d_data->paintAttributes |= PaintUsingTextFont;
00146 }
00147 
00149 QFont QwtText::font() const 
00150 { 
00151     return d_data->font; 
00152 }
00153 
00154 QFont QwtText::usedFont(const QFont &font) const
00155 {
00156     if ( d_data->paintAttributes & PaintUsingTextFont )
00157         return d_data->font;
00158 
00159     return font;
00160 }
00161 
00162 void QwtText::setColor(const QColor &color) 
00163 { 
00164     d_data->paintAttributes |= PaintUsingTextColor;
00165     d_data->color = color; 
00166 }
00167 
00168 QColor QwtText::color() const 
00169 { 
00170     return d_data->color; 
00171 }
00172 
00173 QColor QwtText::usedColor(const QColor &color) const
00174 {
00175     if ( d_data->paintAttributes & PaintUsingTextColor )
00176         return d_data->color;
00177 
00178     return color;
00179 }
00180 
00181 void QwtText::setBackgroundPen(const QPen &pen) 
00182 { 
00183     d_data->paintAttributes |= PaintBackground;
00184     d_data->backgroundPen = pen; 
00185 }
00186 
00187 QPen QwtText::backgroundPen() const 
00188 { 
00189     return d_data->backgroundPen; 
00190 }
00191 
00192 void QwtText::setBackgroundBrush(const QBrush &brush) 
00193 { 
00194     d_data->paintAttributes |= PaintBackground;
00195     d_data->backgroundBrush = brush; 
00196 }
00197 
00198 QBrush QwtText::backgroundBrush() const 
00199 { 
00200     return d_data->backgroundBrush; 
00201 }
00202 
00203 void QwtText::setPaintAttributes(int attributes)
00204 {
00205     d_data->paintAttributes = attributes;
00206 }
00207 
00208 int QwtText::paintAttributes() const
00209 {
00210     return d_data->paintAttributes;
00211 }
00212 
00213 void QwtText::setLayoutAttributes(int attributes)
00214 {
00215     d_data->layoutAttributes = attributes;
00216 }
00217 
00218 int QwtText::layoutAttributes() const
00219 {
00220     return d_data->layoutAttributes;
00221 }
00222 
00223 int QwtText::heightForWidth(int width, const QFont &font) const
00224 {
00225     const QwtMetricsMap map = QwtPainter::metricsMap();
00226     width = map.layoutToScreenX(width);
00227 
00228 #if QT_VERSION < 0x040000
00229     const QFont fnt = usedFont(font);
00230 #else
00231     // We want to calculate in screen metrics. So
00232     // we need a font that uses screen metrics
00233 
00234     const QFont fnt(usedFont(font), QApplication::desktop());
00235 #endif
00236 
00237     int h = 0;
00238 
00239     if ( d_data->layoutAttributes & MinimumLayout )
00240     {
00241         int left, right, top, bottom;
00242         d_data->textEngine->textMargins(fnt, d_data->text,
00243             left, right, top, bottom);
00244 
00245         h = d_data->textEngine->heightForWidth(
00246             fnt, d_data->flags, d_data->text, 
00247             width + left + right);
00248 
00249         h -= top + bottom;
00250     }
00251     else
00252     {
00253         h = d_data->textEngine->heightForWidth(
00254             fnt, d_data->flags, d_data->text, width);
00255     }
00256 
00257     h = map.screenToLayoutY(h);
00258     return h;
00259 }
00260 
00261 QSize QwtText::textSize(const QFont &font) const
00262 {
00263 #if QT_VERSION < 0x040000
00264     const QFont fnt(usedFont(font));
00265 #else
00266     // We want to calculate in screen metrics. So
00267     // we need a font that uses screen metrics
00268 
00269     const QFont fnt(usedFont(font), QApplication::desktop());
00270 #endif
00271 
00272     if ( !d_layoutCache->textSize.isValid() 
00273         || d_layoutCache->font != fnt )
00274     {
00275         d_layoutCache->textSize = d_data->textEngine->textSize(
00276             fnt, d_data->flags, d_data->text);
00277         d_layoutCache->font = fnt;
00278     }
00279 
00280     QSize sz = d_layoutCache->textSize;
00281 
00282     if ( d_data->layoutAttributes & MinimumLayout )
00283     {
00284         int left, right, top, bottom;
00285         d_data->textEngine->textMargins(fnt, d_data->text,
00286             left, right, top, bottom);
00287         sz -= QSize(left + right, top + bottom);
00288     }
00289 
00290     const QwtMetricsMap map = QwtPainter::metricsMap();
00291     sz = map.screenToLayout(sz);
00292     return sz;
00293 }
00294 
00295 void QwtText::draw(QPainter *painter, const QRect &rect) const
00296 {
00297     if ( d_data->paintAttributes & PaintBackground )
00298     {
00299         if ( d_data->backgroundPen != Qt::NoPen || 
00300             d_data->backgroundBrush != Qt::NoBrush )
00301         {
00302             painter->save();
00303             painter->setPen(d_data->backgroundPen);
00304             painter->setBrush(d_data->backgroundBrush);
00305             QwtPainter::drawRect(painter, rect);
00306             painter->restore();
00307         }
00308     }
00309 
00310     painter->save();
00311 
00312     if ( d_data->paintAttributes & PaintUsingTextFont )
00313     {
00314         painter->setFont(d_data->font);
00315     }
00316 
00317     if ( d_data->paintAttributes & PaintUsingTextColor )
00318     {
00319         if ( d_data->color.isValid() )
00320             painter->setPen(d_data->color);
00321     }
00322 
00323     QRect expandedRect = rect;
00324     if ( d_data->layoutAttributes & MinimumLayout )
00325     {
00326 #if QT_VERSION < 0x040000
00327         const QFont fnt(painter->font());
00328 #else
00329         // We want to calculate in screen metrics. So
00330         // we need a font that uses screen metrics
00331 
00332         const QFont fnt(painter->font(), QApplication::desktop());
00333 #endif
00334 
00335         int left, right, top, bottom;
00336         d_data->textEngine->textMargins(
00337             fnt, d_data->text,
00338             left, right, top, bottom);
00339 
00340         const QwtMetricsMap map = QwtPainter::metricsMap();
00341         left = map.screenToLayoutX(left);
00342         right = map.screenToLayoutX(right);
00343         top = map.screenToLayoutY(top);
00344         bottom = map.screenToLayoutY(bottom);
00345 
00346         expandedRect.setTop(rect.top() - top);
00347         expandedRect.setBottom(rect.bottom() + bottom);
00348         expandedRect.setLeft(rect.left() - left);
00349         expandedRect.setRight(rect.right() + right);
00350     }
00351 
00352     d_data->textEngine->draw(painter, expandedRect, 
00353         d_data->flags, d_data->text);
00354 
00355     painter->restore();
00356 }
00357 
00358 QwtTextEngine *QwtText::textEngine(const QString &text,
00359     QwtText::TextFormat format) const
00360 {
00361 #ifndef QT_NO_RICHTEXT
00362     static QwtRichTextEngine richTextEngine;
00363 #endif
00364     static QwtPlainTextEngine plainTextEngine;
00365 
00366     switch(format)
00367     {
00368         case QwtText::AutoText:
00369         {
00370 #ifndef QT_NO_RICHTEXT
00371             if ( richTextEngine.mightRender(text) )
00372                 return &richTextEngine;
00373 #endif
00374             break;
00375         }
00376         case QwtText::RichText:
00377         {
00378 #ifndef QT_NO_RICHTEXT
00379             return &richTextEngine;
00380 #endif
00381             break;
00382         }
00383         case QwtText::PlainText:
00384         default:
00385             return &plainTextEngine;
00386     }
00387 
00388     return &plainTextEngine;
00389 }

Generated on Mon Jan 30 22:16:26 2006 for Qwt User's Guide by  doxygen 1.4.4