Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

# qwt_rect.cpp

    00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
    00002  * Qwt Widget Library
    00003  * Copyright (C) 1997   Josef Wilgen
    00004  * Copyright (C) 2002   Uwe Rathmann
    00005  *
    00006  * This library is free software; you can redistribute it and/or
    00007  * modify it under the terms of the Qwt License, Version 1.0
    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 }