Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit b6883510 authored by Adrian Page's avatar Adrian Page

- Replace the non-anti-aliased polygon scan converter with QPainterPath,...

- Replace the non-anti-aliased polygon scan converter with QPainterPath, enabling anti-aliased shape filling and selections.
- Add an 'anti-aliased' option to the selection tools.
- Add an option to not draw the outline of shapes (rectangle, ellipse, etc).

svn path=/trunk/koffice/; revision=658871
parent f849a0be
This diff is collapsed.
......@@ -509,6 +509,12 @@ public:
/// Returns the current fill style
FillStyle fillStyle() const { return m_fillStyle; }
/// Set whether a polygon's filled area should be anti-aliased or not. The default is true.
void setAntiAliasPolygonFill(bool antiAliasPolygonFill) { m_antiAliasPolygonFill = antiAliasPolygonFill; }
/// Return whether a polygon's filled area should be anti-aliased or not
bool antiAliasPolygonFill() { return m_antiAliasPolygonFill; }
/// The style of the brush stroke around polygons and so
enum StrokeStyle {
StrokeStyleNone,
......@@ -605,6 +611,7 @@ protected:
KoColor m_fillColor;
FillStyle m_fillStyle;
StrokeStyle m_strokeStyle;
bool m_antiAliasPolygonFill;
KisBrush *m_brush;
KisPattern *m_pattern;
QPointF m_duplicateOffset;
......
......@@ -154,6 +154,7 @@ void KisToolEllipse::mouseReleaseEvent(KoPointerEvent *event)
m_painter->setPaintColor(m_currentFgColor);
m_painter->setBackgroundColor(m_currentBgColor);
m_painter->setFillStyle(fillStyle());
m_painter->setStrokeStyle(strokeStyle());
m_painter->setBrush(m_currentBrush);
m_painter->setPattern(m_currentPattern);
m_painter->setOpacity(m_opacity);
......
......@@ -151,6 +151,7 @@ void KisToolRectangle::mouseReleaseEvent(KoPointerEvent *event)
m_painter->setPaintColor(m_currentFgColor);
m_painter->setBackgroundColor(m_currentBgColor);
m_painter->setFillStyle(fillStyle());
m_painter->setStrokeStyle(strokeStyle());
m_painter->setBrush(m_currentBrush);
m_painter->setPattern(m_currentPattern);
m_painter->setOpacity(m_opacity);
......
......@@ -8,7 +8,7 @@ set(kritaselectiontools_PART_SRCS
# kis_tool_select_polygonal.cc
kis_tool_select_elliptical.cc
# kis_tool_select_contiguous.cc
# kis_tool_select_outline.cc
kis_tool_select_outline.cc
)
kde4_automoc(${kritaselectiontools_PART_SRCS})
......
......@@ -238,6 +238,7 @@ QWidget* KisToolSelectElliptical::createOptionWidget()
m_optWidget = new KisSelectionOptions(canvas);
Q_CHECK_PTR(m_optWidget);
m_optWidget->setWindowTitle(i18n("Elliptical Selection"));
m_optWidget->disableAntiAliasSelectionOption();
connect (m_optWidget, SIGNAL(actionChanged(int)), this, SLOT(slotSetAction(int)));
......
......@@ -76,8 +76,8 @@ public:
: KoToolFactory(parent, "KisToolSelectElliptical", i18n( "Elliptical Selection" ))
{
setToolTip( i18n( "Select an elliptical area" ) );
// setToolType( TOOL_TYPE_SELECTED);
setToolType( dynamicToolType() );
setToolType( TOOL_TYPE_SELECTED);
// setToolType( dynamicToolType() );
setActivationShapeId( KIS_LAYER_SHAPE_ID );
setIcon( "tool_elliptical_selection" );
setShortcut( KShortcut(Qt::Key_J) );
......
......@@ -19,44 +19,34 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <kis_tool_select_outline.h>
#include <QApplication>
#include <QPainter>
#include <qregion.h>
#include <QWidget>
#include <QLayout>
#include <QVBoxLayout>
#include <kaction.h>
#include <kactioncollection.h>
#include <kdebug.h>
#include <k3command.h>
#include <klocale.h>
#include <KoPointerEvent.h>
#include <kis_layer.h>
#include <kis_selection_options.h>
#include <kis_canvas_controller.h>
#include <kis_canvas_subject.h>
#include <kis_cursor.h>
#include <kis_image.h>
#include <kis_tool_select_outline.h>
#include <kis_vec.h>
#include <kis_undo_adapter.h>
#include <KoPointerEvent.h>
#include <KoPointerEvent.h>
#include <KoPointerEvent.h>
#include "kis_selected_transaction.h"
#include "kis_painter.h"
#include "kis_paintop_registry.h"
#include "kis_canvas.h"
#include "QPainter"
#include "kis_canvas2.h"
#include "kis_undo_adapter.h"
KisToolSelectOutline::KisToolSelectOutline()
: super(i18n("Select Outline"))
KisToolSelectOutline::KisToolSelectOutline(KoCanvasBase * canvas)
: KisTool(canvas, KisCursor::load("tool_outline_selection_cursor.png", 5, 5))
{
setObjectName("tool_select_outline");
setCursor(KisCursor::load("tool_outline_selection_cursor.png", 5, 5));
m_subject = 0;
m_dragging = false;
m_optWidget = 0;
m_selectAction = SELECTION_ADD;
......@@ -77,40 +67,32 @@ void KisToolSelectOutline::activate()
}
void KisToolSelectOutline::buttonPress(KoPointerEvent *event)
void KisToolSelectOutline::mousePressEvent(KoPointerEvent *event)
{
if (event->button() == Qt::LeftButton) {
m_dragging = true;
m_dragStart = event->pos();
m_dragEnd = event->pos();
m_points.clear();
m_points.append(m_dragStart);
m_points.append(convertToPixelCoord(event));
}
}
void KisToolSelectOutline::move(KoPointerEvent *event)
void KisToolSelectOutline::mouseMoveEvent(KoPointerEvent *event)
{
if (m_dragging) {
m_dragStart = m_dragEnd;
m_dragEnd = event->pos();
m_points.append (m_dragEnd);
// draw new lines on canvas
draw();
m_points.append(convertToPixelCoord(event));
updateFeedback();
}
}
void KisToolSelectOutline::buttonRelease(KoPointerEvent *event)
void KisToolSelectOutline::mouseReleaseEvent(KoPointerEvent *event)
{
if (!m_subject)
if (!m_canvas)
return;
if (m_dragging && event->button() == Qt::LeftButton) {
m_dragging = false;
deactivate();
if (m_currentImage && m_currentImage->activeDevice()) {
QApplication::setOverrideCursor(KisCursor::waitCursor());
KisPaintDeviceSP dev = m_currentImage->activeDevice();
......@@ -123,22 +105,22 @@ void KisToolSelectOutline::buttonRelease(KoPointerEvent *event)
selection->clear();
}
KisPainter painter(KisPaintDeviceSP(selection.data()));
KisPainter painter(selection);
painter.setPaintColor(KoColor(Qt::black, selection->colorSpace()));
painter.setFillStyle(KisPainter::FillStyleForegroundColor);
painter.setStrokeStyle(KisPainter::StrokeStyleNone);
painter.setBrush(m_subject->currentBrush());
painter.setOpacity(OPACITY_OPAQUE);
KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter);
painter.setPaintOp(op); // And now the painter owns the op and will destroy it.
painter.setAntiAliasPolygonFill(m_optWidget->antiAliasSelection());
switch (m_selectAction) {
case SELECTION_ADD:
painter.setCompositeOp(dev->colorSpace()->compositeOp(COMPOSITE_OVER));
painter.setCompositeOp(selection->colorSpace()->compositeOp(COMPOSITE_OVER));
break;
case SELECTION_SUBTRACT:
painter.setCompositeOp(dev->colorSpace()->compositeOp(COMPOSITE_SUBTRACT));
painter.setCompositeOp(selection->colorSpace()->compositeOp(COMPOSITE_SUBTRACT));
break;
default:
break;
......@@ -146,11 +128,10 @@ void KisToolSelectOutline::buttonRelease(KoPointerEvent *event)
painter.paintPolygon(m_points);
if(hasSelection) {
QRect dirty(painter.dirtyRegion());
QRegion dirty(painter.dirtyRegion());
dev->setDirty(dirty);
dev->emitSelectionChanged(dirty);
dev->emitSelectionChanged(dirty.boundingRect());
} else {
dev->setDirty();
dev->emitSelectionChanged();
......@@ -166,105 +147,52 @@ void KisToolSelectOutline::buttonRelease(KoPointerEvent *event)
}
}
void KisToolSelectOutline::paint(QPainter& gc)
{
draw(gc);
}
#define FEEDBACK_LINE_WIDTH 1
void KisToolSelectOutline::paint(QPainter& gc, const QRect&)
void KisToolSelectOutline::paint(QPainter& gc, KoViewConverter &converter)
{
draw(gc);
}
Q_UNUSED(converter);
void KisToolSelectOutline::draw()
{
if (m_subject) {
KisCanvasController *controller = m_subject->canvasController();
KisCanvas *canvas = controller->kiscanvas();
QPainter gc(canvas->canvasWidget());
draw(gc);
}
}
void KisToolSelectOutline::draw(QPainter& gc)
{
if (!m_subject)
return;
if (m_dragging && !m_points.empty()) {
QPen pen(Qt::white, 0, Qt::DotLine);
if (m_dragging && m_points.count() > 1) {
QPen pen(Qt::white, FEEDBACK_LINE_WIDTH, Qt::DotLine);
gc.save();
gc.setPen(pen);
//gc.setRasterOp(Qt::XorROP);
KisCanvasController *controller = m_subject->canvasController();
QPointF start, end;
QPoint startPos;
QPoint endPos;
for (qint32 pointIndex = 0; pointIndex < m_points.count() - 1; pointIndex++) {
QPointF startPos = pixelToView(m_points[pointIndex]);
QPointF endPos = pixelToView(m_points[pointIndex + 1]);
gc.drawLine(startPos, endPos);
}
startPos = controller->windowToView(m_dragStart.floorQPoint());
endPos = controller->windowToView(m_dragEnd.floorQPoint());
gc.drawLine(startPos, endPos);
gc.restore();
}
}
void KisToolSelectOutline::deactivate()
void KisToolSelectOutline::updateFeedback()
{
if (m_subject) {
KisCanvasController *controller = m_subject->canvasController();
KisCanvas *canvas = controller->kiscanvas();
QPainter gc(canvas->canvasWidget());
QPen pen(Qt::white, 0, Qt::DotLine);
gc.setPen(pen);
//gc.setRasterOp(Qt::XorROP);
if (m_points.count() > 1) {
qint32 lastPointIndex = m_points.count() - 1;
QPointF start, end;
QPoint startPos;
QPoint endPos;
QRectF updateRect = QRectF(m_points[lastPointIndex - 1], m_points[lastPointIndex]).normalized();
updateRect.adjust(-FEEDBACK_LINE_WIDTH, -FEEDBACK_LINE_WIDTH, FEEDBACK_LINE_WIDTH, FEEDBACK_LINE_WIDTH);
for (KoPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) {
if (it == m_points.begin())
{
start = (*it);
} else {
end = (*it);
startPos = controller->windowToView(start.floorQPoint());
endPos = controller->windowToView(end.floorQPoint());
gc.drawLine(startPos, endPos);
start = end;
}
}
updateCanvasPixelRect(updateRect);
}
}
void KisToolSelectOutline::setup(KActionCollection *collection)
void KisToolSelectOutline::deactivate()
{
m_action = collection->action(objectName());
if (m_action == 0) {
m_action = new KAction(KIcon("tool_outline_selection"),
i18n("&Outline Selection"),
collection,
objectName());
Q_CHECK_PTR(m_action);
connect(m_action, SIGNAL(triggered()), this, SLOT(activate()));
m_action->setActionGroup(actionGroup());
m_action->setToolTip(i18n("Select an outline"));
m_ownAction = true;
if (m_canvas) {
updateCanvasPixelRect(image()->bounds());
}
}
QWidget* KisToolSelectOutline::createOptionWidget()
{
m_optWidget = new KisSelectionOptions(parent, m_subject);
KisCanvas2* canvas = dynamic_cast<KisCanvas2*>(m_canvas);
Q_ASSERT(canvas);
m_optWidget = new KisSelectionOptions(canvas);
Q_CHECK_PTR(m_optWidget);
m_optWidget->setWindowTitle(i18n("Outline Selection"));
......
......@@ -24,30 +24,28 @@
#define __selecttoolfreehand_h__
#include <QPoint>
#include <q3pointarray.h>
#include <KoToolFactory.h>
#include "kis_tool_non_paint.h"
#include "KoToolFactory.h"
#include "kis_tool.h"
#include "kis_selection.h"
#include "kis_layer_shape.h"
class KisSelectionOptions;
class KisToolSelectOutline : public KisToolNonPaint {
class KisToolSelectOutline : public KisTool {
typedef KisToolNonPaint super;
typedef KisTool super;
Q_OBJECT
public:
KisToolSelectOutline();
KisToolSelectOutline(KoCanvasBase *canvas);
virtual ~KisToolSelectOutline();
virtual void setup(KActionCollection *collection);
virtual quint32 priority() { return 6; }
virtual enumToolType toolType() { return TOOL_SELECT; }
virtual void mousePressEvent(KoPointerEvent *event);
virtual void mouseMoveEvent(KoPointerEvent *event);
virtual void mouseReleaseEvent(KoPointerEvent *event);
virtual void buttonPress(KoPointerEvent *event);
virtual void move(KoPointerEvent *event);
virtual void buttonRelease(KoPointerEvent *event);
virtual void paint(QPainter& gc, KoViewConverter &converter);
QWidget* createOptionWidget();
virtual QWidget* optionWidget();
......@@ -55,24 +53,13 @@ public:
public slots:
virtual void slotSetAction(int);
virtual void activate();
void deactivate();
virtual void deactivate();
protected:
virtual void paint(QPainter& gc);
virtual void paint(QPainter& gc, const QRect& rc);
void draw(QPainter& gc);
void draw();
protected:
QPointF m_dragStart;
QPointF m_dragEnd;
private:
void updateFeedback();
bool m_dragging;
private:
typedef Q3ValueVector<QPointF> KoPointVector;
KoPointVector m_points;
vQPointF m_points;
KisSelectionOptions * m_optWidget;
enumSelectionMode m_selectAction;
};
......@@ -86,8 +73,10 @@ public:
{
setToolTip( i18n( "Select an area by its outline" ) );
setToolType( TOOL_TYPE_SELECTED );
//setToolType( dynamicToolType() );
setIcon( "tool_outline_selection" );
setPriority( 0 );
setActivationShapeId( KIS_LAYER_SHAPE_ID );
}
virtual ~KisToolSelectOutlineFactory(){}
......@@ -95,7 +84,6 @@ public:
virtual KoTool * createTool(KoCanvasBase *canvas) {
return new KisToolSelectOutline(canvas);
}
};
......
......@@ -242,6 +242,7 @@ QWidget* KisToolSelectRectangular::createOptionWidget()
m_optWidget = new KisSelectionOptions(canvas);
Q_CHECK_PTR(m_optWidget);
m_optWidget->setWindowTitle(i18n("Rectangular Selection"));
m_optWidget->disableAntiAliasSelectionOption();
connect (m_optWidget, SIGNAL(actionChanged(int)), this, SLOT(slotSetAction(int)));
......
......@@ -74,8 +74,8 @@ public:
: KoToolFactory(parent, "KisToolSelectRectangular", i18n( "Rectangular Selection" ))
{
setToolTip( i18n( "Select a rectangular area" ) );
// setToolType( TOOL_TYPE_SELECTED );
setToolType( dynamicToolType() );
setToolType( TOOL_TYPE_SELECTED );
// setToolType( dynamicToolType() );
setActivationShapeId( KIS_LAYER_SHAPE_ID );
setIcon( "tool_rect_selection" );
setShortcut( KShortcut( Qt::Key_R ) );
......
......@@ -37,7 +37,7 @@
#include "selection_tools.h"
// #include "kis_tool_select_outline.h"
#include "kis_tool_select_outline.h"
// #include "kis_tool_select_polygonal.h"
#include "kis_tool_select_rectangular.h"
// #include "kis_tool_select_contiguous.h"
......@@ -56,7 +56,7 @@ SelectionTools::SelectionTools(QObject *parent, const QStringList &)
KoToolRegistry * r = KoToolRegistry::instance();
// r->add(KoToolFactorySP(new KisToolSelectOutlineFactory()));
r->add(new KisToolSelectOutlineFactory( r, QStringList()));
// r->add(KoToolFactorySP(new KisToolSelectPolygonalFactory()));
r->add(new KisToolSelectRectangularFactory( r, QStringList()));
// r->add(KoToolFactorySP(new KisToolSelectBrushFactory()));
......
......@@ -129,6 +129,7 @@ void KisToolPolygon::finish()
painter.setPaintColor(m_currentFgColor);
painter.setBackgroundColor(m_currentBgColor);
painter.setFillStyle(fillStyle());
painter.setStrokeStyle(strokeStyle());
painter.setBrush(m_currentBrush);
painter.setPattern(m_currentPattern);
painter.setOpacity(m_opacity);
......
......@@ -210,6 +210,7 @@ QWidget* KisToolSelectSimilar::createOptionWidget()
Q_ASSERT(canvas);
m_selectionOptionsWidget = new KisSelectionOptions(canvas);
Q_CHECK_PTR(m_selectionOptionsWidget);
m_selectionOptionsWidget->disableAntiAliasSelectionOption();
l->addWidget(m_selectionOptionsWidget);
connect (m_selectionOptionsWidget, SIGNAL(actionChanged(int)), this, SLOT(slotSetAction(int)));
......
......@@ -87,8 +87,8 @@ public:
: KoToolFactory(parent, "KisToolSelectSimilar", i18n( "Select similar colors"))
{
setToolTip( i18n( "Select similar colors" ) );
// setToolType( TOOL_TYPE_SELECTED );
setToolType( dynamicToolType() );
setToolType( TOOL_TYPE_SELECTED );
// setToolType( dynamicToolType() );
setActivationShapeId( KIS_LAYER_SHAPE_ID );
setIcon( "tool_similar_selection" );
setShortcut( KShortcut(Qt::CTRL + Qt::Key_E) );
......
......@@ -107,6 +107,7 @@ void KisToolStar::mouseReleaseEvent(KoPointerEvent *event)
painter.setPaintColor(m_currentFgColor);
painter.setBackgroundColor(m_currentBgColor);
painter.setFillStyle(fillStyle());
painter.setStrokeStyle(strokeStyle());
painter.setBrush(m_currentBrush);
painter.setPattern(m_currentPattern);
painter.setOpacity(m_opacity);
......
......@@ -63,4 +63,14 @@ void KisSelectionOptions::slotActivated()
}
}
bool KisSelectionOptions::antiAliasSelection()
{
return m_page->chkAntiAliasing->isChecked();
}
void KisSelectionOptions::disableAntiAliasSelectionOption()
{
m_page->chkAntiAliasing->setDisabled(true);
}
#include "kis_selection_options.moc"
......@@ -50,6 +50,9 @@ public:
int action();
bool antiAliasSelection();
void disableAntiAliasSelectionOption();
signals:
void actionChanged(int);
......
......@@ -50,10 +50,23 @@ QWidget * KisToolShape::createOptionWidget()
m_shapeOptionsWidget->cmbFill->setParent(optionWidget);
m_shapeOptionsWidget->cmbFill->move(QPoint(0, 0));
m_shapeOptionsWidget->cmbFill->show();
m_shapeOptionsWidget->textLabel3->setParent(optionWidget);
m_shapeOptionsWidget->textLabel3->move(QPoint(0, 0));
m_shapeOptionsWidget->textLabel3->show();
addOptionWidgetOption(m_shapeOptionsWidget->cmbFill, m_shapeOptionsWidget->textLabel3);
m_shapeOptionsWidget->textLabelFill->setParent(optionWidget);
m_shapeOptionsWidget->textLabelFill->move(QPoint(0, 0));
m_shapeOptionsWidget->textLabelFill->show();
addOptionWidgetOption(m_shapeOptionsWidget->cmbFill, m_shapeOptionsWidget->textLabelFill);
m_shapeOptionsWidget->cmbFill->setCurrentIndex(KisPainter::FillStyleNone);
m_shapeOptionsWidget->cmbOutline->setParent(optionWidget);
m_shapeOptionsWidget->cmbOutline->move(QPoint(0, 0));
m_shapeOptionsWidget->cmbOutline->show();
m_shapeOptionsWidget->textLabelOutline->setParent(optionWidget);
m_shapeOptionsWidget->textLabelOutline->move(QPoint(0, 0));
m_shapeOptionsWidget->textLabelOutline->show();
addOptionWidgetOption(m_shapeOptionsWidget->cmbOutline, m_shapeOptionsWidget->textLabelOutline);
m_shapeOptionsWidget->cmbOutline->setCurrentIndex(KisPainter::StrokeStyleBrush);
return optionWidget;
}
......@@ -66,5 +79,14 @@ KisPainter::FillStyle KisToolShape::fillStyle(void)
}
}
KisPainter::StrokeStyle KisToolShape::strokeStyle(void)
{
if (m_shapeOptionsWidget) {
return static_cast<KisPainter::StrokeStyle>(m_shapeOptionsWidget->cmbOutline->currentIndex());
} else {
return KisPainter::StrokeStyleNone;
}
}
#include "kis_tool_shape.moc"
......@@ -54,6 +54,7 @@ protected:
virtual QWidget * createOptionWidget();
KisPainter::FillStyle fillStyle();
KisPainter::StrokeStyle strokeStyle();
private:
QGridLayout *m_optionLayout;
......
<ui version="4.0" stdsetdef="1" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<class>WdgSelectionOptions</class>
<widget class="QWidget" name="WdgSelectionOptions" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>180</width>
<height>34</height>
</rect>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>0</number>
<ui version="4.0" >
<class>WdgSelectionOptions</class>
<widget class="QWidget" name="WdgSelectionOptions" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>224</width>
<height>86</height>
</rect>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="lblAction" >
<property name="text" >
<string>Action:</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QComboBox" name="cmbAction" >
<item>
<property name="text" >
<string>Add</string>
</property>
<property name="spacing" >
<number>0</number>
</item>
<item>
<property name="text" >
<string>Subtract</string>
</property>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="lblAction" >
<property name="text" >
<string>Action:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cmbAction" >
<item>
<property name="text" >
<string>Add</string>
</property>
</item>
<item>
<property name="text" >
<string>Subtract</string>