KDEUI
kcolorutils.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 * Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net> 00003 * Copyright (C) 2007 Thomas Zander <zander@kde.org> 00004 * Copyright (C) 2007 Zack Rusin <zack@kde.org> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Library General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Library General Public License 00017 * along with this library; see the file COPYING.LIB. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 */ 00021 #include <kcolorutils.h> 00022 #include "kcolorspaces.h" 00023 #include "kcolorhelpers_p.h" 00024 00025 #include <QColor> 00026 #include <QImage> 00027 00028 #include <math.h> 00029 00030 // BEGIN internal helper functions 00031 static inline qreal mixQreal(qreal a, qreal b, qreal bias) 00032 { 00033 return a + (b - a) * bias; 00034 } 00035 // END internal helper functions 00036 00037 qreal KColorUtils::luma(const QColor &color) 00038 { 00039 return KColorSpaces::KHCY::luma(color); 00040 } 00041 00042 static qreal contrastRatioForLuma(qreal y1, qreal y2) 00043 { 00044 if (y1 > y2) 00045 return (y1 + 0.05) / (y2 + 0.05); 00046 else 00047 return (y2 + 0.05) / (y1 + 0.05); 00048 } 00049 00050 qreal KColorUtils::contrastRatio(const QColor &c1, const QColor &c2) 00051 { 00052 return contrastRatioForLuma(luma(c1), luma(c2)); 00053 } 00054 00055 QColor KColorUtils::lighten(const QColor &color, qreal ky, qreal kc) 00056 { 00057 KColorSpaces::KHCY c(color); 00058 c.y = 1.0 - normalize((1.0 - c.y) * (1.0 - ky)); 00059 c.c = 1.0 - normalize((1.0 - c.c) * kc); 00060 return c.qColor(); 00061 } 00062 00063 QColor KColorUtils::darken(const QColor &color, qreal ky, qreal kc) 00064 { 00065 KColorSpaces::KHCY c(color); 00066 c.y = normalize(c.y * (1.0 - ky)); 00067 c.c = normalize(c.c * kc); 00068 return c.qColor(); 00069 } 00070 00071 QColor KColorUtils::shade(const QColor &color, qreal ky, qreal kc) 00072 { 00073 KColorSpaces::KHCY c(color); 00074 c.y = normalize(c.y + ky); 00075 c.c = normalize(c.c + kc); 00076 return c.qColor(); 00077 } 00078 00079 static QColor tintHelper(const QColor &base, qreal baseLuma, const QColor &color, qreal amount) 00080 { 00081 KColorSpaces::KHCY result(KColorUtils::mix(base, color, pow(amount, 0.3))); 00082 result.y = mixQreal(baseLuma, result.y, amount); 00083 00084 return result.qColor(); 00085 } 00086 00087 QColor KColorUtils::tint(const QColor &base, const QColor &color, qreal amount) 00088 { 00089 if (amount <= 0.0) return base; 00090 if (amount >= 1.0) return color; 00091 if (isnan(amount)) return base; 00092 00093 qreal baseLuma = luma(base); //cache value because luma call is expensive 00094 double ri = contrastRatioForLuma(baseLuma, luma(color)); 00095 double rg = 1.0 + ((ri + 1.0) * amount * amount * amount); 00096 double u = 1.0, l = 0.0; 00097 QColor result; 00098 for (int i = 12 ; i ; --i) { 00099 double a = 0.5 * (l+u); 00100 result = tintHelper(base, baseLuma, color, a); 00101 double ra = contrastRatioForLuma(baseLuma, luma(result)); 00102 if (ra > rg) 00103 u = a; 00104 else 00105 l = a; 00106 } 00107 return result; 00108 } 00109 00110 QColor KColorUtils::mix(const QColor &c1, const QColor &c2, qreal bias) 00111 { 00112 if (bias <= 0.0) return c1; 00113 if (bias >= 1.0) return c2; 00114 if (isnan(bias)) return c1; 00115 00116 qreal r = mixQreal(c1.redF(), c2.redF(), bias); 00117 qreal g = mixQreal(c1.greenF(), c2.greenF(), bias); 00118 qreal b = mixQreal(c1.blueF(), c2.blueF(), bias); 00119 qreal a = mixQreal(c1.alphaF(), c2.alphaF(), bias); 00120 00121 return QColor::fromRgbF(r, g, b, a); 00122 } 00123 00124 QColor KColorUtils::overlayColors(const QColor &base, const QColor &paint, 00125 QPainter::CompositionMode comp) 00126 { 00127 // This isn't the fastest way, but should be "fast enough". 00128 // It's also the only safe way to use QPainter::CompositionMode 00129 QImage img(1, 1, QImage::Format_ARGB32_Premultiplied); 00130 QPainter p(&img); 00131 QColor start = base; 00132 start.setAlpha(255); // opaque 00133 p.fillRect(0, 0, 1, 1, start); 00134 p.setCompositionMode(comp); 00135 p.fillRect(0, 0, 1, 1, paint); 00136 p.end(); 00137 return img.pixel(0, 0); 00138 } 00139 // kate: space-indent on; indent-width 4; replace-tabs on; auto-insert-doxygen on;
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:56:53 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:56:53 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.