00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <qpainter.h>
00014 #include <qpalette.h>
00015 #include <qwidget.h>
00016 #include "qwt_math.h"
00017 #include "qwt_painter.h"
00018 #include "qwt_layout_metrics.h"
00019 #include "qwt_scale_div.h"
00020 #include "qwt_scale_draw.h"
00021 #if QT_VERSION < 0x040000
00022 #include <qwmatrix.h>
00023 #define QwtMatrix QWMatrix
00024 #else
00025 #include <qmatrix.h>
00026 #define QwtMatrix QMatrix
00027 #endif
00028
00029 class QwtScaleDraw::PrivateData
00030 {
00031 public:
00032 PrivateData():
00033 options(QwtScaleDraw::Backbone),
00034 hpad(4),
00035 vpad(4),
00036 medLen(6),
00037 majLen(8),
00038 minLen(4),
00039 minAngle(-135 * 16),
00040 maxAngle(135 * 16),
00041 fmt('g'),
00042 prec(4),
00043 fieldwidth(0),
00044 labelFlags(0),
00045 labelRotation(0.0)
00046 {
00047
00048
00049 sprintf(formatBuffer, "%%%d.%d%c", fieldwidth, prec, fmt);
00050 }
00051
00052 int options;
00053
00054 QwtScaleMap map;
00055 QwtScaleDiv scldiv;
00056 QwtScaleDraw::Orientation orient;
00057
00058 int xorg;
00059 int yorg;
00060 int len;
00061
00062 unsigned int hpad;
00063 unsigned int vpad;
00064
00065 unsigned int medLen;
00066 unsigned int majLen;
00067 unsigned int minLen;
00068
00069 int minAngle;
00070 int maxAngle;
00071
00072 double xCenter;
00073 double yCenter;
00074 double radius;
00075
00076 char fmt;
00077 int prec;
00078 int fieldwidth;
00079
00080 int labelFlags;
00081 double labelRotation;
00082
00083
00084
00085
00086
00087
00088
00089
00090 char formatBuffer[8];
00091 };
00092
00101 QwtScaleDraw::QwtScaleDraw()
00102 {
00103 d_data = new QwtScaleDraw::PrivateData;
00104 setGeometry(0,0,100,Bottom);
00105 }
00106
00107 QwtScaleDraw::QwtScaleDraw(const QwtScaleDraw &other)
00108 {
00109 d_data = new QwtScaleDraw::PrivateData(*other.d_data);
00110 }
00111
00112
00114 QwtScaleDraw::~QwtScaleDraw()
00115 {
00116 delete d_data;
00117 }
00118
00119 QwtScaleDraw &QwtScaleDraw::operator=(const QwtScaleDraw &other)
00120 {
00121 *d_data = *other.d_data;
00122 return *this;
00123 }
00124
00126 void QwtScaleDraw::setOptions(int opt)
00127 {
00128 d_data->options = opt;
00129 }
00130
00134 int QwtScaleDraw::options() const
00135 {
00136 return d_data->options;
00137 }
00138
00143 void QwtScaleDraw::setScaleDiv(const QwtScaleDiv &sd)
00144 {
00145 d_data->scldiv = sd;
00146 d_data->map.setScaleInterval(sd.lBound(), sd.hBound());
00147 }
00148
00149 void QwtScaleDraw::setTransformation(
00150 const QwtScaleTransformation &transformation)
00151 {
00152 d_data->map.setTransformation(transformation);
00153 }
00154
00155 const QwtScaleMap &QwtScaleDraw::map() const
00156 {
00157 return d_data->map;
00158 }
00159
00161 const QwtScaleDiv& QwtScaleDraw::scaleDiv() const
00162 {
00163 return d_data->scldiv;
00164 }
00165
00178 #if QT_VERSION < 0x040000
00179 void QwtScaleDraw::draw(QPainter *painter, const QColorGroup& colorGroup) const
00180 #else
00181 void QwtScaleDraw::draw(QPainter *painter, const QPalette& palette) const
00182 #endif
00183 {
00184 uint i;
00185
00186 QPen pen = painter->pen();
00187
00188 #if QT_VERSION < 0x040000
00189 painter->setPen(colorGroup.text());
00190 #else
00191 painter->setPen(palette.color(QPalette::Text));
00192 #endif
00193
00194 const QwtTickList &majorTicks =
00195 d_data->scldiv.ticks(QwtScaleDiv::MajorTick);
00196
00197 for (i=0; i< (uint)majorTicks.count(); i++)
00198 {
00199 const double v = majorTicks[i];
00200 if ( d_data->scldiv.contains(v) )
00201 drawLabel(painter, majorTicks[i]);
00202 }
00203
00204 #if QT_VERSION < 0x040000
00205 pen.setColor(colorGroup.foreground());
00206 #else
00207 pen.setColor(palette.color(QPalette::Foreground));
00208 #endif
00209
00210 int tickLength[QwtScaleDiv::NTickTypes];
00211 tickLength[QwtScaleDiv::MinorTick] = d_data->minLen;
00212 tickLength[QwtScaleDiv::MediumTick] = d_data->medLen;
00213 tickLength[QwtScaleDiv::MajorTick] = d_data->majLen;
00214
00215 for ( int tickType = QwtScaleDiv::MinorTick;
00216 tickType < QwtScaleDiv::NTickTypes; tickType++ )
00217 {
00218 const QwtTickList &ticks = d_data->scldiv.ticks(tickType);
00219 for (i=0; i < (uint)ticks.count(); i++)
00220 {
00221 const double v = ticks[i];
00222 if ( d_data->scldiv.contains(v) )
00223 drawTick(painter, ticks[i], tickLength[tickType]);
00224 }
00225 }
00226
00227 if ( options() & Backbone )
00228 drawBackbone(painter);
00229 }
00230
00231
00233 void QwtScaleDraw::drawTick(QPainter *painter, double val, int len) const
00234 {
00235 if ( len <= 0 )
00236 return;
00237
00238 const int tval = map().transform(val);
00239
00240 switch(d_data->orient)
00241 {
00242 case Left:
00243 QwtPainter::drawLine(painter, d_data->xorg, tval,
00244 d_data->xorg - len, tval);
00245 break;
00246
00247 case Right:
00248 QwtPainter::drawLine(painter, d_data->xorg, tval,
00249 d_data->xorg + len, tval);
00250 break;
00251
00252 case Bottom:
00253 QwtPainter::drawLine(painter, tval, d_data->yorg,
00254 tval, d_data->yorg + len);
00255 break;
00256
00257 case Top:
00258 QwtPainter::drawLine(painter, tval, d_data->yorg,
00259 tval, d_data->yorg - len);
00260 break;
00261
00262 case Round:
00263 if ((tval <= d_data->minAngle + 359 * 16)
00264 || (tval >= d_data->minAngle - 359 * 16))
00265 {
00266 const double arc = double(tval) / 16.0 * M_PI / 180.0;
00267 const int x1 = qRound( d_data->xCenter + sin(arc)
00268 * d_data->radius);
00269 const int x2 = qRound(d_data->xCenter + sin(arc)
00270 * (d_data->radius + double(len)));
00271 const int y1 = qRound(d_data->yCenter - cos(arc)
00272 * d_data->radius);
00273 const int y2 = qRound(d_data->yCenter - cos(arc)
00274 * (d_data->radius + double(len)));
00275
00276 QwtPainter::drawLine(painter, x1, y1, x2, y2);
00277 }
00278 break;
00279 }
00280 }
00281
00283 void QwtScaleDraw::drawLabel(QPainter *painter, double val) const
00284 {
00285 QPoint pos;
00286 int flags;
00287 double rotation;
00288 labelPlacement(QFontMetrics(painter->font()), val, pos, flags, rotation);
00289
00290 if ( flags )
00291 {
00292 const QString txt = label(val);
00293 if ( !txt.isEmpty() )
00294 {
00295 QwtMatrix m = labelWorldMatrix(QFontMetrics(painter->font()),
00296 pos, flags, rotation, txt);
00297
00298 painter->save();
00299 #ifndef QT_NO_TRANSFORMATIONS
00300 #if QT_VERSION < 0x040000
00301 painter->setWorldMatrix(m, true);
00302 #else
00303 painter->setMatrix(m, true);
00304 #endif
00305 #else
00306 painter->translate(m.dx(), m.dy());
00307 #endif
00308 QwtPainter::drawText(painter, 0, 0, txt);
00309 painter->restore();
00310 }
00311 }
00312 }
00313
00315 void QwtScaleDraw::labelPlacement( const QFontMetrics &fm, double val,
00316 QPoint &pos, int &flags, double &rotation) const
00317 {
00318 const int tval = map().transform(val);
00319
00320 int x = 0;
00321 int y = 0;
00322 int flgs = 0;
00323
00324 switch(d_data->orient)
00325 {
00326 case Right:
00327 {
00328 x = d_data->xorg + d_data->majLen + d_data->hpad + 1;
00329 y = tval;
00330 flgs = d_data->labelFlags;
00331 if ( flgs == 0 )
00332 flgs = Qt::AlignRight | Qt::AlignVCenter;
00333 break;
00334 }
00335 case Left:
00336 {
00337 x = d_data->xorg - d_data->majLen - d_data->hpad - 1;
00338 y = tval;
00339 flgs = d_data->labelFlags;
00340 if ( flgs == 0 )
00341 flgs = Qt::AlignLeft | Qt::AlignVCenter;
00342 break;
00343 }
00344 case Bottom:
00345 {
00346 x = tval;
00347 y = d_data->yorg + d_data->majLen + d_data->vpad + 1;
00348 flgs = d_data->labelFlags;
00349 if ( flgs == 0 )
00350 flgs = Qt::AlignHCenter | Qt::AlignBottom;
00351 break;
00352 }
00353 case Top:
00354 {
00355 x = tval;
00356 y = d_data->yorg - d_data->majLen - d_data->vpad - 1;
00357 flgs = d_data->labelFlags;
00358 if ( flgs == 0 )
00359 flgs = Qt::AlignHCenter | Qt::AlignTop;
00360 break;
00361 }
00362 case Round:
00363 {
00364 if ((tval > d_data->minAngle + 359 * 16)
00365 || (tval < d_data->minAngle - 359 * 16))
00366 {
00367 break;
00368 }
00369
00370 const int fmh = fm.ascent() - 2;
00371 const double arc = tval / 16.0 / 360.0 * 2 * M_PI;
00372 const double radius = d_data->radius + d_data->majLen + d_data->vpad;
00373
00374
00375
00376
00377 double xOffset = ( radius + fmh / 2 ) * sin(arc);
00378 double yOffset = ( radius + fmh / 2 ) * cos(arc);
00379
00380 if ( qRound(xOffset) != 0 )
00381 {
00382
00383
00384
00385
00386
00387
00388 const int fmw = fm.width(label(val));
00389
00390 const double circleX = radius * sin(arc);
00391 if ( xOffset < 0 )
00392 xOffset = circleX - fmw / 2;
00393 else
00394 xOffset = circleX + fmw / 2;
00395 }
00396 x = qRound(d_data->xCenter + xOffset);
00397 y = qRound(d_data->yCenter - yOffset);
00398 flgs = Qt::AlignHCenter | Qt::AlignVCenter;
00399
00400 break;
00401 }
00402 }
00403
00404 pos = QPoint(x, y);
00405 flags = flgs;
00406 rotation = d_data->labelRotation;
00407 }
00408
00410 QwtMatrix QwtScaleDraw::labelWorldMatrix(const QFontMetrics &fm,
00411 const QPoint &pos, int flags,
00412 #ifdef QT_NO_TRANSFORMATIONS
00413 double,
00414 #else
00415 double rotation,
00416 #endif
00417 const QString &txt) const
00418 {
00419 const int w = fm.boundingRect(0, 0,
00420 QWIDGETSIZE_MAX, QWIDGETSIZE_MAX, 0, txt).width() - 2;
00421 const int h = fm.ascent() - 2;
00422
00423 int x, y;
00424 if ( flags & Qt::AlignLeft )
00425 x = -w;
00426 else if ( flags & Qt::AlignRight )
00427 x = 0 - w % 2;
00428 else
00429 x = -(w / 2);
00430
00431 if ( flags & Qt::AlignTop )
00432 y = 0;
00433 else if ( flags & Qt::AlignBottom )
00434 y = h - 1;
00435 else
00436 y = h / 2;
00437
00438 QwtMatrix m;
00439 m.translate(pos.x(), pos.y());
00440 #ifndef QT_NO_TRANSFORMATIONS
00441 m.rotate(rotation);
00442 #endif
00443 m.translate(x, y);
00444
00445 return m;
00446 }
00447
00449 void QwtScaleDraw::drawBackbone(QPainter *painter) const
00450 {
00451 const int bw2 = painter->pen().width() / 2;
00452
00453 switch(d_data->orient)
00454 {
00455 case Left:
00456 QwtPainter::drawLine(painter, d_data->xorg - bw2,
00457 d_data->yorg, d_data->xorg - bw2, d_data->yorg + d_data->len - 1);
00458 break;
00459 case Right:
00460 QwtPainter::drawLine(painter, d_data->xorg + bw2,
00461 d_data->yorg, d_data->xorg + bw2, d_data->yorg + d_data->len - 1);
00462 break;
00463 case Top:
00464 QwtPainter::drawLine(painter, d_data->xorg, d_data->yorg - bw2,
00465 d_data->xorg + d_data->len - 1, d_data->yorg - bw2);
00466 break;
00467 case Bottom:
00468 QwtPainter::drawLine(painter, d_data->xorg, d_data->yorg + bw2,
00469 d_data->xorg + d_data->len - 1, d_data->yorg + bw2);
00470 break;
00471 case Round:
00472 {
00473 const int a1 = qRound(qwtMin(map().p1(), map().p2()) - 90 * 16);
00474 const int a2 = qRound(qwtMax(map().p1(), map().p2()) - 90 * 16);
00475
00476 painter->drawArc(d_data->xorg, d_data->yorg, d_data->len,
00477 d_data->len, -a2, a2 - a1 + 1);
00478 break;
00479 }
00480 }
00481 }
00482
00483
00523 void QwtScaleDraw::setGeometry(int xorigin, int yorigin,
00524 int length, Orientation o)
00525 {
00526 static int minLen = 10;
00527
00528 d_data->xorg = xorigin;
00529 d_data->yorg = yorigin;
00530 d_data->radius = double(length) * 0.5;
00531 d_data->xCenter = double(xorigin) + double(length) * 0.5;
00532 d_data->yCenter = double(yorigin) + double(length) * 0.5;
00533
00534 if (length > minLen)
00535 d_data->len = length;
00536 else
00537 d_data->len = minLen;
00538
00539 d_data->orient = o;
00540
00541 switch(d_data->orient)
00542 {
00543 case Left:
00544 case Right:
00545 d_data->map.setPaintInterval(d_data->yorg + d_data->len - 1, d_data->yorg);
00546 break;
00547 case Round:
00548 d_data->map.setPaintInterval(d_data->minAngle, d_data->maxAngle);
00549 break;
00550 case Top:
00551 case Bottom:
00552 d_data->map.setPaintInterval(d_data->xorg, d_data->xorg + d_data->len - 1);
00553 break;
00554 }
00555 }
00556
00562 int QwtScaleDraw::maxWidth(const QPen &pen, const QFont &font) const
00563 {
00564 int w = 0;
00565
00566 switch (d_data->orient)
00567 {
00568 case Left:
00569 case Right:
00570 w += pen.width() + d_data->majLen
00571 + d_data->hpad + maxLabelWidth(font);
00572 break;
00573 case Round:
00574 w += pen.width() + d_data->majLen
00575 + d_data->vpad + maxLabelWidth(font);
00576 break;
00577 case Top:
00578 case Bottom:
00579 w = d_data->len + maxLabelWidth(font);
00580 break;
00581 }
00582 return w;
00583 }
00584
00590 int QwtScaleDraw::maxHeight(const QPen &pen, const QFont &font) const
00591 {
00592 int h = 0;
00593
00594 switch (d_data->orient)
00595 {
00596 case Top:
00597 case Bottom:
00598 h = pen.width() + d_data->vpad
00599 + d_data->majLen + maxLabelHeight(font);
00600 break;
00601 case Left:
00602 case Right:
00603 h = d_data->len + maxLabelHeight(font);
00604 break;
00605 case Round:
00606 h = d_data->vpad + d_data->majLen;
00607 if ( maxLabelHeight(font) > 0 )
00608 {
00609 const QFontMetrics fm(font);
00610 h += fm.ascent() - 2;
00611 }
00612 break;
00613 }
00614
00615 return h;
00616 }
00617
00627 void QwtScaleDraw::setLabelRotation(double rotation)
00628 {
00629 d_data->labelRotation = rotation;
00630 }
00631
00636 double QwtScaleDraw::labelRotation() const
00637 {
00638 return d_data->labelRotation;
00639 }
00640
00660 void QwtScaleDraw::setLabelFlags(int flags)
00661 {
00662 d_data->labelFlags = flags;
00663 }
00664
00669 int QwtScaleDraw::labelFlags() const
00670 {
00671 return d_data->labelFlags;
00672 }
00673
00692 void QwtScaleDraw::setAngleRange(double angle1, double angle2)
00693 {
00694 angle1 = qwtLim(angle1, -360.0, 360.0);
00695 angle2 = qwtLim(angle2, -360.0, 360.0);
00696
00697 int amin = qRound(qwtMin(angle1, angle2) * 16.0);
00698 int amax = qRound(qwtMax(angle1, angle2) * 16.0);
00699
00700 if (amin == amax)
00701 {
00702 amin -= 1;
00703 amax += 1;
00704 }
00705
00706 d_data->minAngle = amin;
00707 d_data->maxAngle = amax;
00708 d_data->map.setPaintInterval(d_data->minAngle, d_data->maxAngle);
00709 }
00710
00727 void QwtScaleDraw::setLabelFormat(char f, int prec, int fieldwidth)
00728 {
00729 switch(f)
00730 {
00731 case 'e':
00732 case 'f':
00733 case 'g':
00734 d_data->fmt = f;
00735 break;
00736 default:
00737 break;
00738 }
00739 if ((prec > -1) && (prec < 99))
00740 d_data->prec = prec;
00741 if ((fieldwidth > -1) && (fieldwidth < 99))
00742 d_data->fieldwidth = fieldwidth;
00743
00744 sprintf(d_data->formatBuffer, "%%%d.%d%c", d_data->fieldwidth, d_data->prec, d_data->fmt);
00745 }
00746
00760 void QwtScaleDraw::labelFormat(char &f, int &prec, int &fieldwidth) const
00761 {
00762 f = d_data->fmt;
00763 prec = d_data->prec;
00764 fieldwidth = d_data->fieldwidth;
00765 }
00766
00773 void QwtScaleDraw::setMargin(uint hMargin, uint vMargin)
00774 {
00775 d_data->hpad = hMargin;
00776 d_data->vpad = vMargin;
00777 }
00778
00782 void QwtScaleDraw::setTickLength(unsigned int minLen,
00783 unsigned int medLen, unsigned int majLen)
00784 {
00785 const unsigned int maxTickLen = 1000;
00786
00787 d_data->minLen = qwtMin(minLen, maxTickLen);
00788 d_data->medLen = qwtMin(medLen, maxTickLen);
00789 d_data->majLen = qwtMin(majLen, maxTickLen);
00790 }
00791
00796 void QwtScaleDraw::tickLength(unsigned int &minLen,
00797 unsigned int &medLen, unsigned int &majLen) const
00798 {
00799 minLen = d_data->minLen;
00800 medLen = d_data->medLen;
00801 majLen = d_data->majLen;
00802 }
00803
00808 unsigned int QwtScaleDraw::majTickLength() const
00809 {
00810 return d_data->majLen;
00811 }
00812
00817 int QwtScaleDraw::maxLabelWidth(const QFont &font) const
00818 {
00819 int maxWidth = 0;
00820
00821 const QwtTickList &ticks = d_data->scldiv.ticks(QwtScaleDiv::MajorTick);
00822 for (uint i = 0; i < (uint)ticks.count(); i++)
00823 {
00824 const double v = ticks[i];
00825 if ( d_data->scldiv.contains(v) )
00826 {
00827 const int w = labelBoundingRect(font, ticks[i]).width();
00828 if ( w > maxWidth )
00829 maxWidth = w;
00830 }
00831 }
00832
00833 return maxWidth;
00834 }
00835
00840 int QwtScaleDraw::maxLabelHeight(const QFont &font) const
00841 {
00842 int maxHeight = 0;
00843
00844 const QwtTickList &ticks = d_data->scldiv.ticks(QwtScaleDiv::MajorTick);
00845 for (uint i = 0; i < (uint)ticks.count(); i++)
00846 {
00847 const double v = ticks[i];
00848 if ( d_data->scldiv.contains(v) )
00849 {
00850 const int h = labelBoundingRect(font, ticks[i]).height();
00851 if ( h > maxHeight )
00852 maxHeight = h;
00853 }
00854 }
00855
00856 return maxHeight;
00857 }
00858
00864 QRect QwtScaleDraw::labelBoundingRect(
00865 const QFont &font, double val) const
00866 {
00867 const QFontMetrics fm(font);
00868
00869 QString zeroString;
00870 if ( d_data->fieldwidth > 0 )
00871 zeroString.fill('0', d_data->fieldwidth);
00872
00873 const QString lbl = label(val);
00874
00875 const QString &txt = fm.width(zeroString) > fm.width(lbl)
00876 ? zeroString : lbl;
00877 if ( txt.isEmpty() )
00878 return QRect(0, 0, 0, 0);
00879
00880 QRect br;
00881
00882 QPoint pos;
00883 int flags;
00884 double rotation;
00885
00886 labelPlacement(fm, val, pos, flags, rotation);
00887 if ( flags )
00888 {
00889
00890 const int w = fm.boundingRect(0, 0,
00891 QWIDGETSIZE_MAX, QWIDGETSIZE_MAX, 0, txt).width();
00892 const int h = -(fm.ascent() - 2);
00893
00894 QwtMatrix m = labelWorldMatrix(fm, pos, flags, rotation, txt);
00895 br = QwtMetricsMap::translate(m, QRect(0, 0, w, h));
00896 #if QT_VERSION < 0x040000
00897 br.moveBy(-pos.x(), -pos.y());
00898 #else
00899 br.translate(-pos.x(), -pos.y());
00900 #endif
00901 }
00902
00903 return br;
00904 }
00905
00916 void QwtScaleDraw::minBorderDist(const QFont &font,
00917 int &start, int &end ) const
00918 {
00919 start = 0;
00920 end = 0;
00921
00922 const QwtTickList &ticks = d_data->scldiv.ticks(QwtScaleDiv::MajorTick);
00923 if ( ticks.count() > 0 )
00924 {
00925 #ifdef __GNUC__
00926 #warning Wrong calculation for scales without bounding labels
00927 #endif
00928
00929 const QRect labelRectMin = labelBoundingRect(font, ticks[0]);
00930 const QRect labelRectMax = labelBoundingRect(font,
00931 ticks[ticks.count() - 1]);
00932
00933 switch (d_data->orient)
00934 {
00935 case Left:
00936 case Right:
00937 end = -labelRectMin.y();
00938 start = labelRectMax.height() + labelRectMax.y();
00939 break;
00940 case Top:
00941 case Bottom:
00942 start = -labelRectMin.x();
00943 end = labelRectMax.width() + labelRectMax.x();
00944 break;
00945 case Round:
00946 start = labelRectMin.width();
00947 end = labelRectMax.width();
00948 break;
00949 }
00950 }
00951 }
00952
00962 int QwtScaleDraw::minLabelDist(const QFont &font) const
00963 {
00964 if ( d_data->orient == Round )
00965 return 0;
00966
00967 const QwtTickList &ticks = d_data->scldiv.ticks(QwtScaleDiv::MajorTick);
00968 if (ticks.count() == 0)
00969 return 0;
00970
00971 const QFontMetrics fm(font);
00972
00973 const bool vertical = (d_data->orient == Left || d_data->orient == Right);
00974
00975 QRect bRect1;
00976 QRect bRect2 = labelBoundingRect(font, ticks[0]);
00977 if ( vertical )
00978 {
00979 bRect2.setRect(-bRect2.bottom(), 0, bRect2.height(), bRect2.width());
00980 }
00981 int maxDist = 0;
00982
00983 for (uint i = 1; i < (uint)ticks.count(); i++ )
00984 {
00985 bRect1 = bRect2;
00986 bRect2 = labelBoundingRect(font, ticks[i]);
00987 if ( vertical )
00988 {
00989 bRect2.setRect(-bRect2.bottom(), 0,
00990 bRect2.height(), bRect2.width());
00991 }
00992
00993 int dist = fm.leading();
00994 if ( bRect1.right() > 0 )
00995 dist += bRect1.right();
00996 if ( bRect2.left() < 0 )
00997 dist += -bRect2.left();
00998
00999 if ( dist > maxDist )
01000 maxDist = dist;
01001 }
01002
01003 double angle = d_data->labelRotation / 180.0 * M_PI;
01004 if ( vertical )
01005 angle += M_PI / 2;
01006
01007 if ( sin(angle) == 0.0 )
01008 return maxDist;
01009
01010 const int fmHeight = fm.ascent() - 2;
01011
01012
01013
01014
01015
01016 int labelDist = (int)(fmHeight / sin(angle) * cos(angle));
01017 if ( labelDist < 0 )
01018 labelDist = -labelDist;
01019
01020
01021 labelDist++;
01022
01023
01024
01025 if ( labelDist > maxDist )
01026 labelDist = maxDist;
01027
01028
01029
01030
01031 if ( labelDist < fmHeight )
01032 labelDist = fmHeight;
01033
01034 return labelDist;
01035 }
01036
01043 int QwtScaleDraw::minHeight( const QPen &pen, const QFont &font ) const
01044 {
01045 const int pw = qwtMax( 1, pen.width() );
01046
01047 int h = 0;
01048 switch ( d_data->orient )
01049 {
01050 case Left:
01051 case Right:
01052 {
01053 const uint minorCount =
01054 d_data->scldiv.ticks(QwtScaleDiv::MinorTick).count() +
01055 d_data->scldiv.ticks(QwtScaleDiv::MediumTick).count();
01056 const uint majorCount =
01057 d_data->scldiv.ticks(QwtScaleDiv::MajorTick).count();
01058
01059 int bottomDist, topDist;
01060 minBorderDist(font, bottomDist, topDist);
01061
01062 h = bottomDist + topDist;
01063 if ( majorCount >= 2 )
01064 h += minLabelDist(font) * (majorCount - 1);
01065
01066 int th = 2 * (majorCount + minorCount) * pw;
01067 if ( th > h )
01068 h = th;
01069 break;
01070 }
01071 case Round:
01072
01073 h = pw + d_data->vpad + d_data->majLen + maxLabelWidth(font);
01074 break;
01075 case Top:
01076 case Bottom:
01077 h = pw + d_data->vpad + d_data->majLen + maxLabelHeight(font);
01078 break;
01079 }
01080 return h;
01081 }
01082
01089 int QwtScaleDraw::minWidth( const QPen &pen, const QFont &font ) const
01090 {
01091 const int pw = qwtMax( 1, pen.width() );
01092
01093 int w = 0;
01094
01095 switch(d_data->orient)
01096 {
01097 case Left:
01098 case Right:
01099 {
01100 w = pw + d_data->hpad + d_data->majLen + maxLabelWidth(font);
01101 break;
01102 }
01103 case Round:
01104 {
01105 w = pw + d_data->vpad + d_data->majLen + maxLabelWidth(font);
01106 break;
01107 }
01108 case Top:
01109 case Bottom:
01110 {
01111 const uint minorCount =
01112 d_data->scldiv.ticks(QwtScaleDiv::MinorTick).count() +
01113 d_data->scldiv.ticks(QwtScaleDiv::MediumTick).count();
01114 const uint majorCount =
01115 d_data->scldiv.ticks(QwtScaleDiv::MajorTick).count();
01116
01117 int leftDist, rightDist;
01118 minBorderDist(font, leftDist, rightDist);
01119
01120 w = leftDist + rightDist +
01121 minLabelDist(font) * (majorCount - 1);
01122
01123 int tw = 2 * (majorCount + minorCount) * pw;
01124 if ( tw > w )
01125 w = tw;
01126
01127 break;
01128 }
01129 }
01130 return w;
01131 }
01132
01140 QString QwtScaleDraw::label(double value) const
01141 {
01142
01143
01144
01145
01146
01147 char buffer[128];
01148 sprintf(buffer, d_data->formatBuffer, value);
01149
01150 return QString::fromLatin1(buffer);
01151 }
01152
01154 int QwtScaleDraw::x() const
01155 {
01156 return d_data->xorg;
01157 }
01158
01160 int QwtScaleDraw::y() const
01161 {
01162 return d_data->yorg;
01163 }
01164
01166 int QwtScaleDraw::length() const
01167 {
01168 return d_data->len;
01169 }
01170
01172 QwtScaleDraw::Orientation QwtScaleDraw::orientation() const
01173 {
01174 return d_data->orient;
01175 }