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 <QColor>
16 #include <QDebug>
17 #include <QList>
18 #include <QPainterPath>
19 #include <QTransform>
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 
191 class OKULARCORE_EXPORT NormalizedRect
192 {
193 public:
198  NormalizedRect();
199 
217  NormalizedRect(double left, double top, double right, double bottom);
218 
228  NormalizedRect(const QRect &rectangle, double xScale, double yScale);
229 
234 
238  NormalizedRect &operator=(const NormalizedRect &other);
239 
240  ~NormalizedRect();
241 
245  static NormalizedRect fromQRectF(const QRectF &rect);
246 
250  bool isNull() const;
251 
256  bool contains(double x, double y) const;
257 
262  bool intersects(const NormalizedRect &other) const;
263 
268  bool intersects(const NormalizedRect *other) const;
269 
274  bool intersects(double left, double top, double right, double bottom) const;
275 
279  QRect geometry(int xScale, int yScale) const;
280 
286  QRect roundedGeometry(int xScale, int yScale) const;
287 
292  NormalizedRect operator|(const NormalizedRect &other) const;
293 
298  NormalizedRect &operator|=(const NormalizedRect &other);
299 
306  NormalizedRect operator&(const NormalizedRect &other) const;
307 
312  bool operator==(const NormalizedRect &other) const;
313 
318  NormalizedPoint center() const;
319 
323  void transform(const QTransform &matrix);
324 
329  bool isBottom(const NormalizedPoint &pt) const
330  {
331  return bottom < pt.y;
332  }
333 
338  bool isTop(const NormalizedPoint &pt) const
339  {
340  return top > pt.y;
341  }
342 
347  bool isBottomOrLevel(const NormalizedPoint &pt) const
348  {
349  return top < pt.y;
350  }
351 
356  bool isTopOrLevel(const NormalizedPoint &pt) const
357  {
358  return bottom > pt.y;
359  }
360 
365  bool isLeft(const NormalizedPoint &pt) const
366  {
367  return left < pt.x;
368  }
369 
374  bool isRight(const NormalizedPoint &pt) const
375  {
376  return right > pt.x;
377  }
378 
385  double distanceSqr(double x, double y, double xScale, double yScale) const
386  {
387  double distX = 0;
388  if (x < left)
389  distX = left - x;
390  else if (x > right)
391  distX = x - right;
392 
393  double distY = 0;
394  if (top > y)
395  distY = top - y;
396  else if (bottom < y)
397  distY = y - bottom;
398  return pow(distX * xScale, 2) + pow(distY * yScale, 2);
399  }
400 
402  double width() const
403  {
404  return right - left;
405  }
406 
408  double height() const
409  {
410  return bottom - top;
411  }
412 
416  double left;
417 
421  double top;
422 
426  double right;
427 
431  double bottom;
432 };
433 // KDE_DUMMY_QHASH_FUNCTION(NormalizedRect)
434 
453 class OKULARCORE_EXPORT ObjectRect
454 {
455 public:
459  enum ObjectType {
463  SourceRef
464  };
465 
477  ObjectRect(double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object);
478 
482  ObjectRect(const NormalizedRect &r, bool ellipse, ObjectType type, void *object);
483 
487  ObjectRect(const QPolygonF &poly, ObjectType type, void *object);
488 
492  virtual ~ObjectRect();
493 
494  ObjectRect(const ObjectRect &o) = delete;
495  ObjectRect &operator=(const ObjectRect &o) = delete;
496 
501  ObjectType objectType() const;
502 
506  const void *object() const;
507 
511  const QPainterPath &region() const;
512 
517  virtual QRect boundingRect(double xScale, double yScale) const;
518 
523  virtual bool contains(double x, double y, double xScale, double yScale) const;
524 
528  virtual void transform(const QTransform &matrix);
529 
538  // FIXME this should most probably be a virtual method
539  double distanceSqr(double x, double y, double xScale, double yScale) const;
540 
541 protected:
542  ObjectType m_objectType;
543  void *m_object;
544  QPainterPath m_path;
545  QPainterPath m_transformedPath;
546 };
547 
551 class OKULARCORE_EXPORT AnnotationObjectRect : public ObjectRect
552 {
553 public:
558  explicit AnnotationObjectRect(Annotation *annotation);
559 
563  ~AnnotationObjectRect() override;
564 
568  Annotation *annotation() const;
569 
574  QRect boundingRect(double xScale, double yScale) const override;
575 
580  bool contains(double x, double y, double xScale, double yScale) const override;
581 
585  void transform(const QTransform &matrix) override;
586 
587 private:
588  Annotation *m_annotation;
589 };
590 
594 class OKULARCORE_EXPORT SourceRefObjectRect : public ObjectRect
595 {
596  friend class ObjectRect;
597 
598 public:
605  SourceRefObjectRect(const NormalizedPoint &point, void *srcRef);
606 
611  QRect boundingRect(double xScale, double yScale) const override;
612 
617  bool contains(double x, double y, double xScale, double yScale) const override;
618 
619 private:
620  NormalizedPoint m_point;
621 };
622 
627 class OKULARCORE_EXPORT NonOwningObjectRect : public ObjectRect
628 {
629 public:
630  NonOwningObjectRect(double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object);
631  ~NonOwningObjectRect() override;
632 };
633 
635 
637 template<typename T> T *givePtr(T &t)
638 {
639  return &t;
640 }
641 
643 template<typename T> T &deref(T &t)
644 {
645  return t;
646 }
648 
666 template<class NormalizedShape, class Shape> class RegularArea : public QList<NormalizedShape>
667 {
668 public:
672  bool contains(double x, double y) const;
673 
680  bool contains(const NormalizedShape &shape) const;
681 
685  bool intersects(const RegularArea<NormalizedShape, Shape> *area) const;
686 
690  bool intersects(const NormalizedShape &shape) const;
691 
695  void appendArea(const RegularArea<NormalizedShape, Shape> *area);
696 
700  void appendShape(const NormalizedShape &shape, MergeSide side = MergeAll);
701 
706  void simplify();
707 
711  bool isNull() const;
712 
718  QList<Shape> geometry(int xScale, int yScale, int dx = 0, int dy = 0) const;
719 
723  void transform(const QTransform &matrix);
724 };
725 
726 template<class NormalizedShape, class Shape> void RegularArea<NormalizedShape, Shape>::simplify()
727 {
728 #ifdef DEBUG_REGULARAREA
729  int prev_end = this->count();
730 #endif
731  int end = this->count() - 1, x = 0;
732  for (int i = 0; i < end; ++i) {
733  if (givePtr((*this)[x])->intersects(deref((*this)[i + 1]))) {
734  deref((*this)[x]) |= deref((*this)[i + 1]);
735  this->removeAt(i + 1);
736  --end;
737  --i;
738  } else {
739  x = i + 1;
740  }
741  }
742 #ifdef DEBUG_REGULARAREA
743  qCDebug(OkularCoreDebug) << "from" << prev_end << "to" << this->count();
744 #endif
745 }
746 
747 template<class NormalizedShape, class Shape> bool RegularArea<NormalizedShape, Shape>::isNull() const
748 {
749  if (this->isEmpty())
750  return true;
751 
752  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
753  for (; it != itEnd; ++it)
754  if (!givePtr(*it)->isNull())
755  return false;
756 
757  return true;
758 }
759 
760 template<class NormalizedShape, class Shape> bool RegularArea<NormalizedShape, Shape>::intersects(const NormalizedShape &shape) const
761 {
762  if (this->isEmpty())
763  return false;
764 
765  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
766  for (; it != itEnd; ++it)
767  if (!givePtr(*it)->isNull() && givePtr(*it)->intersects(shape))
768  return true;
769 
770  return false;
771 }
772 
773 template<class NormalizedShape, class Shape> bool RegularArea<NormalizedShape, Shape>::intersects(const RegularArea<NormalizedShape, Shape> *area) const
774 {
775  if (this->isEmpty())
776  return false;
777 
778  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
779  for (; it != itEnd; ++it) {
780  typename QList<NormalizedShape>::const_iterator areaIt = area->begin(), areaItEnd = area->end();
781  for (; areaIt != areaItEnd; ++areaIt) {
782  if (!(*it).isNull() && (*it).intersects(*areaIt))
783  return true;
784  }
785  }
786 
787  return false;
788 }
789 
790 template<class NormalizedShape, class Shape> void RegularArea<NormalizedShape, Shape>::appendArea(const RegularArea<NormalizedShape, Shape> *area)
791 {
792  typename QList<NormalizedShape>::const_iterator areaIt = area->begin(), areaItEnd = area->end();
793  for (; areaIt != areaItEnd; ++areaIt)
794  this->append(*areaIt);
795 }
796 
797 template<class NormalizedShape, class Shape> void RegularArea<NormalizedShape, Shape>::appendShape(const NormalizedShape &shape, MergeSide side)
798 {
799  int size = this->count();
800  // if the list is empty, adds the shape normally
801  if (size == 0) {
802  this->append(shape);
803  } else {
804  bool intersection = false;
805  NormalizedShape &last = (*this)[size - 1];
806 #define O_LAST givePtr(last)
807 #define O_LAST_R O_LAST->right
808 #define O_LAST_L O_LAST->left
809 #define O_LAST_T O_LAST->top
810 #define O_LAST_B O_LAST->bottom
811 #define O_NEW givePtr(shape)
812 #define O_NEW_R O_NEW->right
813 #define O_NEW_L O_NEW->left
814 #define O_NEW_T O_NEW->top
815 #define O_NEW_B O_NEW->bottom
816  switch (side) {
817  case MergeRight:
818  intersection = (O_LAST_R >= O_NEW_L) && (O_LAST_L <= O_NEW_R) && ((O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B) || (O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B));
819  break;
820  case MergeBottom:
821  intersection = (O_LAST_B >= O_NEW_T) && (O_LAST_T <= O_NEW_B) && ((O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L) || (O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L));
822  break;
823  case MergeLeft:
824  intersection = (O_LAST_L <= O_NEW_R) && (O_LAST_R >= O_NEW_L) && ((O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B) || (O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B));
825  break;
826  case MergeTop:
827  intersection = (O_LAST_T <= O_NEW_B) && (O_LAST_B >= O_NEW_T) && ((O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L) || (O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L));
828  break;
829  case MergeAll:
830  intersection = O_LAST->intersects(shape);
831  break;
832  }
833 #undef O_LAST
834 #undef O_LAST_R
835 #undef O_LAST_L
836 #undef O_LAST_T
837 #undef O_LAST_B
838 #undef O_NEW
839 #undef O_NEW_R
840 #undef O_NEW_L
841 #undef O_NEW_T
842 #undef O_NEW_B
843  // if the new shape intersects with the last shape in the list, then
844  // merge it with that and delete the shape
845  if (intersection) {
846  deref((*this)[size - 1]) |= deref(shape);
847  } else
848  this->append(shape);
849  }
850 }
851 
852 template<class NormalizedShape, class Shape> bool RegularArea<NormalizedShape, Shape>::contains(double x, double y) const
853 {
854  if (this->isEmpty())
855  return false;
856 
857  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
858  for (; it != itEnd; ++it)
859  if ((*it).contains(x, y))
860  return true;
861 
862  return false;
863 }
864 
865 template<class NormalizedShape, class Shape> bool RegularArea<NormalizedShape, Shape>::contains(const NormalizedShape &shape) const
866 {
867  if (this->isEmpty())
868  return false;
869 
870  return QList<NormalizedShape>::contains(shape);
871 }
872 
873 template<class NormalizedShape, class Shape> QList<Shape> RegularArea<NormalizedShape, Shape>::geometry(int xScale, int yScale, int dx, int dy) const
874 {
875  if (this->isEmpty())
876  return QList<Shape>();
877 
878  QList<Shape> ret;
879  Shape t;
880  typename QList<NormalizedShape>::const_iterator it = this->begin(), itEnd = this->end();
881  for (; it != itEnd; ++it) {
882  t = givePtr(*it)->geometry(xScale, yScale);
883  t.translate(dx, dy);
884  ret.append(t);
885  }
886 
887  return ret;
888 }
889 
890 template<class NormalizedShape, class Shape> void RegularArea<NormalizedShape, Shape>::transform(const QTransform &matrix)
891 {
892  if (this->isEmpty())
893  return;
894 
895  for (int i = 0; i < this->count(); ++i)
896  givePtr((*this)[i])->transform(matrix);
897 }
898 
911 class OKULARCORE_EXPORT RegularAreaRect : public RegularArea<NormalizedRect, QRect>
912 {
913 public:
914  RegularAreaRect();
915  RegularAreaRect(const RegularAreaRect &rar);
916  ~RegularAreaRect();
917 
918  RegularAreaRect &operator=(const RegularAreaRect &rar);
919 
920 private:
921  class Private;
922  Private *const d;
923 };
924 
930 {
931 public:
936  explicit HighlightAreaRect(const RegularAreaRect *area = nullptr);
937 
941  int s_id;
942 
947 };
948 
949 uint qHash(const Okular::NormalizedRect &r, uint seed = 0);
950 }
951 
952 #ifndef QT_NO_DEBUG_STREAM
953 
956 OKULARCORE_EXPORT QDebug operator<<(QDebug str, const Okular::NormalizedPoint &point);
957 
961 OKULARCORE_EXPORT QDebug operator<<(QDebug str, const Okular::NormalizedRect &rect);
962 #endif
963 
964 #endif
NormalizedPoint is a helper class which stores the coordinates of a normalized point.
Definition: area.h:119
Merge only if the bottom side of the first area intersect.
Definition: global.h:68
Merge only if the left side of the first area intersect.
Definition: global.h:69
void appendArea(const RegularArea< NormalizedShape, Shape > *area)
Appends the given area to this area.
Definition: area.h:790
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:873
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:374
MergeSide
The side(s) to be considered when merging areas.
Definition: global.h:66
This class describes the object rectangle for a source reference.
Definition: area.h:594
bool contains(double x, double y) const
Returns whether this area contains the normalized point (x, y).
Definition: area.h:852
Merge only if the top side of the first area intersect.
Definition: global.h:70
double left
The normalized left coordinate.
Definition: area.h:416
A NormalizedRect is a rectangle which can be defined by two NormalizedPoints.
Definition: area.h:191
void appendShape(const NormalizedShape &shape, MergeSide side=MergeAll)
Appends the given shape to this area.
Definition: area.h:797
This is a list of NormalizedRect, to describe an area consisting of multiple rectangles using normali...
Definition: area.h:911
Merge only if the right side of the first area intersect.
Definition: global.h:67
double y
The normalized y coordinate.
Definition: area.h:174
double width() const
Definition: area.h:402
bool intersects(const RegularArea< NormalizedShape, Shape > *area) const
Returns whether this area intersects with the given area.
Definition: area.h:773
global.h
Definition: action.h:19
This class describes the object rectangle for an annotation.
Definition: area.h:551
double right
The normalized right coordinate.
Definition: area.h:426
bool isNull() const
Returns whether the regular area is a null area.
Definition: area.h:747
void append(const T &value)
QColor color
The color of the highlight.
Definition: area.h:946
double height() const
Definition: area.h:408
An area with normalized coordinates that contains a reference to an object.
Definition: area.h:453
int s_id
The search ID of the highlight owner.
Definition: area.h:941
bool isTopOrLevel(const NormalizedPoint &pt) const
Returns true if the point pt is located above the bottom of the rectangle.
Definition: area.h:356
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:385
An area with normalized coordinates, consisting of NormalizedShape objects.
Definition: area.h:666
This class is an object rect that doesn&#39;t own the given pointer, i.e.
Definition: area.h:627
bool isBottom(const NormalizedPoint &pt) const
Returns true if the point pt is located below the bottom of the rectangle.
Definition: area.h:329
Merge if the areas intersects, no matter which side(s).
Definition: global.h:71
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:890
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:347
double top
The normalized top coordinate.
Definition: area.h:421
ObjectType
Describes the type of storable object.
Definition: area.h:459
QDataStream & operator<<(QDataStream &out, const KDateTime::Spec &spec)
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:338
Annotation struct holds properties shared by all annotations.
Definition: annotations.h:88
void simplify()
Simplifies this regular area by merging its intersecting subareas.
Definition: area.h:726
double bottom
The normalized bottom coordinate.
Definition: area.h:431
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:365
This class stores the geometry of a highlighting area in normalized coordinates, together with highli...
Definition: area.h:929
QList::iterator begin()
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed Sep 23 2020 22:36:12 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.