You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digikam/digikam/imageplugins/perspective/perspectivewidget.cpp

840 lines
27 KiB

/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2005-01-18
* Description : a widget class to edit perspective.
*
* Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
* Copyright (C) 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
*
* Matrix3 implementation inspired from gimp 2.0
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* ============================================================ */
// C++ includes.
#include <cstdio>
#include <cstdlib>
#include <cmath>
// TQt includes.
#include <tqregion.h>
#include <tqpainter.h>
#include <tqpen.h>
#include <tqbrush.h>
#include <tqpixmap.h>
#include <tqimage.h>
#include <tqpointarray.h>
// KDE includes.
#include <kstandarddirs.h>
#include <kcursor.h>
#include <tdeglobal.h>
#include <tdeapplication.h>
// Local includes.
#include "triangle.h"
#include "ddebug.h"
#include "imageiface.h"
#include "dimgimagefilters.h"
#include "perspectivewidget.h"
#include "perspectivewidget.moc"
namespace DigikamPerspectiveImagesPlugin
{
PerspectiveWidget::PerspectiveWidget(int w, int h, TQWidget *parent)
: TQWidget(parent, 0, TQt::WDestructiveClose)
{
setBackgroundMode(TQt::NoBackground);
setMinimumSize(w, h);
setMouseTracking(true);
m_drawGrid = false;
m_drawWhileMoving = true;
m_currentResizing = ResizingNone;
m_guideColor = TQt::red;
m_guideSize = 1;
m_iface = new Digikam::ImageIface(w, h);
uchar *data = m_iface->setPreviewImageSize(w, h);
m_w = m_iface->previewWidth();
m_h = m_iface->previewHeight();
m_origW = m_iface->originalWidth();
m_origH = m_iface->originalHeight();
m_previewImage = Digikam::DImg(m_w, m_h, m_iface->previewSixteenBit(), m_iface->previewHasAlpha(), data, false);
m_pixmap = new TQPixmap(w, h);
m_rect = TQRect(w/2-m_w/2, h/2-m_h/2, m_w, m_h);
m_grid = TQPointArray(60);
reset();
}
PerspectiveWidget::~PerspectiveWidget()
{
delete m_iface;
delete m_pixmap;
}
Digikam::ImageIface* PerspectiveWidget::imageIface()
{
return m_iface;
}
TQPoint PerspectiveWidget::getTopLeftCorner(void)
{
return TQPoint( lroundf((float)(m_topLeftPoint.x()*m_origW) / (float)m_w),
lroundf((float)(m_topLeftPoint.y()*m_origH) / (float)m_h));
}
TQPoint PerspectiveWidget::getTopRightCorner(void)
{
return TQPoint( lroundf((float)(m_topRightPoint.x()*m_origW) / (float)m_w),
lroundf((float)(m_topRightPoint.y()*m_origH) / (float)m_h));
}
TQPoint PerspectiveWidget::getBottomLeftCorner(void)
{
return TQPoint( lroundf((float)(m_bottomLeftPoint.x()*m_origW) / (float)m_w),
lroundf((float)(m_bottomLeftPoint.y()*m_origH) / (float)m_h));
}
TQPoint PerspectiveWidget::getBottomRightCorner(void)
{
return TQPoint( lroundf((float)(m_bottomRightPoint.x()*m_origW) / (float)m_w),
lroundf((float)(m_bottomRightPoint.y()*m_origH) / (float)m_h));
}
TQRect PerspectiveWidget::getTargetSize(void)
{
TQPointArray perspectiveArea;
perspectiveArea.putPoints( 0, 4,
getTopLeftCorner().x(), getTopLeftCorner().y(),
getTopRightCorner().x(), getTopRightCorner().y(),
getBottomRightCorner().x(), getBottomRightCorner().y(),
getBottomLeftCorner().x(), getBottomLeftCorner().y() );
return perspectiveArea.boundingRect();
}
float PerspectiveWidget::getAngleTopLeft(void)
{
Triangle topLeft(getTopLeftCorner(), getTopRightCorner(), getBottomLeftCorner());
return topLeft.angleBAC();
}
float PerspectiveWidget::getAngleTopRight(void)
{
Triangle topLeft(getTopRightCorner(), getBottomRightCorner(), getTopLeftCorner());
return topLeft.angleBAC();
}
float PerspectiveWidget::getAngleBottomLeft(void)
{
Triangle topLeft(getBottomLeftCorner(), getTopLeftCorner(), getBottomRightCorner());
return topLeft.angleBAC();
}
float PerspectiveWidget::getAngleBottomRight(void)
{
Triangle topLeft(getBottomRightCorner(), getBottomLeftCorner(), getTopRightCorner());
return topLeft.angleBAC();
}
void PerspectiveWidget::reset(void)
{
m_topLeftPoint.setX(0);
m_topLeftPoint.setY(0);
m_topRightPoint.setX(m_w-1);
m_topRightPoint.setY(0);
m_bottomLeftPoint.setX(0);
m_bottomLeftPoint.setY(m_h-1);
m_bottomRightPoint.setX(m_w-1);
m_bottomRightPoint.setY(m_h-1);
m_spot.setX(m_w / 2);
m_spot.setY(m_h / 2);
m_antiAlias = true;
updatePixmap();
repaint(false);
}
void PerspectiveWidget::applyPerspectiveAdjustment(void)
{
Digikam::DImg *orgImage = m_iface->getOriginalImg();
Digikam::DImg destImage(orgImage->width(), orgImage->height(), orgImage->sixteenBit(), orgImage->hasAlpha());
Digikam::DColor background(0, 0, 0, orgImage->hasAlpha() ? 0 : 255, orgImage->sixteenBit());
// Perform perspective adjustment.
buildPerspective(TQPoint(0, 0), TQPoint(m_origW, m_origH),
getTopLeftCorner(), getTopRightCorner(),
getBottomLeftCorner(), getBottomRightCorner(),
orgImage, &destImage, background);
// Perform an auto-croping around the image.
Digikam::DImg targetImg = destImage.copy(getTargetSize());
// Update target image.
m_iface->putOriginalImage(i18n("Perspective Adjustment"),
targetImg.bits(), targetImg.width(), targetImg.height());
}
void PerspectiveWidget::slotToggleAntiAliasing(bool a)
{
m_antiAlias = a;
updatePixmap();
repaint(false);
}
void PerspectiveWidget::slotToggleDrawWhileMoving(bool draw)
{
m_drawWhileMoving = draw;
}
void PerspectiveWidget::slotToggleDrawGrid(bool grid)
{
m_drawGrid = grid;
updatePixmap();
repaint(false);
}
void PerspectiveWidget::slotChangeGuideColor(const TQColor &color)
{
m_guideColor = color;
updatePixmap();
repaint(false);
}
void PerspectiveWidget::slotChangeGuideSize(int size)
{
m_guideSize = size;
updatePixmap();
repaint(false);
}
void PerspectiveWidget::updatePixmap(void)
{
m_topLeftCorner.setRect(m_topLeftPoint.x() + m_rect.topLeft().x(),
m_topLeftPoint.y() + m_rect.topLeft().y(), 8, 8);
m_topRightCorner.setRect(m_topRightPoint.x() - 7 + m_rect.topLeft().x(),
m_topRightPoint.y() + m_rect.topLeft().y(), 8, 8);
m_bottomLeftCorner.setRect(m_bottomLeftPoint.x() + m_rect.topLeft().x(),
m_bottomLeftPoint.y() - 7 + m_rect.topLeft().y(), 8, 8);
m_bottomRightCorner.setRect(m_bottomRightPoint.x() - 7 + m_rect.topLeft().x(),
m_bottomRightPoint.y() - 7 + m_rect.topLeft().y(), 8, 8);
// Compute the grid array
int gXS = m_w / 15;
int gYS = m_h / 15;
for (int i = 0 ; i < 15 ; i++)
{
int j = i*4;
//Horizontal line.
m_grid.setPoint(j , 0, i*gYS);
m_grid.setPoint(j+1, m_w, i*gYS);
//Vertical line.
m_grid.setPoint(j+2, i*gXS, 0);
m_grid.setPoint(j+3, i*gXS, m_h);
}
// Draw background
m_pixmap->fill(colorGroup().background());
// if we are resizing with the mouse, compute and draw only if drawWhileMoving is set
if (m_currentResizing == ResizingNone || m_drawWhileMoving)
{
// Create preview image
Digikam::DImg destImage(m_previewImage.width(), m_previewImage.height(),
m_previewImage.sixteenBit(), m_previewImage.hasAlpha());
Digikam::DColor background(colorGroup().background());
m_transformedCenter = buildPerspective(TQPoint(0, 0), TQPoint(m_w, m_h),
m_topLeftPoint, m_topRightPoint,
m_bottomLeftPoint, m_bottomRightPoint,
&m_previewImage, &destImage, background);
m_iface->putPreviewImage(destImage.bits());
// Draw image
m_iface->paint(m_pixmap, m_rect.x(), m_rect.y(),
m_rect.width(), m_rect.height());
}
else
{
m_transformedCenter = buildPerspective(TQPoint(0, 0), TQPoint(m_w, m_h),
m_topLeftPoint, m_topRightPoint,
m_bottomLeftPoint, m_bottomRightPoint);
}
// Drawing selection borders.
TQPainter p(m_pixmap);
p.setPen(TQPen(TQColor(255, 64, 64), 1, TQt::SolidLine));
p.drawLine(m_topLeftPoint+m_rect.topLeft(), m_topRightPoint+m_rect.topLeft());
p.drawLine(m_topRightPoint+m_rect.topLeft(), m_bottomRightPoint+m_rect.topLeft());
p.drawLine(m_bottomRightPoint+m_rect.topLeft(), m_bottomLeftPoint+m_rect.topLeft());
p.drawLine(m_bottomLeftPoint+m_rect.topLeft(), m_topLeftPoint+m_rect.topLeft());
// Drawing selection corners.
TQBrush brush(TQColor(255, 64, 64));
p.fillRect(m_topLeftCorner, brush);
p.fillRect(m_topRightCorner, brush);
p.fillRect(m_bottomLeftCorner, brush);
p.fillRect(m_bottomRightCorner, brush);
// Drawing the grid.
if (m_drawGrid)
{
for (uint i = 0 ; i < m_grid.size() ; i += 4)
{
//Horizontal line.
p.drawLine(m_grid.point(i)+m_rect.topLeft(), m_grid.point(i+1)+m_rect.topLeft());
//Vertical line.
p.drawLine(m_grid.point(i+2)+m_rect.topLeft(), m_grid.point(i+3)+m_rect.topLeft());
}
}
// Drawing transformed center.
p.setPen(TQPen(TQColor(255, 64, 64), 3, TQt::SolidLine));
p.drawEllipse( m_transformedCenter.x()+m_rect.topLeft().x()-2,
m_transformedCenter.y()+m_rect.topLeft().y()-2, 4, 4 );
// Drawing vertical and horizontal guide lines.
int xspot = m_spot.x() + m_rect.x();
int yspot = m_spot.y() + m_rect.y();
p.setPen(TQPen(TQt::white, m_guideSize, TQt::SolidLine));
p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom());
p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot);
p.setPen(TQPen(m_guideColor, m_guideSize, TQt::DotLine));
p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom());
p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot);
p.end();
emit signalPerspectiveChanged(getTargetSize(), getAngleTopLeft(), getAngleTopRight(),
getAngleBottomLeft(), getAngleBottomRight());
}
TQPoint PerspectiveWidget::buildPerspective(TQPoint orignTopLeft, TQPoint orignBottomRight,
TQPoint transTopLeft, TQPoint transTopRight,
TQPoint transBottomLeft, TQPoint transBottomRight,
Digikam::DImg *orgImage, Digikam::DImg *destImage,
Digikam::DColor background)
{
Matrix matrix, transform;
double scalex;
double scaley;
double x1 = (double)orignTopLeft.x();
double y1 = (double)orignTopLeft.y();
double x2 = (double)orignBottomRight.x();
double y2 = (double)orignBottomRight.y();
double tx1 = (double)transTopLeft.x();
double ty1 = (double)transTopLeft.y();
double tx2 = (double)transTopRight.x();
double ty2 = (double)transTopRight.y();
double tx3 = (double)transBottomLeft.x();
double ty3 = (double)transBottomLeft.y();
double tx4 = (double)transBottomRight.x();
double ty4 = (double)transBottomRight.y();
scalex = scaley = 1.0;
if ((x2 - x1) > 0)
scalex = 1.0 / (double) (x2 - x1);
if ((y2 - y1) > 0)
scaley = 1.0 / (double) (y2 - y1);
// Determine the perspective transform that maps from
// the unit cube to the transformed coordinates
double dx1, dx2, dx3, dy1, dy2, dy3;
dx1 = tx2 - tx4;
dx2 = tx3 - tx4;
dx3 = tx1 - tx2 + tx4 - tx3;
dy1 = ty2 - ty4;
dy2 = ty3 - ty4;
dy3 = ty1 - ty2 + ty4 - ty3;
// Is the mapping affine?
if ((dx3 == 0.0) && (dy3 == 0.0))
{
matrix.coeff[0][0] = tx2 - tx1;
matrix.coeff[0][1] = tx4 - tx2;
matrix.coeff[0][2] = tx1;
matrix.coeff[1][0] = ty2 - ty1;
matrix.coeff[1][1] = ty4 - ty2;
matrix.coeff[1][2] = ty1;
matrix.coeff[2][0] = 0.0;
matrix.coeff[2][1] = 0.0;
}
else
{
double det1, det2;
det1 = dx3 * dy2 - dy3 * dx2;
det2 = dx1 * dy2 - dy1 * dx2;
if (det1 == 0.0 && det2 == 0.0)
matrix.coeff[2][0] = 1.0;
else
matrix.coeff[2][0] = det1 / det2;
det1 = dx1 * dy3 - dy1 * dx3;
if (det1 == 0.0 && det2 == 0.0)
matrix.coeff[2][1] = 1.0;
else
matrix.coeff[2][1] = det1 / det2;
matrix.coeff[0][0] = tx2 - tx1 + matrix.coeff[2][0] * tx2;
matrix.coeff[0][1] = tx3 - tx1 + matrix.coeff[2][1] * tx3;
matrix.coeff[0][2] = tx1;
matrix.coeff[1][0] = ty2 - ty1 + matrix.coeff[2][0] * ty2;
matrix.coeff[1][1] = ty3 - ty1 + matrix.coeff[2][1] * ty3;
matrix.coeff[1][2] = ty1;
}
matrix.coeff[2][2] = 1.0;
// transform is initialized to the identity matrix
transform.translate(-x1, -y1);
transform.scale (scalex, scaley);
transform.multiply (matrix);
// Compute perspective transformation to image if image data containers exist.
if (orgImage && destImage)
transformAffine(orgImage, destImage, transform, background);
// Calculate the grid array points.
double newX, newY;
for (uint i = 0 ; i < m_grid.size() ; i++)
{
transform.transformPoint(m_grid.point(i).x(), m_grid.point(i).y(), &newX, &newY);
m_grid.setPoint(i, lround(newX), lround(newY));
}
// Calculate and return new image center.
double newCenterX, newCenterY;
transform.transformPoint(x2/2.0, y2/2.0, &newCenterX, &newCenterY);
return TQPoint(lround(newCenterX), lround(newCenterY));
}
void PerspectiveWidget::transformAffine(Digikam::DImg *orgImage, Digikam::DImg *destImage,
const Matrix &matrix, Digikam::DColor background)
{
Matrix m(matrix), inv(matrix);
int x1, y1, x2, y2; // target bounding box
int x, y; // target coordinates
int u1, v1, u2, v2; // source bounding box
double uinc, vinc, winc; // increments in source coordinates
// pr horizontal target coordinate
double u[5],v[5]; // source coordinates,
// 2
// / \ 0 is sample in the center of pixel
// 1 0 3 1..4 is offset 1 pixel in each
// \ / direction (in target space)
// 4
double tu[5],tv[5],tw[5]; // undivided source coordinates and divisor
uchar *data, *newData;
bool sixteenBit;
int coords;
int width, height;
int bytesDepth;
int offset;
uchar *dest, *d;
Digikam::DColor color;
bytesDepth = orgImage->bytesDepth();
data = orgImage->bits();
sixteenBit = orgImage->sixteenBit();
width = orgImage->width();
height = orgImage->height();
newData = destImage->bits();
if (sixteenBit)
background.convertToSixteenBit();
//destImage->fill(background);
Digikam::DImgImageFilters filters;
// Find the inverse of the transformation matrix
m.invert();
u1 = 0;
v1 = 0;
u2 = u1 + width;
v2 = v1 + height;
x1 = u1;
y1 = v1;
x2 = u2;
y2 = v2;
dest = new uchar[width * bytesDepth];
uinc = m.coeff[0][0];
vinc = m.coeff[1][0];
winc = m.coeff[2][0];
coords = 1;
// these loops could be rearranged, depending on which bit of code
// you'd most like to write more than once.
for (y = y1; y < y2; y++)
{
// set up inverse transform steps
tu[0] = uinc * (x1 + 0.5) + m.coeff[0][1] * (y + 0.5) + m.coeff[0][2] - 0.5;
tv[0] = vinc * (x1 + 0.5) + m.coeff[1][1] * (y + 0.5) + m.coeff[1][2] - 0.5;
tw[0] = winc * (x1 + 0.5) + m.coeff[2][1] * (y + 0.5) + m.coeff[2][2];
d = dest;
for (x = x1; x < x2; x++)
{
int i; // normalize homogeneous coords
for (i = 0; i < coords; i++)
{
if (tw[i] == 1.0)
{
u[i] = tu[i];
v[i] = tv[i];
}
else if (tw[i] != 0.0)
{
u[i] = tu[i] / tw[i];
v[i] = tv[i] / tw[i];
}
else
{
DDebug() << "homogeneous coordinate = 0...\n" << endl;
}
}
// Set the destination pixels
int iu = lround( u [0] );
int iv = lround( v [0] );
if (iu >= u1 && iu < u2 && iv >= v1 && iv < v2)
{
// u, v coordinates into source
int u = iu - u1;
int v = iv - v1;
//TODO: Check why antialiasing shows no effect
/*if (m_antiAlias)
{
if (sixteenBit)
{
unsigned short *d16 = (unsigned short *)d;
filters.pixelAntiAliasing16((unsigned short *)data,
width, height, u, v, d16+3, d16+2, d16+1, d16);
}
else
{
filters.pixelAntiAliasing(data, width, height, u, v,
d+3, d+2, d+1, d);
}
}
else
{*/
offset = (v * width * bytesDepth) + (u * bytesDepth);
color.setColor(data + offset, sixteenBit);
color.setPixel(d);
//}
d += bytesDepth;
}
else // not in source range
{
// set to background color
background.setPixel(d);
d += bytesDepth;
}
for (i = 0; i < coords; i++)
{
tu[i] += uinc;
tv[i] += vinc;
tw[i] += winc;
}
}
// set the pixel region row
offset = (y - y1) * width * bytesDepth;
memcpy(newData + offset, dest, width * bytesDepth);
}
delete [] dest;
}
void PerspectiveWidget::paintEvent( TQPaintEvent * )
{
bitBlt(this, 0, 0, m_pixmap);
}
void PerspectiveWidget::resizeEvent(TQResizeEvent * e)
{
int old_w = m_w;
int old_h = m_h;
delete m_pixmap;
int w = e->size().width();
int h = e->size().height();
uchar *data = m_iface->setPreviewImageSize(w, h);
m_w = m_iface->previewWidth();
m_h = m_iface->previewHeight();
m_previewImage = Digikam::DImg(m_w, m_h, m_iface->previewSixteenBit(), m_iface->previewHasAlpha(), data, false);
m_pixmap = new TQPixmap(w, h);
TQRect oldRect = m_rect;
m_rect = TQRect(w/2-m_w/2, h/2-m_h/2, m_w, m_h);
float xFactor = (float)m_rect.width()/(float)(oldRect.width());
float yFactor = (float)m_rect.height()/(float)(oldRect.height());
m_topLeftPoint = TQPoint(lroundf(m_topLeftPoint.x()*xFactor),
lroundf(m_topLeftPoint.y()*yFactor));
m_topRightPoint = TQPoint(lroundf(m_topRightPoint.x()*xFactor),
lroundf(m_topRightPoint.y()*yFactor));
m_bottomLeftPoint = TQPoint(lroundf(m_bottomLeftPoint.x()*xFactor),
lroundf(m_bottomLeftPoint.y()*yFactor));
m_bottomRightPoint = TQPoint(lroundf(m_bottomRightPoint.x()*xFactor),
lroundf(m_bottomRightPoint.y()*yFactor));
m_transformedCenter = TQPoint(lroundf(m_transformedCenter.x()*xFactor),
lroundf(m_transformedCenter.y()*yFactor));
m_spot.setX((int)((float)m_spot.x() * ( (float)m_w / (float)old_w)));
m_spot.setY((int)((float)m_spot.y() * ( (float)m_h / (float)old_h)));
updatePixmap();
}
void PerspectiveWidget::mousePressEvent ( TQMouseEvent * e )
{
if ( e->button() == TQt::LeftButton &&
m_rect.contains( e->x(), e->y() ))
{
if ( m_topLeftCorner.contains( e->x(), e->y() ) )
m_currentResizing = ResizingTopLeft;
else if ( m_bottomRightCorner.contains( e->x(), e->y() ) )
m_currentResizing = ResizingBottomRight;
else if ( m_topRightCorner.contains( e->x(), e->y() ) )
m_currentResizing = ResizingTopRight;
else if ( m_bottomLeftCorner.contains( e->x(), e->y() ) )
m_currentResizing = ResizingBottomLeft;
else
{
m_spot.setX(e->x()-m_rect.x());
m_spot.setY(e->y()-m_rect.y());
}
}
}
void PerspectiveWidget::mouseReleaseEvent ( TQMouseEvent * e )
{
if ( m_currentResizing != ResizingNone )
{
unsetCursor();
m_currentResizing = ResizingNone;
// in this case, the pixmap has not been drawn on mouse move
if (!m_drawWhileMoving)
{
updatePixmap();
repaint(false);
}
}
else
{
m_spot.setX(e->x()-m_rect.x());
m_spot.setY(e->y()-m_rect.y());
updatePixmap();
repaint(false);
}
}
void PerspectiveWidget::mouseMoveEvent ( TQMouseEvent * e )
{
if ( e->state() == TQt::LeftButton )
{
if ( m_currentResizing != ResizingNone )
{
TQPointArray unsablePoints;
TQPoint pm(e->x(), e->y());
if (!m_rect.contains( pm ))
{
if (pm.x() > m_rect.right())
pm.setX(m_rect.right());
else if (pm.x() < m_rect.left())
pm.setX(m_rect.left());
if (pm.y() > m_rect.bottom())
pm.setY(m_rect.bottom());
else if (pm.y() < m_rect.top())
pm.setY(m_rect.top());
}
if ( m_currentResizing == ResizingTopLeft )
{
unsablePoints.putPoints(0, 7,
m_w-1, m_h-1,
0, m_h-1,
0, m_bottomLeftPoint.y()-10,
m_bottomLeftPoint.x(), m_bottomLeftPoint.y()-10,
m_topRightPoint.x()-10, m_topRightPoint.y(),
m_topRightPoint.x()-10, 0,
m_w-1, 0 );
TQRegion unsableArea(unsablePoints);
if ( unsableArea.contains(pm) ) return;
m_topLeftPoint = pm - m_rect.topLeft();
setCursor( KCursor::sizeFDiagCursor() );
}
else if ( m_currentResizing == ResizingTopRight )
{
unsablePoints.putPoints(0, 7,
0, m_h-1,
0, 0,
m_topLeftPoint.x()+10, 0,
m_topLeftPoint.x()+10, m_topLeftPoint.y(),
m_bottomRightPoint.x(), m_bottomRightPoint.y()-10,
m_w-1, m_bottomRightPoint.y()-10,
m_w-1, m_h-1);
TQRegion unsableArea(unsablePoints);
if ( unsableArea.contains(pm) ) return;
m_topRightPoint = pm - m_rect.topLeft();
setCursor( KCursor::sizeBDiagCursor() );
}
else if ( m_currentResizing == ResizingBottomLeft )
{
unsablePoints.putPoints(0, 7,
m_w-1, 0,
m_w-1, m_h-1,
m_bottomRightPoint.x()-10, m_h-1,
m_bottomRightPoint.x()-10, m_bottomRightPoint.y()+10,
m_topLeftPoint.x(), m_topLeftPoint.y()+10,
0, m_topLeftPoint.y(),
0, 0);
TQRegion unsableArea(unsablePoints);
if ( unsableArea.contains(pm) ) return;
m_bottomLeftPoint = pm - m_rect.topLeft();
setCursor( KCursor::sizeBDiagCursor() );
}
else if ( m_currentResizing == ResizingBottomRight )
{
unsablePoints.putPoints(0, 7,
0, 0,
m_w-1, 0,
m_w-1, m_topRightPoint.y()+10,
m_topRightPoint.x(), m_topRightPoint.y()+10,
m_bottomLeftPoint.x()+10, m_bottomLeftPoint.y(),
m_bottomLeftPoint.x()+10, m_w-1,
0, m_w-1);
TQRegion unsableArea(unsablePoints);
if ( unsableArea.contains(pm) ) return;
m_bottomRightPoint = pm - m_rect.topLeft();
setCursor( KCursor::sizeFDiagCursor() );
}
else
{
m_spot.setX(e->x()-m_rect.x());
m_spot.setY(e->y()-m_rect.y());
}
updatePixmap();
repaint(false);
}
}
else
{
if ( m_topLeftCorner.contains( e->x(), e->y() ) ||
m_bottomRightCorner.contains( e->x(), e->y() ) )
setCursor( KCursor::sizeFDiagCursor() );
else if ( m_topRightCorner.contains( e->x(), e->y() ) ||
m_bottomLeftCorner.contains( e->x(), e->y() ) )
setCursor( KCursor::sizeBDiagCursor() );
else
unsetCursor();
}
}
} // NameSpace DigikamPerspectiveImagesPlugin