Commit 93e51a53 authored by Jan Hambrecht's avatar Jan Hambrecht

use precise but expensive hitTest based on shape outline only for path based...

use precise but expensive hitTest based on shape outline only for path based shapes as suggested by Thomas


svn path=/trunk/koffice/; revision=873669
parent fe189d9d
......@@ -29,6 +29,7 @@
#include "KoShapeLoadingContext.h"
#include "KoShapeShadow.h"
#include "KoShapeBackground.h"
#include "KoShapeContainer.h"
#include <KoXmlReader.h>
#include <KoXmlWriter.h>
......@@ -1141,3 +1142,33 @@ KoPathShape * KoPathShape::fromQPainterPath(const QPainterPath &path)
shape->normalize();
return shape;
}
bool KoPathShape::hitTest(const QPointF &position) const
{
if (parent() && parent()->childClipped(this) && ! parent()->hitTest(position))
return false;
QPointF point = absoluteTransformation(0).inverted().map(position);
const QPainterPath outlinePath = outline();
if (border()) {
KoInsets insets;
border()->borderInsets(this, insets);
QRectF roi( QPointF(-insets.left, -insets.top), QPointF(insets.right, insets.bottom) );
roi.moveCenter( point );
if( outlinePath.intersects( roi ) || outlinePath.contains( roi ) )
return true;
} else {
if( outlinePath.contains( point ) )
return true;
}
// if there is no shadow we can as well just leave
if (! shadow())
return false;
// the shadow has an offset to the shape, so we simply
// check if the position minus the shadow offset hits the shape
point = absoluteTransformation(0).inverted().map(position - shadow()->offset());
return outlinePath.contains(point);
}
......@@ -96,7 +96,9 @@ public:
virtual QSizeF size() const;
/// reimplemented
virtual void setSize(const QSizeF &size);
/// reimplemented
virtual bool hitTest(const QPointF &position) const;
// reimplemented
virtual void saveOdf(KoShapeSavingContext & context) const;
// reimplemented
......
......@@ -249,19 +249,15 @@ bool KoShape::hitTest(const QPointF &position) const
return false;
QPointF point = absoluteTransformation(0).inverted().map(position);
const QPainterPath outlinePath = outline();
QRectF bb(QPointF(), size());
if (d->border) {
KoInsets insets;
d->border->borderInsets(this, insets);
QRectF roi( QPointF(-insets.left, -insets.top), QPointF(insets.right, insets.bottom) );
roi.moveCenter( point );
if( outlinePath.intersects( roi ) || outlinePath.contains( roi ) )
return true;
} else {
if( outlinePath.contains( point ) )
return true;
bb.adjust(-insets.left, -insets.top, insets.right, insets.bottom);
}
if (bb.contains(point))
return true;
// if there is no shadow we can as well just leave
if (! d->shadow)
return false;
......@@ -270,7 +266,7 @@ bool KoShape::hitTest(const QPointF &position) const
// check if the position minus the shadow offset hits the shape
point = absoluteTransformation(0).inverted().map(position - d->shadow->offset());
return outlinePath.contains(point);
return bb.contains(point);
}
QRectF KoShape::boundingRect() const
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment