summaryrefslogtreecommitdiffstats
path: root/lib/kopainter
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kopainter')
-rw-r--r--lib/kopainter/Makefile.am21
-rw-r--r--lib/kopainter/koColor.cc742
-rw-r--r--lib/kopainter/koColor.h217
-rw-r--r--lib/kopainter/koColorChooser.cc675
-rw-r--r--lib/kopainter/koColorChooser.h236
-rw-r--r--lib/kopainter/koColorSlider.cc365
-rw-r--r--lib/kopainter/koColorSlider.h119
-rw-r--r--lib/kopainter/koFrameButton.cc102
-rw-r--r--lib/kopainter/koFrameButton.h60
-rw-r--r--lib/kopainter/koIconChooser.cc482
-rw-r--r--lib/kopainter/koIconChooser.h145
-rw-r--r--lib/kopainter/ko_cmyk_widget.cc403
-rw-r--r--lib/kopainter/ko_cmyk_widget.h116
-rw-r--r--lib/kopainter/ko_color_wheel.cc117
-rw-r--r--lib/kopainter/ko_color_wheel.h54
-rw-r--r--lib/kopainter/ko_gray_widget.cc157
-rw-r--r--lib/kopainter/ko_gray_widget.h80
-rw-r--r--lib/kopainter/ko_hsv_widget.cc274
-rw-r--r--lib/kopainter/ko_hsv_widget.h99
-rw-r--r--lib/kopainter/ko_rgb_widget.cc235
-rw-r--r--lib/kopainter/ko_rgb_widget.h98
-rw-r--r--lib/kopainter/kogradientmanager.cc559
-rw-r--r--lib/kopainter/kogradientmanager.h115
-rw-r--r--lib/kopainter/svgnamedcolors.h306
-rw-r--r--lib/kopainter/svgpathparser.cc577
-rw-r--r--lib/kopainter/svgpathparser.h60
26 files changed, 6414 insertions, 0 deletions
diff --git a/lib/kopainter/Makefile.am b/lib/kopainter/Makefile.am
new file mode 100644
index 00000000..8143db4d
--- /dev/null
+++ b/lib/kopainter/Makefile.am
@@ -0,0 +1,21 @@
+INCLUDES= $(KOFFICECORE_INCLUDES) $(KOFFICEUI_INCLUDES) $(all_includes)
+
+lib_LTLIBRARIES = libkopainter.la
+libkopainter_la_SOURCES = svgpathparser.cc \
+ koColor.cc \
+ koFrameButton.cc \
+ koColorSlider.cc \
+ koColorChooser.cc \
+ koIconChooser.cc \
+ kogradientmanager.cc \
+ ko_color_wheel.cc \
+ ko_gray_widget.cc \
+ ko_hsv_widget.cc \
+ ko_rgb_widget.cc \
+ ko_cmyk_widget.cc
+
+libkopainter_la_LDFLAGS = $(all_libraries) -version-info 2:0:0 -no-undefined
+
+libkopainter_la_LIBADD = $(LIB_KOFFICEUI)
+
+METASOURCES = AUTO
diff --git a/lib/kopainter/koColor.cc b/lib/kopainter/koColor.cc
new file mode 100644
index 00000000..e808ca8b
--- /dev/null
+++ b/lib/kopainter/koColor.cc
@@ -0,0 +1,742 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Matthias Elter (me@kde.org)
+ Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "koColor.h"
+#include "kdebug.h"
+#include <cmath>
+
+KoColor::KoColor()
+{
+ // initialise to black
+ mNative = csRGB;
+ // RGB
+ mR = 0;
+ mG = 0;
+ mB = 0;
+ // HSV
+ mH = mV = 0;
+ mS = 100;
+ // CMYK
+ mC = 0;
+ mY = 0;
+ mM = 0;
+ mK = 0;
+ // Lab
+ mL = 0;
+ ma = 0;
+ mB = 0;
+ rgbChanged();
+}
+
+KoColor::KoColor(int a, int b, int c, cSpace m)
+{
+ switch(m)
+ {
+ case csRGB:
+ mR = a;
+ mG = b;
+ mB = c;
+ mNative = csRGB;
+ rgbChanged();
+ break;
+ case csHSV:
+ mH = a;
+ mS = b;
+ mV = c;
+ mNative = csHSV;
+ hsvChanged();
+ break;
+ case csLab:
+ mL = a;
+ ma = b;
+ mB = c;
+ mNative = csLab;
+ labChanged();
+ break;
+ default:
+ mR = 0;
+ mG = 0;
+ mB = 0;
+ mNative = csRGB;
+ rgbChanged();
+ }
+}
+
+KoColor::KoColor(int c, int m, int y, int k)
+{
+ mC = c;
+ mM = m;
+ mY = y;
+ mK = k;
+ mNative = csCMYK;
+ cmykChanged();
+}
+
+KoColor::KoColor(const QColor &c)
+{
+ mR = c.red();
+ mG = c.green();
+ mB = c.blue();
+ mNative = csRGB;
+ rgbChanged();
+}
+
+KoColor::KoColor(const QString &name)
+{
+ setNamedColor(name);
+}
+
+int KoColor::R() const
+{
+ if(!mRGBvalid)
+ calcRGB();
+ return mR;
+}
+
+int KoColor::G() const
+{
+ if(!mRGBvalid)
+ calcRGB();
+ return mG;
+}
+
+int KoColor::B() const
+{
+ if(!mRGBvalid)
+ calcRGB();
+ return mB;
+}
+
+int KoColor::H() const
+{
+ if(!mHSVvalid)
+ calcHSV();
+ return mH;
+}
+
+int KoColor::S() const
+{
+ if(!mHSVvalid)
+ calcHSV();
+ return mS;
+}
+
+int KoColor::V() const
+{
+ if(!mHSVvalid)
+ calcHSV();
+ return mV;
+}
+
+int KoColor::C() const
+{
+ if(!mCMYKvalid)
+ calcCMYK();
+ return mC;
+}
+
+int KoColor::M() const
+{
+ if(!mCMYKvalid)
+ calcCMYK();
+ return mM;
+}
+
+int KoColor::Y() const
+{
+ if(!mCMYKvalid)
+ calcCMYK();
+ return mY;
+}
+
+int KoColor::K() const
+{
+ if(!mCMYKvalid)
+ calcCMYK();
+ return mK;
+}
+
+int KoColor::L() const
+{
+ if(!mLABvalid)
+ calcLAB();
+ return mL;
+}
+
+int KoColor::a() const
+{
+ if(!mLABvalid)
+ calcLAB();
+ return ma;
+}
+
+int KoColor::b() const
+{
+ if(!mLABvalid)
+ calcLAB();
+ return mB;
+}
+
+void KoColor::rgb(int *R, int *G, int *B) const
+{
+ if(!mRGBvalid)
+ calcRGB();
+ *R = mR;
+ *G = mG;
+ *B = mB;
+}
+
+void KoColor::hsv(int *H, int *S, int *V) const
+{
+ if(!mHSVvalid)
+ calcHSV();
+ *H = mH;
+ *S = mS;
+ *V = mV;
+}
+
+void KoColor::lab(int *L, int *a, int *b) const
+{
+ if(!mLABvalid)
+ calcLAB();
+ *L = mL;
+ *a = ma;
+ *b = mB;
+}
+
+void KoColor::cmyk(int *C, int *M, int *Y, int *K) const
+{
+ if(!mCMYKvalid)
+ calcCMYK();
+ *C = mC;
+ *M = mM;
+ *Y = mY;
+ *K = mK;
+}
+
+QString KoColor::name() const
+{
+ QString s;
+ switch(mNative)
+ {
+ case csRGB:
+ s.sprintf("#%02x%02x%02x", R(), G(), B());
+ break;
+ case csHSV:
+ s.sprintf("$%02x%02x%02x", H(), S(), V());
+ break;
+ case csCMYK:
+ s.sprintf("@%02x%02x%02x%02x", C(), M(), Y(), K());
+ break;
+ case csLab:
+ s.sprintf("*%02x%02x%02x", L(), a(), b());
+ break;
+ default:
+ s.sprintf("#%02x%02x%02x", R(), G(), B());
+ }
+ return s;
+}
+
+QColor KoColor::color() const
+{
+ if(!mRGBvalid)
+ calcRGB();
+ return QColor(mR, mG, mB);
+}
+
+void KoColor::setRGB(int R, int G, int B)
+{
+ mR = R;
+ mG = G;
+ mB = B;
+ mNative = csRGB;
+ rgbChanged();
+}
+
+void KoColor::setHSV(int H, int S, int V)
+{
+ mH = H;
+ mS = S;
+ mV = V;
+ mNative = csHSV;
+ hsvChanged();
+}
+
+void KoColor::setLab(int L, int a, int b)
+{
+ mL = L;
+ ma = a;
+ mB = b;
+ mNative = csLab;
+ labChanged();
+}
+
+void KoColor::setCMYK(int C, int M, int Y, int K)
+{
+ mC = C;
+ mM = M;
+ mY = Y;
+ mK = K;
+ mNative = csCMYK;
+ cmykChanged();
+}
+
+void KoColor::setNamedColor(const QString &name)
+{
+ switch(name[0])
+ {
+ case '#':
+ mR = (hex2int(name[1]) << 4) + hex2int(name[2]);
+ mG = (hex2int(name[3]) << 4) + hex2int(name[4]);
+ mB = (hex2int(name[5]) << 4) + hex2int(name[6]);
+ mNative = csRGB;
+ rgbChanged();
+ break;
+ case '$':
+ mH = (hex2int(name[1]) << 4) + hex2int(name[2]);
+ mS = (hex2int(name[3]) << 4) + hex2int(name[4]);
+ mV = (hex2int(name[5]) << 4) + hex2int(name[6]);
+ mNative = csHSV;
+ hsvChanged();
+ break;
+ case '@':
+ mC = (hex2int(name[1]) << 4) + hex2int(name[2]);
+ mM = (hex2int(name[3]) << 4) + hex2int(name[4]);
+ mY = (hex2int(name[5]) << 4) + hex2int(name[6]);
+ mK = (hex2int(name[7]) << 4) + hex2int(name[8]);
+ mNative = csCMYK;
+ cmykChanged();
+ break;
+ case '*':
+ mL = (hex2int(name[1]) << 4) + hex2int(name[2]);
+ ma = (hex2int(name[3]) << 4) + hex2int(name[4]);
+ mb = (hex2int(name[5]) << 4) + hex2int(name[6]);
+ mNative = csLab;
+ labChanged();
+ break;
+ default:
+ mR = 0;
+ mG = 0;
+ mB = 0;
+ mNative = csRGB;
+ rgbChanged();
+ }
+}
+
+void KoColor::setColor(const QColor &c)
+{
+ mR = c.red();
+ mG = c.green();
+ mB = c.blue();
+ mNative = csRGB;
+ rgbChanged();
+}
+
+void KoColor::RGBtoHSV(int R, int G, int B, int *H, int *S, int *V)
+{
+ unsigned int max = R;
+ unsigned int min = R;
+ unsigned char maxValue = 0; // r = 0, g = 1, b = 2
+
+ // find maximum and minimum RGB values
+ if(static_cast<unsigned int>(G) > max)
+ {
+ max = G;
+ maxValue = 1;
+ }
+ if(static_cast<unsigned int>(B) > max)
+ {
+ max = B;
+ maxValue = 2;
+ }
+
+ if(static_cast<unsigned int>(G) < min)
+ min = G;
+ if(static_cast<unsigned int>(B) < min )
+ min = B;
+
+ int delta = max - min;
+ *V = max; // value
+ *S = max ? (510 * delta + max) / ( 2 * max) : 0; // saturation
+
+ // calc hue
+ if(*S == 0)
+ *H = -1; // undefined hue
+ else
+ {
+ switch(maxValue)
+ {
+ case 0: // red
+ if(G >= B)
+ *H = (120 * (G - B) + delta) / (2 * delta);
+ else
+ *H = (120 * (G - B + delta) + delta) / (2 * delta) + 300;
+ break;
+ case 1: // green
+ if(B > R)
+ *H = 120 + (120 * (B - R) + delta) / (2 * delta);
+ else
+ *H = 60 + (120 * (B - R + delta) + delta) / (2 * delta);
+ break;
+ case 2: // blue
+ if(R > G)
+ *H = 240 + (120 * (R - G) + delta) / (2 * delta);
+ else
+ *H = 180 + (120 * (R - G + delta) + delta) / (2 * delta);
+ break;
+ }
+ }
+}
+
+void KoColor::RGBtoLAB(int R, int G, int B, int *L, int *a, int *b)
+{
+ // Convert between RGB and CIE-Lab color spaces
+ // Uses ITU-R recommendation BT.709 with D65 as reference white.
+ // algorithm contributed by "Mark A. Ruzon" <ruzon@CS.Stanford.EDU>
+
+ double X, Y, Z, fX, fY, fZ;
+
+ X = 0.412453 * R + 0.357580 * G + 0.180423 * B;
+ Y = 0.212671 * R + 0.715160 * G + 0.072169 * B;
+ Z = 0.019334 * R + 0.119193 * G + 0.950227 * B;
+
+ X /= (255 * 0.950456);
+ Y /= 255;
+ Z /= (255 * 1.088754);
+
+ if(Y > 0.008856)
+ {
+ fY = pow(Y, 1.0 / 3.0);
+ *L = static_cast<int>(116.0 * fY - 16.0 + 0.5);
+ }
+ else
+ {
+ fY = 7.787 * Y + 16.0 / 116.0;
+ *L = static_cast<int>(903.3 * Y + 0.5);
+ }
+
+ if(X > 0.008856)
+ fX = pow(X, 1.0 / 3.0);
+ else
+ fX = 7.787 * X + 16.0 / 116.0;
+
+ if(Z > 0.008856)
+ fZ = pow(Z, 1.0 / 3.0);
+ else
+ fZ = 7.787 * Z + 16.0 / 116.0;
+
+ *a = static_cast<int>(500.0 * (fX - fY) + 0.5);
+ *b = static_cast<int>(200.0 * (fY - fZ) + 0.5);
+}
+
+void KoColor::RGBtoCMYK(int R, int G, int B, int *C, int *M, int *Y, int *K)
+{
+ // XXX: these algorithms aren't the best. See www.littlecms.com
+ // for a suitable library, or the posting by Leo Rosenthol for
+ // a better, but slower algorithm at
+ // http://lists.kde.org/?l=koffice-devel&m=106698241227054&w=2
+
+ *C = 255 - R;
+ *M = 255 - G;
+ *Y = 255 - B;
+
+ int min = (*C < *M) ? *C : *M;
+ *K = (min < *Y) ? min : *Y;
+
+ *C -= *K;
+ *M -= *K;
+ *Y -= *K;
+
+}
+
+
+void KoColor::HSVtoRGB(int H, int S, int V, int *R, int *G, int *B)
+{
+ *R = *G = *B = V;
+
+ if(S != 0 && H != -1) // chromatic
+ {
+ if(H >= 360) // angle > 360
+ H %= 360;
+
+ unsigned int f = H % 60;
+ H /= 60;
+ unsigned int p = static_cast<unsigned int>(2*V*(255-S)+255)/510;
+ unsigned int q, t;
+
+ if(H & 1)
+ {
+ q = static_cast<unsigned int>(2 * V * (15300 - S * f) + 15300) / 30600;
+ switch(H)
+ {
+ case 1:
+ *R = static_cast<int>(q);
+ *G = static_cast<int>(V);
+ *B = static_cast<int>(p);
+ break;
+ case 3:
+ *R = static_cast<int>(p);
+ *G = static_cast<int>(q);
+ *B = static_cast<int>(V);
+ break;
+ case 5:
+ *R = static_cast<int>(V);
+ *G = static_cast<int>(p);
+ *B = static_cast<int>(q);
+ break;
+ }
+ }
+ else
+ {
+ t = static_cast<unsigned int>(2 * V * (15300 - (S * (60 - f))) + 15300) / 30600;
+ switch(H)
+ {
+ case 0:
+ *R = static_cast<int>(V);
+ *G = static_cast<int>(t);
+ *B = static_cast<int>(p);
+ break;
+ case 2:
+ *R = static_cast<int>(p);
+ *G = static_cast<int>(V);
+ *B = static_cast<int>(t);
+ break;
+ case 4:
+ *R = static_cast<int>(t);
+ *G = static_cast<int>(p);
+ *B = static_cast<int>(V);
+ break;
+ }
+ }
+ }
+}
+
+void KoColor::HSVtoLAB(int H, int S, int V, int *L, int *a, int *b)
+{
+ int R, G, B;
+ HSVtoRGB(H, S, V, &R, &G, &B);
+ RGBtoLAB(R, G, B, L, a, b);
+}
+
+void KoColor::HSVtoCMYK(int H, int S, int V, int *C, int *M, int *Y, int*K)
+{
+ int R, G, B;
+ HSVtoRGB(H, S, V, &R, &G, &B);
+ RGBtoCMYK(R, G, B, C, M, Y, K);
+}
+
+void KoColor::LABtoRGB(int L, int a, int b, int *R, int *G, int *B)
+{
+ // Convert between RGB and CIE-Lab color spaces
+ // Uses ITU-R recommendation BT.709 with D65 as reference white.
+ // algorithm contributed by "Mark A. Ruzon" <ruzon@CS.Stanford.EDU>
+
+ double X, Y, Z, fX, fY, fZ;
+ int RR, GG, BB;
+
+ fY = pow((L + 16.0) / 116.0, 3.0);
+ if(fY < 0.008856)
+ fY = L / 903.3;
+ Y = fY;
+
+ if(fY > 0.008856)
+ fY = pow(fY, 1.0 / 3.0);
+ else
+ fY = 7.787 * fY + 16.0 / 116.0;
+
+ fX = a / 500.0 + fY;
+ if(fX > 0.206893)
+ X = pow(fX, 3.0);
+ else
+ X = (fX - 16.0 / 116.0) / 7.787;
+
+ fZ = fY - b / 200.0;
+ if(fZ > 0.206893)
+ Z = pow(fZ, 3.0);
+ else
+ Z = (fZ - 16.0/116.0) / 7.787;
+
+ X *= 0.950456 * 255;
+ Y *= 255;
+ Z *= 1.088754 * 255;
+
+ RR = static_cast<int>(3.240479 * X - 1.537150 * Y - 0.498535 * Z + 0.5);
+ GG = static_cast<int>(-0.969256 * X + 1.875992 * Y + 0.041556 * Z + 0.5);
+ BB = static_cast<int>(0.055648 * X - 0.204043 * Y + 1.057311 * Z + 0.5);
+
+ *R = RR < 0 ? 0 : RR > 255 ? 255 : RR;
+ *G = GG < 0 ? 0 : GG > 255 ? 255 : GG;
+ *B = BB < 0 ? 0 : BB > 255 ? 255 : BB;
+}
+
+void KoColor::LABtoHSV(int L, int a, int b, int *H, int *S, int *V)
+{
+ int R, G, B;
+ LABtoRGB(L, a, b, &R, &G, &B);
+ RGBtoHSV(R, G, B, H, S, V);
+}
+
+void KoColor::LABtoCMYK(int L, int a, int b, int *C, int *M, int *Y, int*K)
+{
+ int R, G, B;
+ LABtoRGB(L, a, b, &R, &G, &B);
+ RGBtoCMYK(R, G, B, C, M, Y, K);
+}
+
+void KoColor::CMYKtoRGB(int C, int M, int Y, int K, int *R, int *G, int *B)
+{
+ *R = 255 - (C + K);
+ *G = 255 - (M + K);
+ *B = 255 - (Y + K);
+}
+
+void KoColor::CMYKtoHSV(int C, int M, int Y, int K, int *H, int *S, int *V)
+{
+ int R, G, B;
+ CMYKtoRGB(C, M, Y, K, &R, &G, &B);
+ RGBtoHSV(R, G, B, H, S, V);
+}
+
+void KoColor::CMYKtoLAB(int C, int M, int Y, int K, int *L, int *a, int *b)
+{
+ int R, G, B;
+ CMYKtoRGB(C, M, Y, K, &R, &G, &B);
+ RGBtoLAB(R, G, B, L, a, b);
+}
+
+int KoColor::hex2int(QChar c)
+{
+ if(c.isDigit())
+ return c.digitValue();
+ else if('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ else if('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ else
+ return 0;
+}
+
+void KoColor::calcRGB() const
+{
+ switch(mNative)
+ {
+ case csHSV:
+ HSVtoRGB(mH, mS, mV, &mR, &mG, &mB);
+ break;
+ case csLab:
+ LABtoRGB(mL, ma, mB, &mR, &mG, &mB);
+ break;
+ case csCMYK:
+ CMYKtoRGB(mC, mM, mY, mK, &mR, &mG, &mB);
+ break;
+ default:
+ break;
+ }
+ mRGBvalid = true;
+}
+
+void KoColor::calcHSV() const
+{
+ switch(mNative)
+ {
+ case csRGB:
+ RGBtoHSV(mR, mG, mB, &mH, &mS, &mV);
+ break;
+ case csLab:
+ LABtoHSV(mL, ma, mB, &mH, &mS, &mV);
+ break;
+ case csCMYK:
+ CMYKtoHSV(mC, mM, mY, mK, &mH, &mS, &mV);
+ break;
+ default:
+ break;
+ }
+ mHSVvalid = true;
+}
+
+void KoColor::calcCMYK() const
+{
+ switch(mNative)
+ {
+ case csRGB:
+ RGBtoCMYK(mR, mG, mB, &mC, &mM, &mY, &mK);
+ break;
+ case csLab:
+ LABtoCMYK(mL, ma, mB, &mC, &mM, &mY, &mK);
+ break;
+ case csHSV:
+ HSVtoCMYK(mH, mS, mV, &mC, &mM, &mY, &mK);
+ break;
+ default:
+ break;
+ }
+ mCMYKvalid = true;
+}
+
+void KoColor::calcLAB() const
+{
+ switch(mNative)
+ {
+ case csRGB:
+ RGBtoLAB(mR, mG, mB, &mL, &ma, &mB);
+ break;
+ case csHSV:
+ HSVtoLAB(mH, mS, mV, &mL, &ma, &mB);
+ break;
+ case csCMYK:
+ CMYKtoLAB(mC, mM, mY, mK, &mL, &ma, &mB);
+ break;
+ default:
+ break;
+ }
+ mLABvalid = true;
+}
+
+void KoColor::rgbChanged() const
+{
+ mRGBvalid = true;
+ mHSVvalid = false;
+ mCMYKvalid = false;
+ mLABvalid = false;
+}
+
+void KoColor::hsvChanged() const
+{
+ mRGBvalid = false;
+ mHSVvalid = true;
+ mCMYKvalid = false;
+ mLABvalid = false;
+}
+
+void KoColor::cmykChanged() const
+{
+ mRGBvalid = false;
+ mHSVvalid = false;
+ mCMYKvalid = true;
+ mLABvalid = false;
+}
+
+void KoColor::labChanged() const
+{
+ mRGBvalid = false;
+ mHSVvalid = false;
+ mCMYKvalid = false;
+ mLABvalid = true;
+}
diff --git a/lib/kopainter/koColor.h b/lib/kopainter/koColor.h
new file mode 100644
index 00000000..f955754f
--- /dev/null
+++ b/lib/kopainter/koColor.h
@@ -0,0 +1,217 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Matthias Elter (me@kde.org)
+ Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __ko_color_h__
+#define __ko_color_h__
+
+#include <qcolor.h>
+#include <koffice_export.h>
+class KOPAINTER_EXPORT KoColor
+{
+public:
+ enum cSpace{ csIndexed, csRGB, csHSV, csCMYK, csLab };
+
+ KoColor();
+ KoColor(int a, int b, int c, cSpace m = csRGB);
+ KoColor(int c, int m, int y, int k);
+ KoColor(const QString &name);
+ KoColor(const QColor &c);
+
+ cSpace native() const {return mNative; }
+
+ int R() const;
+ int G() const;
+ int B() const;
+ int H() const;
+ int S() const;
+ int V() const;
+ int L() const;
+ int a() const;
+ int b() const;
+ int C() const;
+ int M() const;
+ int Y() const;
+ int K() const;
+
+ void rgb(int *R, int *G, int *B) const;
+ void hsv(int *H, int *S, int *V) const;
+ void lab(int *L, int *a, int *b) const;
+ void cmyk(int *C, int *M, int *Y, int *K) const;
+ QString name() const;
+ QColor color() const;
+
+ void setRGB(int R, int G, int B);
+ void setHSV(int H, int S, int V);
+ void setLab(int L, int a, int b);
+ void setCMYK(int C, int M, int Y, int K);
+ void setNamedColor(const QString &name);
+ void setColor(const QColor &c);
+
+ static void RGBtoHSV(int R, int G, int B, int *H, int *S, int *V);
+ static void RGBtoLAB(int R, int G, int B, int *L, int *a, int *b);
+ static void RGBtoCMYK(int R, int G, int B, int *C, int *M, int *Y, int *K);
+
+ static void HSVtoRGB(int H, int S, int V, int *R, int *G, int *B);
+ static void HSVtoLAB(int H, int S, int V, int *L, int *a, int *b);
+ static void HSVtoCMYK(int H, int S, int V, int *C, int *M, int *Y, int*K);
+
+ static void LABtoRGB(int L, int a, int b, int *R, int *G, int *B);
+ static void LABtoHSV(int L, int a, int b, int *H, int *S, int *V);
+ static void LABtoCMYK(int L, int a, int b, int *C, int *M, int *Y, int*K);
+
+ static void CMYKtoRGB(int C, int M, int Y, int K, int *R, int *G, int *B);
+ static void CMYKtoHSV(int C, int M, int Y, int K, int *H, int *S, int *V);
+ static void CMYKtoLAB(int C, int M, int Y, int K, int *L, int *a, int *b);
+
+ static const KoColor black();
+ static const KoColor white();
+ static const KoColor gray();
+ static const KoColor lightGray();
+ static const KoColor darkGray();
+ static const KoColor red();
+ static const KoColor darkRed();
+ static const KoColor green();
+ static const KoColor darkGreen();
+ static const KoColor blue();
+ static const KoColor darkBlue();
+ static const KoColor cyan();
+ static const KoColor darkCyan();
+ static const KoColor magenta();
+ static const KoColor darkMagenta();
+ static const KoColor yellow();
+ static const KoColor darkYellow();
+
+protected:
+ int hex2int(QChar c);
+
+ void calcRGB() const;
+ void calcHSV() const;
+ void calcCMYK() const;
+ void calcLAB() const;
+
+ void rgbChanged() const;
+ void hsvChanged() const;
+ void cmykChanged() const;
+ void labChanged() const;
+
+private:
+ /*
+ * Mutable to make it possible for const objects to transform the native cModel
+ * in functions like KoColor::rgb(...) to the requested.
+ */
+ mutable int mR, mG, mB; // RGB
+ mutable int mC, mM, mY, mK; // CMYK
+ mutable int mH, mS, mV; // HSV
+ mutable int mL, ma, mb; // LAB
+
+ mutable bool mRGBvalid;
+ mutable bool mHSVvalid;
+ mutable bool mCMYKvalid;
+ mutable bool mLABvalid;
+
+ cSpace mNative;
+};
+
+inline const KoColor KoColor::white()
+{
+ return KoColor(255, 255, 255, csRGB);
+}
+
+inline const KoColor KoColor::black()
+{
+ return KoColor(0, 0, 0, csRGB);
+}
+
+inline const KoColor KoColor::gray()
+{
+ return KoColor(160, 160, 164, csRGB);
+}
+
+inline const KoColor KoColor::lightGray()
+{
+ return KoColor(192, 192, 192, csRGB);
+}
+
+inline const KoColor KoColor::darkGray()
+{
+ return KoColor(128, 128, 128, csRGB);
+}
+
+inline const KoColor KoColor::red()
+{
+ return KoColor(255, 0, 0, csRGB);
+}
+
+inline const KoColor KoColor::darkRed()
+{
+ return KoColor(128, 0, 0, csRGB);
+}
+
+inline const KoColor KoColor::green()
+{
+ return KoColor(0, 255, 0, csRGB);
+}
+
+inline const KoColor KoColor::darkGreen()
+{
+ return KoColor(0, 128, 0, csRGB);
+}
+
+inline const KoColor KoColor::blue()
+{
+ return KoColor(0, 0, 255, csRGB);
+}
+
+inline const KoColor KoColor::darkBlue()
+{
+ return KoColor(0, 0, 128, csRGB);
+}
+
+inline const KoColor KoColor::cyan()
+{
+ return KoColor(0, 255, 255, csRGB);
+}
+
+inline const KoColor KoColor::darkCyan()
+{
+ return KoColor(0, 128, 128, csRGB);
+}
+
+inline const KoColor KoColor::magenta()
+{
+ return KoColor(255, 0, 255, csRGB);
+}
+
+inline const KoColor KoColor::darkMagenta()
+{
+ return KoColor(128, 0, 128, csRGB);
+}
+
+inline const KoColor KoColor::yellow()
+{
+ return KoColor(255, 255, 0, csRGB);
+}
+
+inline const KoColor KoColor::darkYellow()
+{
+ return KoColor(128, 128, 0, csRGB);
+}
+
+#endif
diff --git a/lib/kopainter/koColorChooser.cc b/lib/kopainter/koColorChooser.cc
new file mode 100644
index 00000000..e321123a
--- /dev/null
+++ b/lib/kopainter/koColorChooser.cc
@@ -0,0 +1,675 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Matthias Elter (me@kde.org)
+ Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "koColorChooser.h"
+
+#include <qcolor.h>
+#include <qlayout.h>
+#include <qspinbox.h>
+#include <qtabwidget.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kcolordialog.h>
+#include <ktabctl.h>
+#include <koFrameButton.h>
+#include <koColorSlider.h>
+
+KoColorChooser::KoColorChooser(QWidget *parent, const char *name) : QWidget(parent, name)
+{
+ m_current = 0;
+ m_tab = new QTabWidget(this, "KoColorChooser tab");
+ mGrid = new QGridLayout(this, 3, 5);
+ mRGBWidget = new RGBWidget(m_tab);
+ m_current = mRGBWidget;
+ m_tab -> addTab(mRGBWidget, "RGB");
+ mHSVWidget = new HSVWidget(m_tab);
+ m_tab -> addTab(mHSVWidget, "HSV");
+#if 0
+ mCMYKWidget = new QWidget(m_tab);
+ m_tab -> addTab(mCMYKWidget, "CMYK");
+ mLABWidget = new LABWidget(m_tab);
+ m_tab -> addTab(mLABWidget, "LAB");
+#endif
+ mGreyWidget = new GreyWidget(m_tab);
+ m_tab -> addTab(mGreyWidget, i18n("Gray"));
+ mColorSelector = new KHSSelector(this);
+ mColorSelector->setFixedHeight(20);
+ mGrid->addMultiCellWidget(m_tab, 0, 1, 0, 4);
+ mGrid->addMultiCellWidget(mColorSelector, 2, 2, 0, 4);
+ connect(mRGBWidget, SIGNAL(colorChanged(const KoColor &)), this, SLOT(childColorChanged(const KoColor &)));
+ connect(mHSVWidget, SIGNAL(colorChanged(const KoColor &)), this, SLOT(childColorChanged(const KoColor &)));
+// connect(mLABWidget, SIGNAL(colorChanged(const KoColor &)), this, SLOT(childColorChanged(const KoColor &)));
+ connect(mGreyWidget, SIGNAL(colorChanged(const KoColor &)), this, SLOT(childColorChanged(const KoColor &)));
+ connect(mColorSelector, SIGNAL(valueChanged(int, int)), this, SLOT(slotChangeXY(int, int)));
+ connect(m_tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(slotCurrentChanged(QWidget*)));
+ slotChangeColor(KoColor::black());
+}
+
+void KoColorChooser::slotCurrentChanged(QWidget *current)
+{
+ m_current = static_cast<ColorWidget*>(current);
+ m_current -> slotChangeColor(mColor);
+}
+
+void KoColorChooser::slotChangeXY(int h, int s)
+{
+ KoColor c(h, s, 192, KoColor::csHSV);
+
+ m_current -> slotChangeColor(c);
+}
+
+void KoColorChooser::slotChangeColor(const QColor &c)
+{
+ slotChangeColor(KoColor(c));
+}
+
+void KoColorChooser::childColorChanged(const KoColor& c)
+{
+ mColor.setRGB(c.R(), c.G(), c.B());
+ emit colorChanged(mColor);
+}
+
+void KoColorChooser::slotChangeColor(const KoColor &c)
+{
+ mColor = c;
+ m_current -> slotChangeColor(mColor);
+ mColorSelector->setValues(c.H(), c.S());
+}
+
+/* RGBWidget */
+RGBWidget::RGBWidget(QWidget *parent) : ColorWidget(parent)
+{
+ QGridLayout *mGrid = new QGridLayout(this, 4, 5);
+
+ mColorPatch = new KColorPatch(this);
+
+ /* setup color sliders */
+ mRSlider = new KoColorSlider(this);
+ mRSlider->setMaximumHeight(20);
+ mRSlider->slotSetRange(0, 255);
+
+ mGSlider = new KoColorSlider(this);
+ mGSlider->setMaximumHeight(20);
+ mGSlider->slotSetRange(0, 255);
+
+ mBSlider = new KoColorSlider(this);
+ mBSlider->setMaximumHeight(20);
+ mBSlider->slotSetRange(0, 255);
+
+ /* setup slider labels */
+ mRLabel = new QLabel("R", this);
+ mRLabel->setFixedWidth(16);
+ mRLabel->setFixedHeight(20);
+ mGLabel = new QLabel("G", this);
+ mGLabel->setFixedWidth(16);
+ mGLabel->setFixedHeight(20);
+ mBLabel = new QLabel("B", this);
+ mBLabel->setFixedWidth(16);
+ mBLabel->setFixedHeight(20);
+
+ /* setup spin box */
+ mRIn = new QSpinBox(0, 255, 1, this);
+ mRIn->setFixedWidth(42);
+ mRIn->setFixedHeight(20);
+ mGIn = new QSpinBox(0, 255, 1, this);
+ mGIn->setFixedWidth(42);
+ mGIn->setFixedHeight(20);
+ mBIn = new QSpinBox(0, 255, 1, this);
+ mBIn->setFixedWidth(42);
+ mBIn->setFixedHeight(20);
+
+ mGrid->addMultiCellWidget(mColorPatch, 0, 4, 0, 0);
+ mGrid->addWidget(mRLabel, 1, 1);
+ mGrid->addWidget(mGLabel, 2, 1);
+ mGrid->addWidget(mBLabel, 3, 1);
+ mGrid->addMultiCellWidget(mRSlider, 1, 1, 2, 3);
+ mGrid->addMultiCellWidget(mGSlider, 2, 2, 2, 3);
+ mGrid->addMultiCellWidget(mBSlider, 3, 3, 2, 3);
+ mGrid->addWidget(mRIn, 1, 4);
+ mGrid->addWidget(mGIn, 2, 4);
+ mGrid->addWidget(mBIn, 3, 4);
+
+ connect(mColorPatch, SIGNAL(colorChanged(const QColor &)), this, SLOT(slotPatchChanged(const QColor &)));
+
+ /* connect color sliders */
+ connect(mRSlider, SIGNAL(valueChanged(int)), this, SLOT(slotRSliderChanged(int)));
+ connect(mGSlider, SIGNAL(valueChanged(int)), this, SLOT(slotGSliderChanged(int)));
+ connect(mBSlider, SIGNAL(valueChanged(int)), this, SLOT(slotBSliderChanged(int)));
+
+ /* connect spin box */
+ connect(mRIn, SIGNAL(valueChanged(int)), this, SLOT(slotRInChanged(int)));
+ connect(mGIn, SIGNAL(valueChanged(int)), this, SLOT(slotGInChanged(int)));
+ connect(mBIn, SIGNAL(valueChanged(int)), this, SLOT(slotBInChanged(int)));
+}
+
+ColorWidget::ColorWidget(QWidget *parent) : QWidget(parent)
+{
+}
+
+ColorWidget::~ColorWidget()
+{
+}
+
+void ColorWidget::slotChangeColor(const KoColor& c)
+{
+ mColor.setRGB(c.R(), c.G(), c.B());
+ slotRefreshColor();
+}
+
+void ColorWidget::slotChangeColor(const QColor& c)
+{
+ mColor.setColor(c);
+ slotRefreshColor();
+}
+
+void RGBWidget::slotRefreshColor()
+{
+ int r = mColor.R();
+ int g = mColor.G();
+ int b = mColor.B();
+
+ mRSlider->slotSetColor1(QColor(0, g, b));
+ mRSlider->slotSetColor2(QColor(255, g, b));
+ mRSlider->slotSetValue(r);
+ mRIn->setValue(r);
+
+ mGSlider->slotSetColor1(QColor(r, 0, b));
+ mGSlider->slotSetColor2(QColor(r, 255, b));
+ mGSlider->slotSetValue(g);
+ mGIn->setValue(g);
+
+ mBSlider->slotSetColor1(QColor(r, g, 0));
+ mBSlider->slotSetColor2(QColor(r, g, 255));
+ mBSlider->slotSetValue(b);
+ mBIn->setValue(b);
+ mColorPatch -> setColor(mColor.color());
+}
+
+void RGBWidget::slotRSliderChanged(int r)
+{
+ int g = mColor.G();
+ int b = mColor.B();
+
+ mColor.setRGB(r, g, b);
+ slotRefreshColor();
+ emit colorChanged(KoColor(r, g, b, KoColor::csRGB));
+}
+
+void RGBWidget::slotGSliderChanged(int g)
+{
+ int r = mColor.R();
+ int b = mColor.B();
+
+ mColor.setRGB(r, g, b);
+ slotRefreshColor();
+ emit colorChanged(KoColor( r, g, b, KoColor::csRGB));
+}
+
+void RGBWidget::slotBSliderChanged(int b)
+{
+ int r = mColor.R();
+ int g = mColor.G();
+
+ mColor.setRGB(r, g, b);
+ slotRefreshColor();
+ emit colorChanged(KoColor(r, g, b, KoColor::csRGB));
+}
+
+void RGBWidget::slotRInChanged(int r)
+{
+ int g = mColor.G();
+ int b = mColor.B();
+
+ mColor.setRGB(r, g, b);
+ slotRefreshColor();
+ emit colorChanged(KoColor(r, g, b, KoColor::csRGB));
+}
+
+void RGBWidget::slotGInChanged(int g)
+{
+ int r = mColor.R();
+ int b = mColor.B();
+
+ mColor.setRGB(r, g, b);
+ slotRefreshColor();
+ emit colorChanged(KoColor(r, g, b, KoColor::csRGB));
+}
+
+void RGBWidget::slotBInChanged(int b)
+{
+ int r = mColor.R();
+ int g = mColor.G();
+
+ mColor.setRGB(r, g, b);
+ slotRefreshColor();
+ emit colorChanged(KoColor(r, g, b, KoColor::csRGB));
+}
+
+void RGBWidget::slotPatchChanged(const QColor& clr)
+{
+ int r = clr.red();
+ int g = clr.green();
+ int b = clr.blue();
+
+ mColor.setRGB(r, g, b);
+ slotRefreshColor();
+ emit colorChanged(KoColor(r, g, b, KoColor::csRGB));
+}
+
+/* HSVWidget */
+
+HSVWidget::HSVWidget(QWidget *parent): ColorWidget(parent)
+{
+ QGridLayout *mGrid = new QGridLayout(this, 3, 3);
+
+ mColorPatch = new KColorPatch(this);
+
+ /* setup color sliders */
+ mHSlider = new KoColorSlider(this);
+ mHSlider->setMaximumHeight(20);
+ mHSlider->slotSetRange(0, 359);
+
+ mSSlider = new KoColorSlider(this);
+ mSSlider->setMaximumHeight(20);
+ mSSlider->slotSetRange(0, 255);
+
+ mVSlider = new KoColorSlider(this);
+ mVSlider->setMaximumHeight(20);
+ mVSlider->slotSetRange(0, 255);
+
+ /* setup slider labels */
+ mHLabel = new QLabel("H", this);
+ mHLabel->setFixedWidth(16);
+ mHLabel->setFixedHeight(20);
+ mSLabel = new QLabel("S", this);
+ mSLabel->setFixedWidth(16);
+ mSLabel->setFixedHeight(20);
+ mVLabel = new QLabel("V", this);
+ mVLabel->setFixedWidth(16);
+ mVLabel->setFixedHeight(20);
+
+ /* setup spin box */
+ mHIn = new QSpinBox(0, 359, 1, this);
+ mHIn->setFixedWidth(42);
+ mHIn->setFixedHeight(20);
+ mSIn = new QSpinBox(0, 255, 1, this);
+ mSIn->setFixedWidth(42);
+ mSIn->setFixedHeight(20);
+ mVIn = new QSpinBox(0, 255, 1, this);
+ mVIn->setFixedWidth(42);
+ mVIn->setFixedHeight(20);
+
+ mGrid->addMultiCellWidget(mColorPatch, 0, 4, 0, 0);
+ mGrid->addWidget(mHLabel, 1, 1);
+ mGrid->addWidget(mSLabel, 2, 1);
+ mGrid->addWidget(mVLabel, 3, 1);
+ mGrid->addMultiCellWidget(mHSlider, 1, 1, 2, 3);
+ mGrid->addMultiCellWidget(mSSlider, 2, 2, 2, 3);
+ mGrid->addMultiCellWidget(mVSlider, 3, 3, 2, 3);
+ mGrid->addWidget(mHIn, 1, 4);
+ mGrid->addWidget(mSIn, 2, 4);
+ mGrid->addWidget(mVIn, 3, 4);
+
+ connect(mColorPatch, SIGNAL(colorChanged(const QColor &)), this, SLOT(slotPatchChanged(const QColor &)));
+
+ /* connect color sliders */
+ connect(mHSlider, SIGNAL(valueChanged(int)), this, SLOT(slotHSliderChanged(int)));
+ connect(mSSlider, SIGNAL(valueChanged(int)), this, SLOT(slotSSliderChanged(int)));
+ connect(mVSlider, SIGNAL(valueChanged(int)), this, SLOT(slotVSliderChanged(int)));
+
+ /* connect spin box */
+ connect(mHIn, SIGNAL(valueChanged(int)), this, SLOT(slotHInChanged(int)));
+ connect(mSIn, SIGNAL(valueChanged(int)), this, SLOT(slotSInChanged(int)));
+ connect(mVIn, SIGNAL(valueChanged(int)), this, SLOT(slotVInChanged(int)));
+}
+
+void HSVWidget::slotRefreshColor()
+{
+ int h = mColor.H();
+ int s = mColor.S();
+ int v = mColor.V();
+
+ mHSlider->slotSetColor1(KoColor(0, s, v, KoColor::csHSV).color());
+ mHSlider->slotSetColor2(KoColor(359, s, v, KoColor::csHSV).color());
+ mHSlider->slotSetValue(h);
+ mHIn->setValue(h);
+
+ mSSlider->slotSetColor1(KoColor(h, 0, v, KoColor::csHSV).color());
+ mSSlider->slotSetColor2(KoColor(h, 255, v, KoColor::csHSV).color());
+ mSSlider->slotSetValue(s);
+ mSIn->setValue(s);
+
+ mVSlider->slotSetColor1(KoColor(h, s, 0, KoColor::csHSV).color());
+ mVSlider->slotSetColor2(KoColor(h, s, 255, KoColor::csHSV).color());
+ mVSlider->slotSetValue(v);
+ mVIn->setValue(v);
+ mColorPatch -> setColor(mColor.color());
+}
+
+void HSVWidget::slotHSliderChanged(int h)
+{
+ int v = mColor.V();
+ int s = mColor.S();
+
+ mColor.setHSV(h, s, v);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void HSVWidget::slotSSliderChanged(int s)
+{
+ int h = mColor.H();
+ int v = mColor.V();
+
+ mColor.setHSV(h, s, v);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void HSVWidget::slotVSliderChanged(int v)
+{
+ int h = mColor.H();
+ int s = mColor.S();
+
+ mColor.setHSV(h, s, v);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void HSVWidget::slotHInChanged(int h)
+{
+ int s = mColor.S();
+ int v = mColor.V();
+
+ mColor.setHSV(h, s, v);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void HSVWidget::slotSInChanged(int s)
+{
+ int h = mColor.H();
+ int v = mColor.V();
+
+ mColor.setHSV(h, s, v);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void HSVWidget::slotVInChanged(int v)
+{
+ int h = mColor.H();
+ int s = mColor.S();
+
+ mColor.setHSV(h, s, v);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void HSVWidget::slotPatchChanged(const QColor& clr)
+{
+ int r = clr.red();
+ int g = clr.green();
+ int b = clr.blue();
+
+ mColor.setRGB(r, g, b);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+/* GreyWidget */
+
+GreyWidget::GreyWidget(QWidget *parent): ColorWidget(parent)
+{
+ QGridLayout *mGrid = new QGridLayout(this, 3, 3);
+
+ mColorPatch = new KColorPatch(this);
+
+ /* setup slider */
+ mVSlider = new KoColorSlider(this);
+ mVSlider->setMaximumHeight(20);
+ mVSlider->slotSetRange(0, 255);
+ mVSlider->slotSetColor1(QColor(255, 255, 255));
+ mVSlider->slotSetColor2(QColor(0, 0, 0));
+
+ /* setup slider label */
+ mVLabel = new QLabel("K", this);
+ mVLabel->setFixedWidth(18);
+ mVLabel->setFixedHeight(20);
+
+ /* setup spin box */
+ mVIn = new QSpinBox(0, 255, 1, this);
+ mVIn->setFixedWidth(42);
+ mVIn->setFixedHeight(20);
+
+ mGrid->addMultiCellWidget(mColorPatch, 0, 4, 0, 0);
+ mGrid->addWidget(mVLabel, 1, 1);
+ mGrid->addMultiCellWidget(mVSlider, 1, 1, 2, 3);
+ mGrid->addWidget(mVIn, 1, 4);
+
+ connect(mColorPatch, SIGNAL(colorChanged(const QColor &)), this, SLOT(slotPatchChanged(const QColor &)));
+
+ /* connect color slider */
+ connect(mVSlider, SIGNAL(valueChanged(int)), this, SLOT(slotVSliderChanged(int)));
+
+ /* connect spin box */
+ connect(mVIn, SIGNAL(valueChanged(int)), mVSlider, SLOT(slotSetValue(int)));
+}
+
+void GreyWidget::slotRefreshColor()
+{
+ double v = mColor.R() + mColor.G() + mColor.B();
+ v /= 3.0;
+ v = 255.0 - v;
+ mVIn->setValue(static_cast<int>(v));
+ mVSlider->slotSetValue(static_cast<int>(v));
+ mColorPatch -> setColor(mColor.color());
+}
+
+void GreyWidget::slotVSliderChanged(int v)
+{
+ v = 255 - v;
+
+ mColor.setRGB(v, v, v);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void GreyWidget::slotVInChanged(int v)
+{
+ v = 255 - v;
+
+ mColor.setRGB(v, v, v);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void GreyWidget::slotPatchChanged(const QColor& clr)
+{
+ int gray = qGray(clr.red(), clr.green(), clr.blue());
+
+ mColor.setRGB(gray, gray, gray);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+LABWidget::LABWidget(QWidget *parent) : ColorWidget(parent)
+{
+ QGridLayout *mGrid = new QGridLayout(this, 4, 5);
+
+ mColorPatch = new KColorPatch(this);
+
+ /* setup color sliders */
+ mLSlider = new KoColorSlider(this);
+ mLSlider->setMaximumHeight(20);
+ mLSlider->slotSetRange(0, 255);
+
+ mASlider = new KoColorSlider(this);
+ mASlider->setMaximumHeight(20);
+ mASlider->slotSetRange(0, 255);
+
+ mBSlider = new KoColorSlider(this);
+ mBSlider->setMaximumHeight(20);
+ mBSlider->slotSetRange(0, 255);
+
+ /* setup slider labels */
+ mLLabel = new QLabel("L", this);
+ mLLabel->setFixedWidth(16);
+ mLLabel->setFixedHeight(20);
+ mALabel = new QLabel("A", this);
+ mALabel->setFixedWidth(16);
+ mALabel->setFixedHeight(20);
+ mBLabel = new QLabel("B", this);
+ mBLabel->setFixedWidth(16);
+ mBLabel->setFixedHeight(20);
+
+ /* setup spin box */
+ mLIn = new QSpinBox(0, 255, 1, this);
+ mLIn->setFixedWidth(42);
+ mLIn->setFixedHeight(20);
+ mAIn = new QSpinBox(0, 255, 1, this);
+ mAIn->setFixedWidth(42);
+ mAIn->setFixedHeight(20);
+ mBIn = new QSpinBox(0, 255, 1, this);
+ mBIn->setFixedWidth(42);
+ mBIn->setFixedHeight(20);
+
+ mGrid->addMultiCellWidget(mColorPatch, 0, 4, 0, 0);
+ mGrid->addWidget(mLLabel, 1, 1);
+ mGrid->addWidget(mALabel, 2, 1);
+ mGrid->addWidget(mBLabel, 3, 1);
+ mGrid->addMultiCellWidget(mLSlider, 1, 1, 2, 3);
+ mGrid->addMultiCellWidget(mASlider, 2, 2, 2, 3);
+ mGrid->addMultiCellWidget(mBSlider, 3, 3, 2, 3);
+ mGrid->addWidget(mLIn, 1, 4);
+ mGrid->addWidget(mAIn, 2, 4);
+ mGrid->addWidget(mBIn, 3, 4);
+
+ connect(mColorPatch, SIGNAL(colorChanged(const QColor &)), this, SLOT(slotPatchChanged(const QColor &)));
+
+ /* connect color sliders */
+ connect(mLSlider, SIGNAL(valueChanged(int)), this, SLOT(slotLSliderChanged(int)));
+ connect(mASlider, SIGNAL(valueChanged(int)), this, SLOT(slotASliderChanged(int)));
+ connect(mBSlider, SIGNAL(valueChanged(int)), this, SLOT(slotBSliderChanged(int)));
+
+ /* connect spin box */
+ connect(mLIn, SIGNAL(valueChanged(int)), this, SLOT(slotLInChanged(int)));
+ connect(mAIn, SIGNAL(valueChanged(int)), this, SLOT(slotAInChanged(int)));
+ connect(mBIn, SIGNAL(valueChanged(int)), this, SLOT(slotBInChanged(int)));
+}
+
+void LABWidget::slotRefreshColor()
+{
+ int l = mColor.L();
+ int a = mColor.a();
+ int b = mColor.b();
+
+ mLSlider->slotSetColor1(KoColor(0, a, b, KoColor::csLab).color());
+ mLSlider->slotSetColor2(KoColor(255, a, b, KoColor::csLab).color());
+ mLSlider->slotSetValue(l);
+ mLIn->setValue(l);
+
+ mASlider->slotSetColor1(KoColor(l, 0, b, KoColor::csLab).color());
+ mASlider->slotSetColor2(KoColor(l, 255, b, KoColor::csLab).color());
+ mASlider->slotSetValue(a);
+ mAIn->setValue(a);
+
+ mBSlider->slotSetColor1(KoColor(l, a, 0, KoColor::csLab).color());
+ mBSlider->slotSetColor2(KoColor(l, a, 255, KoColor::csLab).color());
+ mBSlider->slotSetValue(b);
+ mBIn->setValue(b);
+ mColorPatch -> setColor(mColor.color());
+}
+
+void LABWidget::slotLSliderChanged(int l)
+{
+ int a = mColor.a();
+ int b = mColor.b();
+
+ mColor.setLab(l, a, b);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+
+}
+
+void LABWidget::slotASliderChanged(int a)
+{
+ int l = mColor.L();
+ int b = mColor.b();
+
+ mColor.setLab(l, a, b);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void LABWidget::slotBSliderChanged(int b)
+{
+ int l = mColor.L();
+ int a = mColor.a();
+
+ mColor.setLab(l, a, b);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void LABWidget::slotLInChanged(int l)
+{
+ int a = mColor.a();
+ int b = mColor.b();
+
+ mColor.setLab(l, a, b);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void LABWidget::slotAInChanged(int a)
+{
+ int l = mColor.L();
+ int b = mColor.b();
+
+ mColor.setLab(l, a, b);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void LABWidget::slotBInChanged(int b)
+{
+ int l = mColor.L();
+ int a = mColor.a();
+
+ mColor.setLab(l, a, b);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+void LABWidget::slotPatchChanged(const QColor& clr)
+{
+ int r = clr.red();
+ int g = clr.green();
+ int b = clr.blue();
+
+ mColor.setRGB(r, g, b);
+ slotRefreshColor();
+ emit colorChanged(mColor);
+}
+
+#include "koColorChooser.moc"
+
diff --git a/lib/kopainter/koColorChooser.h b/lib/kopainter/koColorChooser.h
new file mode 100644
index 00000000..3dddcb8b
--- /dev/null
+++ b/lib/kopainter/koColorChooser.h
@@ -0,0 +1,236 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Matthias Elter (me@kde.org)
+ Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __ko_ColorChooser_h__
+#define __ko_ColorChooser_h__
+
+#include <qwidget.h>
+#include "koColor.h"
+
+class KoFrameButton;
+class QGridLayout;
+class QTabWidget;
+class RGBWidget;
+class HSVWidget;
+class CMYKWidget;
+class LABWidget;
+class GreyWidget;
+class KoColor;
+class KoColorSlider;
+class QLabel;
+class QSpinBox;
+class KHSSelector;
+class KColorPatch;
+class ColorWidget;
+
+class KoColorChooser : public QWidget
+{
+ Q_OBJECT
+public:
+ KoColorChooser(QWidget *parent = 0L, const char *name = 0L);
+
+ const KoColor &color() const {return mColor; }
+
+public slots:
+ void slotChangeColor(const KoColor &c);
+ void slotChangeColor(const QColor &c);
+
+signals:
+ void colorChanged(const KoColor &c);
+
+protected slots:
+ void slotChangeXY(int h, int s);
+
+private slots:
+ void childColorChanged(const KoColor& c);
+ void slotCurrentChanged(QWidget *current);
+
+private:
+ ColorWidget *m_current;
+ KoColor mColor;
+ QTabWidget *m_tab;
+ QGridLayout *mGrid;
+ KoFrameButton *btnRGB;
+ KoFrameButton *btnHSV;
+ KoFrameButton *btnCMYK;
+ KoFrameButton *btnLAB;
+ KoFrameButton *btnGrey;
+ RGBWidget *mRGBWidget;
+ HSVWidget *mHSVWidget;
+ QWidget *mCMYKWidget;
+ LABWidget *mLABWidget;
+ GreyWidget *mGreyWidget;
+ KHSSelector *mColorSelector;
+};
+
+class ColorWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ ColorWidget(QWidget *parent = 0);
+ virtual ~ColorWidget();
+
+public slots:
+ virtual void slotChangeColor(const KoColor& c);
+ virtual void slotChangeColor(const QColor& c);
+ virtual void slotRefreshColor() = 0;
+
+protected:
+ KoColor mColor;
+};
+
+class RGBWidget : public ColorWidget
+{
+ Q_OBJECT
+public:
+ RGBWidget(QWidget *parent = 0L);
+ virtual ~RGBWidget() {}
+
+public slots:
+ virtual void slotRefreshColor();
+
+protected slots:
+ void slotRSliderChanged(int r);
+ void slotGSliderChanged(int g);
+ void slotBSliderChanged(int b);
+
+ void slotRInChanged(int r);
+ void slotGInChanged(int g);
+ void slotBInChanged(int b);
+
+ void slotPatchChanged(const QColor& clr);
+
+signals:
+ void colorChanged(const KoColor &c);
+
+private:
+ KoColorSlider *mRSlider;
+ KoColorSlider *mGSlider;
+ KoColorSlider *mBSlider;
+ QLabel *mRLabel;
+ QLabel *mGLabel;
+ QLabel *mBLabel;
+ QSpinBox *mRIn;
+ QSpinBox *mGIn;
+ QSpinBox *mBIn;
+ KColorPatch *mColorPatch;
+};
+
+class HSVWidget : public ColorWidget
+{
+ Q_OBJECT
+public:
+ HSVWidget(QWidget *parent = 0L);
+ virtual ~HSVWidget() {}
+
+public slots:
+ virtual void slotRefreshColor();
+
+protected slots:
+ void slotHSliderChanged(int h);
+ void slotSSliderChanged(int s);
+ void slotVSliderChanged(int v);
+
+ void slotHInChanged(int h);
+ void slotSInChanged(int s);
+ void slotVInChanged(int v);
+
+ void slotPatchChanged(const QColor& clr);
+
+signals:
+ void colorChanged(const KoColor &c);
+
+private:
+ KoColorSlider *mHSlider;
+ KoColorSlider *mSSlider;
+ KoColorSlider *mVSlider;
+ QLabel *mHLabel;
+ QLabel *mSLabel;
+ QLabel *mVLabel;
+ QSpinBox *mHIn;
+ QSpinBox *mSIn;
+ QSpinBox *mVIn;
+ KColorPatch *mColorPatch;
+};
+
+class GreyWidget : public ColorWidget
+{
+ Q_OBJECT
+public:
+ GreyWidget(QWidget *parent = 0L);
+ virtual ~GreyWidget() {}
+
+public slots:
+ virtual void slotRefreshColor();
+
+protected slots:
+ void slotVSliderChanged(int v);
+ void slotVInChanged(int v);
+ void slotPatchChanged(const QColor& clr);
+
+signals:
+ void colorChanged(const KoColor &c);
+
+protected:
+ KoColorSlider *mVSlider;
+ QLabel *mVLabel;
+ QSpinBox *mVIn;
+ KColorPatch *mColorPatch;
+};
+
+class LABWidget : public ColorWidget
+{
+ Q_OBJECT
+public:
+ LABWidget(QWidget *parent = 0L);
+ virtual ~LABWidget() {}
+
+public slots:
+ virtual void slotRefreshColor();
+
+protected slots:
+ void slotLSliderChanged(int l);
+ void slotASliderChanged(int a);
+ void slotBSliderChanged(int b);
+
+ void slotLInChanged(int l);
+ void slotAInChanged(int a);
+ void slotBInChanged(int b);
+
+ void slotPatchChanged(const QColor& clr);
+
+signals:
+ void colorChanged(const KoColor &c);
+
+private:
+ KoColorSlider *mLSlider;
+ KoColorSlider *mASlider;
+ KoColorSlider *mBSlider;
+ QLabel *mLLabel;
+ QLabel *mALabel;
+ QLabel *mBLabel;
+ QSpinBox *mLIn;
+ QSpinBox *mAIn;
+ QSpinBox *mBIn;
+ KColorPatch *mColorPatch;
+};
+
+#endif
+
diff --git a/lib/kopainter/koColorSlider.cc b/lib/kopainter/koColorSlider.cc
new file mode 100644
index 00000000..08c8020a
--- /dev/null
+++ b/lib/kopainter/koColorSlider.cc
@@ -0,0 +1,365 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Matthias Elter (me@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "koColorSlider.h"
+
+#include <qpainter.h>
+#include <qcursor.h>
+#include <qpen.h>
+
+#include <kdebug.h>
+#include <kpixmapeffect.h>
+
+KoColorFrame::KoColorFrame(QWidget *parent):
+QFrame(parent)
+{
+ setFrameStyle(Panel | Sunken);
+ setBackgroundMode(NoBackground);
+
+ /* default values */
+ mC1 = QColor(0, 0, 0);
+ mC2 = QColor(255, 255, 255);
+
+ mColorChanged = false;
+ mPixChanged = false;
+ mDragging = false;
+}
+
+const QColor KoColorFrame::colorAt(const QPoint &p)
+{
+ if(mPixChanged)
+ {
+ mImage = mPixmap.convertToImage();
+ mPixChanged = false;
+ }
+
+ if(p.x() >= mPixmap.width() || p.y() >= mPixmap.height())
+ return QColor(255,255,255);
+
+ return QColor(mImage.pixel(p.x(), p.y()));
+}
+
+void KoColorFrame::slotSetColor1(const QColor &c)
+{
+ mC1 = c;
+ mColorChanged = true;
+ mPixChanged = true;
+ repaint();
+}
+
+void KoColorFrame::slotSetColor2(const QColor &c)
+{
+ mC2 = c;
+ mColorChanged = true;
+ repaint();
+}
+
+void KoColorFrame::drawContents(QPainter *p)
+{
+ QRect r = contentsRect();
+
+ if((mPixmap.size() != r.size()) || mColorChanged)
+ {
+ mPixmap.resize(r.width() + 1, r.height() + 1);
+ KPixmapEffect::gradient(mPixmap, mC1, mC2, KPixmapEffect::HorizontalGradient);
+ mColorChanged = false;
+ mPixChanged = true;
+ }
+
+ p->drawPixmap(r.left(), r.top(), mPixmap);
+}
+
+void KoColorFrame::mousePressEvent(QMouseEvent *e)
+{
+ if(e->button() & LeftButton)
+ {
+ emit clicked(e->pos());
+
+ mDragging = true;
+ QPoint pos = QPoint(e->pos().x() - contentsRect().left(), e->pos().y() - contentsRect().top());
+
+ if(pos.x() < 0)
+ pos.setX(0);
+ else if(pos.x() >= contentsRect().width())
+ pos.setX(contentsRect().width()-1);
+
+ if(pos.y() < 0)
+ pos.setY(0);
+ else if(pos.y() >= contentsRect().height())
+ pos.setY(contentsRect().height()-1);
+
+ QColor c = colorAt(pos);
+ emit colorSelected(c);
+ }
+ else
+ QFrame::mousePressEvent(e);
+}
+
+void KoColorFrame::mouseReleaseEvent(QMouseEvent *e)
+{
+ if(e->button() & LeftButton)
+ mDragging = false;
+ else
+ QFrame::mouseReleaseEvent(e);
+}
+
+void KoColorFrame::mouseMoveEvent(QMouseEvent *e)
+{
+ if(mDragging)
+ {
+ bool set = false;
+ int x = e->pos().x();
+ int y = e->pos().y();
+
+ int left = contentsRect().left();
+ int right = contentsRect().left() + contentsRect().width();
+ int top = contentsRect().top();
+ int bottom = contentsRect().top() + contentsRect().height();
+
+ if(x < left)
+ {
+ x = left;
+ set = true;
+ }
+ else if(x > right)
+ {
+ x = right;
+ set = true;
+ }
+ if(y < top)
+ {
+ y = top;
+ set = true;
+ }
+ else if(y > bottom)
+ {
+ y = bottom;
+ set = true;
+ }
+
+// if(set)
+// QCursor::setPos(mapToGlobal(QPoint(x,y)));
+
+ QPoint pos = QPoint(x - contentsRect().left(), y - contentsRect().top());
+
+ QColor c = colorAt(pos);
+ emit colorSelected(c);
+ }
+ else
+ QFrame::mouseMoveEvent(e);
+}
+
+/***********************************************************************************/
+
+KoSliderWidget::KoSliderWidget(QWidget *parent):
+QWidget(parent)
+{
+ mDragging = false;
+ setFixedHeight(6);
+ setFixedWidth(11);
+}
+
+void KoSliderWidget::paintEvent(QPaintEvent *)
+{
+ QPainter p;
+ QPen pen(black, 1);
+ p.begin(this);
+
+ p.setPen(pen);
+ p.drawLine(0, 5, 5, 0);
+ p.drawLine(10, 5, 5, 0);
+ p.drawLine(0, 5, 10, 5);
+ p.end();
+}
+
+void KoSliderWidget::mousePressEvent(QMouseEvent *e)
+{
+ if(e->button() & LeftButton)
+ {
+ mPos = e->pos();
+ mDragging = true;
+ }
+ else
+ QWidget::mousePressEvent(e);
+}
+
+void KoSliderWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ if(e->button() & LeftButton)
+ mDragging = false;
+ else
+ QWidget::mouseReleaseEvent(e);
+}
+
+void KoSliderWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ if(mDragging)
+ {
+ QWidget *p = parentWidget();
+
+ if(!p)
+ return;
+
+ QPoint newPos = p->mapFromGlobal(QCursor::pos()) - mPos;
+
+ /* don't drag vertically */
+ newPos.setY(pos().y());
+
+ if(newPos.x() < 0)
+ newPos.setX(0);
+ if(newPos.x() > p->width() - width())
+ newPos.setX(p->width() - width());
+
+ move(newPos);
+ emit positionChanged(newPos.x());
+ }
+ else
+ QWidget::mouseMoveEvent(e);
+}
+
+/***********************************************************************************/
+
+KoColorSlider::KoColorSlider(QWidget *parent):
+QWidget(parent)
+{
+ mColorFrame = new KoColorFrame(this);
+ mSlider = new KoSliderWidget(this);
+
+ mMin = 0;
+ mMax = 255;
+ mValue = 0;
+
+ connect(mSlider, SIGNAL(positionChanged(int)), this, SLOT(slotSliderMoved(int)));
+ connect(mColorFrame, SIGNAL(clicked(const QPoint &)), this, SLOT(slotFrameClicked(const QPoint &)));
+}
+
+KoColorSlider::~KoColorSlider()
+{
+ delete mColorFrame;
+ delete mSlider;
+}
+
+int KoColorSlider::minValue()
+{
+ return mMin;
+}
+
+int KoColorSlider::maxValue()
+{
+ return mMax;
+}
+
+void KoColorSlider::slotSetRange(int min, int max)
+{
+ if(min >= max)
+ return;
+
+ mMin = min;
+ mMax = max;
+}
+
+void KoColorSlider::resizeEvent(QResizeEvent *e)
+{
+ QWidget::resizeEvent(e);
+ // m_pSlider->width()/2 * 2 seems stupid but is not because for example
+ // m_pSlider->width() == 11 I get 10.
+ mColorFrame->setGeometry(mSlider->width() / 2, 0, width() - mSlider->width() / 2 * 2, height() - mSlider->height());
+ slotSetValue(mValue);
+}
+
+void KoColorSlider::slotSetColor1(const QColor &c)
+{
+ mColorFrame->slotSetColor1(c);
+}
+
+void KoColorSlider::slotSetColor2(const QColor &c)
+{
+ mColorFrame->slotSetColor2(c);
+}
+
+void KoColorSlider::slotSetValue(int value)
+{
+ if(value < mMin)
+ value = mMin;
+ if(value > mMax)
+ value = mMax;
+
+ mValue = value;
+
+ int range = mMax - mMin;
+ float v = value;
+ if(mMin < 0)
+ v += -mMin;
+
+ float factor = v / range;
+ int x = static_cast<int>(factor * mColorFrame->contentsRect().width());
+
+ mSlider->move(QPoint(x, height() - mSlider->height()));
+}
+
+void KoColorSlider::slotSliderMoved(int x)
+{
+ if(x < 0)
+ x = 0;
+ if(x > mColorFrame->contentsRect().width())
+ x = mColorFrame->contentsRect().width();
+
+ float factor = x;
+ factor /= mColorFrame->contentsRect().width();
+ int range = mMax - mMin;
+
+ mValue = static_cast<int>(factor * range);
+
+ emit valueChanged(mValue);
+ emit colorSelected(mColorFrame->colorAt(QPoint(x, mColorFrame->contentsRect().height()/2)));
+}
+
+void KoColorSlider::slotFrameClicked(const QPoint &p)
+{
+ QPoint local = mColorFrame->mapToParent(p);
+ QPoint pos = QPoint(local.x() - mSlider->width() / 2, height() - mSlider->height());
+
+ if(pos.x() < 0)
+ pos.setX(0);
+ else if(pos.x() > width() - mSlider->width())
+ pos.setX(width() - mSlider->width());
+
+ mSlider->move(pos);
+ slotSliderMoved(pos.x());
+}
+
+void KoColorSlider::mousePressEvent(QMouseEvent *e)
+{
+ if(e->button() & LeftButton)
+ {
+ QPoint pos = QPoint(e->pos().x() - mSlider->width() / 2, height() - mSlider->height());
+
+ if(pos.x() < 0)
+ pos.setX(0);
+ else if(pos.x() > width() - mSlider->width())
+ pos.setX(width() - mSlider->width());
+
+ mSlider->move(pos);
+ slotSliderMoved(pos.x());
+ }
+ else
+ QWidget::mousePressEvent(e);
+}
+
+#include "koColorSlider.moc"
diff --git a/lib/kopainter/koColorSlider.h b/lib/kopainter/koColorSlider.h
new file mode 100644
index 00000000..5c520ba8
--- /dev/null
+++ b/lib/kopainter/koColorSlider.h
@@ -0,0 +1,119 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Matthias Elter (me@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __ko_ColorSlider_h__
+#define __ko_ColorSlider_h__
+
+#include <qframe.h>
+#include <qpoint.h>
+#include <qimage.h>
+#include <qwidget.h>
+#include <kpixmap.h>
+#include <koffice_export.h>
+class SliderWidget;
+
+class KOPAINTER_EXPORT KoColorFrame : public QFrame
+{
+ Q_OBJECT
+public:
+ KoColorFrame(QWidget *parent = 0L);
+
+ const QColor colorAt(const QPoint &p);
+
+protected:
+ void drawContents(QPainter *p);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+
+public slots:
+ void slotSetColor1(const QColor &c);
+ void slotSetColor2(const QColor &c);
+
+signals:
+ void clicked(const QPoint &p);
+ void colorSelected(const QColor &c);
+
+protected:
+ QColor mC1;
+ QColor mC2;
+ KPixmap mPixmap;
+ QImage mImage;
+ bool mColorChanged;
+ bool mPixChanged;
+ bool mDragging;
+};
+
+class KOPAINTER_EXPORT KoSliderWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ KoSliderWidget(QWidget *parent = 0L);
+
+protected:
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void paintEvent(QPaintEvent *);
+
+signals:
+ void positionChanged(int);
+
+protected:
+ bool mDragging;
+ QPoint mPos;
+};
+
+class KOPAINTER_EXPORT KoColorSlider : public QWidget
+{
+ Q_OBJECT
+public:
+ KoColorSlider(QWidget *parent = 0L);
+ virtual ~KoColorSlider();
+
+ int minValue();
+ int maxValue();
+
+protected:
+ void resizeEvent(QResizeEvent *);
+ void mousePressEvent(QMouseEvent *);
+
+public slots:
+ void slotSetColor1(const QColor &c);
+ void slotSetColor2(const QColor &c);
+
+ void slotSetValue(int value);
+ void slotSetRange(int min, int max);
+
+protected slots:
+ void slotSliderMoved(int x);
+ void slotFrameClicked(const QPoint &p);
+
+signals:
+ void colorSelected(const QColor &c);
+ void valueChanged(int value);
+
+protected:
+ KoSliderWidget *mSlider;
+ KoColorFrame *mColorFrame;
+ int mMin, mMax;
+ int mValue;
+};
+
+#endif
diff --git a/lib/kopainter/koFrameButton.cc b/lib/kopainter/koFrameButton.cc
new file mode 100644
index 00000000..cb752363
--- /dev/null
+++ b/lib/kopainter/koFrameButton.cc
@@ -0,0 +1,102 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Matthias Elter (me@kde.org)
+ Copyright (c) 2001 Igor Jansen (rm@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "koFrameButton.h"
+
+KoFrameButton::KoFrameButton(QWidget *parent, const char *name):
+QLabel(parent, name)
+{
+ setAutoResize(true);
+ setFrameStyle(Panel | Raised);
+ setLineWidth(1);
+ setMaximumHeight(8);
+ mActive = false;
+ mToggle = false;
+}
+
+KoFrameButton::KoFrameButton(const QString &text, QWidget *parent, const char *name):
+QLabel(parent, name)
+{
+ setFrameStyle(Panel | Raised);
+ setLineWidth(1);
+ setText(text);
+ setAlignment(AlignHCenter | AlignVCenter);
+ mActive = false;
+ mToggle = false;
+}
+
+KoFrameButton::KoFrameButton(const QPixmap &pixmap, QWidget *parent, const char *name):
+QLabel(parent, name)
+{
+ setFrameStyle(Panel | Raised);
+ setLineWidth(1);
+ setPixmap(pixmap);
+ mActive = false;
+ mToggle = false;
+}
+
+void KoFrameButton::mousePressEvent(QMouseEvent *)
+{
+ setFrameStyle(Panel | Sunken);
+}
+
+void KoFrameButton::mouseReleaseEvent(QMouseEvent *)
+{
+ if(mToggle)
+ {
+ mActive = !mActive;
+ if(mActive)
+ setFrameStyle(Panel | Sunken);
+ else
+ setFrameStyle(Panel | Raised);
+ }
+ else
+ setFrameStyle(Panel | Raised);
+
+ emit clicked();
+ emit clicked(mText);
+}
+
+void KoFrameButton::setOn(bool v)
+{
+ if(!mToggle)
+ return;
+
+ mActive = v;
+
+ if(mActive)
+ setFrameStyle(Panel | Sunken);
+ else
+ setFrameStyle(Panel | Raised);
+}
+
+
+void KoFrameButton::setToggleButton(bool v)
+{
+ mToggle = v;
+}
+
+void KoFrameButton::setText(const QString &t)
+{
+ mText = t;
+ QLabel::setText(t);
+}
+
+#include "koFrameButton.moc"
diff --git a/lib/kopainter/koFrameButton.h b/lib/kopainter/koFrameButton.h
new file mode 100644
index 00000000..c540fd9f
--- /dev/null
+++ b/lib/kopainter/koFrameButton.h
@@ -0,0 +1,60 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Matthias Elter (me@kde.org)
+ Copyright (c) 2001 Igor Jansen (rm@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __ko_framebutton_h__
+#define __ko_framebutton_h__
+
+#include <qlabel.h>
+
+class QPixmap;
+class QString;
+
+class KoFrameButton : public QLabel
+{
+ Q_OBJECT
+public:
+ KoFrameButton(QWidget *parent = 0, const char *name = 0);
+ KoFrameButton(const QString &text, QWidget *parent = 0, const char *name = 0);
+ KoFrameButton(const QPixmap &pixmap, QWidget *parent = 0, const char *name = 0);
+
+ bool isOn() {return mActive; }
+ void setOn(bool v);
+
+ bool isToggleButton() {return mToggle; }
+ void setToggleButton(bool v);
+
+ QString text() {return mText; }
+ virtual void setText(const QString &t);
+
+signals:
+ void clicked();
+ void clicked(const QString &);
+
+protected:
+ void mousePressEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+
+private:
+ bool mActive;
+ bool mToggle;
+ QString mText;
+};
+
+#endif
diff --git a/lib/kopainter/koIconChooser.cc b/lib/kopainter/koIconChooser.cc
new file mode 100644
index 00000000..57fda8d8
--- /dev/null
+++ b/lib/kopainter/koIconChooser.cc
@@ -0,0 +1,482 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Carsten Pfeiffer (pfeiffer@kde.org)
+ Copyright (c) 2002 Igor Jansen (rm@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <kdebug.h>
+#include <koIconChooser.h>
+#include <kglobal.h>
+
+#include <qpainter.h>
+#include <qcursor.h>
+#include <qapplication.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include <kdebug.h>
+
+KoPixmapWidget::KoPixmapWidget(const QPixmap &aPixmap, QWidget *parent, const char *name):
+QFrame(parent, name, WType_Popup)
+{
+ kdDebug() << "Popup created: " << name << "\n";
+ setFrameStyle(QFrame::WinPanel | QFrame::Raised);
+ mPixmap = aPixmap;
+ int w = mPixmap.width() + 2 * lineWidth();
+ int h = mPixmap.height() + 2 * lineWidth();
+ resize(w, h);
+
+}
+
+KoPixmapWidget::~KoPixmapWidget()
+{
+}
+
+// paint the centered pixmap; don't overpaint the frame
+void KoPixmapWidget::paintEvent(QPaintEvent *e)
+{
+ QFrame::paintEvent(e);
+ QPainter p(this);
+ p.setClipRect(e->rect());
+ p.drawPixmap(lineWidth(), lineWidth(), mPixmap);
+}
+
+
+void KoPixmapWidget::mouseReleaseEvent(QMouseEvent *)
+{
+ hide();
+}
+
+
+KoIconChooser::KoIconChooser(QSize aIconSize, QWidget *parent, const char *name, bool sort):
+QGridView(parent, name)
+{
+ QGridView::setBackgroundColor(Qt::white);
+
+ mMargin = 2;
+ setCellWidth(aIconSize.width() + 2 * mMargin);
+ setCellHeight(aIconSize.height() + 2 * mMargin);
+
+ mIconList.clear();
+ mPixmapWidget = 0L;
+ mNCols = 0;
+ mCurRow = 0;
+ mCurCol = 0;
+ mItemCount = 0;
+ mItemWidth = aIconSize.width();
+ mItemHeight = aIconSize.height();
+ mMouseButtonDown = false;
+ mDragEnabled = false;
+ mSort = sort;
+}
+
+KoIconChooser::~KoIconChooser()
+{
+ mIconList.clear();
+ if(mPixmapWidget)
+ delete mPixmapWidget;
+}
+
+void KoIconChooser::addItem(KoIconItem *item)
+{
+ Q_INT32 n = mItemCount;
+ KoIconItem *current = currentItem();
+
+ Q_ASSERT(item);
+
+ int i;
+
+ if (mSort)
+ {
+ i = sortInsertionIndex(item);
+ }
+ else
+ {
+ i = mItemCount;
+ }
+
+ mIconList.insert(i, item);
+ mItemCount++;
+ calculateCells();
+
+ if (mSort)
+ {
+ setCurrentItem(current);
+ updateContents();
+ }
+ else
+ {
+ updateCell(n / numCols(), n - (n / numCols()) * numCols());
+ }
+}
+
+bool KoIconChooser::removeItem(KoIconItem *item)
+{
+ int index = mIconList.find(item);
+ bool ok = mIconList.remove(item);
+ if( ok )
+ {
+ mItemCount--;
+ // select same cell as deleted cell, or new last cell if we deleted
+ // last cell.
+ setCurrentItem(itemAt(kMin(index, mItemCount - 1)));
+ calculateCells();
+ }
+ return ok;
+}
+
+void KoIconChooser::clear()
+{
+ mItemCount = 0;
+ mIconList.clear();
+ calculateCells();
+}
+
+// return 0L if there is no current item
+KoIconItem *KoIconChooser::currentItem()
+{
+ return itemAt(mCurRow, mCurCol);
+}
+
+// sets the current item to item
+// does NOT emit selected() (should it?)
+void KoIconChooser::setCurrentItem(KoIconItem *item)
+{
+ int index = mIconList.find(item);
+
+ // item is available
+ if(index != -1 && mNCols > 0)
+ {
+ int oldRow = mCurRow;
+ int oldCol = mCurCol;
+
+ mCurRow = index / mNCols;
+ mCurCol = index % mNCols;
+
+ // repaint the old and the new item
+ repaintCell(oldRow, oldCol);
+ repaintCell(mCurRow, mCurCol);
+
+ ensureCellVisible(mCurRow, mCurCol);
+ }
+}
+
+// eventually select the item, clicked on
+void KoIconChooser::mousePressEvent(QMouseEvent *e)
+{
+ QGridView::mousePressEvent(e);
+}
+
+void KoIconChooser::mouseMoveEvent(QMouseEvent *e)
+{
+ if(mMouseButtonDown && mDragEnabled )
+ {
+#if 0
+ if(mPixmapWidget)
+ {
+ delete mPixmapWidget;
+ mPixmapWidget = 0L;
+ }
+#endif
+ if( ( mDragStartPos - e->pos() ).manhattanLength() > QApplication::startDragDistance() )
+ startDrag();
+ }
+}
+
+void
+KoIconChooser::startDrag()
+{
+ mMouseButtonDown = false;
+}
+
+void KoIconChooser::mouseReleaseEvent(QMouseEvent * e)
+{
+ mMouseButtonDown = true;
+ if(e->button() == LeftButton)
+ {
+ QPoint p = e->pos();
+ mDragStartPos = p;
+ int x = contentsX() + p.x();
+ int y = contentsY() + p.y();
+ QSize gridExtent = gridSize();
+
+ if (x < gridExtent.width() && y < gridExtent.height())
+ {
+ int row = rowAt(y);
+ int col = columnAt(x);
+
+ KoIconItem *item = itemAt(row, col);
+ if(item)
+ {
+ const QPixmap &pix = item->pixmap();
+ if(pix.width() > mItemWidth || pix.height() > mItemHeight)
+ showFullPixmap(pix, p);
+
+ setCurrentItem(item);
+ emit selected( item );
+ }
+ }
+ }
+}
+
+// FIXME: implement keyboard navigation
+void KoIconChooser::keyPressEvent(QKeyEvent *e)
+{
+ QGridView::keyPressEvent(e);
+}
+
+// recalculate the number of items that fit into one row
+// set the current item again after calculating the new grid
+void KoIconChooser::resizeEvent(QResizeEvent *e)
+{
+ QGridView::resizeEvent(e);
+
+ KoIconItem *item = currentItem();
+ int oldNCols = mNCols;
+
+ if (cellWidth() != 0)
+ {
+ mNCols = e -> size().width() / cellWidth();
+ }
+
+ if(mNCols != oldNCols)
+ {
+ setNumCols(mNCols);
+ calculateCells();
+ setCurrentItem(item);
+ updateContents();
+ }
+}
+
+// paint one cell
+// mark the current item and center items smaller than the cellSize
+// TODO: scale down big pixmaps and paint the size as text into the pixmap
+void KoIconChooser::paintCell(QPainter *p, int row, int col)
+{
+ KoIconItem *item = itemAt(row, col);
+
+ if(item)
+ {
+ const QPixmap &pix = item->pixmap();
+
+ int x = mMargin;
+ int y = mMargin;
+ int pw = pix.width();
+ int ph = pix.height();
+ int cw = cellWidth();
+ int ch = cellHeight();
+
+ // center small pixmaps
+ if(pw < mItemWidth)
+ x = (cw - pw) / 2;
+ if(ph < mItemHeight)
+ y = (cw - ph) / 2;
+
+ if((!item->hasValidThumb()) || (pw <= mItemWidth && ph <= mItemHeight))
+ p->drawPixmap(x, y, pix, 0, 0, mItemWidth, mItemHeight);
+ else
+ {
+ const QPixmap &thumbpix = item->thumbPixmap();
+ x = mMargin;
+ y = mMargin;
+ pw = thumbpix.width();
+ ph = thumbpix.height();
+ cw = cellWidth();
+ ch = cellHeight();
+
+ // center small pixmaps
+ if(pw < mItemWidth)
+ x = (cw - pw) / 2;
+ if(ph < mItemHeight)
+ y = (cw - ph) / 2;
+ p->drawPixmap(x, y, thumbpix, 0, 0, mItemWidth, mItemHeight);
+ }
+
+ // highlight current item
+ if(row == mCurRow && col == mCurCol)
+ {
+ p->setPen(blue);
+ p->drawRect(0, 0, cw, ch);
+ }
+ else
+ {
+ p->setPen(gray);
+ //p->drawRect(0, 0, cw, ch);
+ p->drawLine(cw-1, 0, cw-1, ch-1);
+ p->drawLine(0, ch-1, cw-1, ch-1);
+ }
+ }
+ else
+ {
+ // empty cell
+ p->fillRect(0, 0, cellWidth(), cellHeight(), QBrush(Qt::white));
+ }
+}
+
+// return the pointer of the item at (row,col) - beware, resizing disturbs
+// rows and cols!
+// return 0L if item is not found
+KoIconItem *KoIconChooser::itemAt(int row, int col)
+{
+ return itemAt(cellIndex(row, col));
+}
+
+// return the pointer of the item at position index
+// return 0L if item is not found
+KoIconItem *KoIconChooser::itemAt(int index)
+{
+ if(index < 0)
+ return 0L;
+ return mIconList.count() > uint(index) ? mIconList.at(index) : 0;
+}
+
+// return the index of a cell, given row and column position
+// maps directly to the position in the itemlist
+// return -1 on failure
+int KoIconChooser::cellIndex(int row, int col)
+{
+ if(row < 0 || col < 0)
+ return -1;
+ else
+ return((row * mNCols) + col);
+}
+
+// calculate the grid and set the number of rows and columns
+// reorder all items approrpriately
+void KoIconChooser::calculateCells()
+{
+ if(mNCols == 0)
+ return;
+ bool update = isUpdatesEnabled();
+ int rows = mItemCount / mNCols;
+ setUpdatesEnabled(false);
+ if((rows * mNCols) < mItemCount)
+ rows++;
+ setNumRows(rows);
+ setUpdatesEnabled(update);
+ updateContents();
+}
+
+// show the full pixmap of a large item in an extra widget
+void KoIconChooser::showFullPixmap(const QPixmap &pix, const QPoint &/*p*/)
+{
+ //delete mPixmapWidget;
+ mPixmapWidget = new KoPixmapWidget(pix, this);
+
+ // center widget under mouse cursor
+ QPoint p = QCursor::pos();
+ int w = mPixmapWidget->width();
+ int h = mPixmapWidget->height();
+ mPixmapWidget->move(p.x() - w / 2, p.y() - h / 2);
+ mPixmapWidget->show();
+}
+
+int KoIconChooser::sortInsertionIndex(const KoIconItem *item)
+{
+ int index = 0;
+
+ if (!mIconList.isEmpty())
+ {
+ // Binary insertion
+ int first = 0;
+ int last = mIconList.count() - 1;
+
+ while (first != last)
+ {
+ int middle = (first + last) / 2;
+
+ if (item -> compare(mIconList.at(middle)) < 0)
+ {
+ last = middle - 1;
+
+ if (last < first)
+ {
+ last = first;
+ }
+ }
+ else
+ {
+ first = middle + 1;
+
+ if (first > last)
+ {
+ first = last;
+ }
+ }
+ }
+
+ if (item -> compare(mIconList.at(first)) < 0)
+ {
+ index = first;
+ }
+ else
+ {
+ index = first + 1;
+ }
+ }
+
+ return index;
+}
+
+KoPatternChooser::KoPatternChooser( const QPtrList<KoIconItem> &list, QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ // only serves as beautifier for the iconchooser
+ //frame = new QHBox( this );
+ //frame->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ chooser = new KoIconChooser( QSize(30,30), this, "pattern chooser" );
+
+ QObject::connect( chooser, SIGNAL(selected( KoIconItem * ) ),
+ this, SIGNAL( selected( KoIconItem * )));
+
+ QPtrListIterator<KoIconItem> itr( list );
+ for( itr.toFirst(); itr.current(); ++itr )
+ chooser->addItem( itr.current() );
+
+ QVBoxLayout *mainLayout = new QVBoxLayout( this, 1, -1, "main layout" );
+ mainLayout->addWidget( chooser, 10 );
+}
+
+
+KoPatternChooser::~KoPatternChooser()
+{
+ delete chooser;
+ //delete frame;
+}
+
+// set the active pattern in the chooser - does NOT emit selected() (should it?)
+void KoPatternChooser::setCurrentPattern( KoIconItem *pattern )
+{
+ chooser->setCurrentItem( pattern );
+}
+
+void KoPatternChooser::addPattern( KoIconItem *pattern )
+{
+ chooser->addItem( pattern );
+}
+
+// return the active pattern
+KoIconItem *KoPatternChooser::currentPattern()
+{
+ return chooser->currentItem();
+}
+
+void KoPatternChooser::removePattern( KoIconItem *pattern )
+{
+ chooser->removeItem( pattern );
+}
+
+#include "koIconChooser.moc"
diff --git a/lib/kopainter/koIconChooser.h b/lib/kopainter/koIconChooser.h
new file mode 100644
index 00000000..5beb25a0
--- /dev/null
+++ b/lib/kopainter/koIconChooser.h
@@ -0,0 +1,145 @@
+/* This file is part of the KDE project
+ Copyright (c) 1999 Carsten Pfeiffer (pfeiffer@kde.org)
+ Copyright (c) 2002 Igor Jansen (rm@kde.org)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __ko_iconchooser_h__
+#define __ko_iconchooser_h__
+
+#include <qgridview.h>
+#include <qptrlist.h>
+#include <qpixmap.h>
+#include <koffice_export.h>
+
+class KoIconItem
+{
+public:
+ KoIconItem() {}
+ virtual ~KoIconItem() {}
+
+ bool hasValidPixmap() {return validPixmap; }
+ bool validPixmap;
+ bool hasValidThumb() {return validThumb; }
+ bool validThumb;
+
+ virtual int spacing() const {return 0; }
+ virtual void setSpacing(int) {}
+ virtual QPixmap &pixmap() const = 0;
+ virtual QPixmap &thumbPixmap() const = 0;
+ // Return -1 if this is less than other, 0 if equal, 1 if greater than.
+ virtual int compare(const KoIconItem */*other*/) const { return 0; }
+};
+
+class KoPixmapWidget : public QFrame
+{
+public:
+ KoPixmapWidget(const QPixmap &aPixmap, QWidget *parent = 0L, const char *name = 0L);
+ ~KoPixmapWidget();
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void mouseReleaseEvent( QMouseEvent *e);
+
+private:
+ QPixmap mPixmap;
+};
+
+class KOPAINTER_EXPORT KoIconChooser: public QGridView
+{
+ Q_OBJECT
+public:
+ // To make the items sorted, set 'sort' to true and override KoIconItem::compare().
+ KoIconChooser(QSize iconSize, QWidget *parent = 0L, const char *name = 0L, bool sort = false);
+ virtual ~KoIconChooser();
+
+ bool autoDelete() const {return mIconList.autoDelete(); }
+ void setAutoDelete(bool b) {mIconList.setAutoDelete(b); }
+
+ void addItem(KoIconItem *item);
+ bool removeItem(KoIconItem *item);
+ void clear();
+
+ KoIconItem *currentItem();
+ void setCurrentItem(KoIconItem *item);
+
+ void setDragEnabled(bool allow) { mDragEnabled = allow; }
+ bool dragEnabled() const { return mDragEnabled; }
+
+ KoIconItem *itemAt(int row, int col);
+ KoIconItem *itemAt(int index);
+
+signals:
+ void selected(KoIconItem *item);
+
+protected:
+ void keyPressEvent(QKeyEvent *e);
+ void mousePressEvent( QMouseEvent *e);
+ void mouseReleaseEvent( QMouseEvent *e);
+ void mouseMoveEvent( QMouseEvent *e);
+ void resizeEvent(QResizeEvent *e);
+ void paintCell(QPainter *p, int row, int col);
+ virtual void startDrag();
+
+private:
+ int cellIndex(int row, int col);
+ void calculateCells();
+ void showFullPixmap(const QPixmap &pix, const QPoint &p);
+ int sortInsertionIndex(const KoIconItem *item);
+
+private:
+ QPtrList<KoIconItem> mIconList;
+ KoPixmapWidget *mPixmapWidget;
+ int mItemWidth;
+ int mItemHeight;
+ int mItemCount;
+ int mNCols;
+ int mCurRow;
+ int mCurCol;
+ int mMargin;
+ QPoint mDragStartPos;
+ bool mMouseButtonDown;
+ bool mDragEnabled;
+ bool mSort;
+};
+
+// This is a first attempt at a pattern chooser widget abstraction which is at least
+// useful for two applications(karbon and krita). It is really a light version of
+// kis_patternchooser. (Rob)
+class KOPAINTER_EXPORT KoPatternChooser : public QWidget
+{
+ Q_OBJECT
+public:
+ KoPatternChooser( const QPtrList<KoIconItem> &list, QWidget *parent, const char *name = 0 );
+ ~KoPatternChooser();
+
+ KoIconItem *currentPattern();
+ void setCurrentPattern( KoIconItem * );
+
+public slots:
+ void addPattern( KoIconItem * );
+ void removePattern( KoIconItem * );
+
+private:
+ KoIconChooser *chooser;
+
+signals:
+ void selected( KoIconItem * );
+};
+
+
+#endif
diff --git a/lib/kopainter/ko_cmyk_widget.cc b/lib/kopainter/ko_cmyk_widget.cc
new file mode 100644
index 00000000..86b20ad9
--- /dev/null
+++ b/lib/kopainter/ko_cmyk_widget.cc
@@ -0,0 +1,403 @@
+/*
+ * This file is part of KOffice
+ *
+ * Copyright (c) 1999 Matthias Elter (me@kde.org)
+ * Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+ * Copyright (c) 2005 Tim Beaulen (tbscope@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "ko_cmyk_widget.h"
+
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qtooltip.h>
+#include <qcolor.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+
+#include <koFrameButton.h>
+#include <koColorSlider.h>
+#include <kcolordialog.h>
+#include <kdualcolorbutton.h>
+
+KoCMYKWidget::KoCMYKWidget(QWidget *parent, const char *name) : super(parent, name)
+{
+ m_ColorButton = new KDualColorButton(this);
+ m_ColorButton -> setFixedSize(m_ColorButton->sizeHint());
+ QGridLayout *mGrid = new QGridLayout(this, 4, 5, 5, 2);
+
+ /* setup color sliders */
+ mCSlider = new KoColorSlider(this);
+ mCSlider->setMaximumHeight(20);
+ mCSlider->slotSetRange(0, 255);
+ mCSlider->setFocusPolicy( QWidget::ClickFocus );
+
+ mMSlider = new KoColorSlider(this);
+ mMSlider->setMaximumHeight(20);
+ mMSlider->slotSetRange(0, 255);
+ mMSlider->setFocusPolicy( QWidget::ClickFocus );
+
+ mYSlider = new KoColorSlider(this);
+ mYSlider->setMaximumHeight(20);
+ mYSlider->slotSetRange(0, 255);
+ mYSlider->setFocusPolicy( QWidget::ClickFocus );
+
+ mKSlider = new KoColorSlider(this);
+ mKSlider->setMaximumHeight(20);
+ mKSlider->slotSetRange(0, 255);
+ mKSlider->setFocusPolicy( QWidget::ClickFocus );
+
+ /* setup slider labels */
+ mCLabel = new QLabel("C", this);
+ mCLabel->setFixedWidth(12);
+ mCLabel->setFixedHeight(20);
+ mMLabel = new QLabel("M", this);
+ mMLabel->setFixedWidth(12);
+ mMLabel->setFixedHeight(20);
+ mYLabel = new QLabel("Y", this);
+ mYLabel->setFixedWidth(12);
+ mYLabel->setFixedHeight(20);
+ mKLabel = new QLabel("K", this);
+ mKLabel->setFixedWidth(12);
+ mKLabel->setFixedHeight(20);
+
+ /* setup spin box */
+ mCIn = new QSpinBox(0, 255, 1, this);
+ mCIn->setFixedWidth(50);
+ mCIn->setFixedHeight(20);
+ mCIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mCIn, i18n( "Cyan" ) );
+
+ mMIn = new QSpinBox(0, 255, 1, this);
+ mMIn->setFixedWidth(50);
+ mMIn->setFixedHeight(20);
+ mMIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mMIn, i18n( "Magenta" ) );
+
+ mYIn = new QSpinBox(0, 255, 1, this);
+ mYIn->setFixedWidth(50);
+ mYIn->setFixedHeight(20);
+ mYIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mYIn, i18n( "Yellow" ) );
+
+ mKIn = new QSpinBox(0, 255, 1, this);
+ mKIn->setFixedWidth(50);
+ mKIn->setFixedHeight(20);
+ mKIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mKIn, i18n( "Black" ) );
+
+ mGrid->addMultiCellWidget(m_ColorButton, 0, 4, 0, 0, Qt::AlignTop);
+ mGrid->addWidget(mCLabel, 0, 1);
+ mGrid->addWidget(mMLabel, 1, 1);
+ mGrid->addWidget(mYLabel, 2, 1);
+ mGrid->addWidget(mKLabel, 3, 1);
+ mGrid->addMultiCellWidget(mCSlider, 0, 0, 2, 3);
+ mGrid->addMultiCellWidget(mMSlider, 1, 1, 2, 3);
+ mGrid->addMultiCellWidget(mYSlider, 2, 2, 2, 3);
+ mGrid->addMultiCellWidget(mKSlider, 3, 3, 2, 3);
+ mGrid->addWidget(mCIn, 0, 4);
+ mGrid->addWidget(mMIn, 1, 4);
+ mGrid->addWidget(mYIn, 2, 4);
+ mGrid->addWidget(mKIn, 3, 4);
+
+ connect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+ connect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+
+ /* connect color sliders */
+ connect(mCSlider, SIGNAL(valueChanged(int)), this, SLOT(slotCChanged(int)));
+ connect(mMSlider, SIGNAL(valueChanged(int)), this, SLOT(slotMChanged(int)));
+ connect(mYSlider, SIGNAL(valueChanged(int)), this, SLOT(slotYChanged(int)));
+ connect(mKSlider, SIGNAL(valueChanged(int)), this, SLOT(slotKChanged(int)));
+
+ /* connect spin box */
+ connect(mCIn, SIGNAL(valueChanged(int)), this, SLOT(slotCChanged(int)));
+ connect(mMIn, SIGNAL(valueChanged(int)), this, SLOT(slotMChanged(int)));
+ connect(mYIn, SIGNAL(valueChanged(int)), this, SLOT(slotYChanged(int)));
+ connect(mKIn, SIGNAL(valueChanged(int)), this, SLOT(slotKChanged(int)));
+}
+
+void KoCMYKWidget::slotCChanged(int c)
+{
+ if (m_ColorButton->current() == KDualColorButton::Foreground){
+ CMYKColor col = RgbToCmyk(m_fgColor);
+ col.C = c / 255.0;
+ m_fgColor = CmykToRgb(col);
+ m_ColorButton->setCurrent(KDualColorButton::Foreground);
+ emit sigFgColorChanged(m_fgColor);
+ }
+ else{
+ CMYKColor col = RgbToCmyk(m_bgColor);
+ col.C = c / 255.0;
+ m_bgColor = CmykToRgb(col);
+ m_ColorButton->setCurrent(KDualColorButton::Background);
+ emit sigBgColorChanged(m_bgColor);
+ }
+}
+
+void KoCMYKWidget::slotMChanged(int m)
+{
+ if (m_ColorButton->current() == KDualColorButton::Foreground){
+ CMYKColor col = RgbToCmyk(m_fgColor);
+ col.M = m / 255.0;
+ m_fgColor = CmykToRgb(col);
+ m_ColorButton->setCurrent(KDualColorButton::Foreground);
+ emit sigFgColorChanged(m_fgColor);
+ }
+ else{
+ CMYKColor col = RgbToCmyk(m_bgColor);
+ col.M = m / 255.0;
+ m_bgColor = CmykToRgb(col);
+ m_ColorButton->setCurrent(KDualColorButton::Background);
+ emit sigBgColorChanged(m_bgColor);
+ }
+}
+
+void KoCMYKWidget::slotYChanged(int y)
+{
+ if (m_ColorButton->current() == KDualColorButton::Foreground){
+ CMYKColor col = RgbToCmyk(m_fgColor);
+ col.Y = y / 255.0;
+ m_fgColor = CmykToRgb(col);
+ m_ColorButton->setCurrent(KDualColorButton::Foreground);
+ emit sigFgColorChanged(m_fgColor);
+ }
+ else{
+ CMYKColor col = RgbToCmyk(m_bgColor);
+ col.Y = y / 255.0;
+ m_bgColor = CmykToRgb(col);
+ m_ColorButton->setCurrent(KDualColorButton::Background);
+ emit sigBgColorChanged(m_bgColor);
+ }
+}
+
+void KoCMYKWidget::slotKChanged(int k)
+{
+ if (m_ColorButton->current() == KDualColorButton::Foreground){
+ CMYKColor col = RgbToCmyk(m_fgColor);
+ col.K = k / 255.0;
+ m_fgColor = CmykToRgb(col);
+ m_ColorButton->setCurrent(KDualColorButton::Foreground);
+ emit sigFgColorChanged(m_fgColor);
+ }
+ else{
+ CMYKColor col = RgbToCmyk(m_bgColor);
+ col.K = k / 255.0;
+ m_bgColor = CmykToRgb(col);
+ m_ColorButton->setCurrent(KDualColorButton::Background);
+ emit sigBgColorChanged(m_bgColor);
+ }
+}
+
+void KoCMYKWidget::setFgColor(const QColor & c)
+{
+ update(c, m_bgColor);
+}
+
+void KoCMYKWidget::setBgColor(const QColor & c)
+{
+ update(m_fgColor, c);
+}
+
+void KoCMYKWidget::update(const QColor fgColor, const QColor bgColor)
+{
+ m_fgColor = fgColor;
+ m_bgColor = bgColor;
+
+ QColor color = (m_ColorButton->current() == KDualColorButton::Foreground)? m_fgColor : m_bgColor;
+
+ CMYKColor col = RgbToCmyk(color);
+
+ disconnect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+ disconnect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+
+ m_ColorButton->setForeground( m_fgColor );
+ m_ColorButton->setBackground( m_bgColor );
+
+ connect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+ connect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+
+ mCSlider->blockSignals(true);
+ mCIn->blockSignals(true);
+ mMSlider->blockSignals(true);
+ mMIn->blockSignals(true);
+ mYSlider->blockSignals(true);
+ mYIn->blockSignals(true);
+ mKSlider->blockSignals(true);
+ mKIn->blockSignals(true);
+
+ CMYKColor minC = col;
+ minC.C = 0.0;
+ CMYKColor maxC = col;
+ maxC.C = 1.0;
+
+ mCSlider->slotSetColor1(CmykToRgb(minC));
+ mCSlider->slotSetColor2(CmykToRgb(maxC));
+ mCSlider->slotSetValue(int(col.C * 255));
+ mCIn->setValue(int(col.C * 255));
+
+ CMYKColor minM = col;
+ minM.M = 0.0;
+ CMYKColor maxM = col;
+ maxM.M = 1.0;
+
+ mMSlider->slotSetColor1(CmykToRgb(minM));
+ mMSlider->slotSetColor2(CmykToRgb(maxM));
+ mMSlider->slotSetValue(int(col.M * 255));
+ mMIn->setValue(int(col.M * 255));
+
+ CMYKColor minY = col;
+ minY.Y = 0.0;
+ CMYKColor maxY = col;
+ maxY.Y = 1.0;
+
+ mYSlider->slotSetColor1(CmykToRgb(minY));
+ mYSlider->slotSetColor2(CmykToRgb(maxY));
+ mYSlider->slotSetValue(int(col.Y * 255));
+ mYIn->setValue(int(col.Y * 255));
+
+ CMYKColor minK = col;
+ minK.K = 0.0;
+ CMYKColor maxK = col;
+ maxK.K = 1.0;
+
+ mKSlider->slotSetColor1(CmykToRgb(minK));
+ mKSlider->slotSetColor2(CmykToRgb(maxK));
+ mKSlider->slotSetValue(int(col.K * 255));
+ mKIn->setValue(int(col.K * 255));
+
+ mCSlider->blockSignals(false);
+ mCIn->blockSignals(false);
+ mMSlider->blockSignals(false);
+ mMIn->blockSignals(false);
+ mYSlider->blockSignals(false);
+ mYIn->blockSignals(false);
+ mKSlider->blockSignals(false);
+ mKIn->blockSignals(false);
+}
+
+void KoCMYKWidget::slotFGColorSelected(const QColor& c)
+{
+ m_fgColor = QColor(c);
+ emit sigFgColorChanged(m_fgColor);
+}
+
+void KoCMYKWidget::slotBGColorSelected(const QColor& c)
+{
+ m_bgColor = QColor(c);
+ emit sigBgColorChanged(m_bgColor);
+}
+
+CMYKColor KoCMYKWidget::RgbToCmyk(const QColor& col)
+{
+ kdDebug() << "--[ KoCMYKWidget::RgbToCmyk ]--------------------------------------" << endl;
+ kdDebug() << endl;
+
+ // RGB to CMY
+ float r = col.red() / 255.0;
+ float g = col.green() / 255.0;
+ float b = col.blue() / 255.0;
+
+ kdDebug() << "float r = col.red() / 255.0;" << endl;
+ kdDebug() << " r = " << col.red() << " / 255.0 = " << r << endl;
+ kdDebug() << "float g = col.green() / 255.0;" << endl;
+ kdDebug() << " g = " << col.green() << " / 255.0 = " << g << endl;
+ kdDebug() << "float b = col.blue() / 255.0;" << endl;
+ kdDebug() << " b = " << col.blue() << " / 255.0 = " << b << endl;
+ kdDebug() << endl;
+
+ float ac = 1.0 - r;
+ float am = 1.0 - g;
+ float ay = 1.0 - b;
+
+ kdDebug() << "float ac = 1.0 - r;" << endl;
+ kdDebug() << " ac = 1.0 - " << r << " = " << ac << endl;
+ kdDebug() << "float am = 1.0 - g;" << endl;
+ kdDebug() << " am = 1.0 - " << g << " = " << am << endl;
+ kdDebug() << "float ay = 1.0 - b;" << endl;
+ kdDebug() << " ay = 1.0 - " << b << " = " << ay << endl;
+ kdDebug() << endl;
+
+ // CMY to CMYK
+ float c = 0.0;
+ float m = 0.0;
+ float y = 0.0;
+ float k = 0.0;
+
+ if ((r == 0.0) && (g == 0.0) && (b == 0.0))
+ {
+ kdDebug() << "r = g = b = 0.0: Therefor k = 1.0" << endl;
+ k = 1.0;
+ }
+ else
+ {
+ kdDebug() << "r = g = b != 0.0: Therefor k = min(ac,am,ay)" << endl;
+
+ if (kMin(ac,am) == ac)
+ k = kMin(ac,ay);
+ else
+ k = kMin(am,ay);
+
+ c = (ac - k) / (1.0 - k);
+ m = (am - k) / (1.0 - k);
+ y = (ay - k) / (1.0 - k);
+ }
+
+ kdDebug() << "float k = " << k << endl;
+ kdDebug() << endl;
+
+ kdDebug() << "float c = (ac - k) / (1.0 - k);" << endl;
+ kdDebug() << " c = (" << ac << " - " << k << ") / (1.0 - " << k << ") = " << c << endl;
+ kdDebug() << "float m = (am - k) / (1.0 - k);" << endl;
+ kdDebug() << " m = (" << am << " - " << k << ") / (1.0 - " << k << ") = " << m << endl;
+ kdDebug() << "float y = (ay - k) / (1.0 - k);" << endl;
+ kdDebug() << " y = (" << ay << " - " << k << ") / (1.0 - " << k << ") = " << y << endl;
+ kdDebug() << endl;
+
+ CMYKColor color;
+ color.C = c;
+ color.M = m;
+ color.Y = y;
+ color.K = k;
+
+ kdDebug() << "===================================================================" << endl;
+
+ return color;
+}
+
+QColor KoCMYKWidget::CmykToRgb(const CMYKColor& c)
+{
+ // CMYK to CMY
+ float ac = kMin(1.0, c.C * (1.0 - c.K) + c.K);
+ float am = kMin(1.0, c.M * (1.0 - c.K) + c.K);
+ float ay = kMin(1.0, c.Y * (1.0 - c.K) + c.K);
+
+ // CMY to RGB
+ int r = int((1.0 - ac) * 255.0);
+ int g = int((1.0 - am) * 255.0);
+ int b = int((1.0 - ay) * 255.0);
+
+ QColor color;
+ color.setRgb(r,g,b);
+
+ return color;
+}
+
+#include "ko_cmyk_widget.moc"
diff --git a/lib/kopainter/ko_cmyk_widget.h b/lib/kopainter/ko_cmyk_widget.h
new file mode 100644
index 00000000..5cb00b7a
--- /dev/null
+++ b/lib/kopainter/ko_cmyk_widget.h
@@ -0,0 +1,116 @@
+/* This file is part of the KDE project
+ * Copyright (c) 1999 Matthias Elter (me@kde.org)
+ * Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+ * Copyright (c) 2005 Tim Beaulen (tbscope@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef KO_CMYK_WIDGET_H
+#define KO_CMYK_WIDGET_H
+
+#include "qwidget.h"
+
+#include <koffice_export.h>
+
+class KoFrameButton;
+class QGridLayout;
+class QColor;
+class KoColorSlider;
+class QLabel;
+class QSpinBox;
+class KDualColorButton;
+
+struct CMYKColor
+{
+ float C;
+ float M;
+ float Y;
+ float K;
+};
+
+class KoCMYKWidget
+ : public QWidget
+{
+ Q_OBJECT
+ typedef QWidget super;
+
+public:
+ KoCMYKWidget(QWidget *parent = 0L, const char *name = 0);
+ virtual ~KoCMYKWidget() {}
+
+public slots:
+ /**
+ * Set the current color to c. Do not emit the color changed signals
+ */
+ virtual void setFgColor(const QColor & c);
+ virtual void setBgColor(const QColor & c);
+
+signals:
+
+ /**
+ * Emitted when the current color is changed.
+ */
+ virtual void sigFgColorChanged(const QColor & c);
+ virtual void sigBgColorChanged(const QColor & c);
+
+
+protected slots:
+
+ virtual void slotCChanged(int c);
+ virtual void slotMChanged(int m);
+ virtual void slotYChanged(int y);
+ virtual void slotKChanged(int k);
+
+ void slotFGColorSelected(const QColor& c);
+ void slotBGColorSelected(const QColor& c);
+
+private:
+
+ void update(const QColor fgColor, const QColor);
+
+ CMYKColor RgbToCmyk(const QColor& col);
+ QColor CmykToRgb(const CMYKColor& c);
+
+private:
+
+ KoColorSlider *mCSlider;
+ KoColorSlider *mMSlider;
+ KoColorSlider *mYSlider;
+ KoColorSlider *mKSlider;
+ QLabel *mCLabel;
+ QLabel *mMLabel;
+ QLabel *mYLabel;
+ QLabel *mKLabel;
+ QSpinBox *mCIn;
+ QSpinBox *mMIn;
+ QSpinBox *mYIn;
+ QSpinBox *mKIn;
+ KDualColorButton *m_ColorButton;
+
+ float m_fgC;
+ float m_fgM;
+ float m_fgY;
+ float m_fgK;
+
+ float m_bgC;
+ float m_bgM;
+ float m_bgY;
+ float m_bgK;
+
+ QColor m_fgColor;
+ QColor m_bgColor;
+};
+
+#endif
diff --git a/lib/kopainter/ko_color_wheel.cc b/lib/kopainter/ko_color_wheel.cc
new file mode 100644
index 00000000..a7a77a44
--- /dev/null
+++ b/lib/kopainter/ko_color_wheel.cc
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2004 Sven Langkamp <longamp@reallygood.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <math.h>
+
+#include <qpoint.h>
+#include <qpainter.h>
+#include <qimage.h>
+
+#include <kdebug.h>
+#include "ko_color_wheel.h"
+
+#define pi 3.14159265
+
+KoColorWheel::KoColorWheel( QWidget *parent, const char *name ): KXYSelector( parent, name )
+{
+
+}
+
+void KoColorWheel::resizeEvent( QResizeEvent * )
+{
+ drawWheel(&m_pixmap);
+ setRange( 0, 0, contentsRect().width(), contentsRect().height() );
+}
+
+void KoColorWheel::drawContents( QPainter *painter )
+{
+ painter->drawPixmap( contentsRect().x(), contentsRect().y(), m_pixmap );
+}
+
+void KoColorWheel::drawWheel( QPixmap *pixmap )
+{
+ int size = QMIN(contentsRect().width(), contentsRect().height());
+ QPoint center(size/2, size/2);
+
+ QImage image( size, size, 32 );
+ image.fill(colorGroup ().background().pixel());
+
+ QColor col;
+ int a, b, h, s;
+ uint *p;
+
+ for ( a = size-1; a >= 0; a-- )
+ {
+ p = (uint*) image.scanLine( size - a - 1 );
+ for( b = 0; b < size; b++ )
+ {
+ s = (int)(sqrt(pow(a-center.y(), 2) + pow(b-center.x(), 2))/(size/2)*255);
+ if(s<=255)
+ {
+ h = (int)(atan2( b-center.x(), a-center.y())* 180.0 / pi);
+ if(h<0) h += 360;
+ if(h>360) h -= 360;
+
+ col.setHsv( h, s, 210 );
+ *p = col.rgb();
+ }
+ p++;
+ }
+ }
+ pixmap->convertFromImage( image );
+}
+
+void KoColorWheel::mousePressEvent( QMouseEvent *e )
+{
+ int size = QMIN(contentsRect().width(), contentsRect().height());
+ QPoint center(size/2, size/2);
+
+ int xVal, yVal;
+ valuesFromPosition( e->pos().x() - 2, e->pos().y() - 2, xVal, yVal );
+ setValues( xVal, yVal );
+
+ int h, s;
+
+ s = (int)(sqrt(pow(yVal-center.y(), 2) + pow(xVal-center.x(), 2))/(size/2)*255);
+ if(s>255) s = 255;
+
+ h = (int)(atan2( xVal-center.x(), yVal-center.y())* 180.0 / pi);
+ if(h<0) h += 360;
+ if(h>360) h -= 360;
+
+ m_color.setHSV( h, s, 255);
+ emit valueChanged(m_color);
+}
+
+void KoColorWheel::mouseMoveEvent( QMouseEvent *e )
+{
+ mousePressEvent( e );
+}
+
+void KoColorWheel::slotSetValue(const KoColor& c)
+{
+ int size = QMIN(contentsRect().width(), contentsRect().height());
+ QPoint center(size/2, size/2);
+
+ int xVal, yVal;
+ xVal = (int)(sin(c.H() * pi /180) * c.S() / 255 * (size/2) + center.x());
+ yVal = (int)(cos(c.H() * pi /180) * c.S() / 255 * (size/2) + center.y());
+ setValues( xVal, yVal );
+}
+
+#include "ko_color_wheel.moc"
diff --git a/lib/kopainter/ko_color_wheel.h b/lib/kopainter/ko_color_wheel.h
new file mode 100644
index 00000000..c084a564
--- /dev/null
+++ b/lib/kopainter/ko_color_wheel.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2004 Sven Langkamp <longamp@reallygood.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KO_COLORWHEEL_H
+#define KO_COLORWHEEL_H
+
+#include <qpixmap.h>
+
+#include <kselect.h>
+#include <koColor.h>
+
+class QPainter;
+
+class KoColorWheel : public KXYSelector
+{
+ Q_OBJECT
+
+public:
+ KoColorWheel( QWidget *parent=0, const char *name=0 );
+
+signals:
+ void valueChanged(const KoColor& c);
+
+public slots:
+ virtual void slotSetValue(const KoColor& c);
+
+protected:
+ virtual void drawWheel( QPixmap *pixmap );
+ virtual void resizeEvent( QResizeEvent * );
+ virtual void mousePressEvent( QMouseEvent *e );
+ virtual void mouseMoveEvent( QMouseEvent *e );
+ virtual void drawContents( QPainter *painter );
+
+private:
+ QPixmap m_pixmap;
+ KoColor m_color;
+};
+
+#endif
diff --git a/lib/kopainter/ko_gray_widget.cc b/lib/kopainter/ko_gray_widget.cc
new file mode 100644
index 00000000..957ee917
--- /dev/null
+++ b/lib/kopainter/ko_gray_widget.cc
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1999 Matthias Elter (me@kde.org)
+ * Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "ko_gray_widget.h"
+
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qcolor.h>
+
+#include <kdebug.h>
+
+#include <koFrameButton.h>
+#include <koColorSlider.h>
+#include <kcolordialog.h>
+
+KoGrayWidget::KoGrayWidget(QWidget *parent, const char *name) : super(parent, name)
+{
+ m_ColorButton = new KDualColorButton(this);
+ Q_CHECK_PTR(m_ColorButton);
+
+ m_ColorButton -> setFixedSize(m_ColorButton->sizeHint());
+ QGridLayout *mGrid = new QGridLayout(this, 3, 5, 5, 2);
+
+ /* setup color sliders */
+ mSlider = new KoColorSlider(this);
+ mSlider->setFocusPolicy( QWidget::ClickFocus );
+ mSlider->setMaximumHeight(20);
+ mSlider->slotSetRange(0, 255);
+ mSlider->slotSetColor1(QColor(255, 255, 255));
+ mSlider->slotSetColor2(QColor(0, 0, 0));
+
+ /* setup slider labels */
+ mLabel = new QLabel("K:", this);
+ mLabel->setFixedWidth(12);
+ mLabel->setFixedHeight(20);
+
+ /* setup spin box */
+ mIn = new QSpinBox(0, 255, 1, this);
+ mIn->setFixedWidth(50);
+ mIn->setFixedHeight(20);
+ mIn->setFocusPolicy( QWidget::ClickFocus );
+
+ mGrid->addMultiCellWidget(m_ColorButton, 0, 3, 0, 0, Qt::AlignTop);
+ mGrid->addWidget(mLabel, 0, 1);
+ mGrid->addMultiCellWidget(mSlider, 0, 0, 2, 3);
+ mGrid->addWidget(mIn, 0, 4);
+
+ connect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+ connect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+
+ /* connect color slider */
+ connect(mSlider, SIGNAL(valueChanged(int)), this, SLOT(slotChanged(int)));
+
+ /* connect spin box */
+ connect(mIn, SIGNAL(valueChanged(int)), this, SLOT(slotChanged(int)));
+}
+
+void KoGrayWidget::slotChanged(int v)
+{
+ v = 255 - v;
+
+ if (m_ColorButton->current() == KDualColorButton::Foreground){
+ slotFGColorSelected( QColor( v, v, v));
+ }
+ else{
+ slotBGColorSelected( QColor( v, v, v));
+ }
+}
+
+void KoGrayWidget::setFgColor(const QColor & c)
+{
+ blockSignals(true);
+ slotFGColorSelected(c);
+ blockSignals(false);
+}
+
+void KoGrayWidget::setBgColor(const QColor & c)
+{
+ blockSignals(true);
+ slotBGColorSelected(c);
+ blockSignals(false);
+}
+
+void KoGrayWidget::update(const QColor & fgColor, const QColor & bgColor)
+{
+
+ m_fgColor = fgColor;
+ m_bgColor = bgColor;
+
+ QColor color = (m_ColorButton->current() == KDualColorButton::Foreground)? m_fgColor : m_bgColor;
+
+ disconnect(mSlider, SIGNAL(valueChanged(int)), this, SLOT(slotChanged(int)));
+ disconnect(mIn, SIGNAL(valueChanged(int)), this, SLOT(slotChanged(int)));
+
+ mIn->blockSignals(true);
+ mSlider->blockSignals(true);
+ double v = color.red() + color.green() + color.blue();
+ v /= 3.0;
+ v = 255.0 - v;
+ mIn->setValue(static_cast<int>(v));
+ mSlider->slotSetValue(static_cast<int>(v));
+ mIn->blockSignals(false);
+ mSlider->blockSignals(false);
+
+ connect(mSlider, SIGNAL(valueChanged(int)), this, SLOT(slotChanged(int)));
+ connect(mIn, SIGNAL(valueChanged(int)), this, SLOT(slotChanged(int)));
+}
+
+void KoGrayWidget::slotFGColorSelected(const QColor& c)
+{
+ m_fgColor = c;
+
+ disconnect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+ m_ColorButton->setForeground( m_fgColor );
+ connect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+
+ emit sigFgColorChanged(m_fgColor);
+}
+
+void KoGrayWidget::slotBGColorSelected(const QColor& c)
+{
+ m_bgColor = c;
+
+ disconnect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+ m_ColorButton->setBackground( m_bgColor );
+ connect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+
+ emit sigBgColorChanged(m_bgColor);
+}
+
+void KoGrayWidget::currentChanged(KDualColorButton::DualColor s)
+{
+ if(s == KDualColorButton::Foreground)
+ slotFGColorSelected(m_ColorButton->currentColor());
+ else
+ slotBGColorSelected(m_ColorButton->currentColor());
+}
+
+#include "ko_gray_widget.moc"
diff --git a/lib/kopainter/ko_gray_widget.h b/lib/kopainter/ko_gray_widget.h
new file mode 100644
index 00000000..818932c5
--- /dev/null
+++ b/lib/kopainter/ko_gray_widget.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 Matthias Elter (me@kde.org)
+ * Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef KO_GRAY_WIDGET_H
+#define KO_GRAY_WIDGET_H
+
+#include "qwidget.h"
+
+#include <koffice_export.h>
+#include <kdualcolorbutton.h>
+
+class KoFrameButton;
+class QGridLayout;
+class QColor;
+class KoColorSlider;
+class QLabel;
+class QSpinBox;
+class KDualColorButton;
+
+class KoGrayWidget
+ : public QWidget
+{
+ Q_OBJECT
+ typedef QWidget super;
+
+public:
+ KoGrayWidget(QWidget *parent = 0L, const char *name = 0);
+ virtual ~KoGrayWidget() {}
+
+public slots:
+ /**
+ * Set the current color to c. Do not emit the color changed signals
+ */
+ virtual void setFgColor(const QColor & c);
+ virtual void setBgColor(const QColor & c);
+
+signals:
+
+ /**
+ * Emitted when the current color is changed.
+ */
+ virtual void sigFgColorChanged(const QColor & c);
+ virtual void sigBgColorChanged(const QColor & c);
+
+protected slots:
+ virtual void slotChanged(int v);
+
+ void slotFGColorSelected(const QColor& c);
+ void slotBGColorSelected(const QColor& c);
+ void currentChanged(KDualColorButton::DualColor);
+
+private:
+
+ void update(const QColor & fgColor, const QColor & bgColor);
+
+ KoColorSlider *mSlider;
+ QLabel *mLabel;
+ QSpinBox *mIn;
+ KDualColorButton *m_ColorButton;
+
+ QColor m_fgColor;
+ QColor m_bgColor;
+};
+
+#endif
diff --git a/lib/kopainter/ko_hsv_widget.cc b/lib/kopainter/ko_hsv_widget.cc
new file mode 100644
index 00000000..3670b5d9
--- /dev/null
+++ b/lib/kopainter/ko_hsv_widget.cc
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 1999 Matthias Elter (me@kde.org)
+ * Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "ko_hsv_widget.h"
+#include "ko_color_wheel.h"
+
+#include <kselect.h>
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qtooltip.h>
+#include <koFrameButton.h>
+#include <koColorSlider.h>
+#include <kcolordialog.h>
+#include <kdualcolorbutton.h>
+#include <koColor.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+KoHSVWidget::KoHSVWidget(QWidget *parent, const char *name) : super(parent, name)
+{
+ m_ColorButton = new KDualColorButton(this);
+ m_ColorButton -> setFixedSize(m_ColorButton->sizeHint());
+
+ QGridLayout *mGrid = new QGridLayout(this, 5, 7, 5, 2);
+ m_colorwheel = new KoColorWheel(this);
+ m_colorwheel->setFixedSize( 120, 120);
+ m_VSelector = new KValueSelector(Qt::Vertical, this);
+ m_VSelector-> setFixedSize( 30, 120);
+
+ /* setup slider labels */
+ mHLabel = new QLabel("H:", this);
+ mHLabel->setFixedSize(12, 20);
+ mSLabel = new QLabel("S:", this);
+ mSLabel->setFixedSize(12, 20);
+ mVLabel = new QLabel("V:", this);
+ mVLabel->setFixedSize(12, 20);
+
+ /* setup spin box */
+ mHIn = new QSpinBox(0, 359, 1, this);
+ mHIn->setFixedSize(50, 20);
+ mHIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mHIn, i18n( "Hue" ) );
+
+ mSIn = new QSpinBox(0, 255, 1, this);
+ mSIn->setFixedSize(50, 20);
+ mSIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mSIn, i18n( "Saturation" ) );
+
+ mVIn = new QSpinBox(0, 255, 1, this);
+ mVIn->setFixedSize(50, 20);
+ mVIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mVIn, i18n( "Value (brightness)" ) );
+
+ mGrid->addMultiCellWidget(m_ColorButton, 0, 0, 0, 1, Qt::AlignTop);
+
+ mGrid->addWidget(mHLabel, 1, 0);
+ mGrid->addWidget(mSLabel, 2, 0);
+ mGrid->addWidget(mVLabel, 3, 0);
+
+ mGrid->addMultiCellWidget(m_colorwheel, 0, 3, 2, 4);
+
+ mGrid->addWidget(mHIn, 1, 1);
+ mGrid->addWidget(mSIn, 2, 1);
+ mGrid->addWidget(mVIn, 3, 1);
+
+ mGrid->addMultiCellWidget(m_VSelector, 0, 3, 5, 5);
+
+
+ connect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+ connect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+ connect(m_ColorButton, SIGNAL(currentChanged(KDualColorButton::DualColor)), this, SLOT(currentChanged(KDualColorButton::DualColor)));
+
+ connect(m_VSelector, SIGNAL(valueChanged(int)), this, SLOT(slotVChanged(int)));
+ connect(m_colorwheel, SIGNAL(valueChanged(const KoColor&)), this, SLOT(slotWheelChanged(const KoColor&)));
+
+ /* connect spin box */
+ connect(mHIn, SIGNAL(valueChanged(int)), this, SLOT(slotHChanged(int)));
+ connect(mSIn, SIGNAL(valueChanged(int)), this, SLOT(slotSChanged(int)));
+ connect(mVIn, SIGNAL(valueChanged(int)), this, SLOT(slotVChanged(int)));
+
+ //setFixedSize(mGrid -> minimumSize());
+ m_autovalue = true; // So on the initial selection of h or v, s gets set to 255.
+
+ update(Qt::black, Qt::white);
+}
+
+void KoHSVWidget::slotHChanged(int h)
+{
+ //kdDebug() << "H changed: " << h << endl;
+ if (m_ColorButton->current() == KDualColorButton::Foreground){
+ m_fgColor.setHSV(h, m_fgColor.S(), m_fgColor.V());
+ changedFgColor();
+ }
+ else{
+ m_bgColor.setHSV(h, m_bgColor.S(), m_bgColor.V());
+ changedBgColor();
+ }
+}
+
+void KoHSVWidget::slotSChanged(int s)
+{
+ //kdDebug() << "S changed: " << s << endl;
+ if (m_ColorButton->current() == KDualColorButton::Foreground){
+ m_fgColor.setHSV(m_fgColor.H(), s, m_fgColor.V());
+ changedFgColor();
+ }
+ else{
+ m_bgColor.setHSV(m_bgColor.H(), s, m_bgColor.V());
+ changedBgColor();
+ }
+}
+
+void KoHSVWidget::slotVChanged(int v)
+{
+ //kdDebug() << "V changed: " << v << ", setting autovalue to false " << endl;
+ m_autovalue = false;
+ if (m_ColorButton->current() == KDualColorButton::Foreground){
+ m_fgColor.setHSV(m_fgColor.H(), m_fgColor.S(), v);
+ changedFgColor();
+ }
+ else{
+ m_bgColor.setHSV(m_bgColor.H(), m_bgColor.S(), v);
+ changedBgColor();
+ }
+}
+
+void KoHSVWidget::slotWheelChanged(const KoColor& c)
+{
+ //kdDebug() << "Wheel changed: " << c.color() << endl;
+ if (m_ColorButton->current() == KDualColorButton::Foreground){
+ if(m_autovalue)
+ m_fgColor.setHSV(c.H(), c.S(), 255);
+ else
+ m_fgColor.setHSV(c.H(), c.S(), m_fgColor.V());
+ changedFgColor();
+ }
+ else{
+ if(m_autovalue)
+ m_bgColor.setHSV(c.H(), c.S(), 255);
+ else
+ m_bgColor.setHSV(c.H(), c.S(), m_bgColor.V());
+ changedBgColor();
+ }
+}
+
+
+void KoHSVWidget::setFgColor(const QColor & c)
+{
+ //kdDebug() << "setFGColor " << c << endl;
+ blockSignals(true);
+ slotFGColorSelected(c);
+ blockSignals(false);
+}
+
+void KoHSVWidget::setBgColor(const QColor & c)
+{
+ //kdDebug() << "setBgColor " << c << endl;
+ blockSignals(true);
+ slotBGColorSelected(c);
+ blockSignals(false);
+}
+
+void KoHSVWidget::changedFgColor()
+{
+ //kdDebug() << "ChangedFgColor\n";
+ disconnect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+ m_ColorButton->setForeground( m_fgColor.color() );
+ connect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+
+ update( m_fgColor, m_bgColor);
+
+ emit sigFgColorChanged(m_fgColor.color());
+}
+
+void KoHSVWidget::changedBgColor()
+{
+ //kdDebug() << "changedBgColor()\n";
+ disconnect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+ m_ColorButton->setBackground( m_bgColor.color() );
+ connect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+
+ update(m_fgColor, m_bgColor );
+
+ emit sigBgColorChanged(m_bgColor.color());
+}
+
+void KoHSVWidget::update(const KoColor & fgColor, const KoColor & bgColor)
+{
+
+ mHIn->blockSignals(true);
+ mSIn->blockSignals(true);
+ mVIn->blockSignals(true);
+ m_VSelector->blockSignals(true);
+ m_colorwheel->blockSignals(true);
+
+ //kdDebug() << "update. FG: " << fgColor.color() << ", bg: " << bgColor.color() << endl;
+ m_fgColor = fgColor;
+ m_bgColor = bgColor;
+
+ KoColor color = (m_ColorButton->current() == KDualColorButton::Foreground)? m_fgColor : m_bgColor;
+
+ int h = color.H();
+ int s = color.S();
+ int v = color.V();
+
+ mHIn->setValue(h);
+ mSIn->setValue(s);
+ mVIn->setValue(v);
+
+ m_VSelector->setHue(h);
+ m_VSelector->setSaturation(s);
+ m_VSelector->setValue(v);
+ m_VSelector->updateContents();
+
+ m_colorwheel->slotSetValue(color);
+
+ mHIn->blockSignals(false);
+ mSIn->blockSignals(false);
+ mVIn->blockSignals(false);
+ m_VSelector->blockSignals(false);
+ m_VSelector->repaint(false);
+ m_colorwheel->blockSignals(false);
+}
+
+void KoHSVWidget::slotFGColorSelected(const QColor& c)
+{
+ //kdDebug() << "slotFGColorSelected " << c << endl;
+ m_fgColor = KoColor(c);
+
+ changedFgColor();
+}
+
+void KoHSVWidget::slotBGColorSelected(const QColor& c)
+{
+ //kdDebug() << "slotBGColorSelected()" << c << endl;
+ m_bgColor = KoColor(c);
+
+ changedBgColor();
+}
+
+void KoHSVWidget::currentChanged(KDualColorButton::DualColor s)
+{
+ //kdDebug() << "currentChanged\n";
+ if(s == KDualColorButton::Foreground)
+ slotFGColorSelected(m_ColorButton->currentColor());
+ else
+ slotBGColorSelected(m_ColorButton->currentColor());
+ emit sigModeChanged( s );
+}
+
+void KoHSVWidget::setMode(KDualColorButton::DualColor s)
+{
+ m_ColorButton->setCurrent( s );
+}
+
+#include "ko_hsv_widget.moc"
diff --git a/lib/kopainter/ko_hsv_widget.h b/lib/kopainter/ko_hsv_widget.h
new file mode 100644
index 00000000..f8fcdcfb
--- /dev/null
+++ b/lib/kopainter/ko_hsv_widget.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 1999 Matthias Elter (me@kde.org)
+ * Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef KO_HSV_WIDGET_H
+#define KO_HSV_WIDGET_H
+
+#include "qwidget.h"
+#include "kdualcolorbutton.h"
+
+#include "koColor.h"
+
+#include <koffice_export.h>
+
+class KDualColorButton;
+class KValueSelector;
+class KoColorWheel;
+class KoColorSlider;
+class KoFrameButton;
+class QGridLayout;
+class QLabel;
+class QSpinBox;
+
+class KoHSVWidget
+ : public QWidget
+{
+ Q_OBJECT
+ typedef QWidget super;
+
+public:
+ KoHSVWidget(QWidget *parent = 0L, const char *name = 0);
+ virtual ~KoHSVWidget() {}
+
+public slots:
+ /**
+ * Set the current color to c. Do not emit the color changed signals
+ */
+ virtual void setFgColor(const QColor & c);
+ virtual void setBgColor(const QColor & c);
+ /// Sets the current mode (foreground/background) without emitting the signal
+ virtual void setMode(KDualColorButton::DualColor);
+signals:
+
+ /**
+ * Emitted when the current color is changed.
+ */
+ virtual void sigFgColorChanged(const QColor & c);
+ virtual void sigBgColorChanged(const QColor & c);
+ /// Emitted when the mode (foreground/background) was changed
+ virtual void sigModeChanged(KDualColorButton::DualColor);
+
+protected slots:
+
+ virtual void slotHChanged(int h);
+ virtual void slotSChanged(int s);
+ virtual void slotVChanged(int v);
+ virtual void slotWheelChanged(const KoColor& c);
+
+ void slotFGColorSelected(const QColor& c);
+ void slotBGColorSelected(const QColor& c);
+ void currentChanged(KDualColorButton::DualColor);
+
+private:
+ void changedFgColor();
+ void changedBgColor();
+
+ void update(const KoColor & fgColor, const KoColor & bgColor);
+
+ KoColorWheel *m_colorwheel;
+ KValueSelector *m_VSelector;
+ QLabel *mHLabel;
+ QLabel *mSLabel;
+ QLabel *mVLabel;
+ QSpinBox *mHIn;
+ QSpinBox *mSIn;
+ QSpinBox *mVIn;
+ KDualColorButton *m_ColorButton;
+
+ KoColor m_fgColor;
+ KoColor m_bgColor;
+
+ bool m_autovalue;
+};
+
+#endif
diff --git a/lib/kopainter/ko_rgb_widget.cc b/lib/kopainter/ko_rgb_widget.cc
new file mode 100644
index 00000000..f533bef5
--- /dev/null
+++ b/lib/kopainter/ko_rgb_widget.cc
@@ -0,0 +1,235 @@
+/*
+ * This file is part of Krita
+ *
+ * Copyright (c) 1999 Matthias Elter (me@kde.org)
+ * Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "ko_rgb_widget.h"
+
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qtooltip.h>
+#include <qcolor.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <koFrameButton.h>
+#include <koColorSlider.h>
+#include <kcolordialog.h>
+
+KoRGBWidget::KoRGBWidget(QWidget *parent, const char *name) : super(parent, name)
+{
+ m_ColorButton = new KDualColorButton(this);
+ m_ColorButton -> setFixedSize(m_ColorButton->sizeHint());
+ QGridLayout *mGrid = new QGridLayout(this, 3, 5, 5, 2);
+
+ /* setup color sliders */
+ mRSlider = new KoColorSlider(this);
+ mRSlider->setMaximumHeight(20);
+ mRSlider->slotSetRange(0, 255);
+ mRSlider->setFocusPolicy( QWidget::ClickFocus );
+
+ mGSlider = new KoColorSlider(this);
+ mGSlider->setMaximumHeight(20);
+ mGSlider->slotSetRange(0, 255);
+ mGSlider->setFocusPolicy( QWidget::ClickFocus );
+
+ mBSlider = new KoColorSlider(this);
+ mBSlider->setMaximumHeight(20);
+ mBSlider->slotSetRange(0, 255);
+ mBSlider->setFocusPolicy( QWidget::ClickFocus );
+
+ /* setup slider labels */
+ mRLabel = new QLabel("R:", this);
+ mRLabel->setFixedWidth(12);
+ mRLabel->setFixedHeight(20);
+ mGLabel = new QLabel("G:", this);
+ mGLabel->setFixedWidth(12);
+ mGLabel->setFixedHeight(20);
+ mBLabel = new QLabel("B:", this);
+ mBLabel->setFixedWidth(12);
+ mBLabel->setFixedHeight(20);
+
+ /* setup spin box */
+ mRIn = new QSpinBox(0, 255, 1, this);
+ mRIn->setFixedWidth(50);
+ mRIn->setFixedHeight(20);
+ mRIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mRIn, i18n( "Red" ) );
+
+ mGIn = new QSpinBox(0, 255, 1, this);
+ mGIn->setFixedWidth(50);
+ mGIn->setFixedHeight(20);
+ mGIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mGIn, i18n( "Green" ) );
+
+ mBIn = new QSpinBox(0, 255, 1, this);
+ mBIn->setFixedWidth(50);
+ mBIn->setFixedHeight(20);
+ mBIn->setFocusPolicy( QWidget::ClickFocus );
+ QToolTip::add( mBIn, i18n( "Blue" ) );
+
+ mGrid->addMultiCellWidget(m_ColorButton, 0, 3, 0, 0, Qt::AlignTop);
+ mGrid->addWidget(mRLabel, 0, 1);
+ mGrid->addWidget(mGLabel, 1, 1);
+ mGrid->addWidget(mBLabel, 2, 1);
+ mGrid->addMultiCellWidget(mRSlider, 0, 0, 2, 3);
+ mGrid->addMultiCellWidget(mGSlider, 1, 1, 2, 3);
+ mGrid->addMultiCellWidget(mBSlider, 2, 2, 2, 3);
+ mGrid->addWidget(mRIn, 0, 4);
+ mGrid->addWidget(mGIn, 1, 4);
+ mGrid->addWidget(mBIn, 2, 4);
+
+ connect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+ connect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+ connect(m_ColorButton, SIGNAL(currentChanged(KDualColorButton::DualColor)), this, SLOT(currentChanged(KDualColorButton::DualColor)));
+
+ /* connect color sliders */
+ connect(mRSlider, SIGNAL(valueChanged(int)), this, SLOT(slotRChanged(int)));
+ connect(mGSlider, SIGNAL(valueChanged(int)), this, SLOT(slotGChanged(int)));
+ connect(mBSlider, SIGNAL(valueChanged(int)), this, SLOT(slotBChanged(int)));
+
+ /* connect spin box */
+ connect(mRIn, SIGNAL(valueChanged(int)), this, SLOT(slotRChanged(int)));
+ connect(mGIn, SIGNAL(valueChanged(int)), this, SLOT(slotGChanged(int)));
+ connect(mBIn, SIGNAL(valueChanged(int)), this, SLOT(slotBChanged(int)));
+
+ update(Qt::black, Qt::white);
+}
+
+void KoRGBWidget::slotRChanged(int r)
+{
+ if (m_ColorButton->current() == KDualColorButton::Foreground)
+ slotFGColorSelected( QColor(r, m_fgColor.green(), m_fgColor.blue()));
+ else
+ slotBGColorSelected( QColor(r, m_bgColor.green(), m_bgColor.blue()));
+}
+
+void KoRGBWidget::slotGChanged(int g)
+{
+ if (m_ColorButton->current() == KDualColorButton::Foreground)
+ slotFGColorSelected( QColor( m_fgColor.red(), g, m_fgColor.blue()));
+ else
+ slotBGColorSelected( QColor( m_bgColor.red(), g, m_bgColor.blue()));;
+}
+
+void KoRGBWidget::slotBChanged(int b)
+{
+ if (m_ColorButton->current() == KDualColorButton::Foreground)
+ slotFGColorSelected( QColor( m_fgColor.red(), m_fgColor.green(), b));
+ else
+ slotBGColorSelected( QColor( m_bgColor.red(), m_bgColor.green(), b));
+}
+
+void KoRGBWidget::setFgColor(const QColor & c)
+{
+ blockSignals(true);
+ slotFGColorSelected(c);
+ blockSignals(false);
+}
+
+void KoRGBWidget::setBgColor(const QColor & c)
+{
+ blockSignals(true);
+ slotBGColorSelected(c);
+ blockSignals(false);
+}
+
+void KoRGBWidget::update(const QColor fgColor, const QColor bgColor)
+{
+
+ m_fgColor = fgColor;
+ m_bgColor = bgColor;
+
+ QColor color = (m_ColorButton->current() == KDualColorButton::Foreground)? m_fgColor : m_bgColor;
+
+ int r = color.red();
+ int g = color.green();
+ int b = color.blue();
+
+ mRSlider->blockSignals(true);
+ mRIn->blockSignals(true);
+ mGSlider->blockSignals(true);
+ mGIn->blockSignals(true);
+ mBSlider->blockSignals(true);
+ mBIn->blockSignals(true);
+
+ mRSlider->slotSetColor1(QColor(0, g, b));
+ mRSlider->slotSetColor2(QColor(255, g, b));
+ mRSlider->slotSetValue(r);
+ mRIn->setValue(r);
+
+ mGSlider->slotSetColor1(QColor(r, 0, b));
+ mGSlider->slotSetColor2(QColor(r, 255, b));
+ mGSlider->slotSetValue(g);
+ mGIn->setValue(g);
+
+ mBSlider->slotSetColor1(QColor(r, g, 0));
+ mBSlider->slotSetColor2(QColor(r, g, 255));
+ mBSlider->slotSetValue(b);
+ mBIn->setValue(b);
+
+ mRSlider->blockSignals(false);
+ mRIn->blockSignals(false);
+ mGSlider->blockSignals(false);
+ mGIn->blockSignals(false);
+ mBSlider->blockSignals(false);
+ mBIn->blockSignals(false);
+}
+
+void KoRGBWidget::slotFGColorSelected(const QColor& c)
+{
+ m_fgColor = c;
+ disconnect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+ m_ColorButton->setForeground( m_fgColor );
+ connect(m_ColorButton, SIGNAL(fgChanged(const QColor &)), this, SLOT(slotFGColorSelected(const QColor &)));
+
+ update( m_fgColor, m_bgColor);
+ emit sigFgColorChanged(m_fgColor);
+}
+
+void KoRGBWidget::slotBGColorSelected(const QColor& c)
+{
+ m_bgColor = c;
+
+ disconnect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+ m_ColorButton->setBackground( m_bgColor );
+ connect(m_ColorButton, SIGNAL(bgChanged(const QColor &)), this, SLOT(slotBGColorSelected(const QColor &)));
+
+ update(m_fgColor, m_bgColor);
+ emit sigBgColorChanged(m_bgColor);
+}
+
+void KoRGBWidget::currentChanged(KDualColorButton::DualColor s)
+{
+ if(s == KDualColorButton::Foreground)
+ slotFGColorSelected(m_ColorButton->currentColor());
+ else
+ slotBGColorSelected(m_ColorButton->currentColor());
+ emit sigModeChanged( s );
+}
+
+void KoRGBWidget::setMode(KDualColorButton::DualColor s)
+{
+ m_ColorButton->setCurrent( s );
+}
+
+#include "ko_rgb_widget.moc"
diff --git a/lib/kopainter/ko_rgb_widget.h b/lib/kopainter/ko_rgb_widget.h
new file mode 100644
index 00000000..ab18c8a5
--- /dev/null
+++ b/lib/kopainter/ko_rgb_widget.h
@@ -0,0 +1,98 @@
+/* This file is part of the KDE project
+ * Copyright (c) 1999 Matthias Elter (me@kde.org)
+ * Copyright (c) 2001-2002 Igor Jansen (rm@kde.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef KO_RGB_WIDGET_H
+#define KO_RGB_WIDGET_H
+
+#include "qwidget.h"
+
+#include <koffice_export.h>
+#include <kdualcolorbutton.h>
+
+class KoFrameButton;
+class QGridLayout;
+class QColor;
+class KoColorSlider;
+class QLabel;
+class QSpinBox;
+class KDualColorButton;
+class KoColorSlider;
+class QColor;
+
+class KoRGBWidget
+ : public QWidget
+{
+ Q_OBJECT
+ typedef QWidget super;
+
+public:
+ KoRGBWidget(QWidget *parent = 0L, const char *name = 0);
+ virtual ~KoRGBWidget() {}
+
+public slots:
+ /**
+ * Set the current color to c. Do not emit the color changed signals
+ */
+ virtual void setFgColor(const QColor & c);
+ virtual void setBgColor(const QColor & c);
+ /// Sets the current mode (foreground/background) without emitting the signal
+ virtual void setMode(KDualColorButton::DualColor);
+
+signals:
+
+ /**
+ * Emitted when the current color is changed.
+ */
+ virtual void sigFgColorChanged(const QColor & c);
+ virtual void sigBgColorChanged(const QColor & c);
+ /// Emitted when the mode (foreground/background) was changed
+ virtual void sigModeChanged(KDualColorButton::DualColor);
+
+
+protected slots:
+
+ virtual void slotRChanged(int r);
+ virtual void slotGChanged(int g);
+ virtual void slotBChanged(int b);
+
+ void slotFGColorSelected(const QColor& c);
+ void slotBGColorSelected(const QColor& c);
+ void currentChanged(KDualColorButton::DualColor);
+
+private:
+
+ void update(const QColor fgColor, const QColor);
+
+private:
+
+ KoColorSlider *mRSlider;
+ KoColorSlider *mGSlider;
+ KoColorSlider *mBSlider;
+ QLabel *mRLabel;
+ QLabel *mGLabel;
+ QLabel *mBLabel;
+ QSpinBox *mRIn;
+ QSpinBox *mGIn;
+ QSpinBox *mBIn;
+ KDualColorButton *m_ColorButton;
+
+ QColor m_fgColor;
+ QColor m_bgColor;
+};
+
+#endif
diff --git a/lib/kopainter/kogradientmanager.cc b/lib/kopainter/kogradientmanager.cc
new file mode 100644
index 00000000..41f31d81
--- /dev/null
+++ b/lib/kopainter/kogradientmanager.cc
@@ -0,0 +1,559 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Tim Beaulen <tbscope@gmail.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "kogradientmanager.h"
+
+#include "svgnamedcolors.h"
+
+#include <qtextstream.h>
+#include <qcstring.h>
+
+#include <kdebug.h>
+
+KoGradientManager::KoGradientManager()
+{
+}
+
+KoGradientManager::~KoGradientManager()
+{
+ // XXX: Should we delete the gradients here?
+}
+
+KoGradient* KoGradientManager::loadGradient(const QString& filename)
+{
+ QString strExt;
+ const int result=filename.findRev('.');
+ if (result>=0)
+ {
+ strExt=filename.mid(result).lower();
+ }
+
+ QFile f(filename);
+
+ if(f.open(IO_ReadOnly))
+ {
+ if(strExt == ".ggr")
+ {
+ return loadKritaGradient(&f);
+ }
+ else if(strExt==".kgr")
+ {
+ return loadKarbonGradient(&f);
+ }
+ else if(strExt==".svg")
+ {
+ return loadSvgGradient(&f);
+ }
+ }
+
+ return 0;
+}
+
+KoGradient* KoGradientManager::loadKarbonGradient(QFile* file)
+{
+ QDomDocument doc;
+
+ if(!(doc.setContent(file)))
+ file->close();
+ else
+ {
+ QDomElement e;
+ QDomNode n = doc.documentElement().firstChild();
+
+ if(!n.isNull())
+ {
+ e = n.toElement();
+
+ if(!e.isNull())
+ if( e.tagName() == "GRADIENT" )
+ return parseKarbonGradient(e);
+ }
+ }
+
+ return 0;
+}
+
+KoGradient* KoGradientManager::loadKritaGradient(QFile* file)
+{
+ KoGradient* grad = new KoGradient();
+
+ QByteArray m_data = file->readAll();
+ file->close();
+
+ QTextIStream fileContent(m_data);
+ fileContent.setEncoding(QTextStream::UnicodeUTF8);
+
+ QString header = fileContent.readLine();
+
+ if (header != "GIMP Gradient")
+ {
+ delete grad;
+ return 0;
+ }
+
+ QString nameDefinition = fileContent.readLine();
+ QString numSegmentsText;
+
+ if (nameDefinition.startsWith("Name: "))
+ {
+ QString nameText = nameDefinition.right(nameDefinition.length() - 6);
+ numSegmentsText = fileContent.readLine();
+ }
+ else
+ {
+ // Older format without name.
+
+ numSegmentsText = nameDefinition;
+ }
+
+ int numSegments;
+ bool ok;
+
+ numSegments = numSegmentsText.toInt(&ok);
+
+ if (!ok || numSegments < 1)
+ {
+ return 0;
+ }
+
+ for (int i = 0; i < numSegments; i++)
+ {
+ KoColorStop *stop = new KoColorStop();
+
+ QString segmentText = fileContent.readLine();
+ QTextIStream segmentFields(&segmentText);
+
+ double leftOffset;
+ double middleOffset;
+ double rightOffset;
+
+ segmentFields >> leftOffset >> middleOffset >> rightOffset;
+
+ double leftRed;
+ double leftGreen;
+ double leftBlue;
+ double leftAlpha;
+
+ segmentFields >> leftRed >> leftGreen >> leftBlue >> leftAlpha;
+
+ double rightRed;
+ double rightGreen;
+ double rightBlue;
+ double rightAlpha;
+
+ segmentFields >> rightRed >> rightGreen >> rightBlue >> rightAlpha;
+
+ int interpolationType;
+ int colorInterpolationType;
+
+ segmentFields >> interpolationType >> colorInterpolationType;
+
+ middleOffset = (middleOffset - leftOffset) / (rightOffset - leftOffset);
+
+ stop->opacity = leftAlpha;
+ stop->midpoint = middleOffset;
+ stop->offset = leftOffset;
+
+ stop->color1 = leftRed;
+ stop->color2 = leftGreen;
+ stop->color3 = leftBlue;
+ stop->color4 = 0.0;
+ stop->colorType = colorInterpolationType;
+ stop->interpolation = interpolationType;
+
+ grad->colorStops.append(stop);
+
+ if(rightOffset == 1.0)
+ {
+ KoColorStop *lastStop = new KoColorStop();
+ lastStop->opacity = rightAlpha;
+ lastStop->midpoint = middleOffset;
+ lastStop->offset = rightOffset;
+ lastStop->color1 = rightRed;
+ lastStop->color2 = rightGreen;
+ lastStop->color3 = rightBlue;
+ lastStop->color4 = 0.0;
+ lastStop->colorType = colorInterpolationType;
+ lastStop->interpolation = interpolationType;
+ grad->colorStops.append(lastStop);
+ }
+ }
+
+ if (!grad->colorStops.isEmpty())
+ {
+ grad->originX = 0.0;
+ grad->originY = 1.0;
+ grad->vectorX = 0.0;
+ grad->vectorY = 0.0;
+ grad->focalpointX = 0.0;
+ grad->focalpointY = 0.0;
+ grad->gradientType = gradient_type_linear;
+ grad->gradientRepeatMethod = repeat_method_none;
+
+ return grad;
+ }
+ else
+ {
+ delete grad;
+ return 0;
+ }
+}
+
+KoGradient* KoGradientManager::loadSvgGradient(QFile* file)
+{
+ QDomDocument doc;
+
+ if(!(doc.setContent(file)))
+ file->close();
+ else
+ {
+ for( QDomNode n = doc.documentElement().firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ QDomElement e = n.toElement();
+ if( e.isNull() ) continue;
+
+ if( e.tagName() == "linearGradient" || e.tagName() == "radialGradient" )
+ return parseSvgGradient(e);
+ }
+ }
+
+ return 0;
+}
+
+KoGradient* KoGradientManager::parseKarbonGradient(const QDomElement& element)
+{
+ KoGradient* grad = new KoGradient();
+
+ grad->originX = element.attribute("originX", "0.0").toDouble();
+ grad->originY = element.attribute("originY", "0.0").toDouble();
+ grad->focalpointX = element.attribute("focalX", "0.0").toDouble();
+ grad->focalpointY = element.attribute("focalY", "0.0").toDouble();
+ grad->vectorX = element.attribute("vectorX", "0.0").toDouble();
+ grad->vectorY = element.attribute("vectorY", "0.0").toDouble();
+ grad->gradientType = (KoGradientType)element.attribute("type", 0).toInt();
+ grad->gradientRepeatMethod = (KoGradientRepeatMethod)element.attribute("repeatMethod", 0).toInt();
+
+ grad->colorStops.clear();
+
+ // load stops
+ QDomNodeList list = element.childNodes();
+ for( uint i = 0; i < list.count(); ++i )
+ {
+ if( list.item( i ).isElement() )
+ {
+ QDomElement colorstop = list.item( i ).toElement();
+
+ if( colorstop.tagName() == "COLORSTOP" )
+ {
+ KoColorStop *stop = new KoColorStop();
+
+ QDomElement e = colorstop.firstChild().toElement();
+
+ switch(e.attribute("colorSpace").toUShort())
+ {
+ case 1: // cmyk
+ stop->color1 = e.attribute( "v1", "0.0" ).toFloat();
+ stop->color2 = e.attribute( "v2", "0.0" ).toFloat();
+ stop->color3 = e.attribute( "v3", "0.0" ).toFloat();
+ stop->color4 = e.attribute( "v4", "0.0" ).toFloat();
+ stop->colorType = color_type_cmyk;
+ stop->interpolation = interpolation_linear;
+ break;
+ case 2: // hsv
+ stop->color1 = e.attribute( "v1", "0.0" ).toFloat();
+ stop->color2 = e.attribute( "v2", "0.0" ).toFloat();
+ stop->color3 = e.attribute( "v3", "0.0" ).toFloat();
+ stop->color4 = 0.0;
+ stop->colorType = color_type_hsv_cw;
+ stop->interpolation = interpolation_linear;
+ break;
+ case 3: // gray
+ stop->color1 = e.attribute( "v1", "0.0" ).toFloat();
+ stop->color2 = 0.0;
+ stop->color3 = 0.0;
+ stop->color4 = 0.0;
+ stop->colorType = color_type_gray;
+ stop->interpolation = interpolation_linear;
+ break;
+ default: // rgb
+ stop->color1 = e.attribute( "v1", "0.0" ).toFloat();
+ stop->color2 = e.attribute( "v2", "0.0" ).toFloat();
+ stop->color3 = e.attribute( "v3", "0.0" ).toFloat();
+ stop->color4 = 0.0;
+ stop->colorType = color_type_rgb;
+ stop->interpolation = interpolation_linear;
+ }
+
+ stop->opacity = e.attribute("opacity", "1.0").toFloat();
+
+ stop->offset = colorstop.attribute("ramppoint", "0.0").toFloat();
+ stop->midpoint = colorstop.attribute("midpoint", "0.5").toFloat();
+
+ grad->colorStops.append(stop);
+ }
+ }
+ }
+
+ return grad;
+}
+
+KoGradient* KoGradientManager::parseSvgGradient(const QDomElement& element)
+{
+ KoGradient* grad = new KoGradient;
+
+ grad->colorStops.clear();
+ grad->gradientRepeatMethod = repeat_method_none;
+
+ /*QString href = e.attribute( "xlink:href" ).mid( 1 );
+ if( !href.isEmpty() )
+ {
+ }*/
+
+ bool bbox = element.attribute( "gradientUnits" ) != "userSpaceOnUse";
+
+ if( element.tagName() == "linearGradient" )
+ {
+ if( bbox )
+ {
+ QString s;
+
+ s = element.attribute( "x1", "0%" );
+ double xOrigin;
+ if( s.endsWith( "%" ) )
+ xOrigin = s.remove( '%' ).toDouble();
+ else
+ xOrigin = s.toDouble() * 100.0;
+
+ s = element.attribute( "y1", "0%" );
+ double yOrigin;
+ if( s.endsWith( "%" ) )
+ yOrigin = s.remove( '%' ).toDouble();
+ else
+ yOrigin = s.toDouble() * 100.0;
+
+ s = element.attribute( "x2", "100%" );
+ double xVector;
+ if( s.endsWith( "%" ) )
+ xVector = s.remove( '%' ).toDouble();
+ else
+ xVector = s.toDouble() * 100.0;
+
+ s = element.attribute( "y2", "0%" );
+ double yVector;
+ if( s.endsWith( "%" ) )
+ yVector = s.remove( '%' ).toDouble();
+ else
+ yVector = s.toDouble() * 100.0;
+
+ grad->originX = xOrigin;
+ grad->originY = yOrigin;
+ grad->vectorX = xVector;
+ grad->vectorY = yVector;
+ }
+ else
+ {
+ grad->originX = element.attribute( "x1" ).toDouble();
+ grad->originY = element.attribute( "y1" ).toDouble();
+ grad->vectorX = element.attribute( "x2" ).toDouble();
+ grad->vectorY = element.attribute( "y2" ).toDouble();
+ }
+ grad->gradientType = gradient_type_linear;
+ }
+ else
+ {
+ if( bbox )
+ {
+ QString s;
+
+ s = element.attribute( "cx", "50%" );
+ double xOrigin;
+ if( s.endsWith( "%" ) )
+ xOrigin = s.remove( '%' ).toDouble();
+ else
+ xOrigin = s.toDouble() * 100.0;
+
+ s = element.attribute( "cy", "50%" );
+ double yOrigin;
+ if( s.endsWith( "%" ) )
+ yOrigin = s.remove( '%' ).toDouble();
+ else
+ yOrigin = s.toDouble() * 100.0;
+
+ s = element.attribute( "cx", "50%" );
+ double xVector;
+ if( s.endsWith( "%" ) )
+ xVector = s.remove( '%' ).toDouble();
+ else
+ xVector = s.toDouble() * 100.0;
+
+ s = element.attribute( "r", "50%" );
+ if( s.endsWith( "%" ) )
+ xVector += s.remove( '%' ).toDouble();
+ else
+ xVector += s.toDouble() * 100.0;
+
+ s = element.attribute( "cy", "50%" );
+ double yVector;
+ if( s.endsWith( "%" ) )
+ yVector = s.remove( '%' ).toDouble();
+ else
+ yVector = s.toDouble() * 100.0;
+
+ s = element.attribute( "fx", "50%" );
+ double xFocal;
+ if( s.endsWith( "%" ) )
+ xFocal = s.remove( '%' ).toDouble();
+ else
+ xFocal = s.toDouble() * 100.0;
+
+ s = element.attribute( "fy", "50%" );
+ double yFocal;
+ if( s.endsWith( "%" ) )
+ yFocal = s.remove( '%' ).toDouble();
+ else
+ yFocal = s.toDouble() * 100.0;
+
+ grad->originX = xOrigin;
+ grad->originY = yOrigin;
+ grad->vectorX = xVector;
+ grad->vectorY = yVector;
+ grad->focalpointX = xFocal;
+ grad->focalpointY = yFocal;
+ }
+ else
+ {
+ grad->originX = element.attribute( "cx" ).toDouble();
+ grad->originY = element.attribute( "cy" ).toDouble();
+ grad->vectorX = element.attribute( "cx" ).toDouble() + element.attribute( "r" ).toDouble();
+ grad->vectorY = element.attribute( "cy" ).toDouble();
+ grad->focalpointX = element.attribute( "fx" ).toDouble();
+ grad->focalpointY = element.attribute( "fy" ).toDouble();
+ }
+ grad->gradientType = gradient_type_radial;
+ }
+ // handle spread method
+ QString spreadMethod = element.attribute( "spreadMethod" );
+ if( !spreadMethod.isEmpty() )
+ {
+ if( spreadMethod == "reflect" )
+ grad->gradientRepeatMethod = repeat_method_reflect;
+ else if( spreadMethod == "repeat" )
+ grad->gradientRepeatMethod = repeat_method_repeat;
+ }
+
+ for( QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ QDomElement colorstop = n.toElement();
+ if( colorstop.tagName() == "stop" )
+ {
+ KoColorStop *stop = new KoColorStop();
+ QColor c;
+ float off;
+ QString temp = colorstop.attribute( "offset" );
+ if( temp.contains( '%' ) )
+ {
+ temp = temp.left( temp.length() - 1 );
+ off = temp.toFloat() / 100.0;
+ }
+ else
+ off = temp.toFloat();
+
+ if( !colorstop.attribute( "stop-color" ).isEmpty() )
+ parseSvgColor( c, colorstop.attribute( "stop-color" ) );
+ else
+ {
+ // try style attr
+ QString style = colorstop.attribute( "style" ).simplifyWhiteSpace();
+ QStringList substyles = QStringList::split( ';', style );
+ for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it )
+ {
+ QStringList substyle = QStringList::split( ':', (*it) );
+ QString command = substyle[0].stripWhiteSpace();
+ QString params = substyle[1].stripWhiteSpace();
+ if( command == "stop-color" )
+ parseSvgColor( c, params );
+ if( command == "stop-opacity" )
+ stop->opacity = params.toDouble();
+ }
+
+ }
+ if( !colorstop.attribute( "stop-opacity" ).isEmpty() )
+ stop->opacity = colorstop.attribute( "stop-opacity" ).toDouble();
+
+ stop->offset = off;
+ stop->midpoint = 0.5;
+ stop->color1 = c.red() / 255.0;
+ stop->color2 = c.green() / 255.0;
+ stop->color3 = c.blue() / 255.0;
+ stop->color4 = 0.0;
+ stop->colorType = color_type_rgb;
+ stop->interpolation = interpolation_linear;
+ grad->colorStops.append(stop);
+ }
+ }
+
+ return grad;
+}
+
+void KoGradientManager::parseSvgColor(QColor &color, const QString &s)
+{
+ if( s.startsWith( "rgb(" ) )
+ {
+ QString parse = s.stripWhiteSpace();
+ QStringList colors = QStringList::split( ',', parse );
+ QString r = colors[0].right( ( colors[0].length() - 4 ) );
+ QString g = colors[1];
+ QString b = colors[2].left( ( colors[2].length() - 1 ) );
+
+ if( r.contains( "%" ) )
+ {
+ r = r.left( r.length() - 1 );
+ r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) );
+ }
+
+ if( g.contains( "%" ) )
+ {
+ g = g.left( g.length() - 1 );
+ g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) );
+ }
+
+ if( b.contains( "%" ) )
+ {
+ b = b.left( b.length() - 1 );
+ b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) );
+ }
+
+ color = QColor( r.toInt(), g.toInt(), b.toInt() );
+ }
+ else
+ {
+ QString rgbColor = s.stripWhiteSpace();
+ QColor c;
+ if( rgbColor.startsWith( "#" ) )
+ c.setNamedColor( rgbColor );
+ else
+ {
+ int r, g, b;
+ svgNamedColorToRGB( rgbColor, r, g, b );
+ c = QColor( r, g, b );
+ }
+ color = c;
+ }
+}
+
diff --git a/lib/kopainter/kogradientmanager.h b/lib/kopainter/kogradientmanager.h
new file mode 100644
index 00000000..08412108
--- /dev/null
+++ b/lib/kopainter/kogradientmanager.h
@@ -0,0 +1,115 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Tim Beaulen <tbscope@gmail.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __GRADIENT_LOADER__
+#define __GRADIENT_LOADER__
+
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qfile.h>
+#include <qdom.h>
+#include <qcolor.h>
+#include <koffice_export.h>
+struct KoColorStop
+{
+ double offset;
+ double midpoint;
+ double opacity;
+ double color1;
+ double color2;
+ double color3;
+ double color4;
+ int colorType;
+ int interpolation;
+};
+
+struct KoGradient
+{
+ double originX;
+ double originY;
+ double vectorX;
+ double vectorY;
+ double focalpointX;
+ double focalpointY;
+ int gradientType;
+ int gradientRepeatMethod;
+
+ QPtrList<KoColorStop> colorStops;
+};
+
+class KOPAINTER_EXPORT KoGradientManager
+{
+public:
+
+ enum KoGradientType
+ {
+ gradient_type_linear = 0,
+ gradient_type_radial = 1,
+ gradient_type_conic = 2
+ };
+
+ enum KoGradientInterpolation
+ {
+ interpolation_linear = 0,
+ interpolation_curved = 1,
+ interpolation_sine = 2,
+ interpolation_sphere_increasing = 3,
+ interpolation_sphere_decreasing = 4
+ };
+
+ enum KoGradientColorType
+ {
+ color_type_rgb = 0,
+ color_type_hsv_ccw = 1,
+ color_type_hsv_cw = 2,
+ color_type_gray = 3,
+ color_type_cmyk = 4
+ };
+
+ enum KoGradientRepeatMethod
+ {
+ repeat_method_none = 0,
+ repeat_method_reflect = 1,
+ repeat_method_repeat = 2
+ };
+
+ KoGradientManager();
+ ~KoGradientManager();
+
+ KoGradient* loadGradient(const QString& filename);
+ static QStringList filters()
+ {
+ QStringList filterList;
+ filterList << "*.kgr" << "*.svg" << "*.ggr";
+ return filterList;
+ }
+
+private:
+ KoGradient* loadKarbonGradient(QFile* file);
+ KoGradient* loadKritaGradient(QFile* file);
+ KoGradient* loadSvgGradient(QFile* file);
+ KoGradient* parseKarbonGradient(const QDomElement& element);
+ KoGradient* parseSvgGradient(const QDomElement& element);
+ void parseSvgColor(QColor &color, const QString &s);
+};
+
+#endif
+
+
diff --git a/lib/kopainter/svgnamedcolors.h b/lib/kopainter/svgnamedcolors.h
new file mode 100644
index 00000000..bf926331
--- /dev/null
+++ b/lib/kopainter/svgnamedcolors.h
@@ -0,0 +1,306 @@
+
+#define TORGB( red, green, blue ) \
+{ \
+ r = red; \
+ b = blue; \
+ g = green; \
+}
+
+void svgNamedColorToRGB( QString rgbColor, int &r, int &g, int &b )
+{
+ if( rgbColor == "aliceblue" )
+ TORGB( 240, 248, 255)
+ else if( rgbColor == "antiquewhite" )
+ TORGB( 250, 235, 215)
+ else if( rgbColor == "aqua" )
+ TORGB( 0, 255, 255)
+ else if( rgbColor == "aquamarine" )
+ TORGB( 127, 255, 212 )
+ else if( rgbColor == "azure" )
+ TORGB( 240, 255, 255 )
+ else if( rgbColor == "beige" )
+ TORGB( 245, 245, 220 )
+ else if( rgbColor == "bisque" )
+ TORGB( 255, 228, 196 )
+ else if( rgbColor == "black" )
+ TORGB( 0, 0, 0 )
+ else if( rgbColor == "blanchedalmond" )
+ TORGB( 255, 235, 205 )
+ else if( rgbColor == "blue" )
+ TORGB( 0, 0, 255 )
+ else if( rgbColor == "blueviolet" )
+ TORGB( 138, 43, 226 )
+ else if( rgbColor == "brown" )
+ TORGB( 165, 42, 42 )
+ else if( rgbColor == "burlywood" )
+ TORGB( 222, 184, 135 )
+ else if( rgbColor == "cadetblue" )
+ TORGB( 95, 158, 160 )
+ else if( rgbColor == "chartreuse" )
+ TORGB( 127, 255, 0 )
+ else if( rgbColor == "chocolate" )
+ TORGB( 210, 105, 30 )
+ else if( rgbColor == "coral" )
+ TORGB( 255, 127, 80 )
+ else if( rgbColor == "cornflowerblue" )
+ TORGB( 100, 149, 237 )
+ else if( rgbColor == "cornsilk" )
+ TORGB( 255, 248, 220 )
+ else if( rgbColor == "crimson" )
+ TORGB( 220, 20, 60 )
+ else if( rgbColor == "cyan" )
+ TORGB( 0, 255, 255 )
+ else if( rgbColor == "darkblue" )
+ TORGB( 0, 0, 139 )
+ else if( rgbColor == "darkcyan" )
+ TORGB( 0, 139, 139 )
+ else if( rgbColor == "darkgoldenrod" )
+ TORGB( 184, 134, 11 )
+ else if( rgbColor == "darkgray" )
+ TORGB( 169, 169, 169 )
+ else if( rgbColor == "darkgrey" )
+ TORGB( 169, 169, 169 )
+ else if( rgbColor == "darkgreen" )
+ TORGB( 0, 100, 0 )
+ else if( rgbColor == "darkkhaki" )
+ TORGB( 189, 183, 107 )
+ else if( rgbColor == "darkmagenta" )
+ TORGB( 139, 0, 139 )
+ else if( rgbColor == "darkolivegreen" )
+ TORGB( 85, 107, 47 )
+ else if( rgbColor == "darkorange" )
+ TORGB( 255, 140, 0 )
+ else if( rgbColor == "darkorchid" )
+ TORGB( 153, 50, 204 )
+ else if( rgbColor == "darkred" )
+ TORGB( 139, 0, 0 )
+ else if( rgbColor == "darksalmon" )
+ TORGB( 233, 150, 122 )
+ else if( rgbColor == "darkseagreen" )
+ TORGB( 143, 188, 143 )
+ else if( rgbColor == "darkslateblue" )
+ TORGB( 72, 61, 139 )
+ else if( rgbColor == "darkslategray" )
+ TORGB( 47, 79, 79 )
+ else if( rgbColor == "darkslategrey" )
+ TORGB( 47, 79, 79 )
+ else if( rgbColor == "darkturquoise" )
+ TORGB( 0, 206, 209 )
+ else if( rgbColor == "darkviolet" )
+ TORGB( 148, 0, 211 )
+ else if( rgbColor == "deeppink" )
+ TORGB( 255, 20, 147 )
+ else if( rgbColor == "deepskyblue" )
+ TORGB( 0, 191, 255 )
+ else if( rgbColor == "dimgray" )
+ TORGB( 105, 105, 105 )
+ else if( rgbColor == "dimgrey" )
+ TORGB( 105, 105, 105 )
+ else if( rgbColor == "dodgerblue" )
+ TORGB( 30, 144, 255 )
+ else if( rgbColor == "firebrick" )
+ TORGB( 178, 34, 34 )
+ else if( rgbColor == "floralwhite" )
+ TORGB( 255, 250, 240 )
+ else if( rgbColor == "forestgreen" )
+ TORGB( 34, 139, 34 )
+ else if( rgbColor == "fuchsia" )
+ TORGB( 255, 0, 255 )
+ else if( rgbColor == "gainsboro" )
+ TORGB( 220, 220, 220 )
+ else if( rgbColor == "ghostwhite" )
+ TORGB( 248, 248, 255 )
+ else if( rgbColor == "gold" )
+ TORGB( 255, 215, 0 )
+ else if( rgbColor == "goldenrod" )
+ TORGB( 218, 165, 32 )
+ else if( rgbColor == "gray" )
+ TORGB( 128, 128, 128 )
+ else if( rgbColor == "grey" )
+ TORGB( 128, 128, 128 )
+ else if( rgbColor == "green" )
+ TORGB( 0, 128, 0 )
+ else if( rgbColor == "greenyellow" )
+ TORGB( 173, 255, 47 )
+ else if( rgbColor == "honeydew" )
+ TORGB( 240, 255, 240 )
+ else if( rgbColor == "hotpink" )
+ TORGB( 255, 105, 180 )
+ else if( rgbColor == "indianred" )
+ TORGB( 205, 92, 92 )
+ else if( rgbColor == "indigo" )
+ TORGB( 75, 0, 130 )
+ else if( rgbColor == "ivory" )
+ TORGB( 255, 255, 240 )
+ else if( rgbColor == "khaki" )
+ TORGB( 240, 230, 140 )
+ else if( rgbColor == "lavender" )
+ TORGB( 230, 230, 250 )
+ else if( rgbColor == "lavenderblush" )
+ TORGB( 255, 240, 245 )
+ else if( rgbColor == "lawngreen" )
+ TORGB( 124, 252, 0 )
+ else if( rgbColor == "lemonchiffon" )
+ TORGB( 255, 250, 205 )
+ else if( rgbColor == "lightblue" )
+ TORGB( 173, 216, 230 )
+ else if( rgbColor == "lightcoral" )
+ TORGB( 240, 128, 128 )
+ else if( rgbColor == "lightcyan" )
+ TORGB( 224, 255, 255 )
+ else if( rgbColor == "lightgoldenrodyellow" )
+ TORGB( 250, 250, 210 )
+ else if( rgbColor == "lightgray" )
+ TORGB( 211, 211, 211 )
+ else if( rgbColor == "lightgrey" )
+ TORGB( 211, 211, 211 )
+ else if( rgbColor == "lightgreen" )
+ TORGB( 144, 238, 144 )
+ else if( rgbColor == "lightpink" )
+ TORGB( 255, 182, 193 )
+ else if( rgbColor == "lightsalmon" )
+ TORGB( 255, 160, 122 )
+ else if( rgbColor == "lightseagreen" )
+ TORGB( 32, 178, 170 )
+ else if( rgbColor == "lightskyblue" )
+ TORGB( 135, 206, 250 )
+ else if( rgbColor == "lightslategray" )
+ TORGB( 119, 136, 153 )
+ else if( rgbColor == "lightslategrey" )
+ TORGB( 119, 136, 153 )
+ else if( rgbColor == "lightsteelblue" )
+ TORGB( 176, 196, 222 )
+ else if( rgbColor == "lightyellow" )
+ TORGB( 255, 255, 224 )
+ else if( rgbColor == "lime" )
+ TORGB( 0, 255, 0 )
+ else if( rgbColor == "limegreen" )
+ TORGB( 50, 205, 50 )
+ else if( rgbColor == "linen" )
+ TORGB( 250, 240, 230 )
+ else if( rgbColor == "magenta" )
+ TORGB( 255, 0, 255 )
+ else if( rgbColor == "maroon" )
+ TORGB( 128, 0, 0 )
+ else if( rgbColor == "mediumaquamarine" )
+ TORGB( 102, 205, 170 )
+ else if( rgbColor == "mediumblue" )
+ TORGB( 0, 0, 205 )
+ else if( rgbColor == "mediumorchid" )
+ TORGB( 186, 85, 211 )
+ else if( rgbColor == "mediumpurple" )
+ TORGB( 147, 112, 219 )
+ else if( rgbColor == "mediumseagreen" )
+ TORGB( 60, 179, 113 )
+ else if( rgbColor == "mediumslateblue" )
+ TORGB( 123, 104, 238 )
+ else if( rgbColor == "mediumspringgreen" )
+ TORGB( 0, 250, 154 )
+ else if( rgbColor == "mediumturquoise" )
+ TORGB( 72, 209, 204 )
+ else if( rgbColor == "mediumvioletred" )
+ TORGB( 199, 21, 133 )
+ else if( rgbColor == "midnightblue" )
+ TORGB( 25, 25, 112 )
+ else if( rgbColor == "mintcream" )
+ TORGB( 245, 255, 250 )
+ else if( rgbColor == "mistyrose" )
+ TORGB( 255, 228, 225 )
+ else if( rgbColor == "moccasin" )
+ TORGB( 255, 228, 181 )
+ else if( rgbColor == "navajowhite" )
+ TORGB( 255, 222, 173 )
+ else if( rgbColor == "navy" )
+ TORGB( 0, 0, 128 )
+ else if( rgbColor == "oldlace" )
+ TORGB( 253, 245, 230 )
+ else if( rgbColor == "olive" )
+ TORGB( 128, 128, 0 )
+ else if( rgbColor == "olivedrab" )
+ TORGB( 107, 142, 35 )
+ else if( rgbColor == "orange" )
+ TORGB( 255, 165, 0 )
+ else if( rgbColor == "orangered" )
+ TORGB( 255, 69, 0 )
+ else if( rgbColor == "orchid" )
+ TORGB( 218, 112, 214 )
+ else if( rgbColor == "palegoldenrod" )
+ TORGB( 238, 232, 170 )
+ else if( rgbColor == "palegreen" )
+ TORGB( 152, 251, 152 )
+ else if( rgbColor == "paleturquoise" )
+ TORGB( 175, 238, 238 )
+ else if( rgbColor == "palevioletred" )
+ TORGB( 219, 112, 147 )
+ else if( rgbColor == "papayawhip" )
+ TORGB( 255, 239, 213 )
+ else if( rgbColor == "peachpuff" )
+ TORGB( 255, 218, 185 )
+ else if( rgbColor == "peru" )
+ TORGB( 205, 133, 63 )
+ else if( rgbColor == "pink" )
+ TORGB( 255, 192, 203 )
+ else if( rgbColor == "plum" )
+ TORGB( 221, 160, 221 )
+ else if( rgbColor == "powderblue" )
+ TORGB( 176, 224, 230 )
+ else if( rgbColor == "purple" )
+ TORGB( 128, 0, 128 )
+ else if( rgbColor == "red" )
+ TORGB( 255, 0, 0 )
+ else if( rgbColor == "rosybrown" )
+ TORGB( 188, 143, 143 )
+ else if( rgbColor == "royalblue" )
+ TORGB( 65, 105, 225 )
+ else if( rgbColor == "saddlebrown" )
+ TORGB( 139, 69, 19 )
+ else if( rgbColor == "salmon" )
+ TORGB( 250, 128, 114 )
+ else if( rgbColor == "sandybrown" )
+ TORGB( 244, 164, 96 )
+ else if( rgbColor == "seagreen" )
+ TORGB( 46, 139, 87 )
+ else if( rgbColor == "seashell" )
+ TORGB( 255, 245, 238 )
+ else if( rgbColor == "sienna" )
+ TORGB( 160, 82, 45 )
+ else if( rgbColor == "silver" )
+ TORGB( 192, 192, 192 )
+ else if( rgbColor == "skyblue" )
+ TORGB( 135, 206, 235 )
+ else if( rgbColor == "slateblue" )
+ TORGB( 106, 90, 205 )
+ else if( rgbColor == "slategray" )
+ TORGB( 112, 128, 144 )
+ else if( rgbColor == "slategrey" )
+ TORGB( 112, 128, 144 )
+ else if( rgbColor == "snow" )
+ TORGB( 255, 250, 250 )
+ else if( rgbColor == "springgreen" )
+ TORGB( 0, 255, 127 )
+ else if( rgbColor == "steelblue" )
+ TORGB( 70, 130, 180 )
+ else if( rgbColor == "tan" )
+ TORGB( 210, 180, 140 )
+ else if( rgbColor == "teal" )
+ TORGB( 0, 128, 128 )
+ else if( rgbColor == "thistle" )
+ TORGB( 216, 191, 216 )
+ else if( rgbColor == "tomato" )
+ TORGB( 255, 99, 71 )
+ else if( rgbColor == "turquoise" )
+ TORGB( 64, 224, 208 )
+ else if( rgbColor == "violet" )
+ TORGB( 238, 130, 238 )
+ else if( rgbColor == "wheat" )
+ TORGB( 245, 222, 179 )
+ else if( rgbColor == "white" )
+ TORGB( 255, 255, 255 )
+ else if( rgbColor == "whitesmoke" )
+ TORGB( 245, 245, 245 )
+ else if( rgbColor == "yellow" )
+ TORGB( 255, 255, 0 )
+ else if( rgbColor == "yellowgreen" )
+ TORGB( 154, 205, 50 )
+}
+
diff --git a/lib/kopainter/svgpathparser.cc b/lib/kopainter/svgpathparser.cc
new file mode 100644
index 00000000..454c921b
--- /dev/null
+++ b/lib/kopainter/svgpathparser.cc
@@ -0,0 +1,577 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, The Karbon Developers
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "svgpathparser.h"
+#include <qstring.h>
+#include <math.h>
+#include <kdebug.h>
+
+// parses the coord into number and forwards to the next token
+const char *
+SVGPathParser::getCoord( const char *ptr, double &number )
+{
+ int integer, exponent;
+ double decimal, frac;
+ int sign, expsign;
+
+ exponent = 0;
+ integer = 0;
+ frac = 1.0;
+ decimal = 0;
+ sign = 1;
+ expsign = 1;
+
+ // read the sign
+ if(*ptr == '+')
+ ptr++;
+ else if(*ptr == '-')
+ {
+ ptr++;
+ sign = -1;
+ }
+
+ // read the integer part
+ while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
+ integer = (integer * 10) + *(ptr++) - '0';
+ if(*ptr == '.') // read the decimals
+ {
+ ptr++;
+ while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
+ decimal += (*(ptr++) - '0') * (frac *= 0.1);
+ }
+
+ if(*ptr == 'e' || *ptr == 'E') // read the exponent part
+ {
+ ptr++;
+
+ // read the sign of the exponent
+ if(*ptr == '+')
+ ptr++;
+ else if(*ptr == '-')
+ {
+ ptr++;
+ expsign = -1;
+ }
+
+ exponent = 0;
+ while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
+ {
+ exponent *= 10;
+ exponent += *ptr - '0';
+ ptr++;
+ }
+ }
+ number = integer + decimal;
+ number *= sign * pow( (double)10, double( expsign * exponent ) );
+
+ // skip the following space
+ if(*ptr == ' ')
+ ptr++;
+
+ return ptr;
+}
+
+void
+SVGPathParser::parseSVG( const QString &s, bool process )
+{
+ if( !s.isEmpty() )
+ {
+ QString d = s;
+ d = d.replace( ',', ' ' );
+ d = d.simplifyWhiteSpace();
+
+ const char *ptr = d.latin1();
+ const char *end = d.latin1() + d.length() + 1;
+
+ double contrlx, contrly, curx, cury, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc;
+ double px1, py1, px2, py2, px3, py3;
+ bool relative;
+ char command = *(ptr++), lastCommand = ' ';
+
+ subpathx = subpathy = curx = cury = contrlx = contrly = 0.0;
+ while( ptr < end )
+ {
+ if( *ptr == ' ' )
+ ptr++;
+
+ relative = false;
+
+ //std::cout << "Command : " << command << std::endl;
+ switch( command )
+ {
+ case 'm':
+ relative = true;
+ case 'M':
+ {
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+
+ if( process )
+ {
+ subpathx = curx = relative ? curx + tox : tox;
+ subpathy = cury = relative ? cury + toy : toy;
+
+ svgMoveTo( curx, cury );
+ }
+ else
+ svgMoveTo( tox, toy, !relative );
+ break;
+ }
+ case 'l':
+ relative = true;
+ case 'L':
+ {
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+
+ if( process )
+ {
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+
+ svgLineTo( curx, cury );
+ }
+ else
+ svgLineTo( tox, toy, !relative );
+ break;
+ }
+ case 'h':
+ {
+ ptr = getCoord( ptr, tox );
+ if( process )
+ {
+ curx = curx + tox;
+ svgLineTo( curx, cury );
+ }
+ else
+ svgLineToHorizontal( tox, false );
+ break;
+ }
+ case 'H':
+ {
+ ptr = getCoord( ptr, tox );
+ if( process )
+ {
+ curx = tox;
+ svgLineTo( curx, cury );
+ }
+ else
+ svgLineToHorizontal( tox );
+ break;
+ }
+ case 'v':
+ {
+ ptr = getCoord( ptr, toy );
+ if( process )
+ {
+ cury = cury + toy;
+ svgLineTo( curx, cury );
+ }
+ else
+ svgLineToVertical( toy, false );
+ break;
+ }
+ case 'V':
+ {
+ ptr = getCoord( ptr, toy );
+ if( process )
+ {
+ cury = toy;
+ svgLineTo( curx, cury );
+ }
+ else
+ svgLineToVertical( toy );
+ break;
+ }
+ case 'z':
+ case 'Z':
+ {
+ // reset curx, cury for next path
+ if( process )
+ {
+ curx = subpathx;
+ cury = subpathy;
+ }
+ svgClosePath();
+ break;
+ }
+ case 'c':
+ relative = true;
+ case 'C':
+ {
+ ptr = getCoord( ptr, x1 );
+ ptr = getCoord( ptr, y1 );
+ ptr = getCoord( ptr, x2 );
+ ptr = getCoord( ptr, y2 );
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+
+ if( process )
+ {
+ px1 = relative ? curx + x1 : x1;
+ py1 = relative ? cury + y1 : y1;
+ px2 = relative ? curx + x2 : x2;
+ py2 = relative ? cury + y2 : y2;
+ px3 = relative ? curx + tox : tox;
+ py3 = relative ? cury + toy : toy;
+
+ svgCurveToCubic( px1, py1, px2, py2, px3, py3 );
+
+ contrlx = relative ? curx + x2 : x2;
+ contrly = relative ? cury + y2 : y2;
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+ }
+ else
+ svgCurveToCubic( x1, y1, x2, y2, tox, toy, !relative );
+
+ break;
+ }
+ case 's':
+ relative = true;
+ case 'S':
+ {
+ ptr = getCoord( ptr, x2 );
+ ptr = getCoord( ptr, y2 );
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+ if( !( lastCommand == 'c' || lastCommand == 'C' ||
+ lastCommand == 's' || lastCommand == 'S' ) )
+ {
+ contrlx = curx;
+ contrly = cury;
+ }
+
+
+ if( process )
+ {
+ px1 = 2 * curx - contrlx;
+ py1 = 2 * cury - contrly;
+ px2 = relative ? curx + x2 : x2;
+ py2 = relative ? cury + y2 : y2;
+ px3 = relative ? curx + tox : tox;
+ py3 = relative ? cury + toy : toy;
+
+ svgCurveToCubic( px1, py1, px2, py2, px3, py3 );
+
+ contrlx = relative ? curx + x2 : x2;
+ contrly = relative ? cury + y2 : y2;
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+ }
+ else
+ svgCurveToCubicSmooth( x2, y2, tox, toy, !relative );
+ break;
+ }
+ case 'q':
+ relative = true;
+ case 'Q':
+ {
+ ptr = getCoord( ptr, x1 );
+ ptr = getCoord( ptr, y1 );
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+
+ if( process )
+ {
+ px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0);
+ py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0);
+ px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0);
+ py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0);
+ px3 = relative ? curx + tox : tox;
+ py3 = relative ? cury + toy : toy;
+
+ svgCurveToCubic( px1, py1, px2, py2, px3, py3 );
+
+ contrlx = relative ? curx + x1 : x1;
+ contrly = relative ? cury + y1 : y1;
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+ }
+ else
+ svgCurveToQuadratic( x1, y1, tox, toy, !relative );
+ break;
+ }
+ case 't':
+ relative = true;
+ case 'T':
+ {
+ ptr = getCoord(ptr, tox);
+ ptr = getCoord(ptr, toy);
+ if( !( lastCommand == 'q' || lastCommand == 'Q' ||
+ lastCommand == 't' || lastCommand == 'T' ) )
+ {
+ contrlx = curx;
+ contrly = cury;
+ }
+
+ if( process )
+ {
+ xc = 2 * curx - contrlx;
+ yc = 2 * cury - contrly;
+
+ px1 = (curx + 2 * xc) * (1.0 / 3.0);
+ py1 = (cury + 2 * yc) * (1.0 / 3.0);
+ px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0);
+ py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0);
+ px3 = relative ? curx + tox : tox;
+ py3 = relative ? cury + toy : toy;
+
+ svgCurveToCubic( px1, py1, px2, py2, px3, py3 );
+
+ contrlx = xc;
+ contrly = yc;
+ curx = relative ? curx + tox : tox;
+ cury = relative ? cury + toy : toy;
+ }
+ else
+ svgCurveToQuadraticSmooth( tox, toy, !relative );
+ break;
+ }
+ case 'a':
+ relative = true;
+ case 'A':
+ {
+ bool largeArc, sweep;
+ double angle, rx, ry;
+ ptr = getCoord( ptr, rx );
+ ptr = getCoord( ptr, ry );
+ ptr = getCoord( ptr, angle );
+ ptr = getCoord( ptr, tox );
+ largeArc = tox == 1;
+ ptr = getCoord( ptr, tox );
+ sweep = tox == 1;
+ ptr = getCoord( ptr, tox );
+ ptr = getCoord( ptr, toy );
+
+ // Spec: radii are nonnegative numbers
+ rx = fabs(rx);
+ ry = fabs(ry);
+
+ if( process )
+ calculateArc( relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep );
+ else
+ svgArcTo( tox, toy, rx, ry, angle, largeArc, sweep, !relative );
+ }
+ default:
+ {
+ // when svg parser is used for a parsing an odf path an unknown command
+ // can be encountered, so we stop parsing here
+ kdDebug() << "SVGPathParser::parseSVG(): unknown command \"" << command << "\"" << endl;
+ return;
+ }
+ }
+
+ lastCommand = command;
+
+ if(*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9'))
+ {
+ // there are still coords in this command
+ if(command == 'M')
+ command = 'L';
+ else if(command == 'm')
+ command = 'l';
+ }
+ else
+ command = *(ptr++);
+
+ if( lastCommand != 'C' && lastCommand != 'c' &&
+ lastCommand != 'S' && lastCommand != 's' &&
+ lastCommand != 'Q' && lastCommand != 'q' &&
+ lastCommand != 'T' && lastCommand != 't')
+ {
+ contrlx = curx;
+ contrly = cury;
+ }
+ }
+ }
+}
+
+// This works by converting the SVG arc to "simple" beziers.
+// For each bezier found a svgToCurve call is done.
+// Adapted from Niko's code in kdelibs/kdecore/svgicons.
+// Maybe this can serve in some shared lib? (Rob)
+void
+SVGPathParser::calculateArc(bool relative, double &curx, double &cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag)
+{
+ double sin_th, cos_th;
+ double a00, a01, a10, a11;
+ double x0, y0, x1, y1, xc, yc;
+ double d, sfactor, sfactor_sq;
+ double th0, th1, th_arc;
+ int i, n_segs;
+
+ sin_th = sin(angle * (M_PI / 180.0));
+ cos_th = cos(angle * (M_PI / 180.0));
+
+ double dx;
+
+ if(!relative)
+ dx = (curx - x) / 2.0;
+ else
+ dx = -x / 2.0;
+
+ double dy;
+
+ if(!relative)
+ dy = (cury - y) / 2.0;
+ else
+ dy = -y / 2.0;
+
+ double _x1 = cos_th * dx + sin_th * dy;
+ double _y1 = -sin_th * dx + cos_th * dy;
+ double Pr1 = r1 * r1;
+ double Pr2 = r2 * r2;
+ double Px = _x1 * _x1;
+ double Py = _y1 * _y1;
+
+ // Spec : check if radii are large enough
+ double check = Px / Pr1 + Py / Pr2;
+ if(check > 1)
+ {
+ r1 = r1 * sqrt(check);
+ r2 = r2 * sqrt(check);
+ }
+
+ a00 = cos_th / r1;
+ a01 = sin_th / r1;
+ a10 = -sin_th / r2;
+ a11 = cos_th / r2;
+
+ x0 = a00 * curx + a01 * cury;
+ y0 = a10 * curx + a11 * cury;
+
+ if(!relative)
+ x1 = a00 * x + a01 * y;
+ else
+ x1 = a00 * (curx + x) + a01 * (cury + y);
+
+ if(!relative)
+ y1 = a10 * x + a11 * y;
+ else
+ y1 = a10 * (curx + x) + a11 * (cury + y);
+
+ /* (x0, y0) is current point in transformed coordinate space.
+ (x1, y1) is new point in transformed coordinate space.
+
+ The arc fits a unit-radius circle in this space.
+ */
+
+ d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
+
+ sfactor_sq = 1.0 / d - 0.25;
+
+ if(sfactor_sq < 0)
+ sfactor_sq = 0;
+
+ sfactor = sqrt(sfactor_sq);
+
+ if(sweepFlag == largeArcFlag)
+ sfactor = -sfactor;
+
+ xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
+ yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
+
+ /* (xc, yc) is center of the circle. */
+ th0 = atan2(y0 - yc, x0 - xc);
+ th1 = atan2(y1 - yc, x1 - xc);
+
+ th_arc = th1 - th0;
+ if(th_arc < 0 && sweepFlag)
+ th_arc += 2 * M_PI;
+ else if(th_arc > 0 && !sweepFlag)
+ th_arc -= 2 * M_PI;
+
+ n_segs = (int) (int) ceil(fabs(th_arc / (M_PI * 0.5 + 0.001)));
+
+ for(i = 0; i < n_segs; i++)
+ {
+ {
+ double sin_th, cos_th;
+ double a00, a01, a10, a11;
+ double x1, y1, x2, y2, x3, y3;
+ double t;
+ double th_half;
+
+ double _th0 = th0 + i * th_arc / n_segs;
+ double _th1 = th0 + (i + 1) * th_arc / n_segs;
+
+ sin_th = sin(angle * (M_PI / 180.0));
+ cos_th = cos(angle * (M_PI / 180.0));
+
+ /* inverse transform compared with rsvg_path_arc */
+ a00 = cos_th * r1;
+ a01 = -sin_th * r2;
+ a10 = sin_th * r1;
+ a11 = cos_th * r2;
+
+ th_half = 0.5 * (_th1 - _th0);
+ t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half);
+ x1 = xc + cos(_th0) - t * sin(_th0);
+ y1 = yc + sin(_th0) + t * cos(_th0);
+ x3 = xc + cos(_th1);
+ y3 = yc + sin(_th1);
+ x2 = x3 + t * sin(_th1);
+ y2 = y3 - t * cos(_th1);
+
+ svgCurveToCubic( a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, a00 * x3 + a01 * y3, a10 * x3 + a11 * y3 );
+ }
+ }
+
+ if(!relative)
+ curx = x;
+ else
+ curx += x;
+
+ if(!relative)
+ cury = y;
+ else
+ cury += y;
+}
+
+void
+SVGPathParser::svgLineToHorizontal( double, bool )
+{
+}
+
+void
+SVGPathParser::svgLineToVertical( double, bool )
+{
+}
+
+void
+SVGPathParser::svgCurveToCubicSmooth( double, double, double, double, bool )
+{
+}
+
+void
+SVGPathParser::svgCurveToQuadratic( double, double, double, double, bool )
+{
+}
+
+void
+SVGPathParser::svgCurveToQuadraticSmooth( double, double, bool )
+{
+}
+
+void
+SVGPathParser::svgArcTo( double, double, double, double, double, bool, bool, bool )
+{
+}
+
diff --git a/lib/kopainter/svgpathparser.h b/lib/kopainter/svgpathparser.h
new file mode 100644
index 00000000..00a23c81
--- /dev/null
+++ b/lib/kopainter/svgpathparser.h
@@ -0,0 +1,60 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, 2003 The Karbon Developers
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __SVGPATHPARSER_H__
+#define __SVGPATHPARSER_H__
+
+class QString;
+
+#include <koffice_export.h>
+/**
+ * Parser for svg path data, contained in the d attribute.
+ *
+ * The parser delivers encountered commands and parameters by calling
+ * methods that correspond to those commands. Clients have to derive
+ * from this class and implement the abstract command methods.
+ *
+ * There are two operating modes. By default the parser just delivers unaltered
+ * svg path data commands and parameters. In the second mode, it will convert all
+ * relative coordinates to absolute ones, and convert all curves to cubic beziers.
+ */
+class KOPAINTER_EXPORT SVGPathParser
+{
+public:
+ virtual ~SVGPathParser(){}
+ void parseSVG( const QString &d, bool process = false );
+
+protected:
+ virtual void svgMoveTo( double x1, double y1, bool abs = true ) = 0;
+ virtual void svgLineTo( double x1, double y1, bool abs = true ) = 0;
+ virtual void svgLineToHorizontal( double x, bool abs = true );
+ virtual void svgLineToVertical( double y, bool abs = true );
+ virtual void svgCurveToCubic( double x1, double y1, double x2, double y2, double x, double y, bool abs = true ) = 0;
+ virtual void svgCurveToCubicSmooth( double x, double y, double x2, double y2, bool abs = true );
+ virtual void svgCurveToQuadratic( double x, double y, double x1, double y1, bool abs = true );
+ virtual void svgCurveToQuadraticSmooth( double x, double y, bool abs = true );
+ virtual void svgArcTo( double x, double y, double r1, double r2, double angle, bool largeArcFlag, bool sweepFlag, bool abs = true );
+ virtual void svgClosePath() = 0;
+
+private:
+ const char *getCoord( const char *, double & );
+ void calculateArc( bool relative, double &curx, double &cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag );
+};
+
+#endif