diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /karbon/commands/vbooleancmd.cc | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'karbon/commands/vbooleancmd.cc')
-rw-r--r-- | karbon/commands/vbooleancmd.cc | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/karbon/commands/vbooleancmd.cc b/karbon/commands/vbooleancmd.cc new file mode 100644 index 00000000..a97fefe9 --- /dev/null +++ b/karbon/commands/vbooleancmd.cc @@ -0,0 +1,240 @@ +/* This file is part of the KDE project + Copyright (C) 2001, The Karbon Developers + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include <qptrlist.h> +#include <qvaluelist.h> + +#include <klocale.h> + +#include "vbooleancmd.h" +#include "vpath.h" +#include "vsegment.h" +#include "vselection.h" +#include "vdocument.h" + +VBooleanCmd::VBooleanCmd( VDocument *doc, VBooleanType type ) + : VCommand( doc, i18n( "Boolean Operation" ) ) +{ + m_selection = document()->selection()->clone(); + m_type = type; +} + +VBooleanCmd::~VBooleanCmd() +{ + delete( m_selection ); +} + +void +VBooleanCmd::execute() +{ + VObjectListIterator itr( m_selection->objects() ); + for ( ; itr.current() ; ++itr ) + { +// TODO: pair wise visiting. + } + +// document()->append( ); + document()->selection()->clear(); +} + +void +VBooleanCmd::unexecute() +{ +} + +bool +VBooleanCmd::visit( VObject& object1, VObject& object2 ) +{ + m_path1 = 0L; + m_path2 = 0L; + object1.accept( *this ); + object2.accept( *this ); + + return success(); +} + +void +VBooleanCmd::visitVSubpath( VSubpath& path ) +{ + if( m_path1 == 0L ) + m_path1 = &path; + else if( m_path2 == 0L ) + { + m_path2 = &path; + + // intersection parameters (t): + VParamList params1; + VParamList params2; + VParamList::iterator pItr; + + double prevParam; + + m_path1->first(); + + // ommit "begin" segment: + while( m_path1->next() ) + { + params1.clear(); + + m_path2->first(); + + // ommit "begin" segment: + while( m_path2->next() ) + { + params2.clear(); + + recursiveSubdivision( + *m_path1->current(), 0.0, 1.0, + *m_path2->current(), 0.0, 1.0, + params1, params2 ); + + qHeapSort( params2 ); + + prevParam = 0.0; + + // walk down all intersection params and insert knots: + for( pItr = params2.begin(); pItr != params2.end(); ++pItr ) + { + m_path2->insert( + m_path2->current()->splitAt( + ( *pItr - prevParam )/( 1.0 - prevParam ) ) ); + + m_path2->next(); + prevParam = *pItr; + } + } + + qHeapSort( params1 ); + + prevParam = 0.0; + + // walk down all intersection params and insert knots: + for( pItr = params1.begin(); pItr != params1.end(); ++pItr ) + { + m_path1->insert( + m_path1->current()->splitAt( + ( *pItr - prevParam )/( 1.0 - prevParam ) ) ); + + m_path1->next(); + prevParam = *pItr; + } + } + } +} + +void +VBooleanCmd::recursiveSubdivision( + const VSegment& segment1, double t0_1, double t1_1, + const VSegment& segment2, double t0_2, double t1_2, + VParamList& params1, VParamList& params2 ) +{ + if( + !segment1.boundingBox().intersects( + segment2.boundingBox() ) ) + { + return; + } + + if( segment1.isFlat() ) + { + // calculate intersection of line segments: + if( segment2.isFlat() ) + { + KoPoint v1 = segment1.knot() - segment1.prev()->knot(); + KoPoint v2 = segment2.knot() - segment2.prev()->knot(); + + double det = v2.x() * v1.y() - v2.y() * v1.x(); + + if( 1.0 + det == 1.0 ) + return; + else + { + KoPoint v = segment2.prev()->knot() - segment1.prev()->knot(); + const double one_det = 1.0 / det; + + double t1 = one_det * ( v2.x() * v.y() - v2.y() * v.x() ); + double t2 = one_det * ( v1.x() * v.y() - v1.y() * v.x() ); + + if ( t1 < 0.0 || t1 > 1.0 || t2 < 0.0 || t2 > 1.0 ) + return; + + params1.append( t0_1 + t1 * ( t1_1 - t0_1 ) ); + params2.append( t0_2 + t2 * ( t1_2 - t0_2 ) ); + } + } + else + { + // "copy segment" and split it at midpoint: + VSubpath path2( segment2 ); + path2.insert( path2.current()->splitAt( 0.5 ) ); + + double mid2 = 0.5 * ( t0_2 + t1_2 ); + + recursiveSubdivision( + *path2.current(), t0_2, mid2, + segment1, t0_1, t1_1, params2, params1 ); + recursiveSubdivision( + *path2.next(), mid2, t1_2, + segment1, t0_1, t1_1, params2, params1 ); + } + } + else + { + // "copy segment" and split it at midpoint: + VSubpath path1( segment1 ); + path1.insert( path1.current()->splitAt( 0.5 ) ); + + double mid1 = 0.5 * ( t0_1 + t1_1 ); + + if( segment2.isFlat() ) + { + recursiveSubdivision( + *path1.current(), t0_1, mid1, + segment2, t0_2, t1_2, params1, params2 ); + recursiveSubdivision( + *path1.next(), mid1, t1_1, + segment2, t0_2, t1_2, params1, params2 ); + } + else + { + // "copy segment" and split it at midpoint: + VSubpath path2( segment2 ); + path2.insert( path2.current()->splitAt( 0.5 ) ); + + double mid2 = 0.5 * ( t0_2 + t1_2 ); + + recursiveSubdivision( + *path1.current(), t0_1, mid1, + *path2.current(), t0_2, mid2, params1, params2 ); + recursiveSubdivision( + *path1.next(), mid1, t1_1, + *path2.current(), t0_2, mid2, params1, params2 ); + + recursiveSubdivision( + *path1.prev(), t0_1, mid1, + *path2.next(), mid2, t1_2, params1, params2 ); + recursiveSubdivision( + *path1.next(), mid1, t1_1, + *path2.current(), mid2, t1_2, params1, params2 ); + } + } +} + |