00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "area.h"
00011
00012 #include <QtCore/QRect>
00013 #include <QtGui/QPolygonF>
00014 #include <kdebug.h>
00015
00016 #include <math.h>
00017
00018 #include "action.h"
00019 #include "annotations.h"
00020 #include "annotations_p.h"
00021 #include "debug_p.h"
00022 #include "sourcereference.h"
00023
00024 using namespace Okular;
00025
00027 NormalizedPoint::NormalizedPoint()
00028 : x( 0.0 ), y( 0.0 ) {}
00029
00030 NormalizedPoint::NormalizedPoint( double dX, double dY )
00031 : x( dX ), y( dY ) {}
00032
00033 NormalizedPoint::NormalizedPoint( int iX, int iY, int xScale, int yScale )
00034 : x( (double)iX / (double)xScale ), y( (double)iY / (double)yScale ) {}
00035
00036 NormalizedPoint& NormalizedPoint::operator=( const NormalizedPoint & p )
00037 {
00038 x = p.x;
00039 y = p.y;
00040 return *this;
00041 }
00042
00043 void NormalizedPoint::transform( const QMatrix &matrix )
00044 {
00045 matrix.map( x, y, &x, &y );
00046 }
00047
00048 QDebug operator<<( QDebug str, const Okular::NormalizedPoint& p )
00049 {
00050 str.nospace() << "NormPt(" << p.x << "," << p.y << ")";
00051 return str.space();
00052 }
00053
00056 NormalizedRect::NormalizedRect()
00057 : left( 0.0 ), top( 0.0 ), right( 0.0 ), bottom( 0.0 ) {}
00058
00059 NormalizedRect::NormalizedRect( double l, double t, double r, double b )
00060
00061 : left( l ), top( t ), right( r ), bottom( b ) {}
00062
00063 NormalizedRect::NormalizedRect( const QRect & r, double xScale, double yScale )
00064 : left( (double)r.left() / xScale ), top( (double)r.top() / yScale ),
00065 right( (double)r.right() / xScale ), bottom( (double)r.bottom() / yScale ) {}
00066
00067 NormalizedRect::NormalizedRect( const NormalizedRect & rect )
00068 : left( rect.left ), top( rect.top ), right( rect.right ), bottom( rect.bottom ) {}
00069
00070 NormalizedRect NormalizedRect::fromQRectF( const QRectF &rect )
00071 {
00072 NormalizedRect ret;
00073 ret.left = rect.left();
00074 ret.top = rect.top();
00075 ret.right = rect.right();
00076 ret.bottom = rect.bottom();
00077 return ret;
00078 }
00079
00080 bool NormalizedRect::isNull() const
00081 {
00082 return left == 0 && top== 0 && right == 0 && bottom == 0;
00083 }
00084
00085 bool NormalizedRect::contains( double x, double y ) const
00086 {
00087 return x >= left && x <= right && y >= top && y <= bottom;
00088 }
00089
00090 bool NormalizedRect::intersects( const NormalizedRect & r ) const
00091 {
00092 return (r.left <= right) && (r.right >= left) && (r.top <= bottom) && (r.bottom >= top);
00093 }
00094
00095 bool NormalizedRect::intersects( const NormalizedRect * r ) const
00096 {
00097 return (r->left <= right) && (r->right >= left) && (r->top <= bottom) && (r->bottom >= top);
00098 }
00099
00100 bool NormalizedRect::intersects( double l, double t, double r, double b ) const
00101 {
00102 return (l <= right) && (r >= left) && (t <= bottom) && (b >= top);
00103 }
00104
00105 NormalizedRect NormalizedRect::operator| (const NormalizedRect & r) const
00106 {
00107 NormalizedRect ret;
00108
00109 ret.left=qMin(left,r.left);
00110 ret.top=qMin(top,r.top);
00111 ret.bottom=qMax(bottom,r.bottom);
00112 ret.right=qMax(right,r.right);
00113 return ret;
00114 }
00115
00116 NormalizedRect& NormalizedRect::operator|= (const NormalizedRect & r)
00117 {
00118 left = qMin( left, r.left );
00119 top = qMin( top, r.top );
00120 bottom = qMax( bottom, r.bottom );
00121 right = qMax( right, r.right );
00122 return *this;
00123 }
00124
00125 NormalizedRect & NormalizedRect::operator=( const NormalizedRect & r )
00126 {
00127 left = r.left;
00128 right = r.right;
00129 top = r.top;
00130 bottom = r.bottom;
00131 return *this;
00132 }
00133
00134 bool NormalizedRect::operator==( const NormalizedRect & r ) const
00135 {
00136 return ( isNull() && r.isNull() ) ||
00137 ( fabs( left - r.left ) < 1e-4 &&
00138 fabs( right - r.right ) < 1e-4 &&
00139 fabs( top - r.top ) < 1e-4 &&
00140 fabs( bottom - r.bottom ) < 1e-4 );
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150 QRect NormalizedRect::geometry( int xScale, int yScale ) const
00151 {
00152 int l = (int)( left * xScale ),
00153 t = (int)( top * yScale ),
00154 r = (int)( right * xScale ),
00155 b = (int)( bottom * yScale );
00156
00157 return QRect( l, t, r - l + 1, b - t + 1 );
00158 }
00159
00160 void NormalizedRect::transform( const QMatrix &matrix )
00161 {
00162 QRectF rect( left, top, right - left, bottom - top );
00163 rect = matrix.mapRect( rect );
00164
00165 left = rect.left();
00166 top = rect.top();
00167 right = rect.right();
00168 bottom = rect.bottom();
00169 }
00170
00171 QDebug operator<<( QDebug str, const Okular::NormalizedRect& r )
00172 {
00173 str.nospace() << "NormRect(" << r.left << "," << r.top << " x " << ( r.right - r.left ) << "+" << ( r.bottom - r.top ) << ")";
00174 return str.space();
00175 }
00176
00177 RegularAreaRect::RegularAreaRect()
00178 : RegularArea< NormalizedRect, QRect >(), d( 0 )
00179 {
00180 }
00181
00182 RegularAreaRect::RegularAreaRect( const RegularAreaRect& rar )
00183 : RegularArea< NormalizedRect, QRect >( rar ), d( 0 )
00184 {
00185 }
00186
00187 RegularAreaRect::~RegularAreaRect()
00188 {
00189 }
00190
00191 RegularAreaRect& RegularAreaRect::operator=( const RegularAreaRect& rar )
00192 {
00193 RegularArea< NormalizedRect, QRect >::operator=( rar );
00194 return *this;
00195 }
00196
00197
00198 HighlightAreaRect::HighlightAreaRect( const RegularAreaRect *area )
00199 : RegularAreaRect(), s_id( -1 )
00200 {
00201 if ( area )
00202 {
00203 RegularAreaRect::ConstIterator it = area->begin();
00204 RegularAreaRect::ConstIterator itEnd = area->end();
00205 for ( ; it != itEnd; ++it )
00206 {
00207 append( NormalizedRect( *it ) );
00208 }
00209 }
00210 }
00211
00214 ObjectRect::ObjectRect( double l, double t, double r, double b, bool ellipse, ObjectType type, void * pnt )
00215 : m_objectType( type ), m_object( pnt )
00216 {
00217
00218 QRectF rect( r > l ? l : r, b > t ? t : b, fabs( r - l ), fabs( b - t ) );
00219 if ( ellipse )
00220 m_path.addEllipse( rect );
00221 else
00222 m_path.addRect( rect );
00223
00224 m_transformedPath = m_path;
00225 }
00226
00227 ObjectRect::ObjectRect( const NormalizedRect& x, bool ellipse, ObjectType type, void * pnt )
00228 : m_objectType( type ), m_object( pnt )
00229 {
00230 QRectF rect( x.left, x.top, fabs( x.right - x.left ), fabs( x.bottom - x.top ) );
00231 if ( ellipse )
00232 m_path.addEllipse( rect );
00233 else
00234 m_path.addRect( rect );
00235
00236 m_transformedPath = m_path;
00237 }
00238
00239 ObjectRect::ObjectRect( const QPolygonF &poly, ObjectType type, void * pnt )
00240 : m_objectType( type ), m_object( pnt )
00241 {
00242 m_path.addPolygon( poly );
00243
00244 m_transformedPath = m_path;
00245 }
00246
00247 ObjectRect::ObjectType ObjectRect::objectType() const
00248 {
00249 return m_objectType;
00250 }
00251
00252 const void * ObjectRect::object() const
00253 {
00254 return m_object;
00255 }
00256
00257 const QPainterPath &ObjectRect::region() const
00258 {
00259 return m_transformedPath;
00260 }
00261
00262 QRect ObjectRect::boundingRect( double xScale, double yScale ) const
00263 {
00264 const QRectF &br = m_transformedPath.boundingRect();
00265
00266 return QRect( (int)( br.left() * xScale ), (int)( br.top() * yScale ),
00267 (int)( br.width() * xScale ), (int)( br.height() * yScale ) );
00268 }
00269
00270 bool ObjectRect::contains( double x, double y, double, double ) const
00271 {
00272 return m_transformedPath.contains( QPointF( x, y ) );
00273 }
00274
00275 void ObjectRect::transform( const QMatrix &matrix )
00276 {
00277 m_transformedPath = matrix.map( m_path );
00278 }
00279
00280 ObjectRect::~ObjectRect()
00281 {
00282 if ( !m_object )
00283 return;
00284
00285 if ( m_objectType == Action )
00286 delete static_cast<Okular::Action*>( m_object );
00287 else if ( m_objectType == SourceRef )
00288 delete static_cast<Okular::SourceReference*>( m_object );
00289 else
00290 kDebug(OkularDebug).nospace() << "Object deletion not implemented for type '" << m_objectType << "'.";
00291 }
00292
00295 AnnotationObjectRect::AnnotationObjectRect( Annotation * annotation )
00296 : ObjectRect( QPolygonF(), OAnnotation, annotation ), m_annotation( annotation )
00297 {
00298 }
00299
00300 Annotation *AnnotationObjectRect::annotation() const
00301 {
00302 return m_annotation;
00303 }
00304
00305 QRect AnnotationObjectRect::boundingRect( double xScale, double yScale ) const
00306 {
00307 return AnnotationUtils::annotationGeometry( m_annotation, xScale, yScale );
00308 }
00309
00310 bool AnnotationObjectRect::contains( double x, double y, double xScale, double yScale ) const
00311 {
00312 return boundingRect( xScale, yScale ).contains( (int)( x * xScale ), (int)( y * yScale ), false );
00313 }
00314
00315 AnnotationObjectRect::~AnnotationObjectRect()
00316 {
00317
00318
00319 m_object = 0;
00320 }
00321
00322 void AnnotationObjectRect::transform( const QMatrix &matrix )
00323 {
00324 m_annotation->d_func()->annotationTransform( matrix );
00325 }
00326
00329 SourceRefObjectRect::SourceRefObjectRect( const NormalizedPoint& point, void * srcRef )
00330 : ObjectRect( point.x, point.y, .0, .0, false, SourceRef, srcRef ), m_point( point )
00331 {
00332 }
00333
00334 QRect SourceRefObjectRect::boundingRect( double , double ) const
00335 {
00336 return QRect();
00337 }
00338
00339 bool SourceRefObjectRect::contains( double x, double y, double xScale, double yScale ) const
00340 {
00341 return ( pow( x - m_point.x, 2 ) + pow( y - m_point.y, 2 ) ) < ( pow( (double)7/xScale, 2 ) + pow( (double)7/yScale, 2 ) );
00342 }