Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 55750 | Differences between
and this patch

Collapse All | Expand All

(-)Eclipse (+150 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Common Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/cpl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.themes;
12
13
import java.util.Hashtable;
14
15
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.IConfigurationElement;
17
import org.eclipse.core.runtime.IExecutableExtension;
18
import org.eclipse.swt.graphics.RGB;
19
import org.eclipse.ui.themes.IColorFactory;
20
21
22
/**
23
 * A <code>IColorFactory</code> that may be used to select a colour with
24
 * a higher contrast.  The colors to blend are specified as per method
25
 * number two in  {@link org.eclipse.core.runtime.IExecutableExtension}.
26
 * <p>
27
 * Example usage:
28
 * <br/>
29
 * <code>
30
 * &lt;colorDefinition
31
 *     label="Red/Blue Contrast"
32
 *     id="example.redblueblend"&gt;
33
 *     &lt;colorFactory 
34
 * 				plugin="org.eclipse.ui" 
35
 * 				class="org.eclipse.ui.internal.themes.RGBContrastFactory"&gt;
36
 *      	&lt;parameter name="foreground" value="0,0,0" /&gt;
37
 *  		&lt;parameter name="background1" value="COLOR_RED" /&gt;
38
 *          &lt;parameter name="background2" value="COLOR_BLUE" /&gt;
39
 *     &lt;/colorFactory&gt;
40
 * &lt;/colorDefinition&gt;
41
 * </code>
42
 * </p>
43
 * 
44
 * <p>
45
 * This will select whichever of Red or Blue has a higher contrst with black.
46
 * The color values may be specified as RGB triples or as SWT constants.
47
 * </p>
48
 * 
49
 * @see org.eclipse.swt.SWT
50
 * @since 3.0
51
 */
52
public class RGBContrastFactory implements IColorFactory, IExecutableExtension {
53
    private String fg, bg1, bg2;
54
55
    /**
56
     * Returns the intensity of an RGB component using the
57
     * sRGB gamma function.
58
     * 
59
     * @param val Value to convert.
60
     * @return Light intensity of the component.
61
     */
62
    double voltage_to_intensity_srgb( double val ) {   
63
        /* Handle invalid values before doing a gamma transform. */
64
        if( val < 0.0 ) return 0.0;
65
        if( val > 1.0 ) return 1.0;
66
67
        if( val <= 0.04045 ) {
68
            return val / 12.92;
69
        }
70
        return Math.pow( ( val + 0.055 ) / 1.055, 2.4 );
71
    }
72
73
    /**
74
     * Returns a measure of the lightness in the perceptual colourspace
75
     * IPT.
76
     * 
77
     * @param color The colour in sRGB
78
     * @return Lightness in IPT space.
79
     */
80
    double lightness( RGB color ) {
81
        double r = voltage_to_intensity_srgb( color.red / 255.0 );
82
        double g = voltage_to_intensity_srgb( color.green / 255.0 );
83
        double b = voltage_to_intensity_srgb( color.blue / 255.0 );
84
        double l = (0.3139 * r) + (0.6395 * g) + (0.0466 * b);
85
        double m = (0.1516 * r) + (0.7482 * g) + (0.1000 * b);
86
        double s = (0.0177 * r) + (0.1095 * g) + (0.8729 * b);
87
        double lp, mp, sp;
88
        
89
        if( l < 0.0 ) lp = -Math.pow( -l, 0.43 ); else lp = Math.pow( l, 0.43 );
90
        if( m < 0.0 ) mp = -Math.pow( -m, 0.43 ); else mp = Math.pow( m, 0.43 );
91
        if( s < 0.0 ) sp = -Math.pow( -s, 0.43 ); else sp = Math.pow( s, 0.43 );
92
93
        return (0.4000 * lp) + (0.4000 *mp) + (0.2000 * sp);
94
    }
95
    
96
    public RGB createColor() {
97
        /**
98
         * Determine which pair has a higher contrast by selecting
99
         * the colour with the furthest distance in lightness.
100
         */
101
        RGB cfg, cbg1, cbg2;
102
103
        if( fg != null ) {
104
            cfg = ColorUtils.getColorValue( fg );
105
        } else {
106
            cfg = new RGB(255,255,255);
107
        }
108
        if( bg1 != null ) {
109
            cbg1 = ColorUtils.getColorValue( bg1 );
110
        } else {
111
            cbg1 = new RGB(0, 0, 0);
112
        }
113
        if( bg2 != null ) {
114
            cbg2 = ColorUtils.getColorValue( bg2 );
115
        } else {
116
            cbg2 = new RGB(0, 0, 0);
117
        }
118
119
        double lfg = lightness( cfg );
120
        double lbg1 = lightness( cbg1 );
121
        double lbg2 = lightness( cbg2 );
122
123
        if( Math.abs(lbg1 - lfg) > Math.abs(lbg2 - lfg) ) {
124
            return cbg1;
125
        } else {
126
            return cbg2;
127
        }
128
    }
129
130
    /**
131
     * This executable extension requires parameters to be explicitly declared 
132
     * via the second method described in the <code>IExecutableExtension</code> 
133
     * documentation.  This class expects that there will be three parameters, 
134
     * <code>foreground</code>, <code>background1</code> and
135
     * <code>background2</code>, that describe the two colors to be blended.
136
     * These values may either be RGB triples or SWT constants.
137
     * 
138
     * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
139
     */
140
    public void setInitializationData(IConfigurationElement config,
141
            String propertyName, Object data) throws CoreException {
142
        if (data instanceof Hashtable) {
143
            Hashtable table = (Hashtable)data;
144
            fg = (String) table.get("foreground"); //$NON-NLS-1$
145
            bg1 = (String) table.get("background1"); //$NON-NLS-1$
146
            bg2 = (String) table.get("background2"); //$NON-NLS-1$
147
        }
148
149
    }
150
}

Return to bug 55750