Commit 0edad6ce authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

Fix pixel-alignment of the Rectangle and Ellipse tools

Now there are a bit complex rules of rounding, but they do exactly
what the user expects from the tool.

BUG:334508
parent 2beeaeda
......@@ -31,8 +31,12 @@ KisToolEllipseBase::KisToolEllipseBase(KoCanvasBase * canvas, KisToolEllipseBase
{
}
void KisToolEllipseBase::paintRectangle(QPainter &gc, const QRect &viewRect)
void KisToolEllipseBase::paintRectangle(QPainter &gc, const QRectF &imageRect)
{
KIS_ASSERT_RECOVER_RETURN(canvas());
QRect viewRect = pixelToView(imageRect).toRect();
QPainterPath path;
path.addEllipse(viewRect);
paintToolOutline(&gc, path);
......
......@@ -28,7 +28,7 @@ class KRITAUI_EXPORT KisToolEllipseBase : public KisToolRectangleBase
public:
KisToolEllipseBase(KoCanvasBase * canvas, KisToolEllipseBase::ToolType type, const QCursor & cursor=KisCursor::load("tool_ellipse_cursor.png", 6, 6));
void paintRectangle(QPainter &gc, const QRect &viewRect);
void paintRectangle(QPainter &gc, const QRectF &imageRect);
};
#endif // KIS_TOOL_ELLIPSE_BASE_H
......@@ -18,6 +18,9 @@
*/
#include "kis_tool_rectangle_base.h"
#include <QtCore/qmath.h>
#include <KoPointerEvent.h>
#include <KoCanvasBase.h>
#include <KoCanvasController.h>
......@@ -35,7 +38,7 @@ KisToolRectangleBase::KisToolRectangleBase(KoCanvasBase * canvas, KisToolRectang
void KisToolRectangleBase::paint(QPainter& gc, const KoViewConverter &converter)
{
if(mode() == KisTool::PAINT_MODE) {
paintRectangle(gc, pixelToView(QRectF(m_dragStart, m_dragEnd)).toRect());
paintRectangle(gc, createRect(m_dragStart, m_dragEnd));
}
KisToolPaint::paint(gc, converter);
......@@ -105,14 +108,41 @@ void KisToolRectangleBase::endPrimaryAction(KoPointerEvent *event)
updateArea();
finishRect(QRectF(m_dragStart, m_dragEnd).normalized());
finishRect(createRect(m_dragStart, m_dragEnd));
event->accept();
}
void KisToolRectangleBase::paintRectangle(QPainter &gc, const QRect &viewRect)
QRectF KisToolRectangleBase::createRect(const QPointF &start, const QPointF &end)
{
/**
* To make the dragging user-friendly it should work in a bit
* non-obvious way: the start-drag point must be handled with
* "ceil"/"floor" (depending on the direction of the drag) and the
* end-drag point should follow usual "round" semantics.
*/
qreal x0 = start.x();
qreal y0 = start.y();
qreal x1 = end.x();
qreal y1 = end.y();
int newX0 = x1 - x0 > 0 ? qCeil(x0) : qFloor(x0);
int newY0 = y1 - y0 > 0 ? qCeil(y0) : qFloor(y0);
int newX1 = qRound(x1);
int newY1 = qRound(y1);
QRectF result;
result.setCoords(newX0, newY0, newX1, newY1);
return result.normalized();
}
void KisToolRectangleBase::paintRectangle(QPainter &gc, const QRectF &imageRect)
{
KIS_ASSERT_RECOVER_RETURN(canvas());
QRect viewRect = pixelToView(imageRect).toAlignedRect();
QPainterPath path;
path.addRect(viewRect);
paintToolOutline(&gc, path);
......
......@@ -50,9 +50,8 @@ protected:
ToolType m_type;
void updateArea();
virtual void paintRectangle(QPainter &gc, const QRect &viewRect);
virtual void paintRectangle(QPainter &gc, const QRectF &imageRect);
virtual QRectF createRect(const QPointF &start, const QPointF &end);
};
#endif // KIS_TOOL_RECTANGLE_BASE_H
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