00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <qpointarray.h>
00011 #include "qwt_rect.h"
00012
00014
00015 QwtRect::QwtRect():
00016 QRect()
00017 {
00018 }
00019
00021 QwtRect::QwtRect(const QRect &r):
00022 QRect(r)
00023 {
00024 }
00025
00026 QRect QwtRect::cutTop(int h, int distTop, int distBottom)
00027 {
00028 QRect rv;
00029 rv.setTop(top() + distTop);
00030 rv.setHeight(h);
00031 setTop(rv.bottom() + distBottom + 1);
00032 rv.setLeft(left());
00033 rv.setRight(right());
00034 return rv;
00035 }
00036
00037 QRect QwtRect::cutBottom(int h, int distTop, int distBottom)
00038 {
00039 QRect rv;
00040 setBottom(bottom() - h - distBottom - distTop);
00041 rv.setTop(bottom() + 1 + distTop);
00042 rv.setHeight(h);
00043 rv.setLeft(left());
00044 rv.setRight(right());
00045 return rv;
00046 }
00047
00048 QRect QwtRect::cutLeft(int w, int distLeft, int distRight)
00049 {
00050 QRect rv;
00051 rv.setLeft(left() + distLeft);
00052 rv.setWidth(w);
00053 setLeft(rv.right() + distRight + 1);
00054 rv.setTop(top());
00055 rv.setBottom(bottom());
00056 return rv;
00057 }
00058
00059 QRect QwtRect::cutRight(int w, int distLeft, int distRight)
00060 {
00061 QRect rv;
00062 setRight(right() - w - distRight - distLeft);
00063 rv.setLeft(right() + 1 + distLeft);
00064 rv.setWidth(w);
00065 rv.setTop(top());
00066 rv.setBottom(bottom());
00067 return rv;
00068 }
00069
00070 const QwtRect& QwtRect::cutMargin(int mLeft, int mRight, int mTop, int mBottom)
00071 {
00072 setHeight(height() - mTop - mBottom);
00073 setWidth(width() - mLeft - mRight);
00074 moveBy(mLeft, mTop);
00075 return *this;
00076 }
00077
00078 inline void addPoint(QPointArray &pa, uint pos, const QPoint &point)
00079 {
00080 if ( pa.size() <= pos )
00081 pa.resize(pos + 5);
00082
00083 pa.setPoint(pos, point);
00084 }
00085
00087
00088 QPointArray QwtRect::clip(const QPointArray &pa) const
00089 {
00090 if ( contains( pa.boundingRect() ) )
00091 return pa;
00092
00093 QPointArray cpa(pa.size());
00094
00095 for ( uint edge = 0; edge < NEdges; edge++ )
00096 {
00097 const QPointArray rpa = (edge == 0) ? pa : cpa.copy();
00098 clipEdge((Edge)edge, rpa, cpa);
00099 }
00100
00101 return cpa;
00102 }
00103
00104 bool QwtRect::insideEdge(const QPoint &p, Edge edge) const
00105 {
00106 switch(edge)
00107 {
00108 case Left:
00109 return p.x() > left();
00110 case Top:
00111 return p.y() > top();
00112 case Right:
00113 return p.x() < right();
00114 case Bottom:
00115 return p.y() < bottom();
00116 default:
00117 break;
00118 }
00119
00120 return FALSE;
00121 }
00122
00123 QPoint QwtRect::intersectEdge(const QPoint &p1,
00124 const QPoint &p2, Edge edge ) const
00125 {
00126 int x=0, y=0;
00127 double m = 0;
00128
00129 const double dy = p2.y() - p1.y();
00130 const double dx = p2.x() - p1.x();
00131
00132 switch ( edge )
00133 {
00134 case Left:
00135 x = left();
00136 m = double(QABS(p1.x() - x)) / QABS(dx);
00137 y = p1.y() + int(dy * m);
00138 break;
00139 case Top:
00140 y = top();
00141 m = double(QABS(p1.y() - y)) / QABS(dy);
00142 x = p1.x() + int(dx * m);
00143 break;
00144 case Right:
00145 x = right();
00146 m = double(QABS(p1.x() - x)) / QABS(dx);
00147 y = p1.y() + int(dy * m);
00148 break;
00149 case Bottom:
00150 y = bottom();
00151 m = double(QABS(p1.y() - y)) / QABS(dy);
00152 x = p1.x() + int(dx * m);
00153 break;
00154 default:
00155 break;
00156 }
00157
00158 return QPoint(x,y);
00159 }
00160
00161 void QwtRect::clipEdge(Edge edge, const QPointArray &pa, QPointArray &cpa) const
00162 {
00163 if ( pa.count() == 0 )
00164 {
00165 cpa.resize(0);
00166 return;
00167 }
00168
00169 unsigned int count = 0;
00170
00171 QPoint p1 = pa.point(0);
00172 if ( insideEdge(p1, edge) )
00173 addPoint(cpa, count++, p1);
00174
00175 const uint nPoints = pa.size();
00176 for ( uint i = 1; i < nPoints; i++ )
00177 {
00178 const QPoint p2 = pa.point(i);
00179 if ( insideEdge(p2, edge) )
00180 {
00181 if ( insideEdge(p1, edge) )
00182 addPoint(cpa, count++, p2);
00183 else
00184 {
00185 addPoint(cpa, count++, intersectEdge(p1, p2, edge));
00186 addPoint(cpa, count++, p2);
00187 }
00188 }
00189 else
00190 {
00191 if ( insideEdge(p1, edge) )
00192 addPoint(cpa, count++, intersectEdge(p1, p2, edge));
00193 }
00194 p1 = p2;
00195 }
00196 cpa.resize(count);
00197 }