1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_RelativeLuminanceUtils_h
8 #define mozilla_RelativeLuminanceUtils_h
14 // Utilities for calculating relative luminance based on the algorithm
15 // defined in https://www.w3.org/TR/WCAG20/#relativeluminancedef
16 class RelativeLuminanceUtils
{
18 // Compute the relative luminance.
19 static float Compute(nscolor aColor
) {
20 float r
= ComputeComponent(NS_GET_R(aColor
));
21 float g
= ComputeComponent(NS_GET_G(aColor
));
22 float b
= ComputeComponent(NS_GET_B(aColor
));
23 return ComputeFromComponents(r
, g
, b
);
26 // Adjust the relative luminance of the given color.
27 static nscolor
Adjust(nscolor aColor
, float aLuminance
) {
28 float r
= ComputeComponent(NS_GET_R(aColor
));
29 float g
= ComputeComponent(NS_GET_G(aColor
));
30 float b
= ComputeComponent(NS_GET_B(aColor
));
31 float luminance
= ComputeFromComponents(r
, g
, b
);
32 float factor
= (aLuminance
+ 0.05f
) / (luminance
+ 0.05f
);
34 DecomputeComponent(std::max(0.0f
, (r
+ 0.05f
) * factor
- 0.05f
));
36 DecomputeComponent(std::max(0.0f
, (g
+ 0.05f
) * factor
- 0.05f
));
38 DecomputeComponent(std::max(0.0f
, (b
+ 0.05f
) * factor
- 0.05f
));
39 return NS_RGBA(r1
, g1
, b1
, NS_GET_A(aColor
));
42 // https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
43 static float ContrastRatio(nscolor aColor1
, nscolor aColor2
) {
44 float l1
= Compute(aColor1
);
45 float l2
= Compute(aColor2
);
49 return (l1
+ 0.05f
) / (l2
+ 0.05f
);
53 static float ComputeComponent(uint8_t aComponent
) {
54 float v
= float(aComponent
) / 255.0f
;
58 return std::pow((v
+ 0.055f
) / 1.055f
, 2.4f
);
61 static constexpr float ComputeFromComponents(float aR
, float aG
, float aB
) {
62 return 0.2126f
* aR
+ 0.7152f
* aG
+ 0.0722f
* aB
;
65 // Inverse function of ComputeComponent.
66 static uint8_t DecomputeComponent(float aComponent
) {
67 if (aComponent
<= 0.03928f
/ 12.92f
) {
70 aComponent
= std::pow(aComponent
, 1.0f
/ 2.4f
) * 1.055f
- 0.055f
;
72 return ClampColor(aComponent
* 255.0f
);
76 } // namespace mozilla
78 #endif // mozilla_RelativeLuminanceUtils_h