00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qdom.h>
00022
00023 #include <KoGenStyles.h>
00024 #include <KoStyleStack.h>
00025 #include <KoUnit.h>
00026 #include <KoXmlNS.h>
00027
00028 #include "vobject.h"
00029 #include "vstroke.h"
00030 #include <kdebug.h>
00031
00032 VStroke::VStroke()
00033 : m_parent(0L), m_lineWidth(1.0), m_lineCap(capButt), m_lineJoin(joinMiter), m_miterLimit(10.0), m_type(none)
00034 {}
00035
00036 VStroke::VStroke( VObject* parent, float width, const VLineCap cap, const VLineJoin join,
00037 float miterLimit )
00038 {
00039 m_parent = parent;
00040 m_type = solid;
00041 m_lineWidth = width;
00042 m_lineCap = cap;
00043 m_lineJoin = join;
00044 m_miterLimit = miterLimit;
00045 }
00046
00047 VStroke::VStroke( const VColor &c, VObject* parent, float width, const VLineCap cap, const VLineJoin join,
00048 float miterLimit )
00049 {
00050 m_parent = parent;
00051 m_type = solid;
00052 m_lineWidth = width;
00053 m_lineCap = cap;
00054 m_lineJoin = join;
00055 m_miterLimit = miterLimit;
00056 m_color = c;
00057 }
00058
00059 VStroke::VStroke( const VStroke& stroke )
00060 {
00061
00062 *this = stroke;
00063 }
00064
00065 void
00066 VStroke::setLineWidth( float width )
00067 {
00068 m_lineWidth = width;
00069
00070
00071 if( m_parent )
00072 m_parent->invalidateBoundingBox();
00073 }
00074
00075 void
00076 VStroke::save( QDomElement& element ) const
00077 {
00078 QDomElement me = element.ownerDocument().createElement( "STROKE" );
00079 element.appendChild( me );
00080
00081
00082 if( m_lineWidth != 1.0 )
00083 me.setAttribute( "lineWidth", m_lineWidth );
00084 if( !( m_lineCap == capButt ) )
00085 me.setAttribute( "lineCap", m_lineCap );
00086 if( !( m_lineJoin == joinMiter ) )
00087 me.setAttribute( "lineJoin", m_lineJoin );
00088 if( m_miterLimit != 10.0 )
00089 me.setAttribute( "miterLimit", m_miterLimit );
00090
00091 if( m_type == solid )
00092 {
00093
00094 m_color.save( me );
00095 }
00096 else if( m_type == grad )
00097 {
00098
00099 m_gradient.save( me );
00100 }
00101 else if( m_type == patt )
00102 {
00103
00104 m_pattern.save( me );
00105 }
00106
00107
00108 m_dashPattern.save( me );
00109 }
00110
00111 void
00112 VStroke::saveOasis( KoGenStyle &style ) const
00113 {
00114 if( m_type == solid )
00115 {
00116 style.addProperty( "draw:stroke", "solid" );
00117 style.addProperty( "svg:stroke-color", QColor( m_color ).name() );
00118 style.addPropertyPt( "svg:stroke-width", m_lineWidth );
00119 if( m_color.opacity() < 1 )
00120 style.addProperty( "svg:stroke-opacity", QString( "%1%" ).arg( m_color.opacity() * 100. ) );
00121 }
00122 else if( m_type == none )
00123 style.addProperty( "draw:stroke", "none" );
00124
00125
00126
00127
00128
00129 if( m_lineJoin == joinRound )
00130 style.addProperty( "draw:stroke-linejoin", "round" );
00131 else if( m_lineJoin == joinBevel )
00132 style.addProperty( "draw:stroke-linejoin", "bevel" );
00133 else if( m_lineJoin == joinMiter )
00134 style.addProperty( "draw:stroke-linejoin", "miter" );
00135 }
00136
00137 void
00138 VStroke::loadOasis( const KoStyleStack &stack )
00139 {
00140 if( stack.hasAttributeNS( KoXmlNS::draw, "stroke" ))
00141 {
00142 if( stack.attributeNS( KoXmlNS::draw, "stroke" ) == "solid" )
00143 {
00144 setType( VStroke::solid );
00145 setColor( QColor( stack.attributeNS( KoXmlNS::svg, "stroke-color" ) ) );
00146 if( stack.hasAttributeNS( KoXmlNS::svg, "stroke-opacity" ) )
00147 m_color.setOpacity( stack.attributeNS( KoXmlNS::svg, "stroke-opacity" ).remove( '%' ).toFloat() / 100. );
00148 QString join = stack.attributeNS( KoXmlNS::draw, "stroke-linejoin" );
00149 if( !join.isEmpty() )
00150 {
00151 if( join == "round" )
00152 m_lineJoin = joinRound;
00153 else if( join == "bevel" )
00154 m_lineJoin = joinBevel;
00155 else
00156 m_lineJoin = joinMiter;
00157 }
00158 }
00159 else if( stack.attributeNS( KoXmlNS::draw, "stroke" ) == "none" )
00160 setType( VStroke::none );
00161 }
00162 if( stack.hasAttributeNS( KoXmlNS::svg, "stroke-width" ) )
00163 m_lineWidth = KoUnit::parseValue( stack.attributeNS( KoXmlNS::svg, "stroke-width" ) );
00164 if( m_lineWidth < 0.0 )
00165 m_lineWidth = 0.0;
00166 }
00167
00168 void
00169 VStroke::load( const QDomElement& element )
00170 {
00171 m_type = none;
00172
00173 m_lineWidth = element.attribute( "lineWidth", "1.0" ).toDouble();
00174 if( m_lineWidth < 0.0 )
00175 m_lineWidth = 0.0;
00176
00177 switch( element.attribute( "lineCap", "0" ).toUShort() )
00178 {
00179 case 1:
00180 m_lineCap = capRound; break;
00181 case 2:
00182 m_lineCap = capSquare; break;
00183 default:
00184 m_lineCap = capButt;
00185 }
00186
00187 switch( element.attribute( "lineJoin", "0" ).toUShort() )
00188 {
00189 case 1:
00190 m_lineJoin = joinRound; break;
00191 case 2:
00192 m_lineJoin = joinBevel; break;
00193 default:
00194 m_lineJoin = joinMiter;
00195 }
00196
00197 m_miterLimit = element.attribute( "miterLimit", "10.0" ).toDouble();
00198 if( m_miterLimit < 0.0 )
00199 m_miterLimit = 0.0;
00200
00201
00202
00203 QDomNodeList list = element.childNodes();
00204 for( uint i = 0; i < list.count(); ++i )
00205 {
00206 if( list.item( i ).isElement() )
00207 {
00208 QDomElement e = list.item( i ).toElement();
00209 if( e.tagName() == "COLOR" )
00210 {
00211 m_color.load( e );
00212 m_type = solid;
00213 }
00214 else if( e.tagName() == "DASHPATTERN" )
00215 {
00216 m_dashPattern.load( e );
00217 }
00218 else if( e.tagName() == "GRADIENT" )
00219 {
00220 m_type = grad;
00221 m_gradient.load( e );
00222 }
00223 else if( e.tagName() == "PATTERN" )
00224 {
00225 m_type = patt;
00226 m_pattern.load( e );
00227 }
00228 }
00229 }
00230 }
00231
00232
00233 VStroke&
00234 VStroke::operator=( const VStroke& stroke )
00235 {
00236 if( this != &stroke )
00237 {
00238
00239 m_type = stroke.m_type;
00240
00241 m_lineWidth = stroke.m_lineWidth;
00242
00243
00244
00245
00246 m_lineCap = stroke.m_lineCap;
00247 m_lineJoin = stroke.m_lineJoin;
00248 m_miterLimit = stroke.m_miterLimit;
00249 m_color = stroke.m_color;
00250 m_dashPattern = stroke.m_dashPattern;
00251 m_gradient = stroke.m_gradient;
00252 m_pattern = stroke.m_pattern;
00253 }
00254
00255 return *this;
00256 }
00257
00258 void
00259 VStroke::transform( const QWMatrix& m )
00260 {
00261 if( type() == VStroke::grad )
00262 gradient().transform( m );
00263 else if( type() == VStroke::patt )
00264 pattern().transform( m );
00265 }