27#include <KoGenStyles.h>
28#include <KoXmlWriter.h>
31int VGradient::VColorStopList::compareItems( TQPtrCollection::Item item1, TQPtrCollection::Item item2 )
33 float r1 = ( (VColorStop*)item1 )->rampPoint;
34 float r2 = ( (VColorStop*)item2 )->rampPoint;
36 return ( r1 == r2 ? 0 : r1 < r2 ? -1 : 1 );
39VGradient::VGradient( VGradientType type )
42 m_colorStops.setAutoDelete(
true );
47 color.
set( 1.0, 0.0, 0.0 );
48 addStop( color, 0.0, 0.5 );
50 color.
set( 1.0, 1.0, 0.0 );
51 addStop( color, 1.0, 0.5 );
53 setOrigin( KoPoint( 0, 0 ) );
54 setVector( KoPoint( 0, 50 ) );
55 setRepeatMethod( VGradient::reflect );
58VGradient::VGradient(
const VGradient& gradient )
60 m_colorStops.setAutoDelete(
true );
62 m_origin = gradient.m_origin;
63 m_focalPoint = gradient.m_focalPoint;
64 m_vector = gradient.m_vector;
65 m_type = gradient.m_type;
66 m_repeatMethod = gradient.m_repeatMethod;
69 TQPtrVector<VColorStop> cs = gradient.colorStops();
70 for( uint i = 0; i < cs.count(); i++ )
71 m_colorStops.append(
new VColorStop( *cs[i] ) );
75VGradient& VGradient::operator=(
const VGradient& gradient )
77 m_colorStops.setAutoDelete(
true );
79 if (
this == &gradient )
82 m_origin = gradient.m_origin;
83 m_focalPoint = gradient.m_focalPoint;
84 m_vector = gradient.m_vector;
85 m_type = gradient.m_type;
86 m_repeatMethod = gradient.m_repeatMethod;
89 TQPtrVector<VColorStop> cs = gradient.colorStops();
90 for( uint i = 0; i < cs.count(); i++ )
91 m_colorStops.append(
new VColorStop( *cs[i] ) );
97const TQPtrVector<VColorStop> VGradient::colorStops()
const
99 TQPtrVector<VColorStop> v;
100 m_colorStops.toVector( &v );
101 v.setAutoDelete(
false );
106VGradient::clearStops()
108 m_colorStops.clear();
112VGradient::addStop(
const VColorStop& colorStop )
114 m_colorStops.inSort(
new VColorStop( colorStop ) );
118VGradient::addStop(
const VColor &color,
float rampPoint,
float midPoint )
121 rampPoint = kMax( 0.0f, rampPoint );
122 rampPoint = kMin( 1.0f, rampPoint );
124 midPoint = kMax( 0.0f, midPoint );
125 midPoint = kMin( 1.0f, midPoint );
129 for(v = m_colorStops.first(); v; v = m_colorStops.next())
131 if(rampPoint == v->rampPoint)
134 m_colorStops.inSort(
new VColorStop( rampPoint, midPoint, color ) );
137void VGradient::removeStop(
const VColorStop& colorstop )
139 m_colorStops.remove( &colorstop );
143VGradient::save( TQDomElement& element )
const
145 TQDomElement me = element.ownerDocument().createElement(
"GRADIENT" );
147 me.setAttribute(
"originX", m_origin.x() );
148 me.setAttribute(
"originY", m_origin.y() );
149 me.setAttribute(
"focalX", m_focalPoint.x() );
150 me.setAttribute(
"focalY", m_focalPoint.y() );
151 me.setAttribute(
"vectorX", m_vector.x() );
152 me.setAttribute(
"vectorY", m_vector.y() );
153 me.setAttribute(
"type", m_type );
154 me.setAttribute(
"repeatMethod", m_repeatMethod );
157 VColorStop* colorstop;
158 TQPtrList<VColorStop>& colorStops =
const_cast<VColorStopList&
>( m_colorStops );
159 for( colorstop = colorStops.first(); colorstop; colorstop = colorStops.next() )
161 TQDomElement stop = element.ownerDocument().createElement(
"COLORSTOP" );
162 colorstop->color.save( stop );
163 stop.setAttribute(
"ramppoint", colorstop->rampPoint );
164 stop.setAttribute(
"midpoint", colorstop->midPoint );
165 me.appendChild( stop );
168 element.appendChild( me );
172VGradient::saveOasis( KoGenStyles &mainStyles )
const
174 bool radial = m_type == VGradient::radial;
175 KoGenStyle gradientStyle( radial ? VDocument::STYLE_RADIAL_GRADIENT :
VDocument::STYLE_LINEAR_GRADIENT );
178 gradientStyle.addAttribute(
"draw:style",
"radial" );
179 gradientStyle.addAttributePt(
"svg:cx", m_origin.x() );
180 gradientStyle.addAttributePt(
"svg:cy", m_origin.y() );
181 double dx = m_vector.x() - m_origin.x();
182 double dy = m_vector.y() - m_origin.y();
183 gradientStyle.addAttributePt(
"svg:r", sqrt( dx * dx + dy * dy ) );
184 gradientStyle.addAttributePt(
"svg:fx", m_focalPoint.x() );
185 gradientStyle.addAttributePt(
"svg:fy", m_focalPoint.y() );
189 gradientStyle.addAttribute(
"draw:style",
"linear" );
190 gradientStyle.addAttributePt(
"svg:x1", m_origin.x() );
191 gradientStyle.addAttributePt(
"svg:y1", m_origin.y() );
192 gradientStyle.addAttributePt(
"svg:x2", m_vector.x() );
193 gradientStyle.addAttributePt(
"svg:y2", m_vector.y() );
195 if( m_repeatMethod == VGradient::repeat )
196 gradientStyle.addAttribute(
"svg:spreadMethod",
"repeat" );
197 else if( m_repeatMethod == VGradient::reflect )
198 gradientStyle.addAttribute(
"svg:spreadMethod",
"reflect" );
200 gradientStyle.addAttribute(
"svg:spreadMethod",
"pad" );
202 buffer.open( IO_WriteOnly );
203 KoXmlWriter elementWriter( &buffer );
206 VColorStop* colorstop;
207 TQPtrList<VColorStop>& colorStops =
const_cast<VColorStopList&
>( m_colorStops );
208 for( colorstop = colorStops.first(); colorstop; colorstop = colorStops.next() )
210 elementWriter.startElement(
"svg:stop" );
211 elementWriter.addAttribute(
"svg:offset", TQString(
"%1" ).arg( colorstop->rampPoint ) );
212 elementWriter.addAttribute(
"svg:color", TQColor( colorstop->color ).name() );
213 if( colorstop->color.opacity() < 1 )
214 elementWriter.addAttribute(
"svg:stop-opacity", TQString(
"%1" ).arg( colorstop->color.opacity() ) );
215 elementWriter.endElement();
218 TQString elementContents = TQString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
219 gradientStyle.addChildElement(
"svg:stop", elementContents );
220 return mainStyles.lookup( gradientStyle,
"gradient" );
224VGradient::loadOasis(
const TQDomElement &
object, KoStyleStack &,
VObject* parent )
226 kdDebug(38000) <<
"namespaceURI: " <<
object.namespaceURI() << endl;
227 kdDebug(38000) <<
"localName: " <<
object.localName() << endl;
234 if(
object.namespaceURI() == KoXmlNS::draw &&
object.localName() ==
"gradient" )
236 m_repeatMethod = VGradient::reflect;
237 TQString strType =
object.attributeNS( KoXmlNS::draw,
"style", TQString() );
238 if( strType ==
"radial" )
240 m_type = VGradient::radial;
242 double cx = KoUnit::parseValue(
object.attributeNS( KoXmlNS::draw,
"cx", TQString() ).remove(
"%") );
243 m_origin.setX( bb.bottomLeft().x() + bb.width() * 0.01 * cx );
244 double cy = KoUnit::parseValue(
object.attributeNS( KoXmlNS::draw,
"cy", TQString() ).remove(
"%") );
245 m_origin.setY( bb.bottomLeft().y() - bb.height() * 0.01 * cy );
246 m_focalPoint = m_origin;
247 m_vector = bb.topRight();
249 else if( strType ==
"linear" )
251 m_type = VGradient::linear;
252 double angle = 90 +
object.attributeNS( KoXmlNS::draw,
"angle",
"0" ).toDouble();
253 double radius = 0.5 * sqrt( bb.width()*bb.width() + bb.height()*bb.height() );
254 double sx = cos( angle * VGlobal::pi / 180 ) * radius;
255 double sy = sin( angle * VGlobal::pi / 180 ) * radius;
256 m_origin.setX( bb.center().x() + sx );
257 m_origin.setY( bb.center().y() + sy );
258 m_vector.setX( bb.center().x() - sx );
259 m_vector.setY( bb.center().y() - sy );
260 m_focalPoint = m_origin;
264 VColor startColor( TQColor(
object.attributeNS( KoXmlNS::draw,
"start-color", TQString() ) ) );
265 VColor endColor( TQColor(
object.attributeNS( KoXmlNS::draw,
"end-color", TQString() ) ) );
267 double startOpacity = 0.01 *
object.attributeNS( KoXmlNS::draw,
"start-intensity",
"100" ).remove(
"%").toDouble();
268 double endOpacity = 0.01 *
object.attributeNS( KoXmlNS::draw,
"end-intensity",
"100" ).remove(
"%").toDouble();
270 startColor.setOpacity( startOpacity );
271 endColor.setOpacity( endOpacity );
272 m_colorStops.clear();
273 addStop( startColor, 0.0, 0.5 );
274 addStop( endColor, 1.0, 0.0 );
278 else if(
object.namespaceURI() == KoXmlNS::svg )
280 if(
object.localName() ==
"linearGradient" )
282 m_type = VGradient::linear;
283 m_origin.setX( KoUnit::parseValue(
object.attributeNS( KoXmlNS::svg,
"x1", TQString() ) ) );
284 m_origin.setY( KoUnit::parseValue(
object.attributeNS( KoXmlNS::svg,
"y1", TQString() ) ) );
285 m_vector.setX( KoUnit::parseValue(
object.attributeNS( KoXmlNS::svg,
"x2", TQString() ) ) );
286 m_vector.setY( KoUnit::parseValue(
object.attributeNS( KoXmlNS::svg,
"y2", TQString() ) ) );
287 m_focalPoint = m_origin;
289 else if(
object.localName() ==
"radialGradient" )
291 m_type = VGradient::radial;
292 m_origin.setX( KoUnit::parseValue(
object.attributeNS( KoXmlNS::svg,
"cx", TQString() ) ) );
293 m_origin.setY( KoUnit::parseValue(
object.attributeNS( KoXmlNS::svg,
"cy", TQString() ) ) );
294 double r = KoUnit::parseValue(
object.attributeNS( KoXmlNS::svg,
"r", TQString() ) );
295 m_vector.setX( m_origin.x() + r );
296 m_vector.setY( m_origin.y() );
297 m_focalPoint.setX( KoUnit::parseValue(
object.attributeNS( KoXmlNS::svg,
"fx", TQString() ) ) );
298 m_focalPoint.setY( KoUnit::parseValue(
object.attributeNS( KoXmlNS::svg,
"fy", TQString() ) ) );
301 TQString strSpread(
object.attributeNS( KoXmlNS::svg,
"spreadMethod",
"pad" ) );
302 if( strSpread ==
"repeat" )
303 m_repeatMethod = VGradient::repeat;
304 else if( strSpread ==
"reflect" )
305 m_repeatMethod = VGradient::reflect;
307 m_repeatMethod = VGradient::none;
309 m_colorStops.clear();
312 TQDomNodeList list =
object.childNodes();
313 for( uint i = 0; i < list.count(); ++i )
315 if( list.item( i ).isElement() )
317 TQDomElement colorstop = list.item( i ).toElement();
319 if( colorstop.namespaceURI() == KoXmlNS::svg && colorstop.localName() ==
"stop" )
321 VColor color( TQColor( colorstop.attributeNS( KoXmlNS::svg,
"color", TQString() ) ) );
322 color.
setOpacity( colorstop.attributeNS( KoXmlNS::svg,
"stop-opacity",
"1.0" ).toDouble() );
323 addStop( color, colorstop.attributeNS( KoXmlNS::svg,
"offset",
"0.0" ).toDouble(), 0.5 );
332VGradient::load(
const TQDomElement& element )
334 m_origin.setX( element.attribute(
"originX",
"0.0" ).toDouble() );
335 m_origin.setY( element.attribute(
"originY",
"0.0" ).toDouble() );
336 m_focalPoint.setX( element.attribute(
"focalX",
"0.0" ).toDouble() );
337 m_focalPoint.setY( element.attribute(
"focalY",
"0.0" ).toDouble() );
338 m_vector.setX( element.attribute(
"vectorX",
"0.0" ).toDouble() );
339 m_vector.setY( element.attribute(
"vectorY",
"0.0" ).toDouble() );
340 m_type = (VGradientType)element.attribute(
"type", 0 ).toInt();
341 m_repeatMethod = (VGradientRepeatMethod)element.attribute(
"repeatMethod", 0 ).toInt();
343 m_colorStops.clear();
346 TQDomNodeList list = element.childNodes();
347 for( uint i = 0; i < list.count(); ++i )
349 if( list.item( i ).isElement() )
351 TQDomElement colorstop = list.item( i ).toElement();
353 if( colorstop.tagName() ==
"COLORSTOP" )
356 color.
load( colorstop.firstChild().toElement() );
357 addStop( color, colorstop.attribute(
"ramppoint",
"0.0" ).toDouble(), colorstop.attribute(
"midpoint",
"0.5" ).toDouble() );
365VGradient::transform(
const TQWMatrix &m )
367 m_origin = m_origin.transform( m );
368 m_focalPoint = m_focalPoint.transform( m );
369 m_vector = m_vector.transform( m );
This class keeps track of color properties.
void set(float v1)
Sets the first color component.
void setOpacity(float opacity)
Sets the color opacity.
void load(const TQDomElement &element)
Load this color's state from xml and initialize it accordingly.
All non-visual, static doc info is in here.
The base class for all karbon objects.
virtual const KoRect & boundingBox() const
Calculates the tightest bounding box around the object.