banshee r4451 - in trunk/banshee: . src/Libraries/Hyena.Gui src/Libraries/Hyena.Gui/Hyena.Gui src/Libraries/Hyena.Gui/Hyena.Gui.Theming
- From: abock svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r4451 - in trunk/banshee: . src/Libraries/Hyena.Gui src/Libraries/Hyena.Gui/Hyena.Gui src/Libraries/Hyena.Gui/Hyena.Gui.Theming
- Date: Tue, 2 Sep 2008 18:33:14 +0000 (UTC)
Author: abock
Date: Tue Sep 2 18:33:14 2008
New Revision: 4451
URL: http://svn.gnome.org/viewvc/banshee?rev=4451&view=rev
Log:
2008-09-02 Aaron Bockover <abock gnome org>
* src/Libraries/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs: Change
GetCairoTextMidColor to use AlphaBlend function (BGO #544840)
* src/Libraries/Hyena.Gui/Hyena.Gui/CairoExtensions.cs: Implemented simple
color alpha blending utility [P=(1-a)P_0 + aP_1]
* src/Libraries/Hyena.Gui/Hyena.Gui/Contrast.cs: Add some color contrast
utilities, copied from Tomboy and modified to work with Cairo colors
Added:
trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui/Contrast.cs
Modified:
trunk/banshee/ChangeLog
trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs
trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp
trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui/CairoExtensions.cs
trunk/banshee/src/Libraries/Hyena.Gui/Makefile.am
Modified: trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs (original)
+++ trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs Tue Sep 2 18:33:14 2008
@@ -45,10 +45,7 @@
{
Cairo.Color text_color = CairoExtensions.GdkColorToCairoColor (widget.Style.Foreground (StateType.Normal));
Cairo.Color background_color = CairoExtensions.GdkColorToCairoColor (widget.Style.Background (StateType.Normal));
- // This is lame
- Cairo.Color c = CairoExtensions.ColorAdjustBrightness (text_color,
- CairoExtensions.ColorIsDark (background_color) ? 0.65 : 0.5);
- return c;
+ return CairoExtensions.AlphaBlend (text_color, background_color, 0.5);
}
public static Gdk.Color GetGdkTextMidColor (Widget widget)
Modified: trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp
==============================================================================
--- trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp (original)
+++ trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui.mdp Tue Sep 2 18:33:14 2008
@@ -84,6 +84,7 @@
<File name="Hyena.Gui/RatingRenderer.cs" subtype="Code" buildaction="Compile" />
<File name="Hyena.Data.Gui/ListView/ListViewBase.cs" subtype="Code" buildaction="Compile" />
<File name="Hyena.Gui/GtkWorkarounds.cs" subtype="Code" buildaction="Compile" />
+ <File name="Hyena.Gui/Contrast.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References>
<ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
Modified: trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui/CairoExtensions.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui/CairoExtensions.cs (original)
+++ trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui/CairoExtensions.cs Tue Sep 2 18:33:14 2008
@@ -74,7 +74,15 @@
((IDisposable)surface_cr).Dispose ();
return surface;
}
-
+
+ public static Cairo.Color AlphaBlend (Cairo.Color ca, Cairo.Color cb, double alpha)
+ {
+ return new Cairo.Color (
+ (1.0 - alpha) * ca.R + alpha * cb.R,
+ (1.0 - alpha) * ca.G + alpha * cb.G,
+ (1.0 - alpha) * ca.B + alpha * cb.B);
+ }
+
public static Cairo.Color GdkColorToCairoColor(Gdk.Color color)
{
return GdkColorToCairoColor(color, 1.0);
Added: trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui/Contrast.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/Hyena.Gui/Hyena.Gui/Contrast.cs Tue Sep 2 18:33:14 2008
@@ -0,0 +1,331 @@
+//
+// Contrast.cs
+//
+// Authors:
+// David Trowbridge
+// Sebastian DrÃge <slomo circular-chaos org>
+//
+// Copyright (C) 2006-2007 David Trowbridge
+// Copyright (C) 2008 Sebastian DrÃge
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Cairo;
+
+namespace Hyena.Gui
+{
+ /* Defined colors. Keep this list alphabetized if you add new ones,
+ * but set the enum value to be at the end of the color_regions table
+ * in contrast.c to maintain binary compatibility
+ */
+
+ public enum ContrastPaletteColor
+ {
+ Aqua = 0,
+ Black = 1,
+ Blue = 2,
+ Brown = 3,
+ Cyan = 4,
+ DarkBlue = 5,
+ DarkGreen = 6,
+ DarkGrey = 7,
+ DarkRed = 8,
+ Green = 9,
+ Grey = 10,
+ LightBlue = 11,
+ LightBrown = 12,
+ LightGreen = 13,
+ LightGrey = 14,
+ LightRed = 15,
+ Magenta = 16,
+ Orange = 17,
+ Purple = 18,
+ Red = 19,
+ Violet = 20,
+ White = 21,
+ Yellow = 22,
+ Last = 23
+ };
+
+ public static class Contrast
+ {
+
+ /* Data for color palette optimization.
+ *
+ * These numbers are completely arbitrary decisions, uninformed by the experts
+ * at crayola. These colors are defined as boxes within the CIE L*a*b* color
+ * space -- while they're not fully inclusive, they are "safe" in that anywhere
+ * within a given region is guaranteed to be the expected color. The data here
+ * are endpoints in each dimension of CIELAB, from which the 8 corners of the
+ * region are created to test.
+ *
+ * Add new entries to the end of this list.
+ */
+ private static readonly float[,] color_regions = {
+ {40.0f, 60.0f, -100.0f, -80.0f, -10.0f, 20.0f}, /* Aqua */
+ { 0.0f, 30.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Black */
+ {25.0f, 35.0f, -100.0f, 0.0f, -100.0f, -50.0f}, /* Blue */
+ {30.0f, 60.0f, 30.0f, 50.0f, 70.0f, 100.0f}, /* Brown */
+ {50.0f, 65.0f, -100.0f, -30.0f, -100.0f, -50.0f}, /* Cyan */
+ { 0.0f, 20.0f, -40.0f, 50.0f, -100.0f, -60.0f}, /* Dark Blue */
+ {20.0f, 35.0f, -100.0f, -70.0f, 60.0f, 100.0f}, /* Dark Green */
+ {20.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Dark Grey */
+ {10.0f, 40.0f, 90.0f, 100.0f, 70.0f, 100.0f}, /* Dark Red */
+ {15.0f, 40.0f, -100.0f, -80.0f, 80.0f, 100.0f}, /* Green */
+ {35.0f, 60.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Grey */
+ {40.0f, 50.0f, -100.0f, 0.0f, -100.0f, -60.0f}, /* Light Blue */
+ {60.0f, 75.0f, 30.0f, 50.0f, 80.0f, 100.0f}, /* Light Brown */
+ {80.0f, 90.0f, -100.0f, -70.0f, 70.0f, 100.0f}, /* Light Green */
+ {50.0f, 80.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Light Grey */
+ {55.0f, 65.0f, 80.0f, 90.0f, 75.0f, 100.0f}, /* Light Red */
+ {40.0f, 55.0f, 90.0f, 100.0f, -50.0f, 0.0f}, /* Magenta */
+ {65.0f, 80.0f, 20.0f, 65.0f, 90.0f, 100.0f}, /* Orange */
+ {35.0f, 45.0f, 85.0f, 100.0f, -90.0f, -80.0f}, /* Purple */
+ {40.0f, 50.0f, 80.0f, 100.0f, 75.0f, 100.0f}, /* Red */
+ {70.0f, 95.0f, 90.0f, 100.0f, -100.0f, 0.0f}, /* Violet */
+ {75.0f, 100.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* White */
+ {90.0f, 100.0f, 5.0f, 15.0f, 92.5f, 105.0f}, /* Yellow */
+ };
+
+ /* This performs the non-linear transformation that accounts for the gamma curve
+ * in sRGB, but avoids numerical problems.
+ */
+
+ private static float srgb_to_xyz_g (float K)
+ {
+ const float a = 0.055f;
+ const float gamma = 2.4f;
+
+
+ if (K > 0.04045f)
+ return (float) Math.Pow((K + a) / (1 + a), gamma);
+ else
+ return K / 12.92f;
+ }
+
+ private static float xyz_to_lab_f(float t)
+ {
+ if (t > 0.008856f)
+ return (float) Math.Pow(t, 1.0f/3.0f);
+ else
+ return 7.787f*t + 16.0f/116.0f;
+ }
+
+ private static void rgb_to_lab(ushort R, ushort G, ushort B, out float L, out float a, out float b)
+ {
+ float x, y, z, gr, gg, gb, fy;
+
+ /* This is the reference white point. Since we're treating "RGB" as
+ * sRGB, this is the D65 point.
+ */
+
+ const float Xn = 0.93819f;
+ const float Yn = 0.98705f;
+ const float Zn = 1.07475f;
+
+ gr = srgb_to_xyz_g(R / 65535.0f);
+ gg = srgb_to_xyz_g(G / 65535.0f);
+ gb = srgb_to_xyz_g(B / 65535.0f);
+
+ x = 0.412424f * gr + 0.357579f * gg + 0.180464f * gb;
+ y = 0.212656f * gr + 0.715158f * gg + 0.072186f * gb;
+ z = 0.019332f * gr + 0.119193f * gg + 0.950444f * gb;
+
+ fy = xyz_to_lab_f(y / Yn);
+
+ L = 116.0f * fy - 16.0f;
+ a = 500.0f * (xyz_to_lab_f(x / Xn) - fy);
+ b = 200.0f * (fy - xyz_to_lab_f(z / Zn));
+ }
+
+ private static float xyz_to_srgb_C(float K)
+ {
+ const float a = 0.055f;
+ const float gamma = 2.4f;
+
+
+ if (K > 0.00304f)
+ return (1.0f + a) * ((float) Math.Pow(K, (1.0f / gamma))) - a;
+ else
+ return K * 12.92f;
+ }
+
+ private static void lab_to_rgb(float L, float a, float b, out ushort R, out ushort G, out ushort B)
+ {
+ float x, y, z, fy, fx, fz, delta, delta2, rs, gs, bs;
+
+ const float Xn = 0.93819f;
+ const float Yn = 0.98705f;
+ const float Zn = 1.07475f;
+
+ fy = (L + 16.0f) / 116.0f;
+ fx = fy + a / 500.0f;
+ fz = fy - b / 200.0f;
+ delta = 6.0f / 29.0f;
+ delta2 = (float) Math.Pow(delta, 2.0f);
+
+ if (fx > delta)
+ x = Xn * ((float) Math.Pow(fx, 3.0f));
+ else
+ x = (fx - 16.0f/116.0f) * 3.0f * delta2 * Xn;
+
+ if (fy > delta)
+ y = Yn * ((float) Math.Pow(fy, 3.0f));
+ else
+ y = (fy - 16.0f/116.0f) * 3.0f * delta2 * Yn;
+
+
+ if (fz > delta)
+ z = Zn * ((float) Math.Pow(fz, 3.0f));
+ else
+ z = (fz - 16.0f/116.0f) * 3.0f * delta2 * Zn;
+
+
+ rs = 3.2410f * x - 1.5374f * y - 0.4986f * z;
+ gs = -0.9692f * x + 1.8760f * y + 0.0416f * z;
+ bs = 0.0556f * x - 0.2040f * y + 1.0570f * z;
+
+ float tmp;
+ tmp = (float) Math.Floor(xyz_to_srgb_C(rs) * 65535.0f + 0.5f);
+ if (tmp < 0.0f)
+ R = 0;
+ else if (tmp > 65535.0f)
+ R = 65535;
+ else
+ R = (ushort) tmp;
+
+ tmp = (float) Math.Floor(xyz_to_srgb_C(gs) * 65535.0f + 0.5f);
+ if (tmp < 0.0f)
+ G = 0;
+ else if (tmp > 65535.0f)
+ G = 65535;
+ else
+ G = (ushort) tmp;
+
+ tmp = (float) Math.Floor(xyz_to_srgb_C(bs) * 65535.0f + 0.5f);
+ if (tmp < 0.0f)
+ B = 0;
+ else if (tmp > 65535.0f)
+ B = 65535;
+ else
+ B = (ushort) tmp;
+ }
+
+ private static float lab_distance(float La, float aa, float ba, float Lb, float ab, float bb)
+ {
+ float dL, da, db;
+
+ dL = Math.Abs(Lb - La);
+ da = Math.Abs(ab - aa);
+ db = Math.Abs(bb - ba);
+
+ return (float) Math.Sqrt(dL*dL + da*da + db*db);
+ }
+
+ /* Creates a specific color value for a foreground color, optimizing for
+ * maximum readability against the background.
+ */
+
+ public static Color RenderForegroundColor(Color background, ContrastPaletteColor color)
+ {
+ float L, a, b;
+ int max_color;
+ float max_dist;
+ float[,] points = new float[8,3];
+ float ld, cd;
+ int i;
+
+ rgb_to_lab((ushort)(background.R * 255), (ushort)(background.G * 255),
+ (ushort)(background.B * 255), out L, out a, out b);
+
+ points[0,0] = color_regions[(int)color,0];
+ points[0,1] = color_regions[(int)color,2];
+ points[0,2] = color_regions[(int)color,4];
+
+ points[1,0] = color_regions[(int)color,0];
+ points[1,1] = color_regions[(int)color,2];
+ points[1,2] = color_regions[(int)color,5];
+
+ points[2,0] = color_regions[(int)color,0];
+ points[2,1] = color_regions[(int)color,3];
+ points[2,2] = color_regions[(int)color,4];
+
+ points[3,0] = color_regions[(int)color,0];
+ points[3,1] = color_regions[(int)color,3];
+ points[3,2] = color_regions[(int)color,5];
+
+ points[4,0] = color_regions[(int)color,1];
+ points[4,1] = color_regions[(int)color,2];
+ points[4,2] = color_regions[(int)color,4];
+
+ points[5,0] = color_regions[(int)color,1];
+ points[5,1] = color_regions[(int)color,2];
+ points[5,2] = color_regions[(int)color,5];
+
+ points[6,0] = color_regions[(int)color,1];
+ points[6,1] = color_regions[(int)color,3];
+ points[6,2] = color_regions[(int)color,4];
+
+ points[7,0] = color_regions[(int)color,1];
+ points[7,1] = color_regions[(int)color,3];
+ points[7,2] = color_regions[(int)color,5];
+
+ max_dist = 0;
+ max_color = 0;
+
+ for (i = 0; i < 8; i++) {
+ float dist = lab_distance(L, a, b, points[i,0], points[i,1], points[i,2]);
+
+ if (dist > max_dist) {
+ max_dist = dist;
+ max_color = i;
+ }
+ }
+
+ /* If the luminosity distance is really short, extend the vector further
+ * out. This may push it outside the bounds of the region that a color
+ * is specified in, but it keeps things readable when the background and
+ * foreground are really close.
+ */
+
+ ld = Math.Abs(L - points[max_color,0]);
+ cd = (float) Math.Sqrt (Math.Pow (Math.Abs (a - points[max_color,1]), 2.0f) + Math.Pow (Math.Abs (b - points[max_color,2]), 2.0f));
+
+ if ((ld < 10.0f) && (cd < 60.0f)) {
+ float dL, da, db;
+
+ dL = points[max_color,0] - L;
+ da = points[max_color,1] - a;
+ db = points[max_color,2] - b;
+ points[max_color,0] = L + (dL * 4.0f);
+ points[max_color,1] = a + (da * 1.5f);
+ points[max_color,2] = b + (db * 1.5f);
+ }
+
+ ushort red, green, blue;
+
+ lab_to_rgb(points[max_color,0], points[max_color,1], points[max_color,2], out red, out green, out blue);
+
+ return new Color (red / 255.0, green / 255.0, blue / 255.0);
+ }
+ }
+}
Modified: trunk/banshee/src/Libraries/Hyena.Gui/Makefile.am
==============================================================================
--- trunk/banshee/src/Libraries/Hyena.Gui/Makefile.am (original)
+++ trunk/banshee/src/Libraries/Hyena.Gui/Makefile.am Tue Sep 2 18:33:14 2008
@@ -39,6 +39,7 @@
Hyena.Gui/CairoExtensions.cs \
Hyena.Gui/CleanRoomStartup.cs \
Hyena.Gui/CompositeUtils.cs \
+ Hyena.Gui/Contrast.cs \
Hyena.Gui/EntryEraseAction.cs \
Hyena.Gui/EntryInsertAction.cs \
Hyena.Gui/EntryUndoAdapter.cs \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]