20#include "kogradientmanager.h"
22#include "svgnamedcolors.h"
24#include <tqtextstream.h>
29KoGradientManager::KoGradientManager()
33KoGradientManager::~KoGradientManager()
38KoGradient* KoGradientManager::loadGradient(
const TQString& filename)
41 const int result=filename.findRev(
'.');
44 strExt=filename.mid(result).lower();
49 if(f.open(IO_ReadOnly))
53 return loadChalkGradient(&f);
55 else if(strExt==
".kgr")
57 return loadKarbonGradient(&f);
59 else if(strExt==
".svg")
61 return loadSvgGradient(&f);
68KoGradient* KoGradientManager::loadKarbonGradient(TQFile* file)
72 if(!(doc.setContent(file)))
77 TQDomNode n = doc.documentElement().firstChild();
84 if( e.tagName() ==
"GRADIENT" )
85 return parseKarbonGradient(e);
92KoGradient* KoGradientManager::loadChalkGradient(TQFile* file)
94 KoGradient* grad =
new KoGradient();
96 TQByteArray m_data = file->readAll();
99 TQTextIStream fileContent(m_data);
100 fileContent.setEncoding(TQTextStream::UnicodeUTF8);
102 TQString header = fileContent.readLine();
104 if (header !=
"GIMP Gradient")
110 TQString nameDefinition = fileContent.readLine();
111 TQString numSegmentsText;
113 if (nameDefinition.startsWith(
"Name: "))
115 TQString nameText = nameDefinition.right(nameDefinition.length() - 6);
116 numSegmentsText = fileContent.readLine();
122 numSegmentsText = nameDefinition;
128 numSegments = numSegmentsText.toInt(&ok);
130 if (!ok || numSegments < 1)
135 for (
int i = 0; i < numSegments; i++)
137 KoColorStop *stop =
new KoColorStop();
139 TQString segmentText = fileContent.readLine();
140 TQTextIStream segmentFields(&segmentText);
146 segmentFields >> leftOffset >> middleOffset >> rightOffset;
153 segmentFields >> leftRed >> leftGreen >> leftBlue >> leftAlpha;
160 segmentFields >> rightRed >> rightGreen >> rightBlue >> rightAlpha;
162 int interpolationType;
163 int colorInterpolationType;
165 segmentFields >> interpolationType >> colorInterpolationType;
167 middleOffset = (middleOffset - leftOffset) / (rightOffset - leftOffset);
169 stop->opacity = leftAlpha;
170 stop->midpoint = middleOffset;
171 stop->offset = leftOffset;
173 stop->color1 = leftRed;
174 stop->color2 = leftGreen;
175 stop->color3 = leftBlue;
177 stop->colorType = colorInterpolationType;
178 stop->interpolation = interpolationType;
180 grad->colorStops.append(stop);
182 if(rightOffset == 1.0)
184 KoColorStop *lastStop =
new KoColorStop();
185 lastStop->opacity = rightAlpha;
186 lastStop->midpoint = middleOffset;
187 lastStop->offset = rightOffset;
188 lastStop->color1 = rightRed;
189 lastStop->color2 = rightGreen;
190 lastStop->color3 = rightBlue;
191 lastStop->color4 = 0.0;
192 lastStop->colorType = colorInterpolationType;
193 lastStop->interpolation = interpolationType;
194 grad->colorStops.append(lastStop);
198 if (!grad->colorStops.isEmpty())
204 grad->focalpointX = 0.0;
205 grad->focalpointY = 0.0;
206 grad->gradientType = gradient_type_linear;
207 grad->gradientRepeatMethod = repeat_method_none;
218KoGradient* KoGradientManager::loadSvgGradient(TQFile* file)
222 if(!(doc.setContent(file)))
226 for( TQDomNode n = doc.documentElement().firstChild(); !n.isNull(); n = n.nextSibling() )
228 TQDomElement e = n.toElement();
229 if( e.isNull() )
continue;
231 if( e.tagName() ==
"linearGradient" || e.tagName() ==
"radialGradient" )
232 return parseSvgGradient(e);
239KoGradient* KoGradientManager::parseKarbonGradient(
const TQDomElement& element)
241 KoGradient* grad =
new KoGradient();
243 grad->originX = element.attribute(
"originX",
"0.0").toDouble();
244 grad->originY = element.attribute(
"originY",
"0.0").toDouble();
245 grad->focalpointX = element.attribute(
"focalX",
"0.0").toDouble();
246 grad->focalpointY = element.attribute(
"focalY",
"0.0").toDouble();
247 grad->vectorX = element.attribute(
"vectorX",
"0.0").toDouble();
248 grad->vectorY = element.attribute(
"vectorY",
"0.0").toDouble();
249 grad->gradientType = (KoGradientType)element.attribute(
"type", 0).toInt();
250 grad->gradientRepeatMethod = (KoGradientRepeatMethod)element.attribute(
"repeatMethod", 0).toInt();
252 grad->colorStops.clear();
255 TQDomNodeList list = element.childNodes();
256 for( uint i = 0; i < list.count(); ++i )
258 if( list.item( i ).isElement() )
260 TQDomElement colorstop = list.item( i ).toElement();
262 if( colorstop.tagName() ==
"COLORSTOP" )
264 KoColorStop *stop =
new KoColorStop();
266 TQDomElement e = colorstop.firstChild().toElement();
268 switch(e.attribute(
"colorSpace").toUShort())
271 stop->color1 = e.attribute(
"v1",
"0.0" ).toFloat();
272 stop->color2 = e.attribute(
"v2",
"0.0" ).toFloat();
273 stop->color3 = e.attribute(
"v3",
"0.0" ).toFloat();
274 stop->color4 = e.attribute(
"v4",
"0.0" ).toFloat();
275 stop->colorType = color_type_cmyk;
276 stop->interpolation = interpolation_linear;
279 stop->color1 = e.attribute(
"v1",
"0.0" ).toFloat();
280 stop->color2 = e.attribute(
"v2",
"0.0" ).toFloat();
281 stop->color3 = e.attribute(
"v3",
"0.0" ).toFloat();
283 stop->colorType = color_type_hsv_cw;
284 stop->interpolation = interpolation_linear;
287 stop->color1 = e.attribute(
"v1",
"0.0" ).toFloat();
291 stop->colorType = color_type_gray;
292 stop->interpolation = interpolation_linear;
295 stop->color1 = e.attribute(
"v1",
"0.0" ).toFloat();
296 stop->color2 = e.attribute(
"v2",
"0.0" ).toFloat();
297 stop->color3 = e.attribute(
"v3",
"0.0" ).toFloat();
299 stop->colorType = color_type_rgb;
300 stop->interpolation = interpolation_linear;
303 stop->opacity = e.attribute(
"opacity",
"1.0").toFloat();
305 stop->offset = colorstop.attribute(
"ramppoint",
"0.0").toFloat();
306 stop->midpoint = colorstop.attribute(
"midpoint",
"0.5").toFloat();
308 grad->colorStops.append(stop);
316KoGradient* KoGradientManager::parseSvgGradient(
const TQDomElement& element)
318 KoGradient* grad =
new KoGradient;
320 grad->colorStops.clear();
321 grad->gradientRepeatMethod = repeat_method_none;
328 bool bbox = element.attribute(
"gradientUnits" ) !=
"userSpaceOnUse";
330 if( element.tagName() ==
"linearGradient" )
336 s = element.attribute(
"x1",
"0%" );
338 if( s.endsWith(
"%" ) )
339 xOrigin = s.remove(
'%' ).toDouble();
341 xOrigin = s.toDouble() * 100.0;
343 s = element.attribute(
"y1",
"0%" );
345 if( s.endsWith(
"%" ) )
346 yOrigin = s.remove(
'%' ).toDouble();
348 yOrigin = s.toDouble() * 100.0;
350 s = element.attribute(
"x2",
"100%" );
352 if( s.endsWith(
"%" ) )
353 xVector = s.remove(
'%' ).toDouble();
355 xVector = s.toDouble() * 100.0;
357 s = element.attribute(
"y2",
"0%" );
359 if( s.endsWith(
"%" ) )
360 yVector = s.remove(
'%' ).toDouble();
362 yVector = s.toDouble() * 100.0;
364 grad->originX = xOrigin;
365 grad->originY = yOrigin;
366 grad->vectorX = xVector;
367 grad->vectorY = yVector;
371 grad->originX = element.attribute(
"x1" ).toDouble();
372 grad->originY = element.attribute(
"y1" ).toDouble();
373 grad->vectorX = element.attribute(
"x2" ).toDouble();
374 grad->vectorY = element.attribute(
"y2" ).toDouble();
376 grad->gradientType = gradient_type_linear;
384 s = element.attribute(
"cx",
"50%" );
386 if( s.endsWith(
"%" ) )
387 xOrigin = s.remove(
'%' ).toDouble();
389 xOrigin = s.toDouble() * 100.0;
391 s = element.attribute(
"cy",
"50%" );
393 if( s.endsWith(
"%" ) )
394 yOrigin = s.remove(
'%' ).toDouble();
396 yOrigin = s.toDouble() * 100.0;
398 s = element.attribute(
"cx",
"50%" );
400 if( s.endsWith(
"%" ) )
401 xVector = s.remove(
'%' ).toDouble();
403 xVector = s.toDouble() * 100.0;
405 s = element.attribute(
"r",
"50%" );
406 if( s.endsWith(
"%" ) )
407 xVector += s.remove(
'%' ).toDouble();
409 xVector += s.toDouble() * 100.0;
411 s = element.attribute(
"cy",
"50%" );
413 if( s.endsWith(
"%" ) )
414 yVector = s.remove(
'%' ).toDouble();
416 yVector = s.toDouble() * 100.0;
418 s = element.attribute(
"fx",
"50%" );
420 if( s.endsWith(
"%" ) )
421 xFocal = s.remove(
'%' ).toDouble();
423 xFocal = s.toDouble() * 100.0;
425 s = element.attribute(
"fy",
"50%" );
427 if( s.endsWith(
"%" ) )
428 yFocal = s.remove(
'%' ).toDouble();
430 yFocal = s.toDouble() * 100.0;
432 grad->originX = xOrigin;
433 grad->originY = yOrigin;
434 grad->vectorX = xVector;
435 grad->vectorY = yVector;
436 grad->focalpointX = xFocal;
437 grad->focalpointY = yFocal;
441 grad->originX = element.attribute(
"cx" ).toDouble();
442 grad->originY = element.attribute(
"cy" ).toDouble();
443 grad->vectorX = element.attribute(
"cx" ).toDouble() + element.attribute(
"r" ).toDouble();
444 grad->vectorY = element.attribute(
"cy" ).toDouble();
445 grad->focalpointX = element.attribute(
"fx" ).toDouble();
446 grad->focalpointY = element.attribute(
"fy" ).toDouble();
448 grad->gradientType = gradient_type_radial;
451 TQString spreadMethod = element.attribute(
"spreadMethod" );
452 if( !spreadMethod.isEmpty() )
454 if( spreadMethod ==
"reflect" )
455 grad->gradientRepeatMethod = repeat_method_reflect;
456 else if( spreadMethod ==
"repeat" )
457 grad->gradientRepeatMethod = repeat_method_repeat;
460 for( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() )
462 TQDomElement colorstop = n.toElement();
463 if( colorstop.tagName() ==
"stop" )
465 KoColorStop *stop =
new KoColorStop();
468 TQString temp = colorstop.attribute(
"offset" );
469 if( temp.contains(
'%' ) )
471 temp = temp.left( temp.length() - 1 );
472 off = temp.toFloat() / 100.0;
475 off = temp.toFloat();
477 if( !colorstop.attribute(
"stop-color" ).isEmpty() )
478 parseSvgColor( c, colorstop.attribute(
"stop-color" ) );
482 TQString style = colorstop.attribute(
"style" ).simplifyWhiteSpace();
483 TQStringList substyles = TQStringList::split(
';', style );
484 for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it )
486 TQStringList substyle = TQStringList::split(
':', (*it) );
487 TQString command = substyle[0].stripWhiteSpace();
488 TQString params = substyle[1].stripWhiteSpace();
489 if( command ==
"stop-color" )
490 parseSvgColor( c, params );
491 if( command ==
"stop-opacity" )
492 stop->opacity = params.toDouble();
496 if( !colorstop.attribute(
"stop-opacity" ).isEmpty() )
497 stop->opacity = colorstop.attribute(
"stop-opacity" ).toDouble();
500 stop->midpoint = 0.5;
501 stop->color1 = c.red() / 255.0;
502 stop->color2 = c.green() / 255.0;
503 stop->color3 = c.blue() / 255.0;
505 stop->colorType = color_type_rgb;
506 stop->interpolation = interpolation_linear;
507 grad->colorStops.append(stop);
514void KoGradientManager::parseSvgColor(TQColor &color,
const TQString &s)
516 if( s.startsWith(
"rgb(" ) )
518 TQString parse = s.stripWhiteSpace();
519 TQStringList colors = TQStringList::split(
',', parse );
520 TQString r = colors[0].right( ( colors[0].length() - 4 ) );
521 TQString g = colors[1];
522 TQString b = colors[2].left( ( colors[2].length() - 1 ) );
524 if( r.contains(
"%" ) )
526 r = r.left( r.length() - 1 );
527 r = TQString::number(
int( (
double( 255 * r.toDouble() ) / 100.0 ) ) );
530 if( g.contains(
"%" ) )
532 g = g.left( g.length() - 1 );
533 g = TQString::number(
int( (
double( 255 * g.toDouble() ) / 100.0 ) ) );
536 if( b.contains(
"%" ) )
538 b = b.left( b.length() - 1 );
539 b = TQString::number(
int( (
double( 255 * b.toDouble() ) / 100.0 ) ) );
542 color = TQColor( r.toInt(), g.toInt(), b.toInt() );
546 TQString rgbColor = s.stripWhiteSpace();
548 if( rgbColor.startsWith(
"#" ) )
549 c.setNamedColor( rgbColor );
553 svgNamedColorToRGB( rgbColor, r, g, b );
554 c = TQColor( r, g, b );