compile
[kdegraphics.git] / okular / core / area.cpp
blob07688af15f7a3d0f0ccff3799722b39425e38796
1 /***************************************************************************
2 * Copyright (C) 2004-05 by Enrico Ros <eros.kde@email.it> *
3 * Copyright (C) 2005 by Piotr Szymanski <niedakh@gmail.com> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 ***************************************************************************/
10 #include "area.h"
12 #include <QtCore/QRect>
13 #include <QtGui/QPolygonF>
14 #include <kdebug.h>
16 #include <math.h>
18 #include "action.h"
19 #include "annotations.h"
20 #include "annotations_p.h"
21 #include "debug_p.h"
22 #include "sourcereference.h"
24 using namespace Okular;
26 /** class NormalizedPoint **/
27 NormalizedPoint::NormalizedPoint()
28 : x( 0.0 ), y( 0.0 ) {}
30 NormalizedPoint::NormalizedPoint( double dX, double dY )
31 : x( dX ), y( dY ) {}
33 NormalizedPoint::NormalizedPoint( int iX, int iY, int xScale, int yScale )
34 : x( (double)iX / (double)xScale ), y( (double)iY / (double)yScale ) {}
36 NormalizedPoint& NormalizedPoint::operator=( const NormalizedPoint & p )
38 x = p.x;
39 y = p.y;
40 return *this;
43 void NormalizedPoint::transform( const QMatrix &matrix )
45 qreal tmp_x = (qreal)x;
46 qreal tmp_y = (qreal)y;
47 matrix.map( tmp_x, tmp_y, &tmp_x, &tmp_y );
48 x = tmp_x;
49 y = tmp_y;
52 QDebug operator<<( QDebug str, const Okular::NormalizedPoint& p )
54 str.nospace() << "NormPt(" << p.x << "," << p.y << ")";
55 return str.space();
58 /** class NormalizedRect **/
60 NormalizedRect::NormalizedRect()
61 : left( 0.0 ), top( 0.0 ), right( 0.0 ), bottom( 0.0 ) {}
63 NormalizedRect::NormalizedRect( double l, double t, double r, double b )
64 // note: check for swapping coords?
65 : left( l ), top( t ), right( r ), bottom( b ) {}
67 NormalizedRect::NormalizedRect( const QRect & r, double xScale, double yScale )
68 : left( (double)r.left() / xScale ), top( (double)r.top() / yScale ),
69 right( (double)r.right() / xScale ), bottom( (double)r.bottom() / yScale ) {}
71 NormalizedRect::NormalizedRect( const NormalizedRect & rect )
72 : left( rect.left ), top( rect.top ), right( rect.right ), bottom( rect.bottom ) {}
74 NormalizedRect NormalizedRect::fromQRectF( const QRectF &rect )
76 QRectF nrect = rect.normalized();
77 NormalizedRect ret;
78 ret.left = nrect.left();
79 ret.top = nrect.top();
80 ret.right = nrect.right();
81 ret.bottom = nrect.bottom();
82 return ret;
85 bool NormalizedRect::isNull() const
87 return left == 0 && top== 0 && right == 0 && bottom == 0;
90 bool NormalizedRect::contains( double x, double y ) const
92 return x >= left && x <= right && y >= top && y <= bottom;
95 bool NormalizedRect::intersects( const NormalizedRect & r ) const
97 return (r.left <= right) && (r.right >= left) && (r.top <= bottom) && (r.bottom >= top);
100 bool NormalizedRect::intersects( const NormalizedRect * r ) const
102 return (r->left <= right) && (r->right >= left) && (r->top <= bottom) && (r->bottom >= top);
105 bool NormalizedRect::intersects( double l, double t, double r, double b ) const
107 return (l <= right) && (r >= left) && (t <= bottom) && (b >= top);
110 NormalizedRect NormalizedRect::operator| (const NormalizedRect & r) const
112 NormalizedRect ret;
113 // todo !
114 ret.left=qMin(left,r.left);
115 ret.top=qMin(top,r.top);
116 ret.bottom=qMax(bottom,r.bottom);
117 ret.right=qMax(right,r.right);
118 return ret;
121 NormalizedRect& NormalizedRect::operator|= (const NormalizedRect & r)
123 left = qMin( left, r.left );
124 top = qMin( top, r.top );
125 bottom = qMax( bottom, r.bottom );
126 right = qMax( right, r.right );
127 return *this;
130 NormalizedRect NormalizedRect::operator&( const NormalizedRect & r ) const
132 if ( isNull() || r.isNull() )
133 return NormalizedRect();
135 NormalizedRect ret;
136 ret.left = qMax( left, r.left );
137 ret.top = qMax( top, r.top );
138 ret.bottom = qMin( bottom, r.bottom );
139 ret.right = qMin( right, r.right );
140 return ret;
143 NormalizedRect & NormalizedRect::operator=( const NormalizedRect & r )
145 left = r.left;
146 right = r.right;
147 top = r.top;
148 bottom = r.bottom;
149 return *this;
152 bool NormalizedRect::operator==( const NormalizedRect & r ) const
154 return ( isNull() && r.isNull() ) ||
155 ( fabs( left - r.left ) < 1e-4 &&
156 fabs( right - r.right ) < 1e-4 &&
157 fabs( top - r.top ) < 1e-4 &&
158 fabs( bottom - r.bottom ) < 1e-4 );
162 QDebug operator << (QDebug str , const NormalizedRect &r)
164 str << "[" <<r.left() << "," << r.top() << "] x "<< "[" <<r.right() << "," << r.bottom() << "]";
165 return str;
168 QRect NormalizedRect::geometry( int xScale, int yScale ) const
170 int l = (int)( left * xScale ),
171 t = (int)( top * yScale ),
172 r = (int)( right * xScale ),
173 b = (int)( bottom * yScale );
175 return QRect( l, t, r - l + 1, b - t + 1 );
178 void NormalizedRect::transform( const QMatrix &matrix )
180 QRectF rect( left, top, right - left, bottom - top );
181 rect = matrix.mapRect( rect );
183 left = rect.left();
184 top = rect.top();
185 right = rect.right();
186 bottom = rect.bottom();
189 QDebug operator<<( QDebug str, const Okular::NormalizedRect& r )
191 str.nospace() << "NormRect(" << r.left << "," << r.top << " x " << ( r.right - r.left ) << "+" << ( r.bottom - r.top ) << ")";
192 return str.space();
195 RegularAreaRect::RegularAreaRect()
196 : RegularArea< NormalizedRect, QRect >(), d( 0 )
200 RegularAreaRect::RegularAreaRect( const RegularAreaRect& rar )
201 : RegularArea< NormalizedRect, QRect >( rar ), d( 0 )
205 RegularAreaRect::~RegularAreaRect()
209 RegularAreaRect& RegularAreaRect::operator=( const RegularAreaRect& rar )
211 RegularArea< NormalizedRect, QRect >::operator=( rar );
212 return *this;
216 HighlightAreaRect::HighlightAreaRect( const RegularAreaRect *area )
217 : RegularAreaRect(), s_id( -1 )
219 if ( area )
221 RegularAreaRect::ConstIterator it = area->begin();
222 RegularAreaRect::ConstIterator itEnd = area->end();
223 for ( ; it != itEnd; ++it )
225 append( NormalizedRect( *it ) );
230 /** class ObjectRect **/
232 ObjectRect::ObjectRect( double l, double t, double r, double b, bool ellipse, ObjectType type, void * pnt )
233 : m_objectType( type ), m_object( pnt )
235 // assign coordinates swapping them if negative width or height
236 QRectF rect( r > l ? l : r, b > t ? t : b, fabs( r - l ), fabs( b - t ) );
237 if ( ellipse )
238 m_path.addEllipse( rect );
239 else
240 m_path.addRect( rect );
242 m_transformedPath = m_path;
245 ObjectRect::ObjectRect( const NormalizedRect& x, bool ellipse, ObjectType type, void * pnt )
246 : m_objectType( type ), m_object( pnt )
248 QRectF rect( x.left, x.top, fabs( x.right - x.left ), fabs( x.bottom - x.top ) );
249 if ( ellipse )
250 m_path.addEllipse( rect );
251 else
252 m_path.addRect( rect );
254 m_transformedPath = m_path;
257 ObjectRect::ObjectRect( const QPolygonF &poly, ObjectType type, void * pnt )
258 : m_objectType( type ), m_object( pnt )
260 m_path.addPolygon( poly );
262 m_transformedPath = m_path;
265 ObjectRect::ObjectType ObjectRect::objectType() const
267 return m_objectType;
270 const void * ObjectRect::object() const
272 return m_object;
275 const QPainterPath &ObjectRect::region() const
277 return m_transformedPath;
280 QRect ObjectRect::boundingRect( double xScale, double yScale ) const
282 const QRectF &br = m_transformedPath.boundingRect();
284 return QRect( (int)( br.left() * xScale ), (int)( br.top() * yScale ),
285 (int)( br.width() * xScale ), (int)( br.height() * yScale ) );
288 bool ObjectRect::contains( double x, double y, double, double ) const
290 return m_transformedPath.contains( QPointF( x, y ) );
293 void ObjectRect::transform( const QMatrix &matrix )
295 m_transformedPath = matrix.map( m_path );
298 ObjectRect::~ObjectRect()
300 if ( !m_object )
301 return;
303 if ( m_objectType == Action )
304 delete static_cast<Okular::Action*>( m_object );
305 else if ( m_objectType == SourceRef )
306 delete static_cast<Okular::SourceReference*>( m_object );
307 else
308 kDebug(OkularDebug).nospace() << "Object deletion not implemented for type '" << m_objectType << "'.";
311 /** class AnnotationObjectRect **/
313 AnnotationObjectRect::AnnotationObjectRect( Annotation * annotation )
314 : ObjectRect( QPolygonF(), OAnnotation, annotation ), m_annotation( annotation )
318 Annotation *AnnotationObjectRect::annotation() const
320 return m_annotation;
323 QRect AnnotationObjectRect::boundingRect( double xScale, double yScale ) const
325 return AnnotationUtils::annotationGeometry( m_annotation, xScale, yScale );
328 bool AnnotationObjectRect::contains( double x, double y, double xScale, double yScale ) const
330 return boundingRect( xScale, yScale ).contains( (int)( x * xScale ), (int)( y * yScale ), false );
333 AnnotationObjectRect::~AnnotationObjectRect()
335 // the annotation pointer is kept elsewehere (in Page, most probably),
336 // so just release its pointer
337 m_object = 0;
340 void AnnotationObjectRect::transform( const QMatrix &matrix )
342 m_annotation->d_func()->annotationTransform( matrix );
345 /** class SourceRefObjectRect **/
347 SourceRefObjectRect::SourceRefObjectRect( const NormalizedPoint& point, void * srcRef )
348 : ObjectRect( point.x, point.y, .0, .0, false, SourceRef, srcRef ), m_point( point )
352 QRect SourceRefObjectRect::boundingRect( double /*xScale*/, double /*yScale*/ ) const
354 return QRect();
357 bool SourceRefObjectRect::contains( double x, double y, double xScale, double yScale ) const
359 return ( pow( x - m_point.x, 2 ) + pow( y - m_point.y, 2 ) ) < ( pow( (double)7/xScale, 2 ) + pow( (double)7/yScale, 2 ) );