Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: ui/gfx/color_utils.cc

Issue 854713003: More old files deletion. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Fix tryjobs? Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gfx/color_utils.h ('k') | ui/gfx/color_utils_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/gfx/color_utils.h"
6
7 #include <math.h>
8 #if defined(OS_WIN)
9 #include <windows.h>
10 #endif
11
12 #include <algorithm>
13
14 #include "base/basictypes.h"
15 #include "base/logging.h"
16 #include "build/build_config.h"
17 #if defined(OS_WIN)
18 #include "skia/ext/skia_utils_win.h"
19 #endif
20 #include "third_party/skia/include/core/SkBitmap.h"
21
22 namespace color_utils {
23
24
25 // Helper functions -----------------------------------------------------------
26
27 namespace {
28
29 int calcHue(double temp1, double temp2, double hue) {
30 if (hue < 0.0)
31 ++hue;
32 else if (hue > 1.0)
33 --hue;
34
35 double result = temp1;
36 if (hue * 6.0 < 1.0)
37 result = temp1 + (temp2 - temp1) * hue * 6.0;
38 else if (hue * 2.0 < 1.0)
39 result = temp2;
40 else if (hue * 3.0 < 2.0)
41 result = temp1 + (temp2 - temp1) * (2.0 / 3.0 - hue) * 6.0;
42
43 // Scale the result from 0 - 255 and round off the value.
44 return static_cast<int>(result * 255 + .5);
45 }
46
47 // Next two functions' formulas from:
48 // http://www.w3.org/TR/WCAG20/#relativeluminancedef
49 // http://www.w3.org/TR/WCAG20/#contrast-ratiodef
50
51 double ConvertSRGB(double eight_bit_component) {
52 const double component = eight_bit_component / 255.0;
53 return (component <= 0.03928) ?
54 (component / 12.92) : pow((component + 0.055) / 1.055, 2.4);
55 }
56
57 SkColor LumaInvertColor(SkColor color) {
58 HSL hsl;
59 SkColorToHSL(color, &hsl);
60 hsl.l = 1.0 - hsl.l;
61 return HSLToSkColor(hsl, 255);
62 }
63
64 double ContrastRatio(double foreground_luminance, double background_luminance) {
65 DCHECK_GE(foreground_luminance, 0.0);
66 DCHECK_GE(background_luminance, 0.0);
67 foreground_luminance += 0.05;
68 background_luminance += 0.05;
69 return (foreground_luminance > background_luminance) ?
70 (foreground_luminance / background_luminance) :
71 (background_luminance / foreground_luminance);
72 }
73
74 } // namespace
75
76
77 // ----------------------------------------------------------------------------
78
79 unsigned char GetLuminanceForColor(SkColor color) {
80 int luma = static_cast<int>((0.3 * SkColorGetR(color)) +
81 (0.59 * SkColorGetG(color)) +
82 (0.11 * SkColorGetB(color)));
83 return std::max(std::min(luma, 255), 0);
84 }
85
86 double RelativeLuminance(SkColor color) {
87 return (0.2126 * ConvertSRGB(SkColorGetR(color))) +
88 (0.7152 * ConvertSRGB(SkColorGetG(color))) +
89 (0.0722 * ConvertSRGB(SkColorGetB(color)));
90 }
91
92 void SkColorToHSL(SkColor c, HSL* hsl) {
93 double r = static_cast<double>(SkColorGetR(c)) / 255.0;
94 double g = static_cast<double>(SkColorGetG(c)) / 255.0;
95 double b = static_cast<double>(SkColorGetB(c)) / 255.0;
96 double vmax = std::max(std::max(r, g), b);
97 double vmin = std::min(std::min(r, g), b);
98 double delta = vmax - vmin;
99 hsl->l = (vmax + vmin) / 2;
100 if (SkColorGetR(c) == SkColorGetG(c) && SkColorGetR(c) == SkColorGetB(c)) {
101 hsl->h = hsl->s = 0;
102 } else {
103 double dr = (((vmax - r) / 6.0) + (delta / 2.0)) / delta;
104 double dg = (((vmax - g) / 6.0) + (delta / 2.0)) / delta;
105 double db = (((vmax - b) / 6.0) + (delta / 2.0)) / delta;
106 // We need to compare for the max value because comparing vmax to r, g, or b
107 // can sometimes result in values overflowing registers.
108 if (r >= g && r >= b)
109 hsl->h = db - dg;
110 else if (g >= r && g >= b)
111 hsl->h = (1.0 / 3.0) + dr - db;
112 else // (b >= r && b >= g)
113 hsl->h = (2.0 / 3.0) + dg - dr;
114
115 if (hsl->h < 0.0)
116 ++hsl->h;
117 else if (hsl->h > 1.0)
118 --hsl->h;
119
120 hsl->s = delta / ((hsl->l < 0.5) ? (vmax + vmin) : (2 - vmax - vmin));
121 }
122 }
123
124 SkColor HSLToSkColor(const HSL& hsl, SkAlpha alpha) {
125 double hue = hsl.h;
126 double saturation = hsl.s;
127 double lightness = hsl.l;
128
129 // If there's no color, we don't care about hue and can do everything based on
130 // brightness.
131 if (!saturation) {
132 uint8 light;
133
134 if (lightness < 0)
135 light = 0;
136 else if (lightness >= 1.0)
137 light = 255;
138 else
139 light = SkDoubleToFixed(lightness) >> 8;
140
141 return SkColorSetARGB(alpha, light, light, light);
142 }
143
144 double temp2 = (lightness < 0.5) ?
145 (lightness * (1.0 + saturation)) :
146 (lightness + saturation - (lightness * saturation));
147 double temp1 = 2.0 * lightness - temp2;
148 return SkColorSetARGB(alpha,
149 calcHue(temp1, temp2, hue + 1.0 / 3.0),
150 calcHue(temp1, temp2, hue),
151 calcHue(temp1, temp2, hue - 1.0 / 3.0));
152 }
153
154 void ClampHSL(HSL* hsl) {
155 if (hsl->h < 0)
156 hsl->h = 0;
157 if (hsl->h > 1)
158 hsl->h = 1;
159 if (hsl->s < 0)
160 hsl->s = 0;
161 if (hsl->s > 1)
162 hsl->s = 1;
163 if (hsl->l < 0)
164 hsl->l = 0;
165 if (hsl->l > 1)
166 hsl->l = 1;
167 }
168
169 bool IsWithinHSLRange(const HSL& hsl,
170 const HSL& lower_bound,
171 const HSL& upper_bound) {
172 DCHECK(hsl.h >= 0 && hsl.h <= 1) << hsl.h;
173 DCHECK(hsl.s >= 0 && hsl.s <= 1) << hsl.s;
174 DCHECK(hsl.l >= 0 && hsl.l <= 1) << hsl.l;
175 DCHECK(lower_bound.h < 0 || upper_bound.h < 0 ||
176 (lower_bound.h <= 1 && upper_bound.h <= lower_bound.h + 1))
177 << "lower_bound.h: " << lower_bound.h
178 << ", upper_bound.h: " << upper_bound.h;
179 DCHECK(lower_bound.s < 0 || upper_bound.s < 0 ||
180 (lower_bound.s <= upper_bound.s && upper_bound.s <= 1))
181 << "lower_bound.s: " << lower_bound.s
182 << ", upper_bound.s: " << upper_bound.s;
183 DCHECK(lower_bound.l < 0 || upper_bound.l < 0 ||
184 (lower_bound.l <= upper_bound.l && upper_bound.l <= 1))
185 << "lower_bound.l: " << lower_bound.l
186 << ", upper_bound.l: " << upper_bound.l;
187
188 // If the upper hue is >1, the given hue bounds wrap around at 1.
189 bool matches_hue = upper_bound.h > 1
190 ? hsl.h >= lower_bound.h || hsl.h <= upper_bound.h - 1
191 : hsl.h >= lower_bound.h && hsl.h <= upper_bound.h;
192 return (upper_bound.h < 0 || lower_bound.h < 0 || matches_hue) &&
193 (upper_bound.s < 0 || lower_bound.s < 0 ||
194 (hsl.s >= lower_bound.s && hsl.s <= upper_bound.s)) &&
195 (upper_bound.l < 0 || lower_bound.l < 0 ||
196 (hsl.l >= lower_bound.l && hsl.l <= upper_bound.l));
197 }
198
199 SkColor HSLShift(SkColor color, const HSL& shift) {
200 HSL hsl;
201 int alpha = SkColorGetA(color);
202 SkColorToHSL(color, &hsl);
203
204 // Replace the hue with the tint's hue.
205 if (shift.h >= 0)
206 hsl.h = shift.h;
207
208 // Change the saturation.
209 if (shift.s >= 0) {
210 if (shift.s <= 0.5)
211 hsl.s *= shift.s * 2.0;
212 else
213 hsl.s += (1.0 - hsl.s) * ((shift.s - 0.5) * 2.0);
214 }
215
216 SkColor result = HSLToSkColor(hsl, alpha);
217
218 if (shift.l < 0)
219 return result;
220
221 // Lightness shifts in the style of popular image editors aren't actually
222 // represented in HSL - the L value does have some effect on saturation.
223 double r = static_cast<double>(SkColorGetR(result));
224 double g = static_cast<double>(SkColorGetG(result));
225 double b = static_cast<double>(SkColorGetB(result));
226 if (shift.l <= 0.5) {
227 r *= (shift.l * 2.0);
228 g *= (shift.l * 2.0);
229 b *= (shift.l * 2.0);
230 } else {
231 r += (255.0 - r) * ((shift.l - 0.5) * 2.0);
232 g += (255.0 - g) * ((shift.l - 0.5) * 2.0);
233 b += (255.0 - b) * ((shift.l - 0.5) * 2.0);
234 }
235 return SkColorSetARGB(alpha,
236 static_cast<int>(r),
237 static_cast<int>(g),
238 static_cast<int>(b));
239 }
240
241 void BuildLumaHistogram(const SkBitmap& bitmap, int histogram[256]) {
242 DCHECK_EQ(kN32_SkColorType, bitmap.colorType());
243
244 SkAutoLockPixels bitmap_lock(bitmap);
245
246 int pixel_width = bitmap.width();
247 int pixel_height = bitmap.height();
248 for (int y = 0; y < pixel_height; ++y) {
249 for (int x = 0; x < pixel_width; ++x)
250 ++histogram[GetLuminanceForColor(bitmap.getColor(x, y))];
251 }
252 }
253
254 SkColor AlphaBlend(SkColor foreground, SkColor background, SkAlpha alpha) {
255 if (alpha == 0)
256 return background;
257 if (alpha == 255)
258 return foreground;
259
260 int f_alpha = SkColorGetA(foreground);
261 int b_alpha = SkColorGetA(background);
262
263 double normalizer = (f_alpha * alpha + b_alpha * (255 - alpha)) / 255.0;
264 if (normalizer == 0.0)
265 return SK_ColorTRANSPARENT;
266
267 double f_weight = f_alpha * alpha / normalizer;
268 double b_weight = b_alpha * (255 - alpha) / normalizer;
269
270 double r = (SkColorGetR(foreground) * f_weight +
271 SkColorGetR(background) * b_weight) / 255.0;
272 double g = (SkColorGetG(foreground) * f_weight +
273 SkColorGetG(background) * b_weight) / 255.0;
274 double b = (SkColorGetB(foreground) * f_weight +
275 SkColorGetB(background) * b_weight) / 255.0;
276
277 return SkColorSetARGB(static_cast<int>(normalizer),
278 static_cast<int>(r),
279 static_cast<int>(g),
280 static_cast<int>(b));
281 }
282
283 SkColor BlendTowardOppositeLuminance(SkColor color, SkAlpha alpha) {
284 unsigned char background_luminance =
285 color_utils::GetLuminanceForColor(color);
286 const SkColor blend_color =
287 (background_luminance < 128) ? SK_ColorWHITE : SK_ColorBLACK;
288 return color_utils::AlphaBlend(blend_color, color, alpha);
289 }
290
291 SkColor GetReadableColor(SkColor foreground, SkColor background) {
292 const SkColor foreground2 = LumaInvertColor(foreground);
293 const double background_luminance = RelativeLuminance(background);
294 return (ContrastRatio(RelativeLuminance(foreground), background_luminance) >=
295 ContrastRatio(RelativeLuminance(foreground2), background_luminance)) ?
296 foreground : foreground2;
297 }
298
299 SkColor InvertColor(SkColor color) {
300 return SkColorSetARGB(
301 SkColorGetA(color),
302 255 - SkColorGetR(color),
303 255 - SkColorGetG(color),
304 255 - SkColorGetB(color));
305 }
306
307 SkColor GetSysSkColor(int which) {
308 #if defined(OS_WIN)
309 return skia::COLORREFToSkColor(GetSysColor(which));
310 #else
311 NOTIMPLEMENTED();
312 return SK_ColorLTGRAY;
313 #endif
314 }
315
316 } // namespace color_utils
OLDNEW
« no previous file with comments | « ui/gfx/color_utils.h ('k') | ui/gfx/color_utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698