2005-07-15 18:20:57 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2004-05 by Enrico Ros <eros.kde@email.it> *
|
|
|
|
* Copyright (C) 2005 by Piotr Szymanski <niedakh@gmail.com> *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
***************************************************************************/
|
2006-09-19 17:17:29 +00:00
|
|
|
|
2007-04-19 18:30:20 +00:00
|
|
|
#include "area.h"
|
|
|
|
|
2006-09-21 08:45:36 +00:00
|
|
|
#include <QtCore/QRect>
|
2006-10-28 18:03:33 +00:00
|
|
|
#include <QtGui/QPolygonF>
|
2014-09-11 00:03:46 +00:00
|
|
|
#include <kdebug.h>
|
2006-09-21 08:45:36 +00:00
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
2007-04-20 11:26:05 +00:00
|
|
|
#include "action.h"
|
2006-09-19 17:17:29 +00:00
|
|
|
#include "annotations.h"
|
2007-05-04 20:45:45 +00:00
|
|
|
#include "annotations_p.h"
|
2008-01-20 16:39:21 +00:00
|
|
|
#include "debug_p.h"
|
2007-01-02 17:50:24 +00:00
|
|
|
#include "sourcereference.h"
|
2005-07-15 18:20:57 +00:00
|
|
|
|
2006-09-21 08:45:36 +00:00
|
|
|
using namespace Okular;
|
2006-07-12 22:00:46 +00:00
|
|
|
|
2005-07-15 18:20:57 +00:00
|
|
|
/** class NormalizedPoint **/
|
|
|
|
NormalizedPoint::NormalizedPoint()
|
|
|
|
: x( 0.0 ), y( 0.0 ) {}
|
|
|
|
|
|
|
|
NormalizedPoint::NormalizedPoint( double dX, double dY )
|
|
|
|
: x( dX ), y( dY ) {}
|
|
|
|
|
|
|
|
NormalizedPoint::NormalizedPoint( int iX, int iY, int xScale, int yScale )
|
|
|
|
: x( (double)iX / (double)xScale ), y( (double)iY / (double)yScale ) {}
|
|
|
|
|
2006-09-26 22:22:01 +00:00
|
|
|
NormalizedPoint& NormalizedPoint::operator=( const NormalizedPoint & p )
|
|
|
|
{
|
|
|
|
x = p.x;
|
|
|
|
y = p.y;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-09-08 15:06:02 +00:00
|
|
|
void NormalizedPoint::transform( const QTransform &matrix )
|
2006-11-20 07:53:32 +00:00
|
|
|
{
|
2008-07-25 20:51:42 +00:00
|
|
|
qreal tmp_x = (qreal)x;
|
|
|
|
qreal tmp_y = (qreal)y;
|
|
|
|
matrix.map( tmp_x, tmp_y, &tmp_x, &tmp_y );
|
|
|
|
x = tmp_x;
|
|
|
|
y = tmp_y;
|
2006-11-20 07:53:32 +00:00
|
|
|
}
|
2005-07-15 18:20:57 +00:00
|
|
|
|
2013-06-23 17:19:25 +00:00
|
|
|
double NormalizedPoint::distanceSqr( double x, double y, double xScale, double yScale ) const
|
|
|
|
{
|
|
|
|
return pow( (this->x - x) * xScale, 2 ) + pow( (this->y - y) * yScale, 2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a vector from the given points @p a and @p b
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
NormalizedPoint operator-( const NormalizedPoint& a, const NormalizedPoint& b )
|
|
|
|
{
|
|
|
|
return NormalizedPoint( a.x - b.x, a.y - b.y );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Calculates distance of the point @p x @p y @p xScale @p yScale to the line segment from @p start to @p end
|
|
|
|
*/
|
|
|
|
double NormalizedPoint::distanceSqr( double x, double y, double xScale, double yScale, const NormalizedPoint& start, const NormalizedPoint& end )
|
|
|
|
{
|
|
|
|
NormalizedPoint point( x, y );
|
|
|
|
double thisDistance;
|
|
|
|
NormalizedPoint lineSegment( end - start );
|
|
|
|
const double lengthSqr = pow( lineSegment.x, 2 ) + pow( lineSegment.y, 2 );
|
|
|
|
|
|
|
|
//if the length of the current segment is null, we can just
|
|
|
|
//measure the distance to either end point
|
|
|
|
if ( lengthSqr == 0.0 )
|
|
|
|
{
|
|
|
|
thisDistance = end.distanceSqr( x, y, xScale, yScale );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//vector from the start point of the current line segment to the measurement point
|
|
|
|
NormalizedPoint a = point - start;
|
|
|
|
//vector from the same start point to the end point of the current line segment
|
|
|
|
NormalizedPoint b = end - start;
|
|
|
|
|
|
|
|
//we're using a * b (dot product) := |a| * |b| * cos(phi) and the knowledge
|
|
|
|
//that cos(phi) is adjacent side / hypotenuse (hypotenuse = |b|)
|
|
|
|
//therefore, t becomes the length of the vector that represents the projection of
|
|
|
|
//the point p onto the current line segment
|
|
|
|
//(hint: if this is still unclear, draw it!)
|
|
|
|
float t = (a.x * b.x + a.y * b.y) / lengthSqr;
|
|
|
|
|
|
|
|
if ( t < 0 )
|
|
|
|
{
|
|
|
|
//projection falls outside the line segment on the side of "start"
|
|
|
|
thisDistance = point.distanceSqr( start.x, start.y, xScale, yScale );
|
|
|
|
}
|
|
|
|
else if ( t > 1 )
|
|
|
|
{
|
|
|
|
//projection falls outside the line segment on the side of the current point
|
|
|
|
thisDistance = point.distanceSqr( end.x, end.y, xScale, yScale );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//projection is within [start, *i];
|
|
|
|
//determine the length of the perpendicular distance from the projection to the actual point
|
|
|
|
NormalizedPoint direction = end - start;
|
|
|
|
NormalizedPoint projection = start - NormalizedPoint( -t * direction.x, -t * direction.y );
|
|
|
|
thisDistance = projection.distanceSqr( x, y, xScale, yScale );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return thisDistance;
|
|
|
|
}
|
|
|
|
|
2007-07-30 23:58:04 +00:00
|
|
|
QDebug operator<<( QDebug str, const Okular::NormalizedPoint& p )
|
2006-12-31 17:52:24 +00:00
|
|
|
{
|
2007-07-31 10:19:48 +00:00
|
|
|
str.nospace() << "NormPt(" << p.x << "," << p.y << ")";
|
|
|
|
return str.space();
|
2006-12-31 17:52:24 +00:00
|
|
|
}
|
|
|
|
|
2005-07-15 18:20:57 +00:00
|
|
|
/** class NormalizedRect **/
|
|
|
|
|
|
|
|
NormalizedRect::NormalizedRect()
|
|
|
|
: left( 0.0 ), top( 0.0 ), right( 0.0 ), bottom( 0.0 ) {}
|
|
|
|
|
|
|
|
NormalizedRect::NormalizedRect( double l, double t, double r, double b )
|
|
|
|
// note: check for swapping coords?
|
|
|
|
: left( l ), top( t ), right( r ), bottom( b ) {}
|
|
|
|
|
|
|
|
NormalizedRect::NormalizedRect( const QRect & r, double xScale, double yScale )
|
|
|
|
: left( (double)r.left() / xScale ), top( (double)r.top() / yScale ),
|
|
|
|
right( (double)r.right() / xScale ), bottom( (double)r.bottom() / yScale ) {}
|
|
|
|
|
2006-06-23 21:11:52 +00:00
|
|
|
NormalizedRect::NormalizedRect( const NormalizedRect & rect )
|
|
|
|
: left( rect.left ), top( rect.top ), right( rect.right ), bottom( rect.bottom ) {}
|
|
|
|
|
2007-02-01 18:31:45 +00:00
|
|
|
NormalizedRect NormalizedRect::fromQRectF( const QRectF &rect )
|
|
|
|
{
|
2008-12-28 01:20:43 +00:00
|
|
|
QRectF nrect = rect.normalized();
|
2007-02-01 18:31:45 +00:00
|
|
|
NormalizedRect ret;
|
2008-12-28 01:20:43 +00:00
|
|
|
ret.left = nrect.left();
|
|
|
|
ret.top = nrect.top();
|
|
|
|
ret.right = nrect.right();
|
|
|
|
ret.bottom = nrect.bottom();
|
2007-02-01 18:31:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-07-15 18:20:57 +00:00
|
|
|
bool NormalizedRect::isNull() const
|
|
|
|
{
|
- GIGANTIC 2700 line diff with LOTS OF FEATURES!
- 1. editor-like text selection, and I do mean it, its not pseudo-editor
(like the ones acroread and kviewshell have) it doesnt intersect the
selection area with words under it, no, it does a lot more, including
work on cursors and searching for the text area closest to the given
cursor
- 2. rotation support, change the orientation of the documents if
you need too :)
- 3. the kfaxview backend works beautifully, porting kviewshell backends
is damn easy ! djvu and dvi will be next!
- 4. Hardware Blending of selection rectangles! We now use XRender
instead of KImageEffect, makes a damn faster blend!
- 5. Overview mode - as seen in Kviewshell, but quite a bit extended,
the kviewshell is only one state, while we support it in both
continous and non-continous form
- BTW. I coded all those features myself, (apart from kfaxview backend library)
it is an impressive bit right? but oKular cant be run by only one person,
join in on the fun! i can introduce you into the code just mail niedakh@gmail.com
svn path=/trunk/playground/graphics/oKular/kpdf/; revision=509871
2006-02-15 18:54:49 +00:00
|
|
|
return left == 0 && top== 0 && right == 0 && bottom == 0;
|
2005-07-15 18:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool NormalizedRect::contains( double x, double y ) const
|
|
|
|
{
|
|
|
|
return x >= left && x <= right && y >= top && y <= bottom;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool NormalizedRect::intersects( const NormalizedRect & r ) const
|
|
|
|
{
|
|
|
|
return (r.left <= right) && (r.right >= left) && (r.top <= bottom) && (r.bottom >= top);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool NormalizedRect::intersects( const NormalizedRect * r ) const
|
|
|
|
{
|
|
|
|
return (r->left <= right) && (r->right >= left) && (r->top <= bottom) && (r->bottom >= top);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool NormalizedRect::intersects( double l, double t, double r, double b ) const
|
|
|
|
{
|
|
|
|
return (l <= right) && (r >= left) && (t <= bottom) && (b >= top);
|
|
|
|
}
|
|
|
|
|
- GIGANTIC 2700 line diff with LOTS OF FEATURES!
- 1. editor-like text selection, and I do mean it, its not pseudo-editor
(like the ones acroread and kviewshell have) it doesnt intersect the
selection area with words under it, no, it does a lot more, including
work on cursors and searching for the text area closest to the given
cursor
- 2. rotation support, change the orientation of the documents if
you need too :)
- 3. the kfaxview backend works beautifully, porting kviewshell backends
is damn easy ! djvu and dvi will be next!
- 4. Hardware Blending of selection rectangles! We now use XRender
instead of KImageEffect, makes a damn faster blend!
- 5. Overview mode - as seen in Kviewshell, but quite a bit extended,
the kviewshell is only one state, while we support it in both
continous and non-continous form
- BTW. I coded all those features myself, (apart from kfaxview backend library)
it is an impressive bit right? but oKular cant be run by only one person,
join in on the fun! i can introduce you into the code just mail niedakh@gmail.com
svn path=/trunk/playground/graphics/oKular/kpdf/; revision=509871
2006-02-15 18:54:49 +00:00
|
|
|
NormalizedRect NormalizedRect::operator| (const NormalizedRect & r) const
|
|
|
|
{
|
|
|
|
NormalizedRect ret;
|
|
|
|
// todo !
|
2006-03-29 17:16:46 +00:00
|
|
|
ret.left=qMin(left,r.left);
|
|
|
|
ret.top=qMin(top,r.top);
|
|
|
|
ret.bottom=qMax(bottom,r.bottom);
|
|
|
|
ret.right=qMax(right,r.right);
|
- GIGANTIC 2700 line diff with LOTS OF FEATURES!
- 1. editor-like text selection, and I do mean it, its not pseudo-editor
(like the ones acroread and kviewshell have) it doesnt intersect the
selection area with words under it, no, it does a lot more, including
work on cursors and searching for the text area closest to the given
cursor
- 2. rotation support, change the orientation of the documents if
you need too :)
- 3. the kfaxview backend works beautifully, porting kviewshell backends
is damn easy ! djvu and dvi will be next!
- 4. Hardware Blending of selection rectangles! We now use XRender
instead of KImageEffect, makes a damn faster blend!
- 5. Overview mode - as seen in Kviewshell, but quite a bit extended,
the kviewshell is only one state, while we support it in both
continous and non-continous form
- BTW. I coded all those features myself, (apart from kfaxview backend library)
it is an impressive bit right? but oKular cant be run by only one person,
join in on the fun! i can introduce you into the code just mail niedakh@gmail.com
svn path=/trunk/playground/graphics/oKular/kpdf/; revision=509871
2006-02-15 18:54:49 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
NormalizedRect& NormalizedRect::operator|= (const NormalizedRect & r)
|
|
|
|
{
|
2006-10-12 21:43:55 +00:00
|
|
|
left = qMin( left, r.left );
|
|
|
|
top = qMin( top, r.top );
|
|
|
|
bottom = qMax( bottom, r.bottom );
|
|
|
|
right = qMax( right, r.right );
|
|
|
|
return *this;
|
- GIGANTIC 2700 line diff with LOTS OF FEATURES!
- 1. editor-like text selection, and I do mean it, its not pseudo-editor
(like the ones acroread and kviewshell have) it doesnt intersect the
selection area with words under it, no, it does a lot more, including
work on cursors and searching for the text area closest to the given
cursor
- 2. rotation support, change the orientation of the documents if
you need too :)
- 3. the kfaxview backend works beautifully, porting kviewshell backends
is damn easy ! djvu and dvi will be next!
- 4. Hardware Blending of selection rectangles! We now use XRender
instead of KImageEffect, makes a damn faster blend!
- 5. Overview mode - as seen in Kviewshell, but quite a bit extended,
the kviewshell is only one state, while we support it in both
continous and non-continous form
- BTW. I coded all those features myself, (apart from kfaxview backend library)
it is an impressive bit right? but oKular cant be run by only one person,
join in on the fun! i can introduce you into the code just mail niedakh@gmail.com
svn path=/trunk/playground/graphics/oKular/kpdf/; revision=509871
2006-02-15 18:54:49 +00:00
|
|
|
}
|
2006-06-23 21:11:52 +00:00
|
|
|
|
2008-05-18 21:08:31 +00:00
|
|
|
NormalizedRect NormalizedRect::operator&( const NormalizedRect & r ) const
|
|
|
|
{
|
|
|
|
if ( isNull() || r.isNull() )
|
|
|
|
return NormalizedRect();
|
|
|
|
|
|
|
|
NormalizedRect ret;
|
|
|
|
ret.left = qMax( left, r.left );
|
|
|
|
ret.top = qMax( top, r.top );
|
|
|
|
ret.bottom = qMin( bottom, r.bottom );
|
|
|
|
ret.right = qMin( right, r.right );
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2006-06-23 21:11:52 +00:00
|
|
|
NormalizedRect & NormalizedRect::operator=( const NormalizedRect & r )
|
|
|
|
{
|
|
|
|
left = r.left;
|
|
|
|
right = r.right;
|
|
|
|
top = r.top;
|
|
|
|
bottom = r.bottom;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2006-07-12 22:00:46 +00:00
|
|
|
bool NormalizedRect::operator==( const NormalizedRect & r ) const
|
|
|
|
{
|
|
|
|
return ( isNull() && r.isNull() ) ||
|
|
|
|
( fabs( left - r.left ) < 1e-4 &&
|
|
|
|
fabs( right - r.right ) < 1e-4 &&
|
|
|
|
fabs( top - r.top ) < 1e-4 &&
|
|
|
|
fabs( bottom - r.bottom ) < 1e-4 );
|
|
|
|
}
|
|
|
|
|
2009-11-12 21:45:35 +00:00
|
|
|
NormalizedPoint NormalizedRect::center() const
|
|
|
|
{
|
|
|
|
return NormalizedPoint((left+right)/2.0, (top+bottom)/2.0);
|
|
|
|
}
|
|
|
|
|
- GIGANTIC 2700 line diff with LOTS OF FEATURES!
- 1. editor-like text selection, and I do mean it, its not pseudo-editor
(like the ones acroread and kviewshell have) it doesnt intersect the
selection area with words under it, no, it does a lot more, including
work on cursors and searching for the text area closest to the given
cursor
- 2. rotation support, change the orientation of the documents if
you need too :)
- 3. the kfaxview backend works beautifully, porting kviewshell backends
is damn easy ! djvu and dvi will be next!
- 4. Hardware Blending of selection rectangles! We now use XRender
instead of KImageEffect, makes a damn faster blend!
- 5. Overview mode - as seen in Kviewshell, but quite a bit extended,
the kviewshell is only one state, while we support it in both
continous and non-continous form
- BTW. I coded all those features myself, (apart from kfaxview backend library)
it is an impressive bit right? but oKular cant be run by only one person,
join in on the fun! i can introduce you into the code just mail niedakh@gmail.com
svn path=/trunk/playground/graphics/oKular/kpdf/; revision=509871
2006-02-15 18:54:49 +00:00
|
|
|
/*
|
2007-07-30 23:58:04 +00:00
|
|
|
QDebug operator << (QDebug str , const NormalizedRect &r)
|
- GIGANTIC 2700 line diff with LOTS OF FEATURES!
- 1. editor-like text selection, and I do mean it, its not pseudo-editor
(like the ones acroread and kviewshell have) it doesnt intersect the
selection area with words under it, no, it does a lot more, including
work on cursors and searching for the text area closest to the given
cursor
- 2. rotation support, change the orientation of the documents if
you need too :)
- 3. the kfaxview backend works beautifully, porting kviewshell backends
is damn easy ! djvu and dvi will be next!
- 4. Hardware Blending of selection rectangles! We now use XRender
instead of KImageEffect, makes a damn faster blend!
- 5. Overview mode - as seen in Kviewshell, but quite a bit extended,
the kviewshell is only one state, while we support it in both
continous and non-continous form
- BTW. I coded all those features myself, (apart from kfaxview backend library)
it is an impressive bit right? but oKular cant be run by only one person,
join in on the fun! i can introduce you into the code just mail niedakh@gmail.com
svn path=/trunk/playground/graphics/oKular/kpdf/; revision=509871
2006-02-15 18:54:49 +00:00
|
|
|
{
|
|
|
|
str << "[" <<r.left() << "," << r.top() << "] x "<< "[" <<r.right() << "," << r.bottom() << "]";
|
|
|
|
return str;
|
|
|
|
}*/
|
|
|
|
|
2005-07-15 18:20:57 +00:00
|
|
|
QRect NormalizedRect::geometry( int xScale, int yScale ) const
|
|
|
|
{
|
|
|
|
int l = (int)( left * xScale ),
|
|
|
|
t = (int)( top * yScale ),
|
|
|
|
r = (int)( right * xScale ),
|
|
|
|
b = (int)( bottom * yScale );
|
2006-11-20 07:53:32 +00:00
|
|
|
|
2005-07-15 18:20:57 +00:00
|
|
|
return QRect( l, t, r - l + 1, b - t + 1 );
|
|
|
|
}
|
|
|
|
|
2011-07-02 15:24:50 +00:00
|
|
|
QRect NormalizedRect::roundedGeometry( int xScale, int yScale ) const
|
|
|
|
{
|
|
|
|
int l = (int)( left * xScale + 0.5 ),
|
|
|
|
t = (int)( top * yScale + 0.5 ),
|
|
|
|
r = (int)( right * xScale + 0.5 ),
|
|
|
|
b = (int)( bottom * yScale + 0.5 );
|
|
|
|
|
|
|
|
return QRect( l, t, r - l + 1, b - t + 1 );
|
|
|
|
}
|
|
|
|
|
2012-09-08 15:06:02 +00:00
|
|
|
void NormalizedRect::transform( const QTransform &matrix )
|
2006-11-20 07:53:32 +00:00
|
|
|
{
|
|
|
|
QRectF rect( left, top, right - left, bottom - top );
|
|
|
|
rect = matrix.mapRect( rect );
|
|
|
|
|
|
|
|
left = rect.left();
|
|
|
|
top = rect.top();
|
|
|
|
right = rect.right();
|
|
|
|
bottom = rect.bottom();
|
|
|
|
}
|
|
|
|
|
2007-07-30 23:58:04 +00:00
|
|
|
QDebug operator<<( QDebug str, const Okular::NormalizedRect& r )
|
2006-12-31 17:52:24 +00:00
|
|
|
{
|
2007-07-31 10:19:48 +00:00
|
|
|
str.nospace() << "NormRect(" << r.left << "," << r.top << " x " << ( r.right - r.left ) << "+" << ( r.bottom - r.top ) << ")";
|
|
|
|
return str.space();
|
2006-12-31 17:52:24 +00:00
|
|
|
}
|
|
|
|
|
2007-07-10 23:15:14 +00:00
|
|
|
RegularAreaRect::RegularAreaRect()
|
|
|
|
: RegularArea< NormalizedRect, QRect >(), d( 0 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
RegularAreaRect::RegularAreaRect( const RegularAreaRect& rar )
|
|
|
|
: RegularArea< NormalizedRect, QRect >( rar ), d( 0 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
RegularAreaRect::~RegularAreaRect()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
RegularAreaRect& RegularAreaRect::operator=( const RegularAreaRect& rar )
|
|
|
|
{
|
|
|
|
RegularArea< NormalizedRect, QRect >::operator=( rar );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-12 21:55:32 +00:00
|
|
|
HighlightAreaRect::HighlightAreaRect( const RegularAreaRect *area )
|
|
|
|
: RegularAreaRect(), s_id( -1 )
|
2005-07-15 18:20:57 +00:00
|
|
|
{
|
2006-10-12 21:55:32 +00:00
|
|
|
if ( area )
|
|
|
|
{
|
|
|
|
RegularAreaRect::ConstIterator it = area->begin();
|
|
|
|
RegularAreaRect::ConstIterator itEnd = area->end();
|
|
|
|
for ( ; it != itEnd; ++it )
|
|
|
|
{
|
2007-09-05 14:51:40 +00:00
|
|
|
append( NormalizedRect( *it ) );
|
2006-10-12 21:55:32 +00:00
|
|
|
}
|
|
|
|
}
|
2005-07-15 18:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** class ObjectRect **/
|
|
|
|
|
2006-07-13 15:03:18 +00:00
|
|
|
ObjectRect::ObjectRect( double l, double t, double r, double b, bool ellipse, ObjectType type, void * pnt )
|
2007-01-02 17:05:49 +00:00
|
|
|
: m_objectType( type ), m_object( pnt )
|
2005-07-15 18:20:57 +00:00
|
|
|
{
|
2006-07-13 15:03:18 +00:00
|
|
|
// assign coordinates swapping them if negative width or height
|
|
|
|
QRectF rect( r > l ? l : r, b > t ? t : b, fabs( r - l ), fabs( b - t ) );
|
|
|
|
if ( ellipse )
|
|
|
|
m_path.addEllipse( rect );
|
|
|
|
else
|
|
|
|
m_path.addRect( rect );
|
2006-11-20 07:53:32 +00:00
|
|
|
|
2007-01-02 17:05:49 +00:00
|
|
|
m_transformedPath = m_path;
|
2006-07-13 15:03:18 +00:00
|
|
|
}
|
|
|
|
|
2006-10-12 22:04:26 +00:00
|
|
|
ObjectRect::ObjectRect( const NormalizedRect& x, bool ellipse, ObjectType type, void * pnt )
|
2007-01-02 17:05:49 +00:00
|
|
|
: m_objectType( type ), m_object( pnt )
|
2006-07-13 15:03:18 +00:00
|
|
|
{
|
|
|
|
QRectF rect( x.left, x.top, fabs( x.right - x.left ), fabs( x.bottom - x.top ) );
|
|
|
|
if ( ellipse )
|
|
|
|
m_path.addEllipse( rect );
|
|
|
|
else
|
|
|
|
m_path.addRect( rect );
|
2006-11-20 07:53:32 +00:00
|
|
|
|
2007-01-02 17:05:49 +00:00
|
|
|
m_transformedPath = m_path;
|
2006-07-13 15:03:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ObjectRect::ObjectRect( const QPolygonF &poly, ObjectType type, void * pnt )
|
2007-01-02 17:05:49 +00:00
|
|
|
: m_objectType( type ), m_object( pnt )
|
2006-07-13 15:03:18 +00:00
|
|
|
{
|
|
|
|
m_path.addPolygon( poly );
|
2006-11-20 07:53:32 +00:00
|
|
|
|
2007-01-02 17:05:49 +00:00
|
|
|
m_transformedPath = m_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjectRect::ObjectType ObjectRect::objectType() const
|
|
|
|
{
|
|
|
|
return m_objectType;
|
|
|
|
}
|
|
|
|
|
|
|
|
const void * ObjectRect::object() const
|
|
|
|
{
|
|
|
|
return m_object;
|
2006-11-20 07:53:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const QPainterPath &ObjectRect::region() const
|
|
|
|
{
|
2007-01-02 17:05:49 +00:00
|
|
|
return m_transformedPath;
|
2005-07-15 18:20:57 +00:00
|
|
|
}
|
|
|
|
|
2006-09-19 17:17:29 +00:00
|
|
|
QRect ObjectRect::boundingRect( double xScale, double yScale ) const
|
2005-08-30 13:24:29 +00:00
|
|
|
{
|
2007-01-02 17:05:49 +00:00
|
|
|
const QRectF &br = m_transformedPath.boundingRect();
|
2006-11-20 07:53:32 +00:00
|
|
|
|
2006-07-13 15:03:18 +00:00
|
|
|
return QRect( (int)( br.left() * xScale ), (int)( br.top() * yScale ),
|
|
|
|
(int)( br.width() * xScale ), (int)( br.height() * yScale ) );
|
2005-08-30 13:24:29 +00:00
|
|
|
}
|
|
|
|
|
2006-11-20 07:53:32 +00:00
|
|
|
bool ObjectRect::contains( double x, double y, double, double ) const
|
|
|
|
{
|
2007-01-02 17:05:49 +00:00
|
|
|
return m_transformedPath.contains( QPointF( x, y ) );
|
2006-11-20 07:53:32 +00:00
|
|
|
}
|
|
|
|
|
2012-09-08 15:06:02 +00:00
|
|
|
void ObjectRect::transform( const QTransform &matrix )
|
2006-11-20 07:53:32 +00:00
|
|
|
{
|
2007-01-02 17:05:49 +00:00
|
|
|
m_transformedPath = matrix.map( m_path );
|
2006-11-20 07:53:32 +00:00
|
|
|
}
|
|
|
|
|
2009-03-23 12:05:00 +00:00
|
|
|
double ObjectRect::distanceSqr( double x, double y, double xScale, double yScale ) const
|
|
|
|
{
|
|
|
|
switch ( m_objectType )
|
|
|
|
{
|
|
|
|
case Action:
|
|
|
|
case Image:
|
2013-06-23 17:19:25 +00:00
|
|
|
{
|
|
|
|
const QRectF& rect( m_transformedPath.boundingRect() );
|
|
|
|
return NormalizedRect( rect.x(), rect.y(), rect.right(), rect.bottom() ).distanceSqr( x, y, xScale, yScale );
|
|
|
|
}
|
2009-03-23 12:05:00 +00:00
|
|
|
case OAnnotation:
|
|
|
|
{
|
2013-06-23 17:19:25 +00:00
|
|
|
return static_cast<Annotation*>(m_object)->d_func()->distanceSqr( x, y, xScale, yScale );
|
2009-03-23 12:05:00 +00:00
|
|
|
}
|
|
|
|
case SourceRef:
|
|
|
|
{
|
|
|
|
const SourceRefObjectRect * sr = static_cast< const SourceRefObjectRect * >( this );
|
|
|
|
const NormalizedPoint& point = sr->m_point;
|
|
|
|
if ( point.x == -1.0 )
|
|
|
|
{
|
2013-06-23 17:19:25 +00:00
|
|
|
return pow( ( y - point.y ) * yScale, 2 );
|
2009-03-23 12:05:00 +00:00
|
|
|
}
|
|
|
|
else if ( point.y == -1.0 )
|
|
|
|
{
|
2013-06-23 17:19:25 +00:00
|
|
|
return pow( ( x - point.x ) * xScale, 2 );
|
2009-03-23 12:05:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-06-23 17:19:25 +00:00
|
|
|
return pow( ( x - point.x ) * xScale, 2 ) + pow( ( y - point.y ) * yScale, 2 );
|
2009-03-23 12:05:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
2005-07-15 18:20:57 +00:00
|
|
|
ObjectRect::~ObjectRect()
|
|
|
|
{
|
2007-01-02 17:05:49 +00:00
|
|
|
if ( !m_object )
|
2005-07-15 18:20:57 +00:00
|
|
|
return;
|
|
|
|
|
2007-04-20 12:37:12 +00:00
|
|
|
if ( m_objectType == Action )
|
|
|
|
delete static_cast<Okular::Action*>( m_object );
|
2006-11-17 22:15:15 +00:00
|
|
|
else if ( m_objectType == SourceRef )
|
2007-01-02 17:05:49 +00:00
|
|
|
delete static_cast<Okular::SourceReference*>( m_object );
|
2005-07-15 18:20:57 +00:00
|
|
|
else
|
2014-09-11 17:36:01 +00:00
|
|
|
qCDebug(OkularCoreDebug).nospace() << "Object deletion not implemented for type '" << m_objectType << "'.";
|
2005-07-15 18:20:57 +00:00
|
|
|
}
|
2006-09-19 17:17:29 +00:00
|
|
|
|
|
|
|
/** class AnnotationObjectRect **/
|
|
|
|
|
2007-01-02 17:05:49 +00:00
|
|
|
AnnotationObjectRect::AnnotationObjectRect( Annotation * annotation )
|
|
|
|
: ObjectRect( QPolygonF(), OAnnotation, annotation ), m_annotation( annotation )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Annotation *AnnotationObjectRect::annotation() const
|
2006-09-19 17:17:29 +00:00
|
|
|
{
|
2007-01-02 17:05:49 +00:00
|
|
|
return m_annotation;
|
2006-09-19 17:17:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QRect AnnotationObjectRect::boundingRect( double xScale, double yScale ) const
|
|
|
|
{
|
2012-12-16 18:35:04 +00:00
|
|
|
const QRect annotRect = AnnotationUtils::annotationGeometry( m_annotation, xScale, yScale );
|
|
|
|
const QPoint center = annotRect.center();
|
|
|
|
|
|
|
|
// Make sure that the rectangle has a minimum size, so that it's possible
|
|
|
|
// to click on it
|
|
|
|
const int minSize = 14;
|
|
|
|
const QRect minRect( center.x()-minSize/2, center.y()-minSize/2, minSize, minSize );
|
|
|
|
|
|
|
|
return annotRect | minRect;
|
2006-09-19 17:17:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool AnnotationObjectRect::contains( double x, double y, double xScale, double yScale ) const
|
|
|
|
{
|
|
|
|
return boundingRect( xScale, yScale ).contains( (int)( x * xScale ), (int)( y * yScale ), false );
|
|
|
|
}
|
|
|
|
|
|
|
|
AnnotationObjectRect::~AnnotationObjectRect()
|
|
|
|
{
|
2006-09-21 08:45:36 +00:00
|
|
|
// the annotation pointer is kept elsewehere (in Page, most probably),
|
2006-09-19 17:17:29 +00:00
|
|
|
// so just release its pointer
|
2007-01-02 17:05:49 +00:00
|
|
|
m_object = 0;
|
2006-09-19 17:17:29 +00:00
|
|
|
}
|
|
|
|
|
2012-09-08 15:06:02 +00:00
|
|
|
void AnnotationObjectRect::transform( const QTransform &matrix )
|
2006-11-20 07:53:32 +00:00
|
|
|
{
|
2007-07-22 20:49:27 +00:00
|
|
|
m_annotation->d_func()->annotationTransform( matrix );
|
2006-11-20 07:53:32 +00:00
|
|
|
}
|
|
|
|
|
2006-11-17 22:15:15 +00:00
|
|
|
/** class SourceRefObjectRect **/
|
|
|
|
|
|
|
|
SourceRefObjectRect::SourceRefObjectRect( const NormalizedPoint& point, void * srcRef )
|
|
|
|
: ObjectRect( point.x, point.y, .0, .0, false, SourceRef, srcRef ), m_point( point )
|
|
|
|
{
|
2009-03-23 12:05:00 +00:00
|
|
|
const double x = m_point.x < 0.0 ? 0.5 : m_point.x;
|
|
|
|
const double y = m_point.y < 0.0 ? 0.5 : m_point.y;
|
|
|
|
const QRectF rect( x - 2, y - 2, 5, 5 );
|
|
|
|
m_path.addRect( rect );
|
|
|
|
|
|
|
|
m_transformedPath = m_path;
|
2006-11-17 22:15:15 +00:00
|
|
|
}
|
|
|
|
|
2009-03-23 12:05:00 +00:00
|
|
|
QRect SourceRefObjectRect::boundingRect( double xScale, double yScale ) const
|
2006-11-17 22:15:15 +00:00
|
|
|
{
|
2009-03-23 12:05:00 +00:00
|
|
|
const double x = m_point.x < 0.0 ? 0.5 : m_point.x;
|
|
|
|
const double y = m_point.y < 0.0 ? 0.5 : m_point.y;
|
|
|
|
|
|
|
|
return QRect( x * xScale, y * yScale, 1, 1 );
|
2006-11-17 22:15:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SourceRefObjectRect::contains( double x, double y, double xScale, double yScale ) const
|
|
|
|
{
|
2009-03-23 12:05:00 +00:00
|
|
|
return distanceSqr( x, y, xScale, yScale ) < ( pow( 7.0 / xScale, 2 ) + pow( 7.0 / yScale, 2 ) );
|
2006-11-17 22:15:15 +00:00
|
|
|
}
|