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 #ifndef _OKULAR_AREA_H_
11 #define _OKULAR_AREA_H_
13 #include <QtCore/QList>
14 #include <QtGui/QColor>
15 #include <QtGui/QPainterPath>
18 #include <okular/core/global.h>
19 #include <okular/core/okular_export.h>
28 class NormalizedShape
;
31 * NormalizedPoint is a helper class which stores the coordinates
32 * of a normalized point. Normalized means that the coordinates are
33 * between 0 and 1 so that it is page size independent.
36 * The normalized point is (0.5, 0.3)
38 * If you want to draw it on a 800x600 page, just multiply the x coordinate (0.5) with
39 * the page width (800) and the y coordinate (0.3) with the page height (600), so
40 * the point will be drawn on the page at (400, 180).
42 * That allows you to zoom the page by just multiplying the normalized points with the
45 class OKULAR_EXPORT NormalizedPoint
49 * Creates a new empty normalized point.
54 * Creates a new normalized point with the normalized coordinates (@p x, @p y ).
56 NormalizedPoint( double x
, double y
);
59 * Creates a new normalized point with the coordinates (@p x, @p y) which are normalized
60 * by the scaling factors @p xScale and @p yScale.
62 NormalizedPoint( int x
, int y
, int xScale
, int yScale
);
67 NormalizedPoint
& operator=( const NormalizedPoint
& );
70 * Transforms the normalized point with the operations defined by @p matrix.
72 void transform( const QMatrix
&matrix
);
75 * The normalized x coordinate.
80 * The normalized y coordinate.
86 * NormalizedRect is a helper class which stores the coordinates
87 * of a normalized rect, which is a rectangle of @see NormalizedPoints.
89 class OKULAR_EXPORT NormalizedRect
93 * Creates a null normalized rectangle.
99 * Creates a normalized rectangle with the normalized coordinates
100 * @p left, @p top, @p right, @p bottom.
102 * If you need the x, y, width and height coordinates use the
103 * following formulas:
107 * @li width = right - left
108 * @li height = bottom - top
110 NormalizedRect( double left
, double top
, double right
, double bottom
);
113 * Creates a normalized rectangle of the given @p rectangle which is normalized
114 * by the scaling factors @p xScale and @p yScale.
116 NormalizedRect( const QRect
&rectangle
, double xScale
, double yScale
);
121 NormalizedRect( const NormalizedRect
& );
126 NormalizedRect
& operator=( const NormalizedRect
&other
);
129 * Build a normalized rect from a QRectF.
131 static NormalizedRect
fromQRectF( const QRectF
&rect
);
134 * Returns whether this normalized rectangle is a null normalized rect.
139 * Returns whether the normalized rectangle contains the normalized coordinates
142 bool contains( double x
, double y
) const;
145 * Returns whether the normalized rectangle intersects the @p other normalized
148 bool intersects( const NormalizedRect
&other
) const;
151 * This is an overloaded member function, provided for convenience. It behaves essentially
152 * like the above function.
154 bool intersects( const NormalizedRect
*other
) const;
157 * Returns whether the normalized rectangle intersects an other normalized
158 * rectangle, which is defined by @p left, @p top, @p right and @p bottom.
160 bool intersects( double left
, double top
, double right
, double bottom
) const;
163 * Returns the rectangle that accrues when the normalized rectangle is multiplyed
164 * with the scaling @p xScale and @p yScale.
166 QRect
geometry( int xScale
, int yScale
) const;
169 * Returns the normalized bounding rectangle of the normalized rectangle
170 * combined with the @p other normalized rectangle.
172 NormalizedRect
operator|( const NormalizedRect
&other
) const;
175 * Sets the normalized rectangle to the normalized bounding rectangle
176 * of itself combined with the @p other normalized rectangle.
178 NormalizedRect
& operator|=( const NormalizedRect
&other
);
181 * Returns the intersection of this normalized rectangle with the specified
182 * @p other. If the rects do not intersect then the result is null.
184 * @since 0.7 (KDE 4.1)
186 NormalizedRect
operator&( const NormalizedRect
&other
) const;
189 * Returns whether the normalized rectangle is equal to the @p other
190 * normalized rectangle.
192 bool operator==( const NormalizedRect
&other
) const;
195 * Transforms the normalized rectangle with the operations defined by @p matrix.
197 void transform( const QMatrix
&matrix
);
200 * The normalized left coordinate.
205 * The normalized top coordinate.
210 * The normalized right coordinate.
215 * The normalized bottom coordinate.
219 KDE_DUMMY_QHASH_FUNCTION(NormalizedRect
)
222 * @short NormalizedRect that contains a reference to an object.
224 * These rects contains a pointer to a okular object (such as an action or something
225 * like that). The pointer is read and stored as 'void pointer' so cast is
226 * performed by accessors based on the value returned by objectType(). Objects
227 * are reparented to this class.
229 * Type / Class correspondency tab:
230 * - Action : class Action: description of an action
231 * - Image : class Image : description of an image (n/a)
232 * - Annotation: class Annotation: description of an annotation
234 class OKULAR_EXPORT ObjectRect
238 * Describes the type of storable object.
242 Action
, ///< An action
244 OAnnotation
, ///< An annotation
245 SourceRef
///< A source reference
249 * Creates a new object rectangle.
251 * @param left The left coordinate of the rectangle.
252 * @param top The top coordinate of the rectangle.
253 * @param right The right coordinate of the rectangle.
254 * @param bottom The bottom coordinate of the rectangle.
255 * @param ellipse If true the rectangle describes an ellipse.
256 * @param type The type of the storable object @see ObjectType.
257 * @param object The pointer to the storable object.
259 ObjectRect( double left
, double top
, double right
, double bottom
, bool ellipse
, ObjectType type
, void *object
);
262 * This is an overloaded member function, provided for convenience.
264 ObjectRect( const NormalizedRect
&rect
, bool ellipse
, ObjectType type
, void *object
);
267 * This is an overloaded member function, provided for convenience.
269 ObjectRect( const QPolygonF
&poly
, ObjectType type
, void *object
);
272 * Destroys the object rectangle.
274 virtual ~ObjectRect();
277 * Returns the object type of the object rectangle.
280 ObjectType
objectType() const;
283 * Returns the storable object of the object rectangle.
285 const void *object() const;
288 * Returns the region that is covered by the object rectangle.
290 const QPainterPath
®ion() const;
293 * Returns the bounding rect of the object rectangle for the
294 * scaling factor @p xScale and @p yScale.
296 virtual QRect
boundingRect( double xScale
, double yScale
) const;
299 * Returns whether the object rectangle contains the point @p x, @p y for the
300 * scaling factor @p xScale and @p yScale.
302 virtual bool contains( double x
, double y
, double xScale
, double yScale
) const;
305 * Transforms the object rectangle with the operations defined by @p matrix.
307 virtual void transform( const QMatrix
&matrix
);
310 ObjectType m_objectType
;
313 QPainterPath m_transformedPath
;
317 * This class describes the object rectangle for an annotation.
319 class OKULAR_EXPORT AnnotationObjectRect
: public ObjectRect
323 * Creates a new annotation object rectangle with the
324 * given @p annotation.
326 AnnotationObjectRect( Annotation
*annotation
);
329 * Destroys the annotation object rectangle.
331 virtual ~AnnotationObjectRect();
334 * Returns the annotation object of the annotation object rectangle.
336 Annotation
*annotation() const;
339 * Returns the bounding rect of the annotation object rectangle for the
340 * scaling factor @p xScale and @p yScale.
342 virtual QRect
boundingRect( double xScale
, double yScale
) const;
345 * Returns whether the annotation object rectangle contains the point @p x, @p y for the
346 * scaling factor @p xScale and @p yScale.
348 virtual bool contains( double x
, double y
, double xScale
, double yScale
) const;
351 * Transforms the annotation object rectangle with the operations defined by @p matrix.
353 virtual void transform( const QMatrix
&matrix
);
356 Annotation
* m_annotation
;
360 * This class describes the object rectangle for a source reference.
362 class OKULAR_EXPORT SourceRefObjectRect
: public ObjectRect
366 * Creates a new source reference object rectangle.
368 * @param point The point of the source reference.
369 * @param reference The storable source reference object.
371 SourceRefObjectRect( const NormalizedPoint
& point
, void *reference
);
374 * Returns the bounding rect of the source reference object rectangle for the
375 * scaling factor @p xScale and @p yScale.
377 virtual QRect
boundingRect( double xScale
, double yScale
) const;
380 * Returns whether the source reference object rectangle contains the point @p x, @p y for the
381 * scaling factor @p xScale and @p yScale.
383 virtual bool contains( double x
, double y
, double xScale
, double yScale
) const;
386 NormalizedPoint m_point
;
391 template <typename T
>
392 void doDelete( T
& t
)
398 template <typename T
>
405 template <typename T
>
412 template <typename T
>
413 static void doDelete( T
* t
)
419 template <typename T
>
420 static T
* givePtr( T
* t
)
426 template <typename T
>
427 static T
& deref( T
* t
)
434 * @short A regular area of NormalizedShape which normalizes a Shape
436 * Class NormalizedShape \b must have the following functions/operators defined:
437 * - bool contains( double, double )
438 * - bool intersects( NormalizedShape )
440 * - Shape geometry( int, int )
441 * - operator|=( NormalizedShape ) which unite two NormalizedShape's
443 template <class NormalizedShape
, class Shape
> class RegularArea
: public QList
<NormalizedShape
>
447 * Destroys a regular area.
452 * Returns whether the regular area contains the
453 * normalized point @p x, @p y.
455 bool contains( double x
, double y
) const;
458 * Returns whether the regular area contains the
461 bool contains( const NormalizedShape
& shape
) const;
464 * Returns whether the regular area intersects with the given @p area.
466 bool intersects( const RegularArea
<NormalizedShape
,Shape
> *area
) const;
469 * Returns whether the regular area intersects with the given @p shape.
471 bool intersects( const NormalizedShape
& shape
) const;
474 * Appends the given @p area to the regular area.
476 void appendArea( const RegularArea
<NormalizedShape
,Shape
> *area
);
479 * Appends the given @p shape to the regular area.
481 void appendShape( const NormalizedShape
& shape
, MergeSide side
= MergeAll
);
484 * Simplifies the regular area by merging its intersecting subareas.
489 * Returns whether the regular area is a null area.
494 * Returns the subareas of the regular areas as shapes for the given scaling factor
495 * @p xScale and @p yScale, translated by @p dx and @p dy.
497 QList
<Shape
> geometry( int xScale
, int yScale
, int dx
= 0, int dy
= 0 ) const;
500 * Transforms the regular area with the operations defined by @p matrix.
502 void transform( const QMatrix
&matrix
);
505 template <class NormalizedShape
, class Shape
>
506 RegularArea
<NormalizedShape
, Shape
>::~RegularArea()
508 int size
= this->count();
509 for ( int i
= 0; i
< size
; ++i
)
510 doDelete( (*this)[i
] );
513 template <class NormalizedShape
, class Shape
>
514 void RegularArea
<NormalizedShape
, Shape
>::simplify()
516 #ifdef DEBUG_REGULARAREA
517 int prev_end
= this->count();
519 int end
= this->count() - 1, x
= 0;
520 for ( int i
= 0; i
< end
; ++i
)
522 if ( givePtr( (*this)[x
] )->intersects( deref( (*this)[i
+1] ) ) )
524 deref((*this)[x
]) |= deref((*this)[i
+1]);
525 NormalizedShape
& tobedeleted
= (*this)[i
+1];
526 this->removeAt( i
+ 1 );
527 doDelete( tobedeleted
);
536 #ifdef DEBUG_REGULARAREA
537 kDebug() << "from" << prev_end
<< "to" << this->count();
541 template <class NormalizedShape
, class Shape
>
542 bool RegularArea
<NormalizedShape
, Shape
>::isNull() const
547 if ( this->isEmpty() )
550 typename QList
<NormalizedShape
>::const_iterator it
= this->begin(), itEnd
= this->end();
551 for ( ; it
!= itEnd
; ++it
)
552 if ( !givePtr( *it
)->isNull() )
558 template <class NormalizedShape
, class Shape
>
559 bool RegularArea
<NormalizedShape
, Shape
>::intersects( const NormalizedShape
& rect
) const
564 if ( this->isEmpty() )
567 typename QList
<NormalizedShape
>::const_iterator it
= this->begin(), itEnd
= this->end();
568 for ( ; it
!= itEnd
; ++it
)
569 if ( !givePtr( *it
)->isNull() && givePtr( *it
)->intersects( rect
) )
575 template <class NormalizedShape
, class Shape
>
576 bool RegularArea
<NormalizedShape
, Shape
>::intersects( const RegularArea
<NormalizedShape
,Shape
> *area
) const
581 if ( this->isEmpty() )
584 typename QList
<NormalizedShape
>::const_iterator it
= this->begin(), itEnd
= this->end();
585 for ( ; it
!= itEnd
; ++it
)
587 typename QList
<NormalizedShape
>::const_iterator areaIt
= area
->begin(), areaItEnd
= area
->end();
588 for ( ; areaIt
!= areaItEnd
; ++areaIt
)
590 if ( !( *it
).isNull() && ( *it
).intersects( *areaIt
) )
598 template <class NormalizedShape
, class Shape
>
599 void RegularArea
<NormalizedShape
, Shape
>::appendArea( const RegularArea
<NormalizedShape
, Shape
> *area
)
604 typename QList
<NormalizedShape
>::const_iterator areaIt
= area
->begin(), areaItEnd
= area
->end();
605 for ( ; areaIt
!= areaItEnd
; ++areaIt
)
606 this->append( *areaIt
);
610 template <class NormalizedShape
, class Shape
>
611 void RegularArea
<NormalizedShape
, Shape
>::appendShape( const NormalizedShape
& shape
, MergeSide side
)
616 int size
= this->count();
617 // if the list is empty, adds the shape normally
620 this->append( shape
);
624 bool intersection
= false;
625 NormalizedShape
& last
= (*this)[size
- 1];
626 #define O_LAST givePtr( last )
627 # define O_LAST_R O_LAST->right
628 # define O_LAST_L O_LAST->left
629 # define O_LAST_T O_LAST->top
630 # define O_LAST_B O_LAST->bottom
631 #define O_NEW givePtr( shape )
632 # define O_NEW_R O_NEW->right
633 # define O_NEW_L O_NEW->left
634 # define O_NEW_T O_NEW->top
635 # define O_NEW_B O_NEW->bottom
639 intersection
= ( O_LAST_R
>= O_NEW_L
) && ( O_LAST_L
<= O_NEW_R
)
640 && ( ( O_LAST_T
<= O_NEW_T
&& O_LAST_B
>= O_NEW_B
)
641 || ( O_LAST_T
>= O_NEW_T
&& O_LAST_B
<= O_NEW_B
) );
644 intersection
= ( O_LAST_B
>= O_NEW_T
) && ( O_LAST_T
<= O_NEW_B
)
645 && ( ( O_LAST_R
<= O_NEW_R
&& O_LAST_L
>= O_NEW_L
)
646 || ( O_LAST_R
>= O_NEW_R
&& O_LAST_L
<= O_NEW_L
) );
649 intersection
= ( O_LAST_L
<= O_NEW_R
) && ( O_LAST_R
>= O_NEW_L
)
650 && ( ( O_LAST_T
<= O_NEW_T
&& O_LAST_B
>= O_NEW_B
)
651 || ( O_LAST_T
>= O_NEW_T
&& O_LAST_B
<= O_NEW_B
) );
654 intersection
= ( O_LAST_T
<= O_NEW_B
) && ( O_LAST_B
>= O_NEW_T
)
655 && ( ( O_LAST_R
<= O_NEW_R
&& O_LAST_L
>= O_NEW_L
)
656 || ( O_LAST_R
>= O_NEW_R
&& O_LAST_L
<= O_NEW_L
) );
659 intersection
= O_LAST
->intersects( shape
);
672 // if the new shape intersects with the last shape in the list, then
673 // merge it with that and delete the shape
676 deref((*this)[size
- 1]) |= deref( shape
);
677 doDelete( const_cast<NormalizedShape
&>( shape
) );
680 this->append( shape
);
685 template <class NormalizedShape
, class Shape
>
686 bool RegularArea
<NormalizedShape
, Shape
>::contains( double x
, double y
) const
691 if ( this->isEmpty() )
694 typename QList
<NormalizedShape
>::const_iterator it
= this->begin(), itEnd
= this->end();
695 for ( ; it
!= itEnd
; ++it
)
696 if ( ( *it
).contains( x
, y
) )
702 template <class NormalizedShape
, class Shape
>
703 bool RegularArea
<NormalizedShape
, Shape
>::contains( const NormalizedShape
& shape
) const
708 if ( this->isEmpty() )
711 return QList
<NormalizedShape
>::contains( shape
);
714 template <class NormalizedShape
, class Shape
>
715 QList
<Shape
> RegularArea
<NormalizedShape
, Shape
>::geometry( int xScale
, int yScale
, int dx
, int dy
) const
717 if ( !this || this->isEmpty() )
718 return QList
<Shape
>();
722 typename QList
<NormalizedShape
>::const_iterator it
= this->begin(), itEnd
= this->end();
723 for ( ; it
!= itEnd
; ++it
)
725 t
= givePtr( *it
)->geometry( xScale
, yScale
);
726 t
.translate( dx
, dy
);
733 template <class NormalizedShape
, class Shape
>
734 void RegularArea
<NormalizedShape
, Shape
>::transform( const QMatrix
&matrix
)
739 if ( this->isEmpty() )
742 for ( int i
= 0; i
< this->count(); ++i
)
743 givePtr( (*this)[i
] )->transform( matrix
);
746 class OKULAR_EXPORT RegularAreaRect
: public RegularArea
< NormalizedRect
, QRect
>
750 RegularAreaRect( const RegularAreaRect
& rar
);
753 RegularAreaRect
& operator=( const RegularAreaRect
& rar
);
761 * This class stores the coordinates of a highlighting area
762 * together with the id of the highlight owner and the color.
764 class HighlightAreaRect
: public RegularAreaRect
768 * Creates a new highlight area rect with the coordinates of
771 HighlightAreaRect( const RegularAreaRect
*area
= 0 );
774 * The search ID of the highlight owner.
779 * The color of the highlight.
786 #ifndef QT_NO_DEBUG_STREAM
788 * Debug operator for normalized @p point.
790 OKULAR_EXPORT QDebug
operator<<( QDebug str
, const Okular::NormalizedPoint
&point
);
793 * Debug operator for normalized @p rect.
795 OKULAR_EXPORT QDebug
operator<<( QDebug str
, const Okular::NormalizedRect
&rect
);