Warning, file /office/calligra/libs/flake/KoGradientHelper.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2008 Jan Hambrecht <jaham@gmx.net> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Library General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Library General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Library General Public License 0015 * along with this library; see the file COPYING.LIB. If not, write to 0016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "KoGradientHelper.h" 0021 0022 #include <QGradient> 0023 #include <math.h> 0024 0025 QGradient* KoGradientHelper::defaultGradient(QGradient::Type type, QGradient::Spread spread, const QGradientStops &stops) 0026 { 0027 QGradient *gradient = 0; 0028 switch (type) { 0029 case QGradient::LinearGradient: 0030 gradient = new QLinearGradient(QPointF(0.0, 0.5), QPointF(1, 0.5)); 0031 break; 0032 case QGradient::RadialGradient: 0033 gradient = new QRadialGradient(QPointF(0.5, 0.5), sqrt(0.5)); 0034 break; 0035 case QGradient::ConicalGradient: 0036 gradient = new QConicalGradient(QPointF(0.5, 0.5), 0.0); 0037 break; 0038 default: 0039 return 0; 0040 } 0041 gradient->setCoordinateMode(QGradient::ObjectBoundingMode); 0042 gradient->setSpread(spread); 0043 gradient->setStops(stops); 0044 0045 return gradient; 0046 } 0047 0048 QGradient* KoGradientHelper::convertGradient(const QGradient * gradient, QGradient::Type newType) 0049 { 0050 QPointF start, stop; 0051 // try to preserve gradient positions 0052 switch (gradient->type()) { 0053 case QGradient::LinearGradient: { 0054 const QLinearGradient *g = static_cast<const QLinearGradient*>(gradient); 0055 start = g->start(); 0056 stop = g->finalStop(); 0057 break; 0058 } 0059 case QGradient::RadialGradient: { 0060 const QRadialGradient *g = static_cast<const QRadialGradient*>(gradient); 0061 start = g->center(); 0062 stop = QPointF(g->radius(), 0.0); 0063 break; 0064 } 0065 case QGradient::ConicalGradient: { 0066 const QConicalGradient *g = static_cast<const QConicalGradient*>(gradient); 0067 start = g->center(); 0068 qreal radAngle = g->angle() * M_PI / 180.0; 0069 stop = QPointF(0.5 * cos(radAngle), 0.5 * sin(radAngle)); 0070 break; 0071 } 0072 default: 0073 start = QPointF(0.0, 0.0); 0074 stop = QPointF(0.5, 0.5); 0075 } 0076 0077 QGradient *newGradient = 0; 0078 switch (newType) { 0079 case QGradient::LinearGradient: 0080 newGradient = new QLinearGradient(start, stop); 0081 break; 0082 case QGradient::RadialGradient: { 0083 QPointF diff(stop - start); 0084 qreal radius = sqrt(diff.x()*diff.x() + diff.y()*diff.y()); 0085 newGradient = new QRadialGradient(start, radius, start); 0086 break; 0087 } 0088 case QGradient::ConicalGradient: { 0089 QPointF diff(stop - start); 0090 qreal angle = atan2(diff.y(), diff.x()); 0091 if (angle < 0.0) 0092 angle += 2 * M_PI; 0093 newGradient = new QConicalGradient(start, angle * 180/M_PI); 0094 break; 0095 } 0096 default: 0097 return 0; 0098 } 0099 newGradient->setCoordinateMode(QGradient::ObjectBoundingMode); 0100 newGradient->setSpread(gradient->spread()); 0101 newGradient->setStops(gradient->stops()); 0102 0103 return newGradient; 0104 } 0105 0106 QColor KoGradientHelper::colorAt(qreal position, const QGradientStops &stops) 0107 { 0108 if (! stops.count()) 0109 return QColor(); 0110 0111 if (stops.count() == 1) 0112 return stops.first().second; 0113 0114 QGradientStop prevStop(-1.0, QColor()); 0115 QGradientStop nextStop(2.0, QColor()); 0116 // find framing gradient stops 0117 foreach(const QGradientStop & stop, stops) { 0118 if (stop.first > prevStop.first && stop.first < position) 0119 prevStop = stop; 0120 if (stop.first < nextStop.first && stop.first > position) 0121 nextStop = stop; 0122 } 0123 0124 QColor theColor; 0125 0126 if (prevStop.first < 0.0) { 0127 // new stop is before the first stop 0128 theColor = nextStop.second; 0129 } else if (nextStop.first > 1.0) { 0130 // new stop is after the last stop 0131 theColor = prevStop.second; 0132 } else { 0133 // linear interpolate colors between framing stops 0134 QColor prevColor = prevStop.second, nextColor = nextStop.second; 0135 qreal colorScale = (position - prevStop.first) / (nextStop.first - prevStop.first); 0136 theColor.setRedF(prevColor.redF() + colorScale *(nextColor.redF() - prevColor.redF())); 0137 theColor.setGreenF(prevColor.greenF() + colorScale *(nextColor.greenF() - prevColor.greenF())); 0138 theColor.setBlueF(prevColor.blueF() + colorScale *(nextColor.blueF() - prevColor.blueF())); 0139 theColor.setAlphaF(prevColor.alphaF() + colorScale *(nextColor.alphaF() - prevColor.alphaF())); 0140 } 0141 return theColor; 0142 }