00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qpainter.h>
00013 #include <qpixmap.h>
00014 #include <qimage.h>
00015 #include <qmap.h>
00016 #include <qwidget.h>
00017 #include "qwt_math.h"
00018 #include "qwt_painter.h"
00019 #include "qwt_text_engine.h"
00020
00021 static QString taggedRichText(const QString &text, int flags)
00022 {
00023 QString richText = text;
00024
00025
00026 if (flags & Qt::AlignJustify)
00027 {
00028 richText.prepend(QString::fromLatin1("<div align=\"justify\">"));
00029 richText.append(QString::fromLatin1("</div>"));
00030 }
00031 else if (flags & Qt::AlignRight)
00032 {
00033 richText.prepend(QString::fromLatin1("<div align=\"right\">"));
00034 richText.append(QString::fromLatin1("</div>"));
00035 }
00036 else if (flags & Qt::AlignHCenter)
00037 {
00038 richText.prepend(QString::fromLatin1("<div align=\"center\">"));
00039 richText.append(QString::fromLatin1("</div>"));
00040 }
00041
00042 return richText;
00043 }
00044
00045 #if QT_VERSION < 0x040000
00046
00047 #include <qsimplerichtext.h>
00048 #include <qstylesheet.h>
00049
00050 class QwtRichTextDocument: public QSimpleRichText
00051 {
00052 public:
00053 QwtRichTextDocument(const QString &text, int flags, const QFont &font):
00054 QSimpleRichText(taggedRichText(text, flags), font)
00055 {
00056 }
00057 };
00058
00059 #else // QT_VERSION >= 0x040000
00060
00061 #include <qtextobject.h>
00062 #include <qtextdocument.h>
00063 #include <qabstracttextdocumentlayout.h>
00064
00065 #if QT_VERSION < 0x040200
00066 #include <qlabel.h>
00067 #endif
00068
00069 class QwtRichTextDocument: public QTextDocument
00070 {
00071 public:
00072 QwtRichTextDocument(const QString &text, int flags, const QFont &font)
00073 {
00074 setUndoRedoEnabled(false);
00075 setDefaultFont(font);
00076 #if QT_VERSION >= 0x040300
00077 setHtml(text);
00078 #else
00079 setHtml(taggedRichText(text, flags));
00080 #endif
00081
00082
00083 (void)documentLayout();
00084
00085 #if QT_VERSION >= 0x040300
00086 QTextOption option = defaultTextOption();
00087 if ( flags & Qt::TextWordWrap )
00088 option.setWrapMode(QTextOption::WordWrap);
00089 else
00090 option.setWrapMode(QTextOption::NoWrap);
00091
00092 option.setAlignment((Qt::Alignment) flags);
00093 setDefaultTextOption(option);
00094
00095 QTextFrame *root = rootFrame();
00096 QTextFrameFormat fm = root->frameFormat();
00097 fm.setBorder(0);
00098 fm.setMargin(0);
00099 fm.setPadding(0);
00100 fm.setBottomMargin(0);
00101 fm.setLeftMargin(0);
00102 root->setFrameFormat(fm);
00103
00104 adjustSize();
00105 #endif
00106 }
00107 };
00108
00109 #endif
00110
00111 class QwtPlainTextEngine::PrivateData
00112 {
00113 public:
00114 int effectiveAscent(const QFont &font) const
00115 {
00116 const QString fontKey = font.key();
00117
00118 QMap<QString, int>::const_iterator it =
00119 d_ascentCache.find(fontKey);
00120 if ( it == d_ascentCache.end() )
00121 {
00122 int ascent = findAscent(font);
00123 it = d_ascentCache.insert(fontKey, ascent);
00124 }
00125
00126 return (*it);
00127 }
00128
00129 private:
00130 int findAscent(const QFont &font) const
00131 {
00132 static const QString dummy("E");
00133 static const QColor white(Qt::white);
00134
00135 const QFontMetrics fm(font);
00136 QPixmap pm(fm.width(dummy), fm.height());
00137 pm.fill(white);
00138
00139 QPainter p(&pm);
00140 p.setFont(font);
00141 p.drawText(0, 0, pm.width(), pm.height(), 0, dummy);
00142 p.end();
00143
00144 #if QT_VERSION < 0x040000
00145 const QImage img = pm.convertToImage();
00146 #else
00147 const QImage img = pm.toImage();
00148 #endif
00149
00150 int row = 0;
00151 for ( row = 0; row < img.height(); row++ )
00152 {
00153 const QRgb *line = (const QRgb *)img.scanLine(row);
00154
00155 const int w = pm.width();
00156 for ( int col = 0; col < w; col++ )
00157 {
00158 if ( line[col] != white.rgb() )
00159 return fm.ascent() - row + 1;
00160 }
00161 }
00162
00163 return fm.ascent();
00164 }
00165
00166 mutable QMap<QString, int> d_ascentCache;
00167 };
00168
00170 QwtTextEngine::QwtTextEngine()
00171 {
00172 }
00173
00175 QwtTextEngine::~QwtTextEngine()
00176 {
00177 }
00178
00180 QwtPlainTextEngine::QwtPlainTextEngine()
00181 {
00182 d_data = new PrivateData;
00183 }
00184
00186 QwtPlainTextEngine::~QwtPlainTextEngine()
00187 {
00188 delete d_data;
00189 }
00190
00201 int QwtPlainTextEngine::heightForWidth(const QFont& font, int flags,
00202 const QString& text, int width) const
00203 {
00204 const QFontMetrics fm(font);
00205 const QRect rect = fm.boundingRect(
00206 0, 0, width, QWIDGETSIZE_MAX, flags, text);
00207
00208 return rect.height();
00209 }
00210
00220 QSize QwtPlainTextEngine::textSize(const QFont &font,
00221 int flags, const QString& text) const
00222 {
00223 const QFontMetrics fm(font);
00224 const QRect rect = fm.boundingRect(
00225 0, 0, QWIDGETSIZE_MAX, QWIDGETSIZE_MAX, flags, text);
00226
00227 return rect.size();
00228 }
00229
00239 void QwtPlainTextEngine::textMargins(const QFont &font, const QString &,
00240 int &left, int &right, int &top, int &bottom) const
00241 {
00242 left = right = top = 0;
00243
00244 const QFontMetrics fm(font);
00245 top = fm.ascent() - d_data->effectiveAscent(font);
00246 bottom = fm.descent() + 1;
00247 }
00248
00259 void QwtPlainTextEngine::draw(QPainter *painter, const QRect &rect,
00260 int flags, const QString& text) const
00261 {
00262 QwtPainter::drawText(painter, rect, flags, text);
00263 }
00264
00269 bool QwtPlainTextEngine::mightRender(const QString &) const
00270 {
00271 return true;
00272 }
00273
00274 #ifndef QT_NO_RICHTEXT
00275
00277 QwtRichTextEngine::QwtRichTextEngine()
00278 {
00279 }
00280
00291 int QwtRichTextEngine::heightForWidth(const QFont& font, int flags,
00292 const QString& text, int width) const
00293 {
00294 QwtRichTextDocument doc(text, flags, font);
00295
00296 #if QT_VERSION < 0x040000
00297 doc.setWidth(width);
00298 const int h = doc.height();
00299 #else
00300 doc.setPageSize(QSize(width, QWIDGETSIZE_MAX));
00301 const int h = qRound(doc.documentLayout()->documentSize().height());
00302 #endif
00303 return h;
00304 }
00305
00316 QSize QwtRichTextEngine::textSize(const QFont &font,
00317 int flags, const QString& text) const
00318 {
00319 QwtRichTextDocument doc(text, flags, font);
00320
00321 #if QT_VERSION < 0x040000
00322 doc.setWidth(QWIDGETSIZE_MAX);
00323
00324 const int w = doc.widthUsed();
00325 const int h = doc.height();
00326 return QSize(w, h);
00327
00328 #else // QT_VERSION >= 0x040000
00329
00330 #if QT_VERSION < 0x040200
00331
00332
00333
00334
00335
00336
00337
00338
00339 static int off = 0;
00340 static QLabel *label = NULL;
00341 if ( label == NULL )
00342 {
00343 label = new QLabel;
00344 label->hide();
00345
00346 const char *s = "XXXXX";
00347 label->setText(s);
00348 int w1 = label->sizeHint().width();
00349 const QFontMetrics fm(label->font());
00350 int w2 = fm.width(s);
00351 off = w1 - w2;
00352 }
00353 label->setFont(doc.defaultFont());
00354 label->setText(text);
00355
00356 int w = qwtMax(label->sizeHint().width() - off, 0);
00357 doc.setPageSize(QSize(w, QWIDGETSIZE_MAX));
00358
00359 int h = qRound(doc.documentLayout()->documentSize().height());
00360 return QSize(w, h);
00361
00362 #else // QT_VERSION >= 0x040200
00363
00364 #if QT_VERSION >= 0x040300
00365 QTextOption option = doc.defaultTextOption();
00366 if ( option.wrapMode() != QTextOption::NoWrap )
00367 {
00368 option.setWrapMode(QTextOption::NoWrap);
00369 doc.setDefaultTextOption(option);
00370 doc.adjustSize();
00371 }
00372 #endif
00373
00374 return doc.size().toSize();
00375 #endif
00376 #endif
00377 }
00378
00387 void QwtRichTextEngine::draw(QPainter *painter, const QRect &rect,
00388 int flags, const QString& text) const
00389 {
00390 QwtRichTextDocument doc(text, flags, painter->font());
00391 QwtPainter::drawSimpleRichText(painter, rect, flags, doc);
00392 }
00393
00402 QString QwtRichTextEngine::taggedText(const QString &text, int flags) const
00403 {
00404 return taggedRichText(text, flags);
00405 }
00406
00413 bool QwtRichTextEngine::mightRender(const QString &text) const
00414 {
00415 #if QT_VERSION < 0x040000
00416 return QStyleSheet::mightBeRichText(text);
00417 #else
00418 return Qt::mightBeRichText(text);
00419 #endif
00420 }
00421
00430 void QwtRichTextEngine::textMargins(const QFont &, const QString &,
00431 int &left, int &right, int &top, int &bottom) const
00432 {
00433 left = right = top = bottom = 0;
00434 }
00435
00436 #endif // !QT_NO_RICHTEXT