00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00232
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
00267
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
00330
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 }