karbon
vspiral.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <math.h>
00022
00023 #include <qwmatrix.h>
00024 #include <qdom.h>
00025
00026 #include "vglobal.h"
00027 #include "vspiral.h"
00028 #include "vtransformcmd.h"
00029 #include <klocale.h>
00030 #include <KoUnit.h>
00031 #include <vdocument.h>
00032
00033 VSpiral::VSpiral( VObject* parent, VState state )
00034 : VPath( parent, state )
00035 {
00036 }
00037
00038 VSpiral::VSpiral( VObject* parent,
00039 const KoPoint& center, double radius, uint segments, double fade,
00040 bool clockwise, double angle, VSpiralType type )
00041 : VPath( parent ), m_center( center), m_radius( radius ), m_fade( fade ), m_segments( segments ), m_clockwise( clockwise ), m_angle( angle ), m_type( type )
00042 {
00043 init();
00044 }
00045
00046 void
00047 VSpiral::init()
00048 {
00049
00050 if( m_segments < 1 )
00051 m_segments = 1;
00052
00053
00054 if( m_radius < 0.0 )
00055 m_radius = -m_radius;
00056
00057
00058 if( m_fade <= 0.0 || m_fade >= 1.0 )
00059 m_fade = 0.5;
00060
00061 setFillRule( winding );
00062
00063
00064 double adv_ang = ( m_clockwise ? -1.0 : 1.0 ) * VGlobal::pi_2;
00065
00066 double r = m_radius;
00067
00068 KoPoint oldP( 0.0, ( m_clockwise ? -1.0 : 1.0 ) * m_radius );
00069 KoPoint newP;
00070 KoPoint newCenter( 0.0, 0.0 );
00071 moveTo( oldP );
00072
00073 for ( uint i = 0; i < m_segments; ++i )
00074 {
00075 newP.setX( r * cos( adv_ang * ( i + 2 ) ) + newCenter.x() );
00076 newP.setY( r * sin( adv_ang * ( i + 2 ) ) + newCenter.y() );
00077
00078 if( m_type == round )
00079 arcTo( oldP + newP - newCenter, newP, r );
00080 else
00081 lineTo( newP );
00082
00083 newCenter += ( newP - newCenter ) * ( 1.0 - m_fade );
00084 oldP = newP;
00085 r *= m_fade;
00086 }
00087
00088
00089 QWMatrix m;
00090 m.translate( m_center.x(), m_center.y() );
00091
00092
00093 m.rotate(
00094 ( m_angle + ( m_clockwise ? VGlobal::pi : 0.0 ) ) *
00095 VGlobal::one_pi_180 );
00096
00097
00098 VTransformCmd cmd( 0L, m );
00099 cmd.VVisitor::visitVPath( *this );
00100
00101 m_matrix.reset();
00102 }
00103
00104 QString
00105 VSpiral::name() const
00106 {
00107 QString result = VObject::name();
00108 return !result.isEmpty() ? result : i18n( "Spiral" );
00109 }
00110
00111 void
00112 VSpiral::save( QDomElement& element ) const
00113 {
00114 VDocument *doc = document();
00115 if( doc && doc->saveAsPath() )
00116 {
00117 VPath::save( element );
00118 return;
00119 }
00120
00121 if( state() != deleted )
00122 {
00123 QDomElement me = element.ownerDocument().createElement( "SPIRAL" );
00124 element.appendChild( me );
00125
00126
00127 VPath path( *this );
00128 VTransformCmd cmd( 0L, m_matrix.invert() );
00129 cmd.visit( path );
00130 path.VObject::save( me );
00131
00132
00133 me.setAttribute( "cx", m_center.x() );
00134 me.setAttribute( "cy", m_center.y() );
00135
00136 me.setAttribute( "radius", m_radius );
00137 me.setAttribute( "angle", m_angle );
00138 me.setAttribute( "fade", m_fade );
00139
00140 me.setAttribute( "segments", m_segments );
00141
00142 me.setAttribute( "clockwise", m_clockwise );
00143
00144 me.setAttribute( "type", m_type );
00145
00146 QString transform = buildSvgTransform();
00147 if( !transform.isEmpty() )
00148 me.setAttribute( "transform", transform );
00149 }
00150 }
00151
00152 void
00153 VSpiral::load( const QDomElement& element )
00154 {
00155 setState( normal );
00156
00157 QDomNodeList list = element.childNodes();
00158 for( uint i = 0; i < list.count(); ++i )
00159 if( list.item( i ).isElement() )
00160 VObject::load( list.item( i ).toElement() );
00161
00162 m_radius = KoUnit::parseValue( element.attribute( "radius" ) );
00163 m_angle = element.attribute( "angle" ).toDouble();
00164 m_fade = element.attribute( "fade" ).toDouble();
00165
00166 m_center.setX( KoUnit::parseValue( element.attribute( "cx" ) ) );
00167 m_center.setY( KoUnit::parseValue( element.attribute( "cy" ) ) );
00168
00169 m_segments = element.attribute( "segments" ).toUInt(),
00170
00171 m_clockwise = element.attribute( "clockwise" ).toInt();
00172
00173 m_type = (VSpiral::VSpiralType)element.attribute( "type" ).toInt();
00174
00175 init();
00176
00177 QString trafo = element.attribute( "transform" );
00178 if( !trafo.isEmpty() )
00179 transform( trafo );
00180 }
00181
00182 VPath*
00183 VSpiral::clone() const
00184 {
00185 return new VSpiral( *this );
00186 }
|