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 ***************************************************************************/
12 #include <QtCore/QRect>
13 #include <QtGui/QPolygonF>
19 #include "annotations.h"
20 #include "annotations_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
)
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
)
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
);
52 QDebug
operator<<( QDebug str
, const Okular::NormalizedPoint
& p
)
54 str
.nospace() << "NormPt(" << p
.x
<< "," << p
.y
<< ")";
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();
78 ret
.left
= nrect
.left();
79 ret
.top
= nrect
.top();
80 ret
.right
= nrect
.right();
81 ret
.bottom
= nrect
.bottom();
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
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
);
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
);
130 NormalizedRect
NormalizedRect::operator&( const NormalizedRect
& r
) const
132 if ( isNull() || r
.isNull() )
133 return NormalizedRect();
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
);
143 NormalizedRect
& NormalizedRect::operator=( const NormalizedRect
& r
)
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() << "]";
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
);
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
) << ")";
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
);
216 HighlightAreaRect::HighlightAreaRect( const RegularAreaRect
*area
)
217 : RegularAreaRect(), s_id( -1 )
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
) );
238 m_path
.addEllipse( rect
);
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
) );
250 m_path
.addEllipse( rect
);
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
270 const void * ObjectRect::object() const
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()
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
);
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
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
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
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 ) );