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 }