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/shapes | |
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/shapes')
-rw-r--r-- | karbon/shapes/Makefile.am | 29 | ||||
-rw-r--r-- | karbon/shapes/vellipse.cc | 316 | ||||
-rw-r--r-- | karbon/shapes/vellipse.h | 63 | ||||
-rw-r--r-- | karbon/shapes/vpolygon.cc | 185 | ||||
-rw-r--r-- | karbon/shapes/vpolygon.h | 52 | ||||
-rw-r--r-- | karbon/shapes/vpolyline.cc | 184 | ||||
-rw-r--r-- | karbon/shapes/vpolyline.h | 50 | ||||
-rw-r--r-- | karbon/shapes/vrectangle.cc | 229 | ||||
-rw-r--r-- | karbon/shapes/vrectangle.h | 54 | ||||
-rw-r--r-- | karbon/shapes/vsinus.cc | 206 | ||||
-rw-r--r-- | karbon/shapes/vsinus.h | 51 | ||||
-rw-r--r-- | karbon/shapes/vspiral.cc | 186 | ||||
-rw-r--r-- | karbon/shapes/vspiral.h | 60 | ||||
-rw-r--r-- | karbon/shapes/vstar.cc | 348 | ||||
-rw-r--r-- | karbon/shapes/vstar.h | 91 |
15 files changed, 2104 insertions, 0 deletions
diff --git a/karbon/shapes/Makefile.am b/karbon/shapes/Makefile.am new file mode 100644 index 00000000..bbb7899b --- /dev/null +++ b/karbon/shapes/Makefile.am @@ -0,0 +1,29 @@ +INCLUDES = $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../core \ + -I$(srcdir)/../commands \ + $(all_includes) + +noinst_LTLIBRARIES = libkarbonshapes.la + +noinst_HEADERS = \ + vellipse.h \ + vpolyline.h \ + vpolygon.h \ + vrectangle.h \ + vsinus.h \ + vspiral.h \ + vstar.h + +libkarbonshapes_la_SOURCES = \ + vellipse.cc \ + vpolyline.cc \ + vpolygon.cc \ + vrectangle.cc \ + vsinus.cc \ + vspiral.cc \ + vstar.cc + +libkarbonshapes_la_METASOURCES = \ + AUTO + diff --git a/karbon/shapes/vellipse.cc b/karbon/shapes/vellipse.cc new file mode 100644 index 00000000..c2afc804 --- /dev/null +++ b/karbon/shapes/vellipse.cc @@ -0,0 +1,316 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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 "vellipse.h" +#include "vtransformcmd.h" +#include <klocale.h> +#include <KoUnit.h> +#include <KoStore.h> +#include <KoXmlWriter.h> +#include <KoXmlNS.h> +#include <vglobal.h> +#include <vdocument.h> +#include <qdom.h> +#include <core/vfill.h> + +VEllipse::VEllipse( VObject* parent, VState state ) : VPath( parent, state ) +{ +} + +VEllipse::VEllipse( VObject* parent, + const KoPoint& topLeft, double width, double height, + VEllipseType type, double startAngle, double endAngle ) + : VPath( parent ), m_type( type ), m_startAngle( startAngle ), m_endAngle( endAngle ) +{ + setDrawCenterNode(); + + m_rx = width / 2.0; + m_ry = height / 2.0; + m_center.setX( topLeft.x() + m_rx ); + m_center.setY( topLeft.y() + m_ry ); + + init(); +} + +void +VEllipse::init() +{ + // to radials + int nsegs; + if( m_startAngle < m_endAngle ) + nsegs = int( floor( ( m_endAngle - m_startAngle ) / 90.0 ) ); + else + nsegs = 4 - int( ceil( ( m_startAngle - m_endAngle ) / 90.0 ) ); + double startAngle = m_startAngle - 90.0; + if( startAngle < 0 ) startAngle += 360.0; + startAngle = VGlobal::pi_2 * ( startAngle / 90.0 ); + double endAngle = m_endAngle - 90.0; + if( endAngle < 0 ) endAngle += 360.0; + endAngle = VGlobal::pi_2 * ( endAngle / 90.0 ); + // Create (half-)unity circle with topLeft at (0|0): + double currentAngle = -startAngle - VGlobal::pi_2; + KoPoint start( 0.5 * sin( -startAngle ), 0.5 * cos( -startAngle ) ); + moveTo( KoPoint( start.x(), start.y() ) ); + double midAngle = currentAngle + VGlobal::pi_2 / 2.0; + double midAmount = 0.5 / sin( VGlobal::pi_2 / 2.0 ); + for( int i = 0;i < nsegs;i++ ) + { + midAngle -= VGlobal::pi_2; + arcTo( KoPoint( cos( midAngle ) * midAmount, -sin( midAngle ) * midAmount ), + KoPoint( 0.5 * sin( currentAngle ), 0.5 * cos( currentAngle ) ), 0.5 ); + currentAngle -= VGlobal::pi_2; + } + double rest = ( -endAngle - VGlobal::pi_2 - currentAngle ) * 90.0 / VGlobal::pi_2; + if( rest > 0 ) + rest -= 360.0; + if( rest != 0 ) + { + midAngle = currentAngle - ( -rest / 360.0 ) * VGlobal::pi; + midAmount = 0.5 / cos( currentAngle - midAngle ); + KoPoint end( 0.5 * sin( -endAngle ), 0.5 * cos( -endAngle ) ); + arcTo( KoPoint( cos( midAngle ) * midAmount, -sin( midAngle ) * midAmount ), + KoPoint( 0.5 * sin( -endAngle ), 0.5 * cos( -endAngle ) ), 0.5 ); + } + if( m_type == cut ) + lineTo( KoPoint( 0.0, 0.0 ) ); + if( m_type != arc ) + close(); + + // Translate and scale: + QWMatrix m; + m.translate( m_center.x(), m_center.y() ); + m.scale( 2.0 * m_rx, 2.0 * m_ry ); + + // only tranform the path data + VTransformCmd cmd( 0L, m ); + cmd.VVisitor::visitVPath( *this ); + + m_matrix.reset(); +} + +QString +VEllipse::name() const +{ + QString result = VObject::name(); + return !result.isEmpty() ? result : i18n( "Ellipse" ); +} + +void +VEllipse::save( QDomElement& element ) const +{ + VDocument *doc = document(); + if( doc && doc->saveAsPath() ) + { + VPath::save( element ); + return; + } + + if( state() != deleted ) + { + QDomElement me = element.ownerDocument().createElement( "ELLIPSE" ); + element.appendChild( me ); + + // save fill/stroke untransformed + VPath path( *this ); + VTransformCmd cmd( 0L, m_matrix.invert() ); + cmd.visit( path ); + path.VObject::save( me ); + //VObject::save( me ); + + me.setAttribute( "cx", m_center.x() ); + me.setAttribute( "cy", m_center.y() ); + + me.setAttribute( "rx", m_rx ); + me.setAttribute( "ry", m_ry ); + + me.setAttribute( "start-angle", m_startAngle ); + me.setAttribute( "end-angle", m_endAngle ); + + if( m_type == cut ) + me.setAttribute( "kind", "cut" ); + else if( m_type == section ) + me.setAttribute( "kind", "section" ); + else if( m_type == arc ) + me.setAttribute( "kind", "arc" ); + else + me.setAttribute( "kind", "full" ); + + QString transform = buildSvgTransform(); + if( !transform.isEmpty() ) + me.setAttribute( "transform", transform ); + } +} + +void +VEllipse::saveOasis( KoStore *store, KoXmlWriter *docWriter, KoGenStyles &mainStyles, int &index ) const +{ + // do not save deleted objects + if( state() == deleted ) + return; + + docWriter->startElement( "draw:ellipse" ); + + //save all into pt + docWriter->addAttributePt( "svg:cx", m_center.x() ); + docWriter->addAttributePt( "svg:cy", m_center.y() ); + docWriter->addAttributePt( "svg:rx", m_rx ); + docWriter->addAttributePt( "svg:ry", m_ry ); + + if( m_type == full ) + docWriter->addAttribute( "draw:kind", "full" ); + else + { + // the meaning of cut and section is mixed up in karbon, so just set them so for now + // be sure to do the right thing tm for karbon 2.0 + if( m_type == section ) + docWriter->addAttribute( "draw:kind", "cut" ); + else if( m_type == cut ) + docWriter->addAttribute( "draw:kind", "section" ); + else + docWriter->addAttribute( "draw:kind", "arc" ); + + docWriter->addAttribute( "draw:start-angle", m_startAngle ); + docWriter->addAttribute( "draw:end-angle", m_endAngle ); + } + + VObject::saveOasis( store, docWriter, mainStyles, index ); + + QWMatrix tmpMat; + tmpMat.scale( 1, -1 ); + tmpMat.translate( 0, -document()->height() ); + + QString transform = buildOasisTransform( m_matrix*tmpMat ); + if( !transform.isEmpty() ) + docWriter->addAttribute( "draw:transform", transform ); + + docWriter->endElement(); +} + +bool +VEllipse::loadOasis( const QDomElement &element, KoOasisLoadingContext &context ) +{ + setState( normal ); + + if( element.tagName() == "ellipse" ) + { + if( element.hasAttributeNS( KoXmlNS::svg, "rx" ) ) + m_rx = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "rx", QString::null ) ); + else + m_rx = 0.5 * KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "width", QString::null ) ); + + if( element.hasAttributeNS( KoXmlNS::svg, "ry" ) ) + m_ry = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "ry", QString::null ) ); + else + m_ry = 0.5 * KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "height", QString::null ) ); + + } + else if( element.tagName() == "circle" ) + { + if( element.hasAttributeNS( KoXmlNS::svg, "r" ) ) + m_rx = m_ry = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "r", QString::null ) ); + else + m_rx = m_ry = 0.5 * KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "width", QString::null ) ); + } + + if( element.hasAttributeNS( KoXmlNS::svg, "cx" ) ) + m_center.setX( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "cx", QString::null ) ) ); + else + m_center.setX( m_rx + KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x", QString::null ) ) ); + + if( element.hasAttributeNS( KoXmlNS::svg, "cy" ) ) + m_center.setY( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "cy", QString::null ) ) ); + else + m_center.setY( m_ry + KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y", QString::null ) ) ); + + // the meaning of cut and section is mixed up in karbon, so just set them so for now + // be sure to do the right thing tm for karbon 2.0 + QString kind = element.attributeNS( KoXmlNS::draw, "kind", QString::null ); + if( kind == "cut" ) + m_type = section; + else if( kind == "section" ) + m_type = cut; + else if( kind == "arc" ) + m_type = arc; + else + m_type = full; + + double startAngle = element.attributeNS( KoXmlNS::draw, "start-angle", QString::null ).toDouble(); + double endAngle = element.attributeNS( KoXmlNS::draw, "end-angle", QString::null ).toDouble(); + + // the shape gets mirrored in y-direction, so make the angles temporary clockwise + // just for creating the path + m_startAngle = 360.0 - endAngle; + m_endAngle = 360.0 - startAngle; + + init(); + + // now set the right angles + m_startAngle = startAngle; + m_endAngle = endAngle; + + transformByViewbox( element, element.attributeNS( KoXmlNS::svg, "viewBox", QString::null ) ); + + QString trafo = element.attributeNS( KoXmlNS::draw, "transform", QString::null ); + if( !trafo.isEmpty() ) + transformOasis( trafo ); + + return VObject::loadOasis( element, context ); +} + +void +VEllipse::load( const QDomElement& element ) +{ + setState( normal ); + + QDomNodeList list = element.childNodes(); + for( uint i = 0; i < list.count(); ++i ) + if( list.item( i ).isElement() ) + VObject::load( list.item( i ).toElement() ); + + m_rx = KoUnit::parseValue( element.attribute( "rx" ) ); + m_ry = KoUnit::parseValue( element.attribute( "ry" ) ); + + m_center.setX( KoUnit::parseValue( element.attribute( "cx" ) ) ); + m_center.setY( KoUnit::parseValue( element.attribute( "cy" ) ) ); + + m_startAngle = element.attribute( "start-angle" ).toDouble(); + m_endAngle = element.attribute( "end-angle" ).toDouble(); + + if( element.attribute( "kind" ) == "cut" ) + m_type = cut; + else if( element.attribute( "kind" ) == "section" ) + m_type = section; + else if( element.attribute( "kind" ) == "arc" ) + m_type = arc; + else + m_type = full; + + init(); + + QString trafo = element.attribute( "transform" ); + if( !trafo.isEmpty() ) + transform( trafo ); +} + +VPath* +VEllipse::clone() const +{ + return new VEllipse( *this ); +} diff --git a/karbon/shapes/vellipse.h b/karbon/shapes/vellipse.h new file mode 100644 index 00000000..e7decbd2 --- /dev/null +++ b/karbon/shapes/vellipse.h @@ -0,0 +1,63 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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. +*/ + +#ifndef __VELLIPSE_H__ +#define __VELLIPSE_H__ + +#include "vcomposite.h" +#include <koffice_export.h> + +class KARBONBASE_EXPORT VEllipse : public VPath +{ +public: + enum VEllipseType + { + full, + section, + cut, + arc + }; + VEllipse( VObject* parent, VState state = edit ); + VEllipse( VObject* parent, + const KoPoint& topLeft, double width, double height, + VEllipseType type = full, double startAngle = 0, double endAngle = 0 ); + + virtual QString name() const; + + virtual void save( QDomElement& element ) const; + virtual void saveOasis( KoStore *store, KoXmlWriter *docWriter, KoGenStyles &mainStyles, int &index ) const; + virtual void load( const QDomElement& element ); + virtual bool loadOasis( const QDomElement &element, KoOasisLoadingContext &context ); + + virtual VPath* clone() const; + +protected: + void init(); + +private: + VEllipseType m_type; + KoPoint m_center; + double m_rx; + double m_ry; + double m_startAngle; + double m_endAngle; +}; + +#endif + diff --git a/karbon/shapes/vpolygon.cc b/karbon/shapes/vpolygon.cc new file mode 100644 index 00000000..aa74ca90 --- /dev/null +++ b/karbon/shapes/vpolygon.cc @@ -0,0 +1,185 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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 <qdom.h> + +#include "vglobal.h" +#include "vpolygon.h" +#include "vtransformcmd.h" +#include <klocale.h> +#include <KoUnit.h> +#include <KoStore.h> +#include <KoXmlWriter.h> +#include <KoXmlNS.h> +#include <vdocument.h> + +VPolygon::VPolygon( VObject* parent, VState state ) + : VPath( parent, state ) +{ +} + +VPolygon::VPolygon( VObject* parent, const QString &points, + const KoPoint& topLeft, double width, double height ) + : VPath( parent ), m_topLeft( topLeft ), m_width( width), m_height( height ), m_points( points ) +{ + init(); +} + +void +VPolygon::init() +{ + bool bFirst = true; + + QString points = m_points.simplifyWhiteSpace(); + points.replace( ',', ' ' ); + points.remove( '\r' ); + points.remove( '\n' ); + QStringList pointList = QStringList::split( ' ', points ); + QStringList::Iterator end(pointList.end()); + for( QStringList::Iterator it = pointList.begin(); it != end; ++it ) + { + KoPoint point; + point.setX( (*it).toDouble() ); + point.setY( (*++it).toDouble() ); + if( bFirst ) + { + moveTo( point ); + bFirst = false; + } + else + lineTo( point ); + } + close(); + + QWMatrix m; + m.translate( m_topLeft.x(), m_topLeft.y() ); + + // only tranform the path data + VTransformCmd cmd( 0L, m ); + cmd.VVisitor::visitVPath( *this ); +} + +QString +VPolygon::name() const +{ + QString result = VObject::name(); + return !result.isEmpty() ? result : i18n( "Polygon" ); +} + +void +VPolygon::save( QDomElement& element ) const +{ + VDocument *doc = document(); + if( doc && doc->saveAsPath() ) + { + VPath::save( element ); + return; + } + + if( state() != deleted ) + { + QDomElement me = element.ownerDocument().createElement( "POLYGON" ); + element.appendChild( me ); + + // save fill/stroke untransformed + VPath path( *this ); + VTransformCmd cmd( 0L, m_matrix.invert() ); + cmd.visit( path ); + path.VObject::save( me ); + //VObject::save( me ); + + me.setAttribute( "x", m_topLeft.x() ); + me.setAttribute( "y", m_topLeft.y() ); + + me.setAttribute( "width", QString("%1pt").arg( m_width ) ); + me.setAttribute( "height", QString("%1pt").arg( m_height ) ); + + me.setAttribute( "points", m_points ); + + QString transform = buildSvgTransform(); + if( !transform.isEmpty() ) + me.setAttribute( "transform", transform ); + } +} + +void +VPolygon::saveOasis( KoStore *store, KoXmlWriter *docWriter, KoGenStyles &mainStyles, int &index ) const +{ + // do not save deleted objects + if( state() == deleted ) + return; + + docWriter->startElement( "draw:polygon" ); + + docWriter->addAttribute( "draw:points", m_points ); + + VObject::saveOasis( store, docWriter, mainStyles, index ); + + docWriter->endElement(); +} + +void +VPolygon::load( const QDomElement& element ) +{ + setState( normal ); + + QDomNodeList list = element.childNodes(); + for( uint i = 0; i < list.count(); ++i ) + if( list.item( i ).isElement() ) + VObject::load( list.item( i ).toElement() ); + + m_points = element.attribute( "points" ); + + m_width = KoUnit::parseValue( element.attribute( "width" ), 10.0 ); + m_height = KoUnit::parseValue( element.attribute( "height" ), 10.0 ); + + m_topLeft.setX( KoUnit::parseValue( element.attribute( "x" ) ) ); + m_topLeft.setY( KoUnit::parseValue( element.attribute( "y" ) ) ); + + init(); + + QString trafo = element.attribute( "transform" ); + if( !trafo.isEmpty() ) + transform( trafo ); +} + +bool +VPolygon::loadOasis( const QDomElement &element, KoOasisLoadingContext &context ) +{ + setState( normal ); + + m_points = element.attributeNS( KoXmlNS::draw, "points", QString::null ); + + init(); + + transformByViewbox( element, element.attributeNS( KoXmlNS::svg, "viewBox", QString::null ) ); + + QString trafo = element.attributeNS( KoXmlNS::draw, "transform", QString::null ); + if( !trafo.isEmpty() ) + transformOasis( trafo ); + + return VObject::loadOasis( element, context ); +} + +VPath* +VPolygon::clone() const +{ + return new VPolygon( *this ); +} diff --git a/karbon/shapes/vpolygon.h b/karbon/shapes/vpolygon.h new file mode 100644 index 00000000..9b7bc940 --- /dev/null +++ b/karbon/shapes/vpolygon.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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. +*/ + +#ifndef __VPOLYGON_H__ +#define __VPOLYGON_H__ + +#include "vcomposite.h" + +class VPolygon : public VPath +{ +public: + VPolygon( VObject* parent, VState state = edit ); + VPolygon( VObject* parent, const QString &points, + const KoPoint& topLeft, double width, double height ); + + virtual QString name() const; + + virtual void save( QDomElement& element ) const; + virtual void saveOasis( KoStore *store, KoXmlWriter *docWriter, KoGenStyles &mainStyles, int &index ) const; + virtual void load( const QDomElement& element ); + virtual bool loadOasis( const QDomElement &element, KoOasisLoadingContext &context ); + + virtual VPath* clone() const; + +protected: + void init(); + +private: + KoPoint m_topLeft; + double m_width; + double m_height; + QString m_points; +}; + +#endif + diff --git a/karbon/shapes/vpolyline.cc b/karbon/shapes/vpolyline.cc new file mode 100644 index 00000000..c55c0d14 --- /dev/null +++ b/karbon/shapes/vpolyline.cc @@ -0,0 +1,184 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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 "vpolyline.h" +#include <qdom.h> + +#include "vglobal.h" +#include <klocale.h> +#include <vdocument.h> +#include "vtransformcmd.h" + +#include <KoStore.h> +#include <KoXmlWriter.h> +#include <KoXmlNS.h> + +VPolyline::VPolyline( VObject* parent, VState state ) + : VPath( parent, state ) +{ +} + +/*VPolyline::VPolyline( VObject* parent, VState state ) + : VPath( parent, state ) +{ +}*/ + +/*VPolyline::VPolyline( VObject* parent, const QString &points ) + : VPath( parent ), m_points( points ) +{ + init(); +}*/ + +void +VPolyline::init() +{ + bool bFirst = true; + + QString points = m_points.simplifyWhiteSpace(); + points.replace( ',', ' ' ); + points.remove( '\r' ); + points.remove( '\n' ); + QStringList pointList = QStringList::split( ' ', points ); + QStringList::Iterator end(pointList.end()); + for( QStringList::Iterator it = pointList.begin(); it != end; ++it ) + { + KoPoint point; + point.setX( (*it).toDouble() ); + point.setY( (*++it).toDouble() ); + if( bFirst ) + { + moveTo( point ); + bFirst = false; + } + else + lineTo( point ); + } +} + +QString +VPolyline::name() const +{ + QString result = VObject::name(); + return !result.isEmpty() ? result : i18n( "Polyline" ); +} + +void +VPolyline::save( QDomElement& element ) const +{ + VDocument *doc = document(); + if( doc && doc->saveAsPath() ) + { + VPath::save( element ); + return; + } + + if( state() != deleted ) + { + QDomElement me = element.ownerDocument().createElement( "POLYLINE" ); + element.appendChild( me ); + + // save fill/stroke untransformed + VPath path( *this ); + VTransformCmd cmd( 0L, m_matrix.invert() ); + cmd.visit( path ); + path.VObject::save( me ); + //VObject::save( me ); + + me.setAttribute( "points", m_points ); + + QString transform = buildSvgTransform(); + if( !transform.isEmpty() ) + me.setAttribute( "transform", transform ); + } +} + +void +VPolyline::saveOasis( KoStore *store, KoXmlWriter *docWriter, KoGenStyles &mainStyles, int &index ) const +{ + // do not save deleted objects + if( state() == deleted ) + return; + + docWriter->startElement( "draw:polyline" ); + + docWriter->addAttribute( "svg:points", m_points ); + + VObject::saveOasis( store, docWriter, mainStyles, index ); + + docWriter->endElement(); +} + +void +VPolyline::load( const QDomElement& element ) +{ + setState( normal ); + + QDomNodeList list = element.childNodes(); + for( uint i = 0; i < list.count(); ++i ) + if( list.item( i ).isElement() ) + VObject::load( list.item( i ).toElement() ); + + m_points = element.attribute( "points" ); + + init(); + + QString trafo = element.attribute( "transform" ); + if( !trafo.isEmpty() ) + transform( trafo ); +} + +bool +VPolyline::loadOasis( const QDomElement &element, KoOasisLoadingContext &context ) +{ + setState( normal ); + + if( element.localName() == "line" ) + { + KoPoint p1, p2; + p1.setX( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x1", QString::null ) ) ); + p1.setY( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y1", QString::null ) ) ); + p2.setX( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x2", QString::null ) ) ); + p2.setY( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y2", QString::null ) ) ); + + m_points = QString( "%1,%2 %3,%4" ).arg( p1.x() ).arg( p1.y() ).arg( p2.x() ).arg( p2.y() ); + + moveTo( p1 ); + lineTo( p2 ); + } + else if( element.localName() == "polyline" ) + { + m_points = element.attributeNS( KoXmlNS::draw, "points", QString::null ); + init(); + } + + transformByViewbox( element, element.attributeNS( KoXmlNS::svg, "viewBox", QString::null ) ); + + QString trafo = element.attributeNS( KoXmlNS::draw, "transform", QString::null ); + if( !trafo.isEmpty() ) + transformOasis( trafo ); + + return VObject::loadOasis( element, context ); +} + +VPath* +VPolyline::clone() const +{ + return new VPolyline( *this ); +} diff --git a/karbon/shapes/vpolyline.h b/karbon/shapes/vpolyline.h new file mode 100644 index 00000000..34da9716 --- /dev/null +++ b/karbon/shapes/vpolyline.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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. +*/ + +#ifndef __VPOLYLINE_H__ +#define __VPOLYLINE_H__ + +#include "vcomposite.h" +#include <qstring.h> + +class VPolyline : public VPath +{ +public: + VPolyline( VObject* parent, VState state = edit ); + //VPolyline( VObject* parent, VState state = edit ); + //VPolyline( VObject* parent, const QString &points ); + + virtual QString name() const; + + virtual void save( QDomElement& element ) const; + virtual void saveOasis( KoStore *store, KoXmlWriter *docWriter, KoGenStyles &mainStyles, int &index ) const; + virtual void load( const QDomElement& element ); + virtual bool loadOasis( const QDomElement &element, KoOasisLoadingContext &context ); + + virtual VPath* clone() const; + +protected: + void init(); + +private: + QString m_points; +}; + +#endif + diff --git a/karbon/shapes/vrectangle.cc b/karbon/shapes/vrectangle.cc new file mode 100644 index 00000000..966c2bb2 --- /dev/null +++ b/karbon/shapes/vrectangle.cc @@ -0,0 +1,229 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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 "vrectangle.h" +#include <klocale.h> +#include <KoUnit.h> +#include <KoStore.h> +#include <KoXmlWriter.h> +#include <KoXmlNS.h> +#include <qdom.h> +#include <kdebug.h> +#include "vglobal.h" +#include <vdocument.h> +#include "vtransformcmd.h" + +VRectangle::VRectangle( VObject* parent, VState state ) + : VPath( parent, state ) +{ +} + +VRectangle::VRectangle( VObject* parent, + const KoPoint& topLeft, double width, double height, double rx, double ry ) + : VPath( parent ), m_topLeft( topLeft ), m_width( width), m_height( height ), m_rx( rx ), m_ry( ry ) +{ + setDrawCenterNode(); + + if( m_rx < 0.0 ) m_rx = 0.0; + if( m_ry < 0.0 ) m_ry = 0.0; + // Catch case, when radius is larger than width or height: + if( m_rx > m_width * 0.5 ) + m_rx = m_width * 0.5; + if( m_ry > m_height * 0.5 ) + m_ry = m_height * 0.5; + + init(); +} + +void +VRectangle::init() +{ + if( m_rx == 0 && m_ry == 0 ) + { + moveTo( m_topLeft ); + lineTo( KoPoint( m_topLeft.x(), m_topLeft.y() - m_height ) ); + lineTo( KoPoint( m_topLeft.x() + m_width, m_topLeft.y() - m_height ) ); + lineTo( KoPoint( m_topLeft.x() + m_width, m_topLeft.y() ) ); + } + else + { + double rx = m_rx; + double ry = m_ry; + double x = m_topLeft.x(); + double y = m_topLeft.y(); + moveTo( KoPoint( x + rx, y ) ); + curveTo( KoPoint( x + rx * ( 1 - 0.552 ), y ), + KoPoint( x, y - ry * ( 1 - 0.552 ) ), + KoPoint( x, y - ry ) ); + if( ry < m_height / 2 ) + lineTo( KoPoint( x, y - m_height + ry ) ); + curveTo( KoPoint( x, y - m_height + ry * ( 1 - 0.552 ) ), + KoPoint( x + rx * ( 1 - 0.552 ), y - m_height ), + KoPoint( x + rx, y - m_height ) ); + if( rx < m_width / 2 ) + lineTo( KoPoint( x + m_width - rx, y - m_height ) ); + curveTo( KoPoint( x + m_width - rx * ( 1 - 0.552 ), y - m_height ), + KoPoint( x + m_width, y - m_height + ry * ( 1 - 0.552 ) ), + KoPoint( x + m_width, y - m_height + ry ) ); + if( ry < m_height / 2 ) + lineTo( KoPoint( x + m_width, y - ry ) ); + curveTo( KoPoint( x + m_width, y - ry * ( 1 - 0.552 ) ), + KoPoint( x + m_width - rx * ( 1 - 0.552 ), y ), + KoPoint( x + m_width - rx, y ) ); + if( rx < m_width / 2 ) + lineTo( KoPoint( x + rx, y ) ); + } + close(); +} + +QString +VRectangle::name() const +{ + QString result = VObject::name(); + return !result.isEmpty() ? result : i18n( "Rectangle" ); +} + +void +VRectangle::save( QDomElement& element ) const +{ + VDocument *doc = document(); + if( doc && doc->saveAsPath() ) + { + VPath::save( element ); + return; + } + + if( state() != deleted ) + { + QDomElement me = element.ownerDocument().createElement( "RECT" ); + element.appendChild( me ); + + // save fill/stroke untransformed + VPath path( *this ); + VTransformCmd cmd( 0L, m_matrix.invert() ); + cmd.visit( path ); + path.VObject::save( me ); + //VObject::save( me ); + + me.setAttribute( "x", m_topLeft.x() ); + me.setAttribute( "y", m_topLeft.y() ); + + me.setAttribute( "width", QString("%1pt").arg( m_width ) ); + me.setAttribute( "height", QString("%1pt").arg( m_height ) ); + + me.setAttribute( "rx", m_rx ); + me.setAttribute( "ry", m_ry ); + + QString transform = buildSvgTransform(); + if( !transform.isEmpty() ) + me.setAttribute( "transform", transform ); + } +} + +void +VRectangle::saveOasis( KoStore *store, KoXmlWriter *docWriter, KoGenStyles &mainStyles, int &index ) const +{ + // do not save deleted objects + if( state() == deleted ) + return; + + // different rx/ry is not supported by oasis, so act like it is a normal path + if( m_rx != 0. && m_ry != 0. && m_rx != m_ry ) + return VPath::saveOasis( store, docWriter, mainStyles, index ); + + docWriter->startElement( "draw:rect" ); + + //save all into pt + docWriter->addAttributePt( "svg:x", m_topLeft.x() ); + docWriter->addAttributePt( "svg:y", m_topLeft.y()-m_height ); + docWriter->addAttributePt( "svg:width", m_width ); + docWriter->addAttributePt( "svg:height", m_height ); + + if( m_rx != 0. && m_ry != 0. && m_rx == m_ry ) + docWriter->addAttributePt( "draw:corner-radius", m_rx ); + + VObject::saveOasis( store, docWriter, mainStyles, index ); + + QWMatrix tmpMat; + tmpMat.scale( 1, -1 ); + tmpMat.translate( 0, -document()->height() ); + + QString transform = buildOasisTransform( m_matrix*tmpMat ); + if( !transform.isEmpty() ) + docWriter->addAttribute( "draw:transform", transform ); + + docWriter->endElement(); +} + +bool +VRectangle::loadOasis( const QDomElement &element, KoOasisLoadingContext &context ) +{ + setState( normal ); + + m_width = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "width", QString::null ), 10.0 ); + m_height = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "height", QString::null ), 10.0 ); + + m_topLeft.setX( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x", QString::null ) ) ); + m_topLeft.setY( m_height + KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y", QString::null ) ) ); + + m_rx = m_ry = KoUnit::parseValue( element.attributeNS( KoXmlNS::draw, "corner-radius", QString::null ) ); + + init(); + + transformByViewbox( element, element.attributeNS( KoXmlNS::svg, "viewBox", QString::null ) ); + + QString trafo = element.attributeNS( KoXmlNS::draw, "transform", QString::null ); + if( !trafo.isEmpty() ) + transformOasis( trafo ); + + return VObject::loadOasis( element, context ); +} + +void +VRectangle::load( const QDomElement& element ) +{ + setState( normal ); + + QDomNodeList list = element.childNodes(); + for( uint i = 0; i < list.count(); ++i ) + if( list.item( i ).isElement() ) + VObject::load( list.item( i ).toElement() ); + + m_width = KoUnit::parseValue( element.attribute( "width" ), 10.0 ); + m_height = KoUnit::parseValue( element.attribute( "height" ), 10.0 ); + + m_topLeft.setX( KoUnit::parseValue( element.attribute( "x" ) ) ); + m_topLeft.setY( KoUnit::parseValue( element.attribute( "y" ) ) ); + + m_rx = KoUnit::parseValue( element.attribute( "rx" ) ); + m_ry = KoUnit::parseValue( element.attribute( "ry" ) ); + + init(); + + QString trafo = element.attribute( "transform" ); + if( !trafo.isEmpty() ) + transform( trafo ); +} + +VPath* +VRectangle::clone() const +{ + return new VRectangle( *this ); +} diff --git a/karbon/shapes/vrectangle.h b/karbon/shapes/vrectangle.h new file mode 100644 index 00000000..04bd20d0 --- /dev/null +++ b/karbon/shapes/vrectangle.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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. +*/ + +#ifndef __VRECTANGLE_H__ +#define __VRECTANGLE_H__ + +#include "vcomposite.h" +#include <koffice_export.h> + +class KARBONBASE_EXPORT VRectangle : public VPath +{ +public: + VRectangle( VObject* parent, VState state = edit ); + VRectangle( VObject* parent, + const KoPoint& topLeft, double width, double height, double rx = 0.0, double ry = 0.0 ); + + virtual QString name() const; + + virtual void save( QDomElement& element ) const; + virtual void saveOasis( KoStore *store, KoXmlWriter *docWriter, KoGenStyles &mainStyles, int &index ) const; + virtual void load( const QDomElement& element ); + virtual bool loadOasis( const QDomElement &element, KoOasisLoadingContext &context ); + + virtual VPath* clone() const; + +protected: + void init(); + +private: + KoPoint m_topLeft; + double m_width; + double m_height; + double m_rx; + double m_ry; +}; + +#endif + diff --git a/karbon/shapes/vsinus.cc b/karbon/shapes/vsinus.cc new file mode 100644 index 00000000..a6c9ec4f --- /dev/null +++ b/karbon/shapes/vsinus.cc @@ -0,0 +1,206 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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 <qwmatrix.h> + +#include "vglobal.h" +#include "vsinus.h" +#include "vtransformcmd.h" +#include <klocale.h> +#include <KoUnit.h> +#include <qdom.h> +#include <vdocument.h> + +VSinus::VSinus( VObject* parent, VState state ) + : VPath( parent, state ) +{ +} + +VSinus::VSinus( VObject* parent, + const KoPoint& topLeft, double width, double height, uint periods ) + : VPath( parent ), m_topLeft( topLeft ), m_width( width), m_height( height ), m_periods( periods ) +{ + // We want at least 1 period: + if( m_periods < 1 ) + m_periods = 1; + init(); +} + +void +VSinus::init() +{ + KoPoint p1; + KoPoint p2; + KoPoint p3( 0.0, 0.0 ); + moveTo( p3 ); + + for ( uint i = 0; i < m_periods; ++i ) + { + p1.setX( i + 1.0/24.0 ); + p1.setY( ( 2.0 * VGlobal::sqrt2 - 1.0 ) * VGlobal::one_7 ); + p2.setX( i + 1.0/12.0 ); + p2.setY( ( 4.0 * VGlobal::sqrt2 - 2.0 ) * VGlobal::one_7 ); + p3.setX( i + 1.0/8.0 ); + p3.setY( VGlobal::sqrt2 * 0.5 ); + curveTo( p1, p2, p3 ); + + p1.setX( i + 1.0/6.0 ); + p1.setY( ( 3.0 * VGlobal::sqrt2 + 2.0 ) * VGlobal::one_7 ); + p2.setX( i + 5.0/24.0 ); + p2.setY( 1.0 ); + p3.setX( i + 1.0/4.0 ); + p3.setY( 1.0 ); + curveTo( p1, p2, p3 ); + + p1.setX( i + 7.0/24.0 ); + p1.setY( 1.0 ); + p2.setX( i + 1.0/3.0 ); + p2.setY( ( 3.0 * VGlobal::sqrt2 + 2.0 ) * VGlobal::one_7 ); + p3.setX( i + 3.0/8.0 ); + p3.setY( VGlobal::sqrt2 * 0.5 ); + curveTo( p1, p2, p3 ); + + p1.setX( i + 5.0/12.0 ); + p1.setY( ( 4.0 * VGlobal::sqrt2 - 2.0 ) * VGlobal::one_7 ); + p2.setX( i + 11.0/24.0 ); + p2.setY( ( 2.0 * VGlobal::sqrt2 - 1.0 ) * VGlobal::one_7 ); + p3.setX( i + 1.0/2.0 ); + p3.setY( 0.0 ); + curveTo( p1, p2, p3 ); + + p1.setX( i + 13.0/24.0 ); + p1.setY( -( 2.0 * VGlobal::sqrt2 - 1.0 ) * VGlobal::one_7 ); + p2.setX( i + 7.0/12.0 ); + p2.setY( -( 4.0 * VGlobal::sqrt2 - 2.0 ) * VGlobal::one_7 ); + p3.setX( i + 5.0/8.0 ); + p3.setY( -VGlobal::sqrt2 * 0.5 ); + curveTo( p1, p2, p3 ); + + p1.setX( i + 2.0/3.0 ); + p1.setY( -( 3.0 * VGlobal::sqrt2 + 2.0 ) * VGlobal::one_7 ); + p2.setX( i + 17.0/24.0 ); + p2.setY( -1.0 ); + p3.setX( i + 3.0/4.0 ); + p3.setY( -1.0 ); + curveTo( p1, p2, p3 ); + + p1.setX( i + 19.0/24.0 ); + p1.setY( -1.0 ); + p2.setX( i + 5.0/6.0 ); + p2.setY( -( 3.0 * VGlobal::sqrt2 + 2.0 ) * VGlobal::one_7 ); + p3.setX( i + 7.0/8.0 ); + p3.setY( -VGlobal::sqrt2 * 0.5 ); + curveTo( p1, p2, p3 ); + + p1.setX( i + 11.0/12.0 ); + p1.setY( -( 4.0 * VGlobal::sqrt2 - 2.0 ) * VGlobal::one_7 ); + p2.setX( i + 23.0/24.0 ); + p2.setY( -( 2.0 * VGlobal::sqrt2 - 1.0 ) * VGlobal::one_7 ); + p3.setX( i + 1.0 ); + p3.setY( 0.0 ); + curveTo( p1, p2, p3 ); + } + + // Translate and scale: + QWMatrix m; + m.translate( m_topLeft.x(), m_topLeft.y() - m_height * 0.5 ); + m.scale( m_width / m_periods, m_height * 0.5 ); + + // only tranform the path data + VTransformCmd cmd( 0L, m ); + cmd.VVisitor::visitVPath( *this ); + + m_matrix.reset(); +} + +QString +VSinus::name() const +{ + QString result = VObject::name(); + return !result.isEmpty() ? result : i18n( "Sinus" ); +} + +void +VSinus::save( QDomElement& element ) const +{ + VDocument *doc = document(); + if( doc && doc->saveAsPath() ) + { + VPath::save( element ); + return; + } + + if( state() != deleted ) + { + QDomElement me = element.ownerDocument().createElement( "SINUS" ); + element.appendChild( me ); + + // save fill/stroke untransformed + VPath path( *this ); + VTransformCmd cmd( 0L, m_matrix.invert() ); + cmd.visit( path ); + path.VObject::save( me ); + //VObject::save( me ); + + me.setAttribute( "x", m_topLeft.x() ); + me.setAttribute( "y", m_topLeft.y() ); + + me.setAttribute( "width", m_width ); + me.setAttribute( "height", m_height ); + + me.setAttribute( "periods", m_periods ); + + QString transform = buildSvgTransform(); + if( !transform.isEmpty() ) + me.setAttribute( "transform", transform ); + } +} + +void +VSinus::load( const QDomElement& element ) +{ + setState( normal ); + + QDomNodeList list = element.childNodes(); + for( uint i = 0; i < list.count(); ++i ) + if( list.item( i ).isElement() ) + VObject::load( list.item( i ).toElement() ); + + m_width = KoUnit::parseValue( element.attribute( "width" ), 10.0 ); + m_height = KoUnit::parseValue( element.attribute( "height" ), 10.0 ); + + m_topLeft.setX( KoUnit::parseValue( element.attribute( "x" ) ) ); + m_topLeft.setY( KoUnit::parseValue( element.attribute( "y" ) ) ); + + m_periods = element.attribute( "periods" ).toUInt(); + + init(); + + QString trafo = element.attribute( "transform" ); + if( !trafo.isEmpty() ) + transform( trafo ); +} + +VPath* +VSinus::clone() const +{ + return new VSinus( *this ); +} + diff --git a/karbon/shapes/vsinus.h b/karbon/shapes/vsinus.h new file mode 100644 index 00000000..eb8d4f00 --- /dev/null +++ b/karbon/shapes/vsinus.h @@ -0,0 +1,51 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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. +*/ + +#ifndef __VSINUS_H__ +#define __VSINUS_H__ + +#include "vcomposite.h" +#include <koffice_export.h> + +class KARBONBASE_EXPORT VSinus : public VPath +{ +public: + VSinus( VObject* parent, VState state = edit ); + VSinus( VObject* parent, + const KoPoint& topLeft, double width, double height, uint periods ); + + virtual QString name() const; + + virtual void save( QDomElement& element ) const; + virtual void load( const QDomElement& element ); + + virtual VPath* clone() const; + +protected: + void init(); + +private: + KoPoint m_topLeft; + double m_width; + double m_height; + uint m_periods; +}; + +#endif + diff --git a/karbon/shapes/vspiral.cc b/karbon/shapes/vspiral.cc new file mode 100644 index 00000000..8f6d17c2 --- /dev/null +++ b/karbon/shapes/vspiral.cc @@ -0,0 +1,186 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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 <math.h> + +#include <qwmatrix.h> +#include <qdom.h> + +#include "vglobal.h" +#include "vspiral.h" +#include "vtransformcmd.h" +#include <klocale.h> +#include <KoUnit.h> +#include <vdocument.h> + +VSpiral::VSpiral( VObject* parent, VState state ) + : VPath( parent, state ) +{ +} + +VSpiral::VSpiral( VObject* parent, + const KoPoint& center, double radius, uint segments, double fade, + bool clockwise, double angle, VSpiralType type ) + : VPath( parent ), m_center( center), m_radius( radius ), m_fade( fade ), m_segments( segments ), m_clockwise( clockwise ), m_angle( angle ), m_type( type ) +{ + init(); +} + +void +VSpiral::init() +{ + // It makes sense to have at least one segment: + if( m_segments < 1 ) + m_segments = 1; + + // Make sure the radius is positive: + if( m_radius < 0.0 ) + m_radius = -m_radius; + + // Fall back, when fade is out of range: + if( m_fade <= 0.0 || m_fade >= 1.0 ) + m_fade = 0.5; + + setFillRule( winding ); + + // advance by pi/2 clockwise or cclockwise? + double adv_ang = ( m_clockwise ? -1.0 : 1.0 ) * VGlobal::pi_2; + // radius of first segment is non-faded radius: + double r = m_radius; + + KoPoint oldP( 0.0, ( m_clockwise ? -1.0 : 1.0 ) * m_radius ); + KoPoint newP; + KoPoint newCenter( 0.0, 0.0 ); + moveTo( oldP ); + + for ( uint i = 0; i < m_segments; ++i ) + { + newP.setX( r * cos( adv_ang * ( i + 2 ) ) + newCenter.x() ); + newP.setY( r * sin( adv_ang * ( i + 2 ) ) + newCenter.y() ); + + if( m_type == round ) + arcTo( oldP + newP - newCenter, newP, r ); + else + lineTo( newP ); + + newCenter += ( newP - newCenter ) * ( 1.0 - m_fade ); + oldP = newP; + r *= m_fade; + } + + // translate path to center: + QWMatrix m; + m.translate( m_center.x(), m_center.y() ); + + // sadly it's not feasible to simply add angle while creation. + m.rotate( + ( m_angle + ( m_clockwise ? VGlobal::pi : 0.0 ) ) * // make cw-spiral start at mouse-pointer + VGlobal::one_pi_180 ); // one_pi_180 = 1/(pi/180) = 180/pi. + + // only tranform the path data + VTransformCmd cmd( 0L, m ); + cmd.VVisitor::visitVPath( *this ); + + m_matrix.reset(); +} + +QString +VSpiral::name() const +{ + QString result = VObject::name(); + return !result.isEmpty() ? result : i18n( "Spiral" ); +} + +void +VSpiral::save( QDomElement& element ) const +{ + VDocument *doc = document(); + if( doc && doc->saveAsPath() ) + { + VPath::save( element ); + return; + } + + if( state() != deleted ) + { + QDomElement me = element.ownerDocument().createElement( "SPIRAL" ); + element.appendChild( me ); + + // save fill/stroke untransformed + VPath path( *this ); + VTransformCmd cmd( 0L, m_matrix.invert() ); + cmd.visit( path ); + path.VObject::save( me ); + //VObject::save( me ); + + me.setAttribute( "cx", m_center.x() ); + me.setAttribute( "cy", m_center.y() ); + + me.setAttribute( "radius", m_radius ); + me.setAttribute( "angle", m_angle ); + me.setAttribute( "fade", m_fade ); + + me.setAttribute( "segments", m_segments ); + + me.setAttribute( "clockwise", m_clockwise ); + + me.setAttribute( "type", m_type ); + + QString transform = buildSvgTransform(); + if( !transform.isEmpty() ) + me.setAttribute( "transform", transform ); + } +} + +void +VSpiral::load( const QDomElement& element ) +{ + setState( normal ); + + QDomNodeList list = element.childNodes(); + for( uint i = 0; i < list.count(); ++i ) + if( list.item( i ).isElement() ) + VObject::load( list.item( i ).toElement() ); + + m_radius = KoUnit::parseValue( element.attribute( "radius" ) ); + m_angle = element.attribute( "angle" ).toDouble(); + m_fade = element.attribute( "fade" ).toDouble(); + + m_center.setX( KoUnit::parseValue( element.attribute( "cx" ) ) ); + m_center.setY( KoUnit::parseValue( element.attribute( "cy" ) ) ); + + m_segments = element.attribute( "segments" ).toUInt(), + + m_clockwise = element.attribute( "clockwise" ).toInt(); + + m_type = (VSpiral::VSpiralType)element.attribute( "type" ).toInt(); + + init(); + + QString trafo = element.attribute( "transform" ); + if( !trafo.isEmpty() ) + transform( trafo ); +} + +VPath* +VSpiral::clone() const +{ + return new VSpiral( *this ); +} diff --git a/karbon/shapes/vspiral.h b/karbon/shapes/vspiral.h new file mode 100644 index 00000000..2b80f6ad --- /dev/null +++ b/karbon/shapes/vspiral.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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. +*/ + +#ifndef __VSPIRAL_H__ +#define __VSPIRAL_H__ + +#include "vcomposite.h" +#include <koffice_export.h> + +class KARBONBASE_EXPORT VSpiral : public VPath +{ +public: + enum VSpiralType + { + round, + rectangular + }; + VSpiral( VObject* parent, VState state = edit ); + VSpiral( VObject* parent, + const KoPoint& center, double radius, uint segments, + double fade, bool clockwise, double angle = 0.0, VSpiralType type = round ); + + virtual QString name() const; + + virtual void save( QDomElement& element ) const; + virtual void load( const QDomElement& element ); + + virtual VPath* clone() const; + +protected: + void init(); + +private: + KoPoint m_center; + double m_radius; + double m_fade; + uint m_segments; + bool m_clockwise; + double m_angle; + VSpiralType m_type; +}; + +#endif + diff --git a/karbon/shapes/vstar.cc b/karbon/shapes/vstar.cc new file mode 100644 index 00000000..98391272 --- /dev/null +++ b/karbon/shapes/vstar.cc @@ -0,0 +1,348 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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 <math.h> + +#include <qwmatrix.h> +#include <qdom.h> + +#include "vglobal.h" +#include "vstar.h" +#include "vtransformcmd.h" +#include <klocale.h> +#include <KoUnit.h> +#include <vdocument.h> + +VStar::VStar( VObject* parent, VState state ) + : VPath( parent, state ) +{ +} + +VStar::VStar( VObject* parent, + const KoPoint& center, double outerRadius, double innerRadius, + uint edges, double angle, uint innerAngle, double roundness, VStarType type ) + : VPath( parent ), m_center( center), m_outerRadius( outerRadius ), m_innerRadius( innerRadius), m_edges( edges ), m_angle( angle ), m_innerAngle( innerAngle ), m_roundness( roundness ), m_type( type ) +{ + init(); +} + +void +VStar::init() +{ + double angle = m_angle; + + // A star should have at least 3 edges: + if( m_edges < 3 ) + m_edges = 3; + + // Make sure, radii are positive: + if( m_outerRadius < 0.0 ) + m_outerRadius = -m_outerRadius; + + if( m_innerRadius < 0.0 ) + m_innerRadius = -m_innerRadius; + + // trick for spoke, wheel (libart bug?) + if( m_type == spoke || m_type == wheel && m_roundness == 0.0 ) + m_roundness = 0.01; + + // We start at angle + VGlobal::pi_2: + KoPoint p2, p3; + KoPoint p( + m_outerRadius * cos( angle + VGlobal::pi_2 ), + m_outerRadius * sin( angle + VGlobal::pi_2 ) ); + moveTo( p ); + + double inAngle = VGlobal::twopi / 360 * m_innerAngle; + + if( m_type == star ) + { + int j = ( m_edges % 2 == 0 ) ? ( m_edges - 2 ) / 2 : ( m_edges - 1 ) / 2; + //innerRadius = getOptimalInnerRadius( outerRadius, edges, innerAngle ); + int jumpto = 0; + bool discontinueous = ( m_edges % 4 == 2 ); + + double outerRoundness = ( VGlobal::twopi * m_outerRadius * m_roundness ) / m_edges; + double nextOuterAngle; + + for ( uint i = 1; i < m_edges + 1; ++i ) + { + double nextInnerAngle = angle + inAngle + VGlobal::pi_2 + VGlobal::twopi / m_edges * ( jumpto + 0.5 ); + p.setX( m_innerRadius * cos( nextInnerAngle ) ); + p.setY( m_innerRadius * sin( nextInnerAngle ) ); + if( m_roundness == 0.0 ) + lineTo( p ); + else + { + nextOuterAngle = angle + VGlobal::pi_2 + VGlobal::twopi / m_edges * jumpto; + p2.setX( m_outerRadius * cos( nextOuterAngle ) - + cos( angle + VGlobal::twopi / m_edges * jumpto ) * outerRoundness ); + p2.setY( m_outerRadius * sin( nextOuterAngle ) - + sin( angle + VGlobal::twopi / m_edges * jumpto ) * outerRoundness ); + + curveTo( p2, p, p ); + } + + jumpto = ( i * j ) % m_edges; + nextInnerAngle = angle + inAngle + VGlobal::pi_2 + VGlobal::twopi / m_edges * ( jumpto - 0.5 ); + p.setX( m_innerRadius * cos( nextInnerAngle ) ); + p.setY( m_innerRadius * sin( nextInnerAngle ) ); + lineTo( p ); + + nextOuterAngle = angle + VGlobal::pi_2 + VGlobal::twopi / m_edges * jumpto; + p.setX( m_outerRadius * cos( nextOuterAngle ) ); + p.setY( m_outerRadius * sin( nextOuterAngle ) ); + + if( m_roundness == 0.0 ) + lineTo( p ); + else + { + p2.setX( m_innerRadius * cos( nextInnerAngle ) ); + p2.setY( m_innerRadius * sin( nextInnerAngle ) ); + + p3.setX( m_outerRadius * cos( nextOuterAngle ) + + cos( angle + VGlobal::twopi / m_edges * jumpto ) * outerRoundness ); + p3.setY( m_outerRadius * sin( nextOuterAngle ) + + sin( angle + VGlobal::twopi / m_edges * jumpto ) * outerRoundness ); + + curveTo( p2, p3, p ); + } + if( discontinueous && i == ( m_edges / 2 ) ) + { + angle += VGlobal::pi; + nextOuterAngle = angle + VGlobal::pi_2 + VGlobal::twopi / m_edges * jumpto; + p.setX( m_outerRadius * cos( nextOuterAngle ) ); + p.setY( m_outerRadius * sin( nextOuterAngle ) ); + moveTo( p ); + } + } + } + else + { + if( m_type == wheel || m_type == spoke ) + m_innerRadius = 0.0; + + double innerRoundness = ( VGlobal::twopi * m_innerRadius * m_roundness ) / m_edges; + double outerRoundness = ( VGlobal::twopi * m_outerRadius * m_roundness ) / m_edges; + + for ( uint i = 0; i < m_edges; ++i ) + { + double nextOuterAngle = angle + VGlobal::pi_2 + VGlobal::twopi / m_edges * ( i + 1.0 ); + double nextInnerAngle = angle + inAngle + VGlobal::pi_2 + VGlobal::twopi / m_edges * ( i + 0.5 ); + if( m_type != polygon ) + { + p.setX( m_innerRadius * cos( nextInnerAngle ) ); + p.setY( m_innerRadius * sin( nextInnerAngle ) ); + + if( m_roundness == 0.0 ) + lineTo( p ); + else + { + p2.setX( m_outerRadius * + cos( angle + VGlobal::pi_2 + VGlobal::twopi / m_edges * ( i ) ) - + cos( angle + VGlobal::twopi / m_edges * ( i ) ) * outerRoundness ); + p2.setY( m_outerRadius * + sin( angle + VGlobal::pi_2 + VGlobal::twopi / m_edges * ( i ) ) - + sin( angle + VGlobal::twopi / m_edges * ( i ) ) * outerRoundness ); + + p3.setX( m_innerRadius * cos( nextInnerAngle ) + + cos( angle + inAngle + VGlobal::twopi / m_edges * ( i + 0.5 ) ) * innerRoundness ); + p3.setY( m_innerRadius * sin( nextInnerAngle ) + + sin( angle + inAngle + VGlobal::twopi / m_edges * ( i + 0.5 ) ) * innerRoundness ); + + if( m_type == gear ) + { + lineTo( p2 ); + lineTo( p3 ); + lineTo( p ); + } + else + curveTo( p2, p3, p ); + } + } + + p.setX( m_outerRadius * cos( nextOuterAngle ) ); + p.setY( m_outerRadius * sin( nextOuterAngle ) ); + + if( m_roundness == 0.0 ) + lineTo( p ); + else + { + p2.setX( m_innerRadius * cos( nextInnerAngle ) - + cos( angle + inAngle + VGlobal::twopi / m_edges * ( i + 0.5 ) ) * innerRoundness ); + p2.setY( m_innerRadius * sin( nextInnerAngle ) - + sin( angle + inAngle + VGlobal::twopi / m_edges * ( i + 0.5 ) ) * innerRoundness ); + + p3.setX( m_outerRadius * cos( nextOuterAngle ) + + cos( angle + VGlobal::twopi / m_edges * ( i + 1.0 ) ) * outerRoundness ); + p3.setY( m_outerRadius * sin( nextOuterAngle ) + + sin( angle + VGlobal::twopi / m_edges * ( i + 1.0 ) ) * outerRoundness ); + + if( m_type == gear ) + { + lineTo( p2 ); + lineTo( p3 ); + lineTo( p ); + } + else + curveTo( p2, p3, p ); + } + } + } + if( m_type == wheel || m_type == framed_star ) + { + close(); + for ( int i = m_edges - 1; i >= 0; --i ) + { + double nextOuterAngle = angle + VGlobal::pi_2 + VGlobal::twopi / m_edges * ( i + 1.0 ); + p.setX( m_outerRadius * cos( nextOuterAngle ) ); + p.setY( m_outerRadius * sin( nextOuterAngle ) ); + lineTo( p ); + } + } + close(); + + // translate path to center: + QWMatrix m; + m.translate( m_center.x(), m_center.y() ); + + // only tranform the path data + VTransformCmd cmd( 0L, m ); + cmd.VVisitor::visitVPath( *this ); + + setFillRule( evenOdd ); + + m_matrix.reset(); +} + +double +VStar::getOptimalInnerRadius( uint edges, double outerRadius, uint /*innerAngle*/ ) +{ + int j = (edges % 2 == 0 ) ? ( edges - 2 ) / 2 : ( edges - 1 ) / 2; + + // get two well chosen lines of the star + KoPoint p1( outerRadius * cos( VGlobal::pi_2 ), outerRadius * sin( VGlobal::pi_2 ) ); + int jumpto = ( j ) % edges; + double nextOuterAngle = VGlobal::pi_2 + VGlobal::twopi / edges * jumpto; + KoPoint p2( outerRadius * cos( nextOuterAngle ), outerRadius * sin( nextOuterAngle ) ); + + nextOuterAngle = VGlobal::pi_2 + VGlobal::twopi / edges; + KoPoint p3( outerRadius * cos( nextOuterAngle ), + outerRadius * sin( nextOuterAngle ) ); + jumpto = ( edges - j + 1 ) % edges; + nextOuterAngle = VGlobal::pi_2 + VGlobal::twopi / edges * jumpto; + KoPoint p4( outerRadius * cos( nextOuterAngle ), outerRadius * sin( nextOuterAngle ) ); + + // calc (x, y) -> intersection point + double b1 = ( p2.y() - p1.y() ) / ( p2.x() - p1.x() ); + double b2 = ( p4.y() - p3.y() ) / ( p4.x() - p3.x() ); + double a1 = p1.y() - b1 * p1.x(); + double a2 = p3.y() - b2 * p3.x(); + double x = -( a1 - a2 ) / ( b1 - b2 ); + double y = a1 + b1 * x; + // calc inner radius from intersection point and center + return sqrt( x * x + y * y ); +} + +QString +VStar::name() const +{ + QString result = VObject::name(); + return !result.isEmpty() ? result : i18n( "Star" ); +} + +void +VStar::save( QDomElement& element ) const +{ + VDocument *doc = document(); + if( doc && doc->saveAsPath() ) + { + VPath::save( element ); + return; + } + + if( state() != deleted ) + { + QDomElement me = element.ownerDocument().createElement( "STAR" ); + element.appendChild( me ); + + // save fill/stroke untransformed + VPath path( *this ); + VTransformCmd cmd( 0L, m_matrix.invert() ); + cmd.visit( path ); + path.VObject::save( me ); + //VObject::save( me ); + + me.setAttribute( "cx", m_center.x() ); + me.setAttribute( "cy", m_center.y() ); + + me.setAttribute( "outerradius", m_outerRadius ); + me.setAttribute( "innerradius", m_innerRadius ); + me.setAttribute( "edges", m_edges ); + + me.setAttribute( "angle", m_angle ); + me.setAttribute( "innerangle", m_innerAngle ); + + me.setAttribute( "roundness", m_roundness ); + + me.setAttribute( "type", m_type ); + + QString transform = buildSvgTransform(); + if( !transform.isEmpty() ) + me.setAttribute( "transform", transform ); + } +} + +void +VStar::load( const QDomElement& element ) +{ + setState( normal ); + + QDomNodeList list = element.childNodes(); + for( uint i = 0; i < list.count(); ++i ) + if( list.item( i ).isElement() ) + VObject::load( list.item( i ).toElement() ); + + m_center.setX( KoUnit::parseValue( element.attribute( "cx" ) ) ); + m_center.setY( KoUnit::parseValue( element.attribute( "cy" ) ) ); + + m_outerRadius = KoUnit::parseValue( element.attribute( "outerradius" ) ); + m_innerRadius = KoUnit::parseValue( element.attribute( "innerradius" ) ); + m_edges = element.attribute( "edges" ).toUInt(); + + m_innerAngle = element.attribute( "innerangle" ).toUInt(); + m_angle = element.attribute( "angle" ).toDouble(); + + m_roundness = element.attribute( "roundness" ).toDouble(); + + m_type =(VStar::VStarType) element.attribute( "type" ).toInt(); + + init(); + + QString trafo = element.attribute( "transform" ); + if( !trafo.isEmpty() ) + transform( trafo ); +} + +VPath* +VStar::clone() const +{ + return new VStar( *this ); +} diff --git a/karbon/shapes/vstar.h b/karbon/shapes/vstar.h new file mode 100644 index 00000000..7b7ec098 --- /dev/null +++ b/karbon/shapes/vstar.h @@ -0,0 +1,91 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 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. +*/ + +#ifndef __VSTAR_H__ +#define __VSTAR_H__ + +#include "vcomposite.h" +#include <koffice_export.h> +/** + * This shape offers star-like shapes with a lot of parameters : + * + * Types : + * + * Star - fully connected star shape. + * Star outline - like star but without the cross connections. + * Framed star - like star outline but with an enclosing path. + * Spoke - basically a star outline with inner radius of zero. + * Wheel - like spoke but with enclosing path. + * Polygon - like VPolygon. + * Gear - variant on star outline, resembling the KDE gear. + * + * Parameters : + * + * Edges - number of edges, which must be greater or equal to 3. + * Outer radius - radius amount of circumcircle of the star. + * Inner radius - inner radius where star has to connect to. This value + * doesn't apply to polygon, spoke and wheel. + * Inner angle - extra radius amount for inner radius. + * Roundness - uses curves instead of lines for the star shape. + */ +class KARBONBASE_EXPORT VStar : public VPath +{ +public: + enum VStarType + { + star_outline, + spoke, + wheel, + polygon, + framed_star, + star, + gear + }; + VStar( VObject* parent, VState state = edit ); + VStar( VObject* parent, + const KoPoint& center, double outerRadius, double innerRadius, + uint edges, double angle = 0.0, uint innerAngle = 0, + double roundness = 0.0, VStarType type = star_outline ); + + static double getOptimalInnerRadius( uint edges, double outerRadius, uint innerAngle ); + + virtual QString name() const; + + + virtual void save( QDomElement& element ) const; + virtual void load( const QDomElement& element ); + + virtual VPath* clone() const; + +protected: + void init(); + +private: + KoPoint m_center; + double m_outerRadius; + double m_innerRadius; + uint m_edges; + double m_angle; + double m_innerAngle; + double m_roundness; + VStarType m_type; +}; + +#endif + |