|
|
|
/*
|
|
|
|
* Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.it>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
#include <tqrect.h>
|
|
|
|
#include "kis_point.h"
|
|
|
|
|
|
|
|
#include "kis_curve_framework.h"
|
|
|
|
|
|
|
|
/* **************************** *
|
|
|
|
* KisCurve methods definitions *
|
|
|
|
* **************************** */
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::addPivot (KisCurve::iterator it, const KisPoint& point)
|
|
|
|
{
|
|
|
|
return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,NOHINTS)));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::pushPivot (const KisPoint& point)
|
|
|
|
{
|
|
|
|
return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,NOHINTS))), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const KisPoint& point, bool pivot, bool selected, int hint)
|
|
|
|
{
|
|
|
|
return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,pivot,selected, hint)));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const CurvePoint& point)
|
|
|
|
{
|
|
|
|
return iterator(*this,m_curve.insert(it.position(), point));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::pushPoint (const KisPoint& point, bool pivot, bool selected,int hint)
|
|
|
|
{
|
|
|
|
return iterator(*this,m_curve.append(CurvePoint(point,pivot,selected,hint)));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::pushPoint (const CurvePoint& point)
|
|
|
|
{
|
|
|
|
return iterator(*this,m_curve.append(point));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve KisCurve::pivots()
|
|
|
|
{
|
|
|
|
KisCurve temp;
|
|
|
|
|
|
|
|
for (iterator it = begin(); it != end(); it = it.nextPivot())
|
|
|
|
temp.pushPoint((*it));
|
|
|
|
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve KisCurve::selectedPivots(bool selected)
|
|
|
|
{
|
|
|
|
KisCurve temp;
|
|
|
|
|
|
|
|
for (iterator it = begin(); it != end(); it = it.nextPivot())
|
|
|
|
if ((*it).isSelected() == selected)
|
|
|
|
temp.pushPoint((*it));
|
|
|
|
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve KisCurve::subCurve(const KisPoint& tend)
|
|
|
|
{
|
|
|
|
return subCurve(find(tend).previousPivot(),find(tend));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve KisCurve::subCurve(const CurvePoint& tend)
|
|
|
|
{
|
|
|
|
return subCurve(find(tend).previousPivot(),find(tend));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve KisCurve::subCurve(iterator tend)
|
|
|
|
{
|
|
|
|
return subCurve(tend.previousPivot(),tend);
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve KisCurve::subCurve(const KisPoint& tstart, const KisPoint& tend)
|
|
|
|
{
|
|
|
|
return subCurve(find(tstart),find(tend));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve KisCurve::subCurve(const CurvePoint& tstart, const CurvePoint& tend)
|
|
|
|
{
|
|
|
|
return subCurve(find(tstart),find(tend));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve KisCurve::subCurve(iterator tstart, iterator tend)
|
|
|
|
{
|
|
|
|
KisCurve temp;
|
|
|
|
|
|
|
|
while (tstart != tend && tstart != m_curve.end())
|
|
|
|
temp.pushPoint((*++tstart));
|
|
|
|
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisCurve::deleteFirstPivot ()
|
|
|
|
{
|
|
|
|
if (!m_curve.isEmpty()) {
|
|
|
|
m_curve.pop_front();
|
|
|
|
while (m_curve.count() > 1 && !first().isPivot())
|
|
|
|
m_curve.pop_front();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisCurve::deleteLastPivot ()
|
|
|
|
{
|
|
|
|
if (!m_curve.isEmpty()) {
|
|
|
|
m_curve.pop_back();
|
|
|
|
while (m_curve.count() > 1 && !last().isPivot())
|
|
|
|
m_curve.pop_back();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::deleteCurve (const KisPoint& pos1, const KisPoint& pos2)
|
|
|
|
{
|
|
|
|
return deleteCurve (CurvePoint(pos1),CurvePoint(pos2));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::deleteCurve (const CurvePoint& pos1, const CurvePoint& pos2)
|
|
|
|
{
|
|
|
|
return deleteCurve (find(pos1),find(pos2));
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::deleteCurve (KisCurve::iterator pos1, KisCurve::iterator pos2)
|
|
|
|
{
|
|
|
|
if (pos1 == pos2)
|
|
|
|
return end();
|
|
|
|
iterator pos = pos1;
|
|
|
|
pos++;
|
|
|
|
while (pos != pos2 && pos != end()) {
|
|
|
|
pos = m_curve.erase(pos.position());
|
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::selectPivot(const KisPoint& pt, bool isSelected)
|
|
|
|
{
|
|
|
|
return selectPivot(find(CurvePoint(pt,true)),isSelected);
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::selectPivot(const CurvePoint& pt, bool isSelected)
|
|
|
|
{
|
|
|
|
return selectPivot(find(pt),isSelected);
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::selectPivot(KisCurve::iterator it, bool isSelected)
|
|
|
|
{
|
|
|
|
bool sel = false;
|
|
|
|
if (m_standardkeepselected) {
|
|
|
|
if (m_actionOptions & KEEPSELECTEDOPTION)
|
|
|
|
sel = true;
|
|
|
|
}
|
|
|
|
KisCurve selected = pivots();
|
|
|
|
for (iterator i = selected.begin(); i != selected.end(); i++)
|
|
|
|
(*find((*i))).setSelected(sel);
|
|
|
|
(*it).setSelected(isSelected);
|
|
|
|
|
|
|
|
return it;
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::movePivot(const KisPoint& oldPt, const KisPoint& newPt)
|
|
|
|
{
|
|
|
|
return movePivot(CurvePoint(oldPt,true), newPt);
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::movePivot(const CurvePoint& oldPt, const KisPoint& newPt)
|
|
|
|
{
|
|
|
|
return movePivot(find(oldPt), newPt);
|
|
|
|
}
|
|
|
|
|
|
|
|
KisCurve::iterator KisCurve::movePivot(KisCurve::iterator it, const KisPoint& newPt)
|
|
|
|
{
|
|
|
|
if (!(*it).isPivot())
|
|
|
|
return end();
|
|
|
|
|
|
|
|
(*it).setPoint(newPt);
|
|
|
|
|
|
|
|
if ((*it) != first()) {
|
|
|
|
deleteCurve (it.previousPivot(), it);
|
|
|
|
calculateCurve (it.previousPivot(), it, it);
|
|
|
|
}
|
|
|
|
if ((*it) != last()) {
|
|
|
|
deleteCurve (it, it.nextPivot());
|
|
|
|
calculateCurve (it, it.nextPivot(), it.nextPivot());
|
|
|
|
}
|
|
|
|
|
|
|
|
return it;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisCurve::deletePivot (const KisPoint& pt)
|
|
|
|
{
|
|
|
|
deletePivot(CurvePoint(pt));
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisCurve::deletePivot (const CurvePoint& pt)
|
|
|
|
{
|
|
|
|
deletePivot(find(pt));
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisCurve::deletePivot (KisCurve::iterator it)
|
|
|
|
{
|
|
|
|
if (!(*it).isPivot())
|
|
|
|
return;
|
|
|
|
|
|
|
|
iterator start = it.previousPivot();
|
|
|
|
iterator end = it.nextPivot();
|
|
|
|
|
|
|
|
if (end == m_curve.end())
|
|
|
|
deleteLastPivot();
|
|
|
|
else if (start == it)
|
|
|
|
deleteFirstPivot();
|
|
|
|
else {
|
|
|
|
deleteCurve(start,end);
|
|
|
|
calculateCurve(start,end,end);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Probably it can be optimized - it is smooth though.
|
|
|
|
void KisCurve::moveSelected (const KisPoint& trans)
|
|
|
|
{
|
|
|
|
KisPoint p;
|
|
|
|
KisCurve sel = selectedPivots();
|
|
|
|
|
|
|
|
for (iterator it = sel.begin(); it != sel.end(); it++) {
|
|
|
|
p = (*it).point() + trans;
|
|
|
|
movePivot((*it),p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisCurve::deleteSelected ()
|
|
|
|
{
|
|
|
|
KisCurve sel = selectedPivots();
|
|
|
|
for (iterator it = sel.begin(); it != sel.end(); it++)
|
|
|
|
deletePivot((*it));
|
|
|
|
}
|
|
|
|
|
|
|
|
void KisCurve::selectAll(bool sel)
|
|
|
|
{
|
|
|
|
for (iterator i = begin(); i != end(); i = i.nextPivot())
|
|
|
|
(*i).setSelected(sel);
|
|
|
|
}
|