Okular

area.h
1 /***************************************************************************
2  * Copyright (C) 2004-05 by Enrico Ros <[email protected]> *
3  * Copyright (C) 2005 by Piotr Szymanski <[email protected]> *
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  ***************************************************************************/
9 
10 #ifndef _OKULAR_AREA_H_
11 #define _OKULAR_AREA_H_
12 
13 #include <math.h>
14 
15 #include <QList>
16 #include <QColor>
17 #include <QPainterPath>
18 #include <QTransform>
19 #include <QDebug>
20 
21 #include "global.h"
22 #include "okularcore_export.h"
23 
24 class QPolygonF;
25 class QRect;
26 
27 namespace Okular {
28 
29 class Annotation;
30 class Action;
31 class NormalizedShape;
32 
119 class OKULARCORE_EXPORT NormalizedPoint
120 {
121  public:
125  NormalizedPoint();
126 
130  NormalizedPoint( double x, double y );
131 
136  NormalizedPoint( int x, int y, int xScale, int yScale );
137 
141  NormalizedPoint& operator=( const NormalizedPoint& );
142 
144  ~NormalizedPoint();
145 
149  void transform( const QTransform &matrix );
150 
156  double distanceSqr( double x, double y, double xScale, double yScale ) const;
157 
164  static double distanceSqr( double x, double y, double xScale, double yScale, const NormalizedPoint& start, const NormalizedPoint& end );
165 
169  double x;
170 
174  double y;
175 };
176 
177 
192 class OKULARCORE_EXPORT NormalizedRect
193 {
194  public:
199  NormalizedRect();
200 
218  NormalizedRect( double left, double top, double right, double bottom );
219 
229  NormalizedRect( const QRect &rectangle, double xScale, double yScale );
230 
234  NormalizedRect( const NormalizedRect& );
235 
239  NormalizedRect& operator=( const NormalizedRect &other );
240 
241  ~NormalizedRect();
242 
246  static NormalizedRect fromQRectF( const QRectF &rect );
247 
251  bool isNull() const;
252 
257  bool contains( double x, double y ) const;
258 
263  bool intersects( const NormalizedRect &other ) const;
264 
269  bool intersects( const NormalizedRect *other ) const;
270 
275  bool intersects( double left, double top, double right, double bottom ) const;
276 
280  QRect geometry( int xScale, int yScale ) const;
281 
287  QRect roundedGeometry( int xScale, int yScale ) const;
288 
293  NormalizedRect operator|( const NormalizedRect &other ) const;
294 
299  NormalizedRect& operator|=( const NormalizedRect &other );
300 
307  NormalizedRect operator&( const NormalizedRect &other ) const;
308 
313  bool operator==( const NormalizedRect &other ) const;
314 
319  NormalizedPoint center() const;
320 
324  void transform( const QTransform &matrix );
325 
330  bool isBottom(const NormalizedPoint& pt) const
331  {
332  return bottom < pt.y;
333  }
334 
339  bool isTop(const NormalizedPoint& pt) const
340  {
341  return top > pt.y;
342  }
343 
348  bool isBottomOrLevel(const NormalizedPoint& pt) const
349  {
350  return top < pt.y;
351  }
352 
357  bool isTopOrLevel(const NormalizedPoint& pt) const
358  {
359  return bottom > pt.y;
360  }
361 
366  bool isLeft(const NormalizedPoint& pt) const
367  {
368  return left < pt.x;
369  }
370 
375  bool isRight(const NormalizedPoint& pt) const
376  {
377  return right > pt.x;
378  }
379 
386  double distanceSqr(double x, double y, double xScale, double yScale) const
387  {
388  double distX = 0;
389  if ( x < left )
390  distX = left - x;
391  else if ( x > right )
392  distX = x - right;
393 
394  double distY = 0;
395  if ( top > y )
396  distY = top - y;
397  else if (bottom < y)
398  distY = y - bottom;
399  return pow( distX * xScale, 2 ) + pow( distY * yScale, 2 );
400  }
401 
403  double width() const
404  {
405  return right - left;
406  }
407 
409  double height() const
410  {
411  return bottom - top;
412  }
413 
417  double left;
418 
422  double top;
423 
427  double right;
428 
432  double bottom;
433 };
434 //KDE_DUMMY_QHASH_FUNCTION(NormalizedRect)
435 
454 class OKULARCORE_EXPORT ObjectRect
455 {
456  public:
461  {
465  SourceRef
466  };
467 
479  ObjectRect( double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object );
480 
484  ObjectRect( const NormalizedRect &r, bool ellipse, ObjectType type, void *object );
485 
489  ObjectRect( const QPolygonF &poly, ObjectType type, void *object );
490 
494  virtual ~ObjectRect();
495 
496  ObjectRect(const ObjectRect &o) = delete;
497  ObjectRect &operator=(const ObjectRect &o) = delete;
498 
503  ObjectType objectType() const;
504 
508  const void *object() const;
509 
513  const QPainterPath &region() const;
514 
519  virtual QRect boundingRect( double xScale, double yScale ) const;
520 
525  virtual bool contains( double x, double y, double xScale, double yScale ) const;
526 
530  virtual void transform( const QTransform &matrix );
531 
540  // FIXME this should most probably be a virtual method
541  double distanceSqr( double x, double y, double xScale, double yScale ) const;
542 
543  protected:
544  ObjectType m_objectType;
545  void * m_object;
546  QPainterPath m_path;
547  QPainterPath m_transformedPath;
548 };
549 
553 class OKULARCORE_EXPORT AnnotationObjectRect : public ObjectRect
554 {
555  public:
560  explicit AnnotationObjectRect( Annotation *annotation );
561 
565  ~AnnotationObjectRect() override;
566 
570  Annotation *annotation() const;
571 
576  QRect boundingRect( double xScale, double yScale ) const override;
577 
582  bool contains( double x, double y, double xScale, double yScale ) const override;
583 
587  void transform( const QTransform &matrix ) override;
588 
589  private:
590  Annotation * m_annotation;
591 };
592 
596 class OKULARCORE_EXPORT SourceRefObjectRect : public ObjectRect
597 {
598  friend class ObjectRect;
599 
600  public:
607  SourceRefObjectRect( const NormalizedPoint& point, void *srcRef );
608 
613  QRect boundingRect( double xScale, double yScale ) const override;
614 
619  bool contains( double x, double y, double xScale, double yScale ) const override;
620 
621  private:
622  NormalizedPoint m_point;
623 };
624 
629 class OKULARCORE_EXPORT NonOwningObjectRect : public ObjectRect
630 {
631  public:
632  NonOwningObjectRect( double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object );
633  ~NonOwningObjectRect() override;
634 };
635 
637 
639 template <typename T>
640 T* givePtr( T& t )
641 {
642  return &t;
643 }
644 
646 template <typename T>
647 T& deref( T& t )
648 {
649  return t;
650 }
652 
670 template <class NormalizedShape, class Shape> class RegularArea : public QList<NormalizedShape>
671 {
672  public:
676  bool contains( double x, double y ) const;
677 
684  bool contains( const NormalizedShape& shape ) const;
685 
689  bool intersects( const RegularArea<NormalizedShape,Shape> *area ) const;
690 
694  bool intersects( const NormalizedShape& shape ) const;
695 
699  void appendArea( const RegularArea<NormalizedShape,Shape> *area );
700 
704  void appendShape( const NormalizedShape& shape, MergeSide side = MergeAll );
705 
710  void simplify();
711 
715  bool isNull() const;
716 
722  QList<Shape> geometry( int xScale, int yScale, int dx = 0, int dy = 0 ) const;
723 
727  void transform( const QTransform &matrix );
728 };
729 
730 template <class NormalizedShape, class Shape>
732 {
733 #ifdef DEBUG_REGULARAREA
734  int prev_end = this->count();
735 #endif
736  int end = this->count() - 1, x = 0;
737  for ( int i = 0; i < end; ++i )
738  {
739  if ( givePtr( (*this)[x] )->intersects( deref( (*this)[i+1] ) ) )
740  {
741  deref((*this)[x]) |= deref((*this)[i+1]);
742  this->removeAt( i + 1 );
743  --end;
744  --i;
745  }
746  else
747  {
748  x=i+1;
749  }
750  }
751 #ifdef DEBUG_REGULARAREA
752  qCDebug(OkularCoreDebug) << "from" << prev_end << "to" << this->count();
753 #endif
754 }
755 
756 template <class NormalizedShape, class Shape>
758 {
759  if ( this->isEmpty() )
760  return true;
761 
762  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
763  for ( ; it != itEnd; ++it )
764  if ( !givePtr( *it )->isNull() )
765  return false;
766 
767  return true;
768 }
769 
770 template <class NormalizedShape, class Shape>
771 bool RegularArea<NormalizedShape, Shape>::intersects( const NormalizedShape& shape ) const
772 {
773  if ( this->isEmpty() )
774  return false;
775 
776  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
777  for ( ; it != itEnd; ++it )
778  if ( !givePtr( *it )->isNull() && givePtr( *it )->intersects( shape ) )
779  return true;
780 
781  return false;
782 }
783 
784 template <class NormalizedShape, class Shape>
786 {
787  if ( this->isEmpty() )
788  return false;
789 
790  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
791  for ( ; it != itEnd; ++it )
792  {
793  typename QList<NormalizedShape>::const_iterator areaIt = area->begin(), areaItEnd = area->end();
794  for ( ; areaIt != areaItEnd; ++areaIt )
795  {
796  if ( !( *it ).isNull() && ( *it ).intersects( *areaIt ) )
797  return true;
798  }
799  }
800 
801  return false;
802 }
803 
804 template <class NormalizedShape, class Shape>
806 {
807  typename QList<NormalizedShape>::const_iterator areaIt = area->begin(), areaItEnd = area->end();
808  for ( ; areaIt != areaItEnd; ++areaIt )
809  this->append( *areaIt );
810 }
811 
812 
813 template <class NormalizedShape, class Shape>
814 void RegularArea<NormalizedShape, Shape>::appendShape( const NormalizedShape& shape, MergeSide side )
815 {
816  int size = this->count();
817  // if the list is empty, adds the shape normally
818  if ( size == 0 )
819  {
820  this->append( shape );
821  }
822  else
823  {
824  bool intersection = false;
825  NormalizedShape& last = (*this)[size - 1];
826 #define O_LAST givePtr( last )
827 # define O_LAST_R O_LAST->right
828 # define O_LAST_L O_LAST->left
829 # define O_LAST_T O_LAST->top
830 # define O_LAST_B O_LAST->bottom
831 #define O_NEW givePtr( shape )
832 # define O_NEW_R O_NEW->right
833 # define O_NEW_L O_NEW->left
834 # define O_NEW_T O_NEW->top
835 # define O_NEW_B O_NEW->bottom
836  switch ( side )
837  {
838  case MergeRight:
839  intersection = ( O_LAST_R >= O_NEW_L ) && ( O_LAST_L <= O_NEW_R )
840  && ( ( O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B )
841  || ( O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B ) );
842  break;
843  case MergeBottom:
844  intersection = ( O_LAST_B >= O_NEW_T ) && ( O_LAST_T <= O_NEW_B )
845  && ( ( O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L )
846  || ( O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L ) );
847  break;
848  case MergeLeft:
849  intersection = ( O_LAST_L <= O_NEW_R ) && ( O_LAST_R >= O_NEW_L )
850  && ( ( O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B )
851  || ( O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B ) );
852  break;
853  case MergeTop:
854  intersection = ( O_LAST_T <= O_NEW_B ) && ( O_LAST_B >= O_NEW_T )
855  && ( ( O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L )
856  || ( O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L ) );
857  break;
858  case MergeAll:
859  intersection = O_LAST->intersects( shape );
860  break;
861  }
862 #undef O_LAST
863 # undef O_LAST_R
864 # undef O_LAST_L
865 # undef O_LAST_T
866 # undef O_LAST_B
867 #undef O_NEW
868 # undef O_NEW_R
869 # undef O_NEW_L
870 # undef O_NEW_T
871 # undef O_NEW_B
872  // if the new shape intersects with the last shape in the list, then
873  // merge it with that and delete the shape
874  if ( intersection )
875  {
876  deref((*this)[size - 1]) |= deref( shape );
877  }
878  else
879  this->append( shape );
880  }
881 }
882 
883 
884 template <class NormalizedShape, class Shape>
885 bool RegularArea<NormalizedShape, Shape>::contains( double x, double y ) const
886 {
887  if ( this->isEmpty() )
888  return false;
889 
890  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
891  for ( ; it != itEnd; ++it )
892  if ( ( *it ).contains( x, y ) )
893  return true;
894 
895  return false;
896 }
897 
898 template <class NormalizedShape, class Shape>
899 bool RegularArea<NormalizedShape, Shape>::contains( const NormalizedShape& shape ) const
900 {
901  if ( this->isEmpty() )
902  return false;
903 
904  return QList<NormalizedShape>::contains( shape );
905 }
906 
907 template <class NormalizedShape, class Shape>
908 QList<Shape> RegularArea<NormalizedShape, Shape>::geometry( int xScale, int yScale, int dx, int dy ) const
909 {
910  if ( this->isEmpty() )
911  return QList<Shape>();
912 
913  QList<Shape> ret;
914  Shape t;
915  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
916  for ( ; it != itEnd; ++it )
917  {
918  t = givePtr( *it )->geometry( xScale, yScale );
919  t.translate( dx, dy );
920  ret.append( t );
921  }
922 
923  return ret;
924 }
925 
926 template <class NormalizedShape, class Shape>
928 {
929  if ( this->isEmpty() )
930  return;
931 
932  for ( int i = 0; i < this->count(); ++i )
933  givePtr( (*this)[i] )->transform( matrix );
934 }
935 
948 class OKULARCORE_EXPORT RegularAreaRect : public RegularArea< NormalizedRect, QRect >
949 {
950  public:
951  RegularAreaRect();
952  RegularAreaRect( const RegularAreaRect& rar );
953  ~RegularAreaRect();
954 
955  RegularAreaRect& operator=( const RegularAreaRect& rar );
956 
957  private:
958  class Private;
959  Private * const d;
960 };
961 
967 {
968  public:
973  explicit HighlightAreaRect( const RegularAreaRect *area = nullptr );
974 
978  int s_id;
979 
984 };
985 
986 uint qHash(const Okular::NormalizedRect& r, uint seed = 0);
987 }
988 
989 
990 #ifndef QT_NO_DEBUG_STREAM
991 
994 OKULARCORE_EXPORT QDebug operator<<( QDebug str, const Okular::NormalizedPoint &point );
995 
999 OKULARCORE_EXPORT QDebug operator<<( QDebug str, const Okular::NormalizedRect &rect );
1000 #endif
1001 
1002 #endif
NormalizedPoint is a helper class which stores the coordinates of a normalized point.
Definition: area.h:119
KCALENDARCORE_EXPORT QDataStream & operator<<(QDataStream &out, const KCalendarCore::Alarm::Ptr &)
Merge only if the bottom side of the first area intersect.
Definition: global.h:73
Merge only if the left side of the first area intersect.
Definition: global.h:74
void appendArea(const RegularArea< NormalizedShape, Shape > *area)
Appends the given area to this area.
Definition: area.h:805
QList< Shape > geometry(int xScale, int yScale, int dx=0, int dy=0) const
Returns the subareas of this regular area mapped to a reference area of size xScale x yScale...
Definition: area.h:908
bool isRight(const NormalizedPoint &pt) const
Returns true if the point pt is located to the left of the right edge of the rectangle.
Definition: area.h:375
MergeSide
The side(s) to be considered when merging areas.
Definition: global.h:70
This class describes the object rectangle for a source reference.
Definition: area.h:596
bool contains(double x, double y) const
Returns whether this area contains the normalized point (x, y).
Definition: area.h:885
Merge only if the top side of the first area intersect.
Definition: global.h:75
double left
The normalized left coordinate.
Definition: area.h:417
A NormalizedRect is a rectangle which can be defined by two NormalizedPoints.
Definition: area.h:192
void appendShape(const NormalizedShape &shape, MergeSide side=MergeAll)
Appends the given shape to this area.
Definition: area.h:814
This is a list of NormalizedRect, to describe an area consisting of multiple rectangles using normali...
Definition: area.h:948
Merge only if the right side of the first area intersect.
Definition: global.h:72
double y
The normalized y coordinate.
Definition: area.h:174
double width() const
Definition: area.h:403
bool intersects(const RegularArea< NormalizedShape, Shape > *area) const
Returns whether this area intersects with the given area.
Definition: area.h:785
global.h
Definition: action.h:19
This class describes the object rectangle for an annotation.
Definition: area.h:553
double right
The normalized right coordinate.
Definition: area.h:427
bool isNull() const
Returns whether the regular area is a null area.
Definition: area.h:757
void append(const T &value)
QColor color
The color of the highlight.
Definition: area.h:983
double height() const
Definition: area.h:409
An area with normalized coordinates that contains a reference to an object.
Definition: area.h:454
int s_id
The search ID of the highlight owner.
Definition: area.h:978
bool isTopOrLevel(const NormalizedPoint &pt) const
Returns true if the point pt is located above the bottom of the rectangle.
Definition: area.h:357
double distanceSqr(double x, double y, double xScale, double yScale) const
Returns the squared distance of the normalized point (x, y) to the closest edge, or 0 if the point is...
Definition: area.h:386
An area with normalized coordinates, consisting of NormalizedShape objects.
Definition: area.h:670
This class is an object rect that doesn&#39;t own the given pointer, i.e.
Definition: area.h:629
bool isBottom(const NormalizedPoint &pt) const
Returns true if the point pt is located below the bottom of the rectangle.
Definition: area.h:330
Merge if the areas intersects, no matter which side(s).
Definition: global.h:76
QList::iterator end()
KCALENDARCORE_EXPORT uint qHash(const KCalendarCore::Period &key)
void transform(const QTransform &matrix)
Transforms the regular area with the operations defined by matrix.
Definition: area.h:927
bool contains(const T &value) const const
bool isBottomOrLevel(const NormalizedPoint &pt) const
Returns true if the point pt is located below the top of the rectangle.
Definition: area.h:348
double top
The normalized top coordinate.
Definition: area.h:422
ObjectType
Describes the type of storable object.
Definition: area.h:460
double x
The normalized x coordinate.
Definition: area.h:169
bool isTop(const NormalizedPoint &pt) const
Returns true if the point pt is located above the top of the rectangle.
Definition: area.h:339
Annotation struct holds properties shared by all annotations.
Definition: annotations.h:91
void simplify()
Simplifies this regular area by merging its intersecting subareas.
Definition: area.h:731
double bottom
The normalized bottom coordinate.
Definition: area.h:432
bool isLeft(const NormalizedPoint &pt) const
Returns true if the point pt is located to the right of the left edge of the rectangle.
Definition: area.h:366
This class stores the geometry of a highlighting area in normalized coordinates, together with highli...
Definition: area.h:966
QList::iterator begin()
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Tue Jun 2 2020 22:31:47 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.