F:/KPlato/koffice/libs/kopainter/kogradientmanager.cc

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Tim Beaulen <tbscope@gmail.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kogradientmanager.h"
00021 
00022 #include "svgnamedcolors.h"
00023 
00024 #include <QTextStream>
00025 #include <q3cstring.h>
00026 
00027 #include <kdebug.h>
00028 
00029 KoGradientManager::KoGradientManager()
00030 {
00031 }
00032 
00033 KoGradientManager::~KoGradientManager()
00034 {
00035     // XXX: Should we delete the gradients here?
00036 }
00037 
00038 KoGradient* KoGradientManager::loadGradient(const QString& filename)
00039 {
00040         QString strExt;
00041         const int result=filename.findRev('.');
00042         if (result>=0)
00043         {
00044                 strExt=filename.mid(result).toLower();
00045         }
00046 
00047         QFile f(filename);
00048 
00049         if(f.open(QIODevice::ReadOnly))
00050         {
00051                 if(strExt == ".ggr")
00052                 {
00053                         return loadKritaGradient(&f);
00054                 }
00055         else if(strExt==".kgr")
00056                 {
00057                         return loadKarbonGradient(&f);
00058                 }
00059                 else if(strExt==".svg")
00060                 {
00061                         return loadSvgGradient(&f);
00062                 }
00063         }
00064 
00065         return 0;
00066 }
00067 
00068 KoGradient* KoGradientManager::loadKarbonGradient(QFile* file)
00069 {
00070         QDomDocument doc;
00071                 
00072         if(!(doc.setContent(file)))
00073                 file->close();
00074         else
00075         {
00076                 QDomElement e;
00077                 QDomNode n = doc.documentElement().firstChild();
00078                 
00079                 if(!n.isNull())
00080                 {
00081                         e = n.toElement();
00082                 
00083                         if(!e.isNull())
00084                                 if( e.tagName() == "GRADIENT" )
00085                                         return parseKarbonGradient(e);
00086                 }
00087         }
00088 
00089         return 0;
00090 }
00091 
00092 KoGradient* KoGradientManager::loadKritaGradient(QFile* file)
00093 {
00094         KoGradient* grad = new KoGradient();
00095         
00096         QByteArray m_data = file->readAll();
00097         file->close();
00098 
00099         QTextStream fileContent(m_data, QIODevice::ReadOnly);
00100         fileContent.setEncoding(QTextStream::UnicodeUTF8);
00101 
00102         QString header = fileContent.readLine();
00103 
00104         if (header != "GIMP Gradient") 
00105         {
00106                 delete grad;
00107                 return 0;
00108         }
00109 
00110         QString nameDefinition = fileContent.readLine();
00111         QString numSegmentsText;
00112 
00113         if (nameDefinition.startsWith("Name: ")) 
00114         {
00115                 QString nameText = nameDefinition.right(nameDefinition.length() - 6);
00116                 numSegmentsText = fileContent.readLine();
00117         }
00118         else 
00119         {
00120                 // Older format without name.
00121 
00122                 numSegmentsText = nameDefinition;
00123         }
00124 
00125         int numSegments;
00126         bool ok;
00127 
00128         numSegments = numSegmentsText.toInt(&ok);
00129 
00130         if (!ok || numSegments < 1) 
00131         {
00132                 return 0;
00133         }
00134 
00135         for (int i = 0; i < numSegments; i++) 
00136         {
00137                 KoColorStop *stop = new KoColorStop();
00138 
00139                 QString segmentText = fileContent.readLine();
00140                 QTextIStream segmentFields(&segmentText);
00141 
00142                 double leftOffset;
00143                 double middleOffset;
00144                 double rightOffset;
00145 
00146                 segmentFields >> leftOffset >> middleOffset >> rightOffset;
00147 
00148                 double leftRed;
00149                 double leftGreen;
00150                 double leftBlue;
00151                 double leftAlpha;
00152 
00153                 segmentFields >> leftRed >> leftGreen >> leftBlue >> leftAlpha;
00154 
00155                 double rightRed;
00156                 double rightGreen;
00157                 double rightBlue;
00158                 double rightAlpha;
00159 
00160                 segmentFields >> rightRed >> rightGreen >> rightBlue >> rightAlpha;
00161 
00162                 int interpolationType;
00163                 int colorInterpolationType;
00164 
00165                 segmentFields >> interpolationType >> colorInterpolationType;
00166 
00167                 middleOffset = (middleOffset - leftOffset) / (rightOffset - leftOffset);
00168 
00169                 stop->opacity = leftAlpha;
00170                 stop->midpoint = middleOffset;
00171                 stop->offset = leftOffset;
00172 
00173                 stop->color1 = leftRed;
00174                 stop->color2 = leftGreen;
00175                 stop->color3 = leftBlue;
00176                 stop->color4 = 0.0;
00177                 stop->colorType = colorInterpolationType;
00178                 stop->interpolation = interpolationType; 
00179 
00180                 grad->colorStops.append(stop);
00181 
00182                 if(rightOffset == 1.0)
00183                 {
00184                         KoColorStop *lastStop = new KoColorStop();
00185                         lastStop->opacity = rightAlpha;
00186                         lastStop->midpoint = middleOffset;
00187                         lastStop->offset = rightOffset;
00188                         lastStop->color1 = rightRed;
00189                         lastStop->color2 = rightGreen;
00190                         lastStop->color3 = rightBlue;
00191                         lastStop->color4 = 0.0;
00192                         lastStop->colorType = colorInterpolationType;
00193                         lastStop->interpolation = interpolationType; 
00194                         grad->colorStops.append(lastStop);
00195                 }
00196         }
00197 
00198         if (!grad->colorStops.isEmpty())
00199         {
00200                 grad->originX = 0.0;
00201                 grad->originY = 1.0;
00202                 grad->vectorX = 0.0;
00203                 grad->vectorY = 0.0;
00204                 grad->focalpointX = 0.0;
00205                 grad->focalpointY = 0.0;
00206                 grad->gradientType = gradient_type_linear;
00207                 grad->gradientRepeatMethod = repeat_method_none;
00208                 
00209                 return grad;
00210         }
00211         else 
00212         {
00213                 delete grad;
00214                 return 0;
00215         }
00216 }
00217 
00218 KoGradient* KoGradientManager::loadSvgGradient(QFile* file)
00219 {
00220         QDomDocument doc;
00221                 
00222         if(!(doc.setContent(file)))
00223                 file->close();
00224         else
00225         {
00226                 for( QDomNode n = doc.documentElement().firstChild(); !n.isNull(); n = n.nextSibling() )
00227                 {
00228                         QDomElement e = n.toElement();
00229                         if( e.isNull() ) continue;
00230                 
00231                         if( e.tagName() == "linearGradient" || e.tagName() == "radialGradient" )
00232                                 return parseSvgGradient(e);
00233                 }
00234         }
00235 
00236         return 0;
00237 }
00238 
00239 KoGradient* KoGradientManager::parseKarbonGradient(const QDomElement& element)
00240 {
00241         KoGradient* grad = new KoGradient();
00242 
00243         grad->originX = element.attribute("originX", "0.0").toDouble();
00244         grad->originY = element.attribute("originY", "0.0").toDouble();
00245         grad->focalpointX = element.attribute("focalX", "0.0").toDouble();
00246         grad->focalpointY = element.attribute("focalY", "0.0").toDouble();
00247         grad->vectorX = element.attribute("vectorX", "0.0").toDouble();
00248         grad->vectorY = element.attribute("vectorY", "0.0").toDouble();
00249         grad->gradientType = (KoGradientType)element.attribute("type", 0).toInt();
00250         grad->gradientRepeatMethod = (KoGradientRepeatMethod)element.attribute("repeatMethod", 0).toInt();
00251 
00252         grad->colorStops.clear();
00253 
00254         // load stops
00255         QDomNodeList list = element.childNodes();
00256         for( uint i = 0; i < list.count(); ++i )
00257         {
00258                 if( list.item( i ).isElement() )
00259                 {
00260                         QDomElement colorstop = list.item( i ).toElement();
00261 
00262                         if( colorstop.tagName() == "COLORSTOP" )
00263                         {
00264                                 KoColorStop *stop = new KoColorStop();
00265 
00266                                 QDomElement e = colorstop.firstChild().toElement();
00267 
00268                                 switch(e.attribute("colorSpace").toUShort())
00269                                 {
00270                                         case 1: // cmyk
00271                                                 stop->color1 = e.attribute( "v1", "0.0" ).toFloat();
00272                                                 stop->color2 = e.attribute( "v2", "0.0" ).toFloat();
00273                                                 stop->color3 = e.attribute( "v3", "0.0" ).toFloat();
00274                                                 stop->color4 = e.attribute( "v4", "0.0" ).toFloat();
00275                                                 stop->colorType = color_type_cmyk;
00276                                                 stop->interpolation = interpolation_linear;
00277                                                 break;
00278                                         case 2: // hsv
00279                                                 stop->color1 = e.attribute( "v1", "0.0" ).toFloat();
00280                                                 stop->color2 = e.attribute( "v2", "0.0" ).toFloat();
00281                                                 stop->color3 = e.attribute( "v3", "0.0" ).toFloat();
00282                                                 stop->color4 = 0.0;
00283                                                 stop->colorType = color_type_hsv_cw;
00284                                                 stop->interpolation = interpolation_linear;
00285                                                 break;
00286                                         case 3: // gray
00287                                                 stop->color1 = e.attribute( "v1", "0.0" ).toFloat();
00288                                                 stop->color2 = 0.0;
00289                                                 stop->color3 = 0.0;
00290                                                 stop->color4 = 0.0;
00291                                                 stop->colorType = color_type_gray;
00292                                                 stop->interpolation = interpolation_linear;
00293                                                 break;
00294                                         default: // rgb
00295                                                 stop->color1 = e.attribute( "v1", "0.0" ).toFloat();
00296                                                 stop->color2 = e.attribute( "v2", "0.0" ).toFloat();
00297                                                 stop->color3 = e.attribute( "v3", "0.0" ).toFloat();
00298                                                 stop->color4 = 0.0;
00299                                                 stop->colorType = color_type_rgb;
00300                                                 stop->interpolation = interpolation_linear;
00301                                 }
00302 
00303                                 stop->opacity = e.attribute("opacity", "1.0").toFloat();
00304 
00305                                 stop->offset = colorstop.attribute("ramppoint", "0.0").toFloat();
00306                                 stop->midpoint = colorstop.attribute("midpoint", "0.5").toFloat();
00307 
00308                                 grad->colorStops.append(stop);
00309                         }
00310                 }
00311         }
00312 
00313         return grad;
00314 }
00315 
00316 KoGradient* KoGradientManager::parseSvgGradient(const QDomElement& element)
00317 {
00318         KoGradient* grad = new KoGradient;
00319 
00320         grad->colorStops.clear();
00321         grad->gradientRepeatMethod = repeat_method_none;
00322 
00323         /*QString href = e.attribute( "xlink:href" ).mid( 1 );
00324         if( !href.isEmpty() )
00325         {
00326         }*/
00327 
00328         bool bbox = element.attribute( "gradientUnits" ) != "userSpaceOnUse";
00329 
00330         if( element.tagName() == "linearGradient" )
00331         {
00332                 if( bbox )
00333                 {
00334                         QString s;
00335 
00336                         s = element.attribute( "x1", "0%" );
00337                         double xOrigin;
00338                         if( s.endsWith( "%" ) )
00339                                 xOrigin = s.remove( '%' ).toDouble();
00340                         else
00341                                 xOrigin = s.toDouble() * 100.0;
00342 
00343                         s = element.attribute( "y1", "0%" );
00344                         double yOrigin;
00345                         if( s.endsWith( "%" ) )
00346                                 yOrigin = s.remove( '%' ).toDouble();
00347                         else
00348                                 yOrigin = s.toDouble() * 100.0;
00349 
00350                         s = element.attribute( "x2", "100%" );
00351                         double xVector;
00352                         if( s.endsWith( "%" ) )
00353                                 xVector = s.remove( '%' ).toDouble();
00354                         else
00355                                 xVector = s.toDouble() * 100.0;
00356 
00357                         s = element.attribute( "y2", "0%" );
00358                         double yVector;
00359                         if( s.endsWith( "%" ) )
00360                                 yVector = s.remove( '%' ).toDouble();
00361                         else
00362                                 yVector = s.toDouble() * 100.0;
00363 
00364                         grad->originX = xOrigin;
00365                         grad->originY = yOrigin;
00366                         grad->vectorX = xVector;
00367                         grad->vectorY = yVector;
00368                 }
00369                 else
00370                 {
00371                         grad->originX = element.attribute( "x1" ).toDouble();
00372                         grad->originY = element.attribute( "y1" ).toDouble();
00373                         grad->vectorX = element.attribute( "x2" ).toDouble();
00374                         grad->vectorY = element.attribute( "y2" ).toDouble();
00375                 }
00376                 grad->gradientType = gradient_type_linear;
00377         }
00378         else
00379         {
00380                 if( bbox )
00381                 {
00382                         QString s;
00383 
00384                         s = element.attribute( "cx", "50%" );
00385                         double xOrigin;
00386                         if( s.endsWith( "%" ) )
00387                                 xOrigin = s.remove( '%' ).toDouble();
00388                         else
00389                                 xOrigin = s.toDouble() * 100.0;
00390 
00391                         s = element.attribute( "cy", "50%" );
00392                         double yOrigin;
00393                         if( s.endsWith( "%" ) )
00394                                 yOrigin = s.remove( '%' ).toDouble();
00395                         else
00396                                 yOrigin = s.toDouble() * 100.0;
00397 
00398                         s = element.attribute( "cx", "50%" );
00399                         double xVector;
00400                         if( s.endsWith( "%" ) )
00401                                 xVector = s.remove( '%' ).toDouble();
00402                         else
00403                                 xVector = s.toDouble() * 100.0;
00404 
00405                         s = element.attribute( "r", "50%" );
00406                         if( s.endsWith( "%" ) )
00407                                 xVector += s.remove( '%' ).toDouble();
00408                         else
00409                                 xVector += s.toDouble() * 100.0;
00410 
00411                         s = element.attribute( "cy", "50%" );
00412                         double yVector;
00413                         if( s.endsWith( "%" ) )
00414                                 yVector = s.remove( '%' ).toDouble();
00415                         else
00416                                 yVector = s.toDouble() * 100.0;
00417 
00418                         s = element.attribute( "fx", "50%" );
00419                         double xFocal;
00420                         if( s.endsWith( "%" ) )
00421                                 xFocal = s.remove( '%' ).toDouble();
00422                         else
00423                                 xFocal = s.toDouble() * 100.0;
00424 
00425                         s = element.attribute( "fy", "50%" );
00426                         double yFocal;
00427                         if( s.endsWith( "%" ) )
00428                                 yFocal = s.remove( '%' ).toDouble();
00429                         else
00430                                 yFocal = s.toDouble() * 100.0;
00431 
00432                         grad->originX = xOrigin;
00433                         grad->originY = yOrigin;
00434                         grad->vectorX = xVector;
00435                         grad->vectorY = yVector;
00436                         grad->focalpointX = xFocal;
00437                         grad->focalpointY = yFocal;
00438                 }
00439                 else
00440                 {
00441                         grad->originX = element.attribute( "cx" ).toDouble();
00442                         grad->originY = element.attribute( "cy" ).toDouble();
00443                         grad->vectorX = element.attribute( "cx" ).toDouble() + element.attribute( "r" ).toDouble();
00444                         grad->vectorY = element.attribute( "cy" ).toDouble();
00445                         grad->focalpointX = element.attribute( "fx" ).toDouble();
00446                         grad->focalpointY = element.attribute( "fy" ).toDouble();
00447                 }
00448                 grad->gradientType = gradient_type_radial;
00449         }
00450         // handle spread method
00451         QString spreadMethod = element.attribute( "spreadMethod" );
00452         if( !spreadMethod.isEmpty() )
00453         {
00454                 if( spreadMethod == "reflect" )
00455                         grad->gradientRepeatMethod = repeat_method_reflect;
00456                 else if( spreadMethod == "repeat" )
00457                         grad->gradientRepeatMethod = repeat_method_repeat;
00458         }
00459 
00460         for( QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() )
00461         {
00462                 QDomElement colorstop = n.toElement();
00463                 if( colorstop.tagName() == "stop" )
00464                 {
00465                         KoColorStop *stop = new KoColorStop();
00466                         QColor c;
00467                         float off;
00468                         QString temp = colorstop.attribute( "offset" );
00469                         if( temp.contains( '%' ) )
00470                         {
00471                                 temp = temp.left( temp.length() - 1 );
00472                                 off = temp.toFloat() / 100.0;
00473                         }
00474                         else
00475                                 off = temp.toFloat();
00476 
00477                         if( !colorstop.attribute( "stop-color" ).isEmpty() )
00478                                 parseSvgColor( c, colorstop.attribute( "stop-color" ) );
00479                         else
00480                         {
00481                                 // try style attr
00482                                 QString style = colorstop.attribute( "style" ).simplified();
00483                                 QStringList substyles = QStringList::split( ';', style );
00484                             for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it )
00485                                 {
00486                                         QStringList substyle = QStringList::split( ':', (*it) );
00487                                         QString command = substyle[0].trimmed();
00488                                         QString params  = substyle[1].trimmed();
00489                                         if( command == "stop-color" )
00490                                                 parseSvgColor( c, params );
00491                                         if( command == "stop-opacity" )
00492                                                 stop->opacity = params.toDouble();
00493                                 }
00494 
00495                         }
00496                         if( !colorstop.attribute( "stop-opacity" ).isEmpty() )
00497                                 stop->opacity = colorstop.attribute( "stop-opacity" ).toDouble();
00498 
00499                         stop->offset = off;
00500                         stop->midpoint = 0.5;
00501                         stop->color1 = c.red() / 255.0;
00502                         stop->color2 = c.green() / 255.0;
00503                         stop->color3 = c.blue() / 255.0;
00504                         stop->color4 = 0.0;
00505                         stop->colorType = color_type_rgb;
00506                         stop->interpolation = interpolation_linear;
00507                         grad->colorStops.append(stop);
00508                 }
00509         }
00510 
00511         return grad;
00512 }
00513 
00514 void KoGradientManager::parseSvgColor(QColor &color, const QString &s)
00515 {
00516         if( s.startsWith( "rgb(" ) )
00517         {
00518                 QString parse = s.trimmed();
00519                 QStringList colors = QStringList::split( ',', parse );
00520                 QString r = colors[0].right( ( colors[0].length() - 4 ) );
00521                 QString g = colors[1];
00522                 QString b = colors[2].left( ( colors[2].length() - 1 ) );
00523 
00524                 if( r.contains( "%" ) )
00525                 {
00526                         r = r.left( r.length() - 1 );
00527                         r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) );
00528                 }
00529 
00530                 if( g.contains( "%" ) )
00531                 {
00532                         g = g.left( g.length() - 1 );
00533                         g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) );
00534                 }
00535 
00536                 if( b.contains( "%" ) )
00537                 {
00538                         b = b.left( b.length() - 1 );
00539                         b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) );
00540                 }
00541 
00542                 color = QColor( r.toInt(), g.toInt(), b.toInt() );
00543         }
00544         else
00545         {
00546                 QString rgbColor = s.trimmed();
00547                 QColor c;
00548                 if( rgbColor.startsWith( "#" ) )
00549                         c.setNamedColor( rgbColor );
00550                 else
00551                 {
00552                         int r, g, b;
00553                         svgNamedColorToRGB( rgbColor, r, g, b );
00554                         c = QColor( r, g, b );
00555                 }
00556                 color = c;
00557         }
00558 }
00559         

Généré le Wed Nov 22 23:41:06 2006 pour KPlato par  doxygen 1.5.1-p1