00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include <qwindowdefs.h>
00013
#include <qrect.h>
00014
#include <qpainter.h>
00015
#include <qpalette.h>
00016
#include <qpaintdevice.h>
00017
#include <qpaintdevicemetrics.h>
00018
#include <qpixmap.h>
00019
#include <qsimplerichtext.h>
00020
00021
#include "qwt_painter.h"
00022
#include "qwt_rect.h"
00023
#include "qwt_math.h"
00024
00025
#if defined(Q_WS_X11)
00026
bool QwtPainter::d_deviceClipping = TRUE;
00027
#else
00028
bool QwtPainter::d_deviceClipping = FALSE;
00029
#endif
00030
00031 QwtMetricsMap QwtPainter::d_metricsMap;
00032
00033
#if defined(QWT_BROKEN_RASTEROP_FONT)
00034
#if QT_VERSION < 300
00035
00036
00037
00038
00039
00040
#include <stdlib.h>
00041
static int qwt_use_xft (
void)
00042 {
00043
static int checked_env=0;
00044
static int use_xft=0;
00045
00046
if (!checked_env) {
00047
char *e = getenv (
"QT_XFT");
00048
if ( e && (*e ==
'1' ||
00049 *e ==
'y' || *e ==
'Y' ||
00050 *e ==
't' || *e ==
'T' ))
00051 use_xft = 1;
00052
else
00053 use_xft = 0;
00054 }
00055 checked_env = 1;
00056
00057
return use_xft;
00058 }
00059
int QwtPainter::d_textXorRopMode = qwt_use_xft() ?
00060 QwtPainter::XorRopTextKeepFont : QwtPainter::XorRopTextNormal;
00061
#else // QT_VERSION >= 300
00062
#if 1
00063
int QwtPainter::d_textXorRopMode = QwtPainter::XorRopTextKeepFont;
00064
#else
00065
int QwtPainter::d_textXorRopMode = QwtPainter::XorRopTextKeepColor;
00066
#endif
00067
#endif // QT_VERSION
00068
#else
00069
int QwtPainter::d_textXorRopMode = QwtPainter::XorRopTextNormal;
00070
#endif
00071
00077 void QwtPainter::setDeviceClipping(
bool enable)
00078 {
00079 d_deviceClipping = enable;
00080 }
00081
00088 bool QwtPainter::deviceClipping()
00089 {
00090
return d_deviceClipping;
00091 }
00092
00097
const QRect &QwtPainter::deviceClipRect()
00098 {
00099
static QRect clip;
00100
00101
if ( !clip.isValid() )
00102 {
00103 clip.setCoords(QWT_COORD_MIN, QWT_COORD_MIN,
00104 QWT_COORD_MAX, QWT_COORD_MAX);
00105 }
00106
return clip;
00107 }
00108
00117 void QwtPainter::setMetricsMap(
const QPaintDevice *layout,
00118
const QPaintDevice *device)
00119 {
00120 d_metricsMap.setMetrics(layout, device);
00121 }
00122
00127 void QwtPainter::setMetricsMap(
const QwtMetricsMap &map)
00128 {
00129 d_metricsMap = map;
00130 }
00131
00136 void QwtPainter::resetMetricsMap()
00137 {
00138 d_metricsMap = QwtMetricsMap();
00139 }
00140
00144 const QwtMetricsMap &
QwtPainter::metricsMap()
00145 {
00146
return d_metricsMap;
00147 }
00148
00152 void QwtPainter::setClipRect(QPainter *painter,
const QRect &rect)
00153 {
00154 painter->setClipRect(d_metricsMap.layoutToDevice(rect, painter));
00155 }
00156
00160 void QwtPainter::drawRect(QPainter *painter,
int x,
int y,
int w,
int h)
00161 {
00162
drawRect(painter, QRect(x, y, w, h));
00163 }
00164
00168 void QwtPainter::drawRect(QPainter *painter,
const QRect &rect)
00169 {
00170
const QRect r = d_metricsMap.layoutToDevice(rect, painter);
00171
00172
if ( d_deviceClipping && !deviceClipRect().contains(r) )
00173
return;
00174
00175 painter->drawRect(r);
00176 }
00177
00181 void QwtPainter::fillRect(QPainter *painter,
00182
const QRect &rect,
const QBrush &brush)
00183 {
00184
const QRect r = d_metricsMap.layoutToDevice(rect, painter);
00185
00186
if ( d_deviceClipping && !deviceClipRect().contains(r) )
00187
return;
00188
00189 painter->fillRect(r, brush);
00190 }
00191
00195 void QwtPainter::drawEllipse(QPainter *painter,
const QRect &rect)
00196 {
00197
const QRect r = d_metricsMap.layoutToDevice(rect, painter);
00198
00199
if ( d_deviceClipping && !deviceClipRect().contains(rect) )
00200
return;
00201
00202 painter->drawEllipse(r);
00203 }
00204
00208 void QwtPainter::drawText(QPainter *painter,
int x,
int y,
00209
const QString &text,
int len)
00210 {
00211
drawText(painter, QPoint(x, y), text, len);
00212 }
00213
00217 void QwtPainter::drawText(QPainter *painter,
const QPoint &pos,
00218
const QString &text,
int len)
00219 {
00220
const QPoint p = d_metricsMap.layoutToDevice(pos, painter);
00221
00222
if ( d_deviceClipping && !deviceClipRect().contains(p) )
00223
return;
00224
00225
#if defined(QWT_BROKEN_RASTEROP_FONT)
00226
00227
#if QT_VERSION >= 300
00228
if (Qt::XorROP == painter->rasterOp()
00229 && d_textXorRopMode == XorRopTextKeepColor)
00230 {
00231
00232
extern bool qt_has_xft;
00233
const bool XftEnabled = qt_has_xft;
00234 qt_has_xft = FALSE;
00235
00236
00237 painter->save();
00238 QFont font = painter->font();
00239 font.setStyleStrategy(QFont::PreferBitmap);
00240 painter->setFont(font);
00241
00242 painter->drawText(p, text, len);
00243
00244
00245 qt_has_xft = XftEnabled;
00246 painter->restore();
00247
00248 }
00249
else
00250
#endif
00251
if (Qt::XorROP == painter->rasterOp()
00252 && d_textXorRopMode == XorRopTextKeepFont)
00253 {
00254
00255
#if QT_VERSION < 300
00256
int flags = Qt::AlignLeft;
00257
#else
00258
int flags = Qt::AlignAuto;
00259
#endif
00260
QFontMetrics fm = painter->fontMetrics();
00261 QPixmap pixmap(fm.boundingRect(
00262 0, 0, QCOORD_MAX, QCOORD_MAX, flags, text, len).size());
00263 pixmap.fill(QColor(0, 0, 0));
00264
00265
00266 QPainter pmPainter(&pixmap);
00267 pmPainter.setPen(painter->pen());
00268 pmPainter.setFont(painter->font());
00269 pmPainter.drawText(pixmap.rect(), flags, text, len);
00270
00271
00272 painter->drawPixmap(p.x(), p.y() - fm.ascent(), pixmap);
00273 }
00274
else
00275
#endif
00276
{
00277 painter->drawText(p, text, len);
00278 }
00279 }
00280
00284 void QwtPainter::drawText(QPainter *painter,
int x,
int y,
int w,
int h,
00285
int flags,
const QString &text,
int len)
00286 {
00287
drawText(painter, QRect(x, y, w, h), flags, text, len);
00288 }
00289
00293 void QwtPainter::drawText(QPainter *painter,
const QRect &rect,
00294
int flags,
const QString &text,
int len)
00295 {
00296
#if defined(QWT_BROKEN_RASTEROP_FONT)
00297
00298
#if QT_VERSION >= 300
00299
if (Qt::XorROP == painter->rasterOp()
00300 && d_textXorRopMode == XorRopTextKeepColor)
00301 {
00302
00303
extern bool qt_has_xft;
00304
const bool XftEnabled = qt_has_xft;
00305 qt_has_xft = FALSE;
00306
00307
00308 painter->save();
00309 QFont font = painter->font();
00310 font.setStyleStrategy(QFont::PreferBitmap);
00311 painter->setFont(font);
00312
00313 painter->drawText(
00314 d_metricsMap.layoutToDevice(rect, painter), flags, text, len);
00315
00316
00317 painter->restore();
00318 qt_has_xft = XftEnabled;
00319
00320 }
00321
else
00322
#endif
00323
if (Qt::XorROP == painter->rasterOp()
00324 && d_textXorRopMode == XorRopTextKeepFont)
00325 {
00326
00327 QRect target = d_metricsMap.layoutToDevice(rect, painter);
00328 QPixmap pixmap(target.size());
00329 pixmap.fill(QColor(0, 0, 0));
00330
00331
00332 QPainter pmPainter(&pixmap);
00333 pmPainter.setPen(painter->pen());
00334 pmPainter.setFont(painter->font());
00335 pmPainter.drawText(pixmap.rect(), flags, text, len);
00336
00337
00338
#if QT_VERSION < 300
00339
painter->drawPixmap(target.x(), target.y(), pixmap);
00340
#else
00341
painter->drawPixmap(target, pixmap);
00342
#endif
00343
}
00344
else
00345
#endif
00346
{
00347 painter->drawText(
00348 d_metricsMap.layoutToDevice(rect, painter), flags, text, len);
00349 }
00350 }
00351
00352
#ifndef QT_NO_RICHTEXT
00353
00357 void QwtPainter::drawSimpleRichText(QPainter *painter,
const QRect &rect,
00358
int flags, QSimpleRichText &text)
00359 {
00360 QColorGroup cg;
00361 cg.setColor(QColorGroup::Text, painter->pen().color());
00362
00363
#if QT_VERSION < 300
00364
const QFont defaultFont = QFont::defaultFont();
00365 QFont::setDefaultFont(painter->font());
00366
#endif
00367
00368
const QRect scaledRect = d_metricsMap.layoutToDevice(rect, painter);
00369
00370 text.setWidth(painter, scaledRect.width());
00371
00372
00373
00374
int y = scaledRect.y();
00375
if (flags & Qt::AlignBottom)
00376 y += (scaledRect.height() - text.height());
00377
else if (flags & Qt::AlignVCenter)
00378 y += (scaledRect.height() - text.height())/2;
00379
00380
#if defined(QWT_BROKEN_RASTEROP_FONT)
00381
00382
#if QT_VERSION >= 300
00383
if (Qt::XorROP == painter->rasterOp()
00384 && d_textXorRopMode == XorRopTextKeepColor)
00385 {
00386
00387
extern bool qt_has_xft;
00388
const bool XftEnabled = qt_has_xft;
00389 qt_has_xft = FALSE;
00390
00391
00392 painter->save();
00393 QFont font = painter->font();
00394 font.setStyleStrategy(QFont::PreferBitmap);
00395 painter->setFont(font);
00396
00397 text.draw(painter, scaledRect.x(), y, scaledRect, cg);
00398
00399
00400 painter->restore();
00401 qt_has_xft = XftEnabled;
00402
00403 }
00404
else
00405
#endif
00406
if (Qt::XorROP == painter->rasterOp()
00407 && d_textXorRopMode == XorRopTextKeepFont)
00408 {
00409
00410 QPixmap pixmap(scaledRect.size());
00411 pixmap.fill(QColor(0, 0, 0));
00412
00413
00414 QPainter pmPainter(&pixmap);
00415 pmPainter.setPen(painter->pen());
00416 pmPainter.setFont(painter->font());
00417 text.draw(&pmPainter, scaledRect.x(), y, scaledRect, cg);
00418
00419
00420
#if QT_VERSION < 300
00421
painter->drawPixmap(scaledRect.x(), scaledRect.y(), pixmap);
00422
#else
00423
painter->drawPixmap(scaledRect, pixmap);
00424
#endif
00425
}
00426
else
00427
#endif
00428
{
00429 text.draw(painter, scaledRect.x(), y, scaledRect, cg);
00430 }
00431
00432
#if QT_VERSION < 300
00433
QFont::setDefaultFont(defaultFont);
00434
#endif
00435
}
00436
00437
#endif // !QT_NO_RICHTEXT
00438
00439
00443 void QwtPainter::drawLine(QPainter *painter,
00444
const QPoint &p1,
const QPoint &p2)
00445 {
00446 QPointArray pa(2);
00447
00448
if ( d_deviceClipping &&
00449 !(deviceClipRect().contains(p1) && deviceClipRect().contains(p2)) )
00450 {
00451 pa.setPoint(0, p1);
00452 pa.setPoint(1, p2);
00453
drawPolyline(painter, pa);
00454 }
00455
else
00456 {
00457 pa.setPoint(0, d_metricsMap.layoutToDevice(p1));
00458 pa.setPoint(1, d_metricsMap.layoutToDevice(p2));
00459
00460
#if QT_VERSION >= 0x030200
00461
if ( painter->device()->isExtDev() )
00462 {
00463
00464
00465
00466
00467 painter->drawLineSegments(pa);
00468 }
00469
else
00470 painter->drawLine(pa[0], pa[1]);
00471
#else
00472
painter->drawLine(pa[0], pa[1]);
00473
#endif
00474
}
00475 }
00476
00481 void QwtPainter::drawLine(QPainter *painter,
int x1,
int y1,
int x2,
int y2)
00482 {
00483
drawLine(painter, QPoint(x1, y1), QPoint(x2, y2));
00484 }
00485
00490 void QwtPainter::drawPolygon(QPainter *painter,
const QPointArray &pa)
00491 {
00492 QPointArray cpa = d_metricsMap.layoutToDevice(pa);
00493
if ( d_deviceClipping )
00494 cpa =
clip(cpa);
00495 painter->drawPolygon(cpa);
00496 }
00497
00501 void QwtPainter::drawPolyline(QPainter *painter,
const QPointArray &pa)
00502 {
00503 QPointArray cpa = d_metricsMap.layoutToDevice(pa);
00504
if ( d_deviceClipping )
00505 cpa =
clip(cpa);
00506 painter->drawPolyline(cpa);
00507 }
00508
00513 void QwtPainter::drawPoint(QPainter *painter,
int x,
int y)
00514 {
00515
const QPoint pos = d_metricsMap.layoutToDevice(QPoint(x, y));
00516
00517
if ( d_deviceClipping && !deviceClipRect().contains(pos) )
00518
return;
00519
00520 painter->drawPoint(pos);
00521 }
00522
00524 QPointArray
QwtPainter::clip(
const QPointArray &pa)
00525 {
00526
const QwtRect rect(deviceClipRect());
00527
return rect.
clip(pa);
00528 }
00529
00530
void QwtPainter::drawColoredArc(QPainter *painter,
const QRect &rect,
00531
int peak,
int arc,
int intervall,
const QColor &c1,
const QColor &c2)
00532 {
00533
int h1, s1, v1;
00534
int h2, s2, v2;
00535
00536 c1.hsv(&h1, &s1, &v1);
00537 c2.hsv(&h2, &s2, &v2);
00538
00539 arc /= 2;
00540
for (
int angle = -arc; angle < arc; angle += intervall)
00541 {
00542
double ratio;
00543
if ( angle >= 0 )
00544 ratio = 1.0 - angle / double(arc);
00545
else
00546 ratio = 1.0 + angle / double(arc);
00547
00548
00549
const QColor c(h1 + qRound(ratio * (h2 - h1)),
00550 s1 + qRound(ratio * (s2 - s1)),
00551 v1 + qRound(ratio * (v2 - v1)),
00552 QColor::Hsv);
00553
00554 painter->setPen(QPen(c, painter->pen().width()));
00555 painter->drawArc(rect, (peak + angle) * 16, intervall * 16);
00556 }
00557 }
00558
00560 void QwtPainter::drawRoundFrame(QPainter *painter,
const QRect &rect,
00561
int width,
const QColorGroup &cg,
bool sunken)
00562 {
00563 QColor c0 = cg.mid();
00564 QColor c1, c2;
00565
if ( sunken )
00566 {
00567 c1 = cg.dark();
00568 c2 = cg.light();
00569 }
00570
else
00571 {
00572 c1 = cg.light();
00573 c2 = cg.dark();
00574 }
00575
00576 painter->setPen(QPen(c0, width));
00577 painter->drawArc(rect, 0, 360 * 16);
00578
00579
const int peak = 150;
00580
const int intervall = 2;
00581
00582
if ( c0 != c1 )
00583 drawColoredArc(painter, rect, peak, 160, intervall, c0, c1);
00584
if ( c0 != c2 )
00585 drawColoredArc(painter, rect, peak + 180, 120, intervall, c0, c2);
00586 }
00587
00594 int QwtPainter::textXorRopMode()
00595 {
00596
return d_textXorRopMode;
00597 }
00598
00618
#if defined(QWT_BROKEN_RASTEROP_FONT)
00619
00620
int QwtPainter::setTextXorRopMode(TextXorRopMode mode)
00621 {
00622
if ((mode == XorRopTextNormal)
00623 || (mode == XorRopTextKeepFont)
00624
#if QT_VERSION >= 300
00625
|| (mode == XorRopTextKeepColor)
00626
#endif
00627
)
00628 d_textXorRopMode = mode;
00629
00630
#if QT_VERSION < 300
00631
if (!qwt_use_xft())
00632 d_textXorRopMode = XorRopTextNormal;
00633
#endif
00634
00635
return d_textXorRopMode;
00636 }
00637
00638
#else
00639
00640 int QwtPainter::setTextXorRopMode(TextXorRopMode)
00641 {
00642
return d_textXorRopMode;
00643 }
00644
00645
#endif
00646
00647
00648
00649
00650
00651