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

Side by Side Diff: chrome/common/gfx/color_utils.cc

Issue 113143: Move color_utils, text_elider, drag_utils, accessibility_types, standard_layo... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « chrome/common/gfx/color_utils.h ('k') | chrome/common/gfx/text_elider.h » ('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) 2006-2008 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 "build/build_config.h"
6
7 #include <math.h>
8 #if defined(OS_WIN)
9 #include <windows.h>
10 #endif
11
12 #include "chrome/common/gfx/color_utils.h"
13
14 #include "base/basictypes.h"
15 #include "base/logging.h"
16 #include "skia/include/SkBitmap.h"
17
18 #if defined(OS_WIN)
19 #include "skia/ext/skia_utils_win.h"
20 #endif
21
22 namespace color_utils {
23
24 // These transformations are based on the equations in:
25 // http://en.wikipedia.org/wiki/Lab_color
26 // http://en.wikipedia.org/wiki/SRGB_color_space#Specification_of_the_transforma tion
27 // See also:
28 // http://www.brucelindbloom.com/index.html?ColorCalculator.html
29
30 static const double kCIEConversionAlpha = 0.055;
31 static const double kCIEConversionGamma = 2.2;
32 static const double kE = 0.008856;
33 static const double kK = 903.3;
34
35 static double CIEConvertNonLinear(uint8 color_component) {
36 double color_component_d = static_cast<double>(color_component) / 255.0;
37 if (color_component_d > 0.04045) {
38 double base = (color_component_d + kCIEConversionAlpha) /
39 (1 + kCIEConversionAlpha);
40 return pow(base, kCIEConversionGamma);
41 } else {
42 return color_component_d / 12.92;
43 }
44 }
45
46 // Note: this works only for sRGB.
47 void SkColorToCIEXYZ(SkColor c, CIE_XYZ* xyz) {
48 uint8 r = SkColorGetR(c);
49 uint8 g = SkColorGetG(c);
50 uint8 b = SkColorGetB(c);
51
52 xyz->X =
53 0.4124 * CIEConvertNonLinear(r) +
54 0.3576 * CIEConvertNonLinear(g) +
55 0.1805 * CIEConvertNonLinear(b);
56 xyz->Y =
57 0.2126 * CIEConvertNonLinear(r) +
58 0.7152 * CIEConvertNonLinear(g) +
59 0.0722 * CIEConvertNonLinear(g);
60 xyz->Z =
61 0.0193 * CIEConvertNonLinear(r) +
62 0.1192 * CIEConvertNonLinear(g) +
63 0.9505 * CIEConvertNonLinear(b);
64 }
65
66 static double LabConvertNonLinear(double value) {
67 if (value > 0.008856) {
68 double goat = pow(value, static_cast<double>(1) / 3);
69 return goat;
70 }
71 return (kK * value + 16) / 116;
72 }
73
74 void CIEXYZToLabColor(const CIE_XYZ& xyz, LabColor* lab) {
75 CIE_XYZ white_xyz;
76 SkColorToCIEXYZ(SkColorSetRGB(255, 255, 255), &white_xyz);
77 double fx = LabConvertNonLinear(xyz.X / white_xyz.X);
78 double fy = LabConvertNonLinear(xyz.Y / white_xyz.Y);
79 double fz = LabConvertNonLinear(xyz.Z / white_xyz.Z);
80 lab->L = static_cast<int>(116 * fy) - 16;
81 lab->a = static_cast<int>(500 * (fx - fy));
82 lab->b = static_cast<int>(200 * (fy - fz));
83 }
84
85 static uint8 sRGBColorComponentFromLinearComponent(double component) {
86 double result;
87 if (component <= 0.0031308) {
88 result = 12.92 * component;
89 } else {
90 result = (1 + kCIEConversionAlpha) *
91 pow(component, (static_cast<double>(1) / 2.4)) -
92 kCIEConversionAlpha;
93 }
94 return std::min(static_cast<uint8>(255), static_cast<uint8>(result * 255));
95 }
96
97 SkColor CIEXYZToSkColor(SkAlpha alpha, const CIE_XYZ& xyz) {
98 double r_linear = 3.2410 * xyz.X - 1.5374 * xyz.Y - 0.4986 * xyz.Z;
99 double g_linear = -0.9692 * xyz.X + 1.8760 * xyz.Y + 0.0416 * xyz.Z;
100 double b_linear = 0.0556 * xyz.X - 0.2040 * xyz.Y + 1.0570 * xyz.Z;
101 uint8 r = sRGBColorComponentFromLinearComponent(r_linear);
102 uint8 g = sRGBColorComponentFromLinearComponent(g_linear);
103 uint8 b = sRGBColorComponentFromLinearComponent(b_linear);
104 return SkColorSetARGB(alpha, r, g, b);
105 }
106
107 static double gen_yr(const LabColor& lab) {
108 if (lab.L > (kE * kK))
109 return pow((lab.L + 16.0) / 116, 3.0);
110 return static_cast<double>(lab.L) / kK;
111 }
112
113 static double fy(const LabColor& lab) {
114 double yr = gen_yr(lab);
115 if (yr > kE)
116 return (lab.L + 16.0) / 116;
117 return (kK * yr + 16.0) / 116;
118 }
119
120 static double fx(const LabColor& lab) {
121 return (static_cast<double>(lab.a) / 500) + fy(lab);
122 }
123
124 static double gen_xr(const LabColor& lab) {
125 double x = fx(lab);
126 double x_cubed = pow(x, 3.0);
127 if (x_cubed > kE)
128 return x_cubed;
129 return (116.0 * x - 16.0) / kK;
130 }
131
132 static double fz(const LabColor& lab) {
133 return fy(lab) - (static_cast<double>(lab.b) / 200);
134 }
135
136 static double gen_zr(const LabColor& lab) {
137 double z = fz(lab);
138 double z_cubed = pow(z, 3.0);
139 if (z_cubed > kE)
140 return z_cubed;
141 return (116.0 * z - 16.0) / kK;
142 }
143
144 void LabColorToCIEXYZ(const LabColor& lab, CIE_XYZ* xyz) {
145 CIE_XYZ result;
146
147 CIE_XYZ white_xyz;
148 SkColorToCIEXYZ(SkColorSetRGB(255, 255, 255), &white_xyz);
149
150 result.X = gen_xr(lab) * white_xyz.X;
151 result.Y = gen_yr(lab) * white_xyz.Y;
152 result.Z = gen_zr(lab) * white_xyz.Z;
153
154 *xyz = result;
155 }
156
157 void SkColorToLabColor(SkColor c, LabColor* lab) {
158 CIE_XYZ xyz;
159 SkColorToCIEXYZ(c, &xyz);
160 CIEXYZToLabColor(xyz, lab);
161 }
162
163 SkColor LabColorToSkColor(const LabColor& lab, SkAlpha alpha) {
164 CIE_XYZ xyz;
165 LabColorToCIEXYZ(lab, &xyz);
166 return CIEXYZToSkColor(alpha, xyz);
167 }
168
169 static const int kCloseToBoundary = 64;
170 static const int kAverageBoundary = 15;
171
172 bool IsColorCloseToTransparent(SkAlpha alpha) {
173 return alpha < kCloseToBoundary;
174 }
175
176 bool IsColorCloseToGrey(int r, int g, int b) {
177 int average = (r + g + b) / 3;
178 return (abs(r - average) < kAverageBoundary) &&
179 (abs(g - average) < kAverageBoundary) &&
180 (abs(b - average) < kAverageBoundary);
181 }
182
183 SkColor GetAverageColorOfFavicon(SkBitmap* favicon, SkAlpha alpha) {
184 int r = 0, g = 0, b = 0;
185
186 SkAutoLockPixels favicon_lock(*favicon);
187 SkColor* pixels = static_cast<SkColor*>(favicon->getPixels());
188 // Assume ARGB_8888 format.
189 DCHECK(favicon->getConfig() == SkBitmap::kARGB_8888_Config);
190 SkColor* current_color = pixels;
191
192 DCHECK(favicon->width() <= 16 && favicon->height() <= 16);
193
194 int pixel_count = favicon->width() * favicon->height();
195 int color_count = 0;
196 for (int i = 0; i < pixel_count; ++i, ++current_color) {
197 // Disregard this color if it is close to black, close to white, or close
198 // to transparent since any of those pixels do not contribute much to the
199 // color makeup of this icon.
200 int cr = SkColorGetR(*current_color);
201 int cg = SkColorGetG(*current_color);
202 int cb = SkColorGetB(*current_color);
203
204 if (IsColorCloseToTransparent(SkColorGetA(*current_color)) ||
205 IsColorCloseToGrey(cr, cg, cb))
206 continue;
207
208 r += cr;
209 g += cg;
210 b += cb;
211 ++color_count;
212 }
213
214 SkColor result;
215 if (color_count > 0) {
216 result = SkColorSetARGB(alpha,
217 r / color_count,
218 g / color_count,
219 b / color_count);
220 } else {
221 result = SkColorSetARGB(alpha, 0, 0, 0);
222 }
223 return result;
224 }
225
226 inline int GetLumaForColor(SkColor* color) {
227 int r = SkColorGetR(*color);
228 int g = SkColorGetG(*color);
229 int b = SkColorGetB(*color);
230
231 int luma = static_cast<int>(0.3*r + 0.59*g + 0.11*b);
232 if (luma < 0)
233 luma = 0;
234 else if (luma > 255)
235 luma = 255;
236
237 return luma;
238 }
239
240 void BuildLumaHistogram(SkBitmap* bitmap, int histogram[256]) {
241 SkAutoLockPixels bitmap_lock(*bitmap);
242 // Assume ARGB_8888 format.
243 DCHECK(bitmap->getConfig() == SkBitmap::kARGB_8888_Config);
244
245 int pixel_width = bitmap->width();
246 int pixel_height = bitmap->height();
247 for (int y = 0; y < pixel_height; ++y) {
248 SkColor* current_color = static_cast<uint32_t*>(bitmap->getAddr32(0, y));
249 for (int x = 0; x < pixel_width; ++x, ++current_color) {
250 histogram[GetLumaForColor(current_color)]++;
251 }
252 }
253 }
254
255 SkColor SetColorAlpha(SkColor c, SkAlpha alpha) {
256 return SkColorSetARGB(alpha, SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));
257 }
258
259 SkColor GetSysSkColor(int which) {
260 #if defined(OS_WIN)
261 return skia::COLORREFToSkColor(::GetSysColor(which));
262 #else
263 NOTIMPLEMENTED();
264 return SK_ColorLTGRAY;
265 #endif
266 }
267
268 } // namespace color_utils
OLDNEW
« no previous file with comments | « chrome/common/gfx/color_utils.h ('k') | chrome/common/gfx/text_elider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698