color_utils.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. #ifndef UI_GFX_COLOR_UTILS_H_
  5. #define UI_GFX_COLOR_UTILS_H_
  6. #include <string>
  7. #include <tuple>
  8. #include "third_party/abseil-cpp/absl/types/optional.h"
  9. #include "third_party/skia/include/core/SkColor.h"
  10. #include "ui/gfx/gfx_export.h"
  11. namespace color_utils {
  12. // Represents an HSL color.
  13. struct HSL {
  14. double h;
  15. double s;
  16. double l;
  17. };
  18. // The blend alpha and resulting color when blending to achieve a desired
  19. // contrast raio.
  20. struct BlendResult {
  21. SkAlpha alpha;
  22. SkColor color;
  23. };
  24. // The minimum contrast between text and background that is still readable.
  25. // This value is taken from w3c accessibility guidelines.
  26. constexpr float kMinimumReadableContrastRatio = 4.5f;
  27. // The minimum contrast between button glyphs, focus indicators, large text, or
  28. // other "have to see it but perhaps don't have to read fine detail" cases and
  29. // background.
  30. constexpr float kMinimumVisibleContrastRatio = 3.0f;
  31. // Determines the contrast ratio of two colors or two relative luminance values
  32. // (as computed by RelativeLuminance()), calculated according to
  33. // http://www.w3.org/TR/WCAG20/#contrast-ratiodef .
  34. GFX_EXPORT float GetContrastRatio(SkColor color_a, SkColor color_b);
  35. GFX_EXPORT float GetContrastRatio(float luminance_a, float luminance_b);
  36. // The relative luminance of |color|, that is, the weighted sum of the
  37. // linearized RGB components, normalized to 0..1, per BT.709. See
  38. // http://www.w3.org/TR/WCAG20/#relativeluminancedef .
  39. GFX_EXPORT float GetRelativeLuminance(SkColor color);
  40. // The luma of |color|, that is, the weighted sum of the gamma-compressed R'G'B'
  41. // components, per BT.601, a.k.a. the Y' in Y'UV. See
  42. // https://en.wikipedia.org/wiki/Luma_(video).
  43. GFX_EXPORT uint8_t GetLuma(SkColor color);
  44. // Note: these transformations assume sRGB as the source color space
  45. GFX_EXPORT void SkColorToHSL(SkColor c, HSL* hsl);
  46. GFX_EXPORT SkColor HSLToSkColor(const HSL& hsl, SkAlpha alpha);
  47. // Determines whether the given |hsl| falls within the given range for each
  48. // component. All components of |hsl| are expected to be in the range [0, 1].
  49. //
  50. // If a component is negative in either |lower_bound| or |upper_bound|, that
  51. // component will be ignored.
  52. //
  53. // For hue, the lower bound should be in the range [0, 1] and the upper bound
  54. // should be in the range [(lower bound), (lower bound + 1)].
  55. // For saturation and value, bounds should be specified in the range [0, 1],
  56. // with the lower bound less than the upper bound.
  57. GFX_EXPORT bool IsWithinHSLRange(const HSL& hsl,
  58. const HSL& lower_bound,
  59. const HSL& upper_bound);
  60. // Makes |hsl| valid input for HSLShift(). Sets values of hue, saturation
  61. // and lightness which are outside of the valid range [0, 1] to -1. -1 is a
  62. // special value which indicates 'no change'.
  63. GFX_EXPORT void MakeHSLShiftValid(HSL* hsl);
  64. // Returns whether pasing |hsl| to HSLShift() would have any effect. Assumes
  65. // |hsl| is a valid shift (as defined by MakeHSLShiftValid()).
  66. GFX_EXPORT bool IsHSLShiftMeaningful(const HSL& hsl);
  67. // HSL-Shift an SkColor. The shift values are in the range of 0-1, with the
  68. // option to specify -1 for 'no change'. The shift values are defined as:
  69. // hsl_shift[0] (hue): The absolute hue value - 0 and 1 map
  70. // to 0 and 360 on the hue color wheel (red).
  71. // hsl_shift[1] (saturation): A saturation shift, with the
  72. // following key values:
  73. // 0 = remove all color.
  74. // 0.5 = leave unchanged.
  75. // 1 = fully saturate the image.
  76. // hsl_shift[2] (lightness): A lightness shift, with the
  77. // following key values:
  78. // 0 = remove all lightness (make all pixels black).
  79. // 0.5 = leave unchanged.
  80. // 1 = full lightness (make all pixels white).
  81. GFX_EXPORT SkColor HSLShift(SkColor color, const HSL& shift);
  82. // Returns a blend of the supplied colors, ranging from |background| (for
  83. // |alpha| == 0) to |foreground| (for |alpha| == 255). The alpha channels of
  84. // the supplied colors are also taken into account, so the returned color may
  85. // be partially transparent.
  86. GFX_EXPORT SkColor AlphaBlend(SkColor foreground,
  87. SkColor background,
  88. SkAlpha alpha);
  89. // As above, but with alpha specified as 0..1.
  90. GFX_EXPORT SkColor AlphaBlend(SkColor foreground,
  91. SkColor background,
  92. float alpha);
  93. // Returns the color that results from painting |foreground| on top of
  94. // |background|.
  95. GFX_EXPORT SkColor GetResultingPaintColor(SkColor foreground,
  96. SkColor background);
  97. // Returns true if |color| contrasts more with white than the darkest color.
  98. GFX_EXPORT bool IsDark(SkColor color);
  99. // Returns whichever of white or the darkest available color contrasts more with
  100. // |color|.
  101. GFX_EXPORT SkColor GetColorWithMaxContrast(SkColor color);
  102. // Returns whichever of white or the darkest available color contrasts less with
  103. // |color|.
  104. GFX_EXPORT SkColor GetEndpointColorWithMinContrast(SkColor color);
  105. // Blends towards the color with max contrast by |alpha|. The alpha of
  106. // the original color is preserved.
  107. GFX_EXPORT SkColor BlendTowardMaxContrast(SkColor color, SkAlpha alpha);
  108. // Returns whichever of |foreground1| or |foreground2| has higher contrast with
  109. // |background|.
  110. GFX_EXPORT SkColor PickContrastingColor(SkColor foreground1,
  111. SkColor foreground2,
  112. SkColor background);
  113. // Alpha-blends |default_foreground| toward either |high_contrast_foreground|
  114. // (if specified) or the color with max contrast with |background| until either
  115. // the result has a contrast ratio against |background| of at least
  116. // |contrast_ratio| or the blend can go no further. Returns the blended color
  117. // and the alpha used to achieve that blend. If |default_foreground| already
  118. // has sufficient contrast, returns an alpha of 0 and color of
  119. // |default_foreground|.
  120. GFX_EXPORT BlendResult BlendForMinContrast(
  121. SkColor default_foreground,
  122. SkColor background,
  123. absl::optional<SkColor> high_contrast_foreground = absl::nullopt,
  124. float contrast_ratio = kMinimumReadableContrastRatio);
  125. // Invert a color.
  126. GFX_EXPORT SkColor InvertColor(SkColor color);
  127. // Gets a Windows system color as a SkColor
  128. GFX_EXPORT SkColor GetSysSkColor(int which);
  129. // Derives a color for icons on a UI surface based on the text color on the same
  130. // surface.
  131. GFX_EXPORT SkColor DeriveDefaultIconColor(SkColor text_color);
  132. // Gets a Google color that matches the hue of `color` and contrasts similarly
  133. // against `background_color`, subject to being at least `min_contrast`. If
  134. // `color` isn't very saturated, grey will be used instead. Even if `color` is
  135. // saturated, if there are no sufficiently-contrasting colors of a matching hue,
  136. // will fall back to white/grey 900.
  137. GFX_EXPORT SkColor PickGoogleColor(SkColor color,
  138. SkColor background_color,
  139. float min_contrast);
  140. // Like the version above, but tries to contrast sufficiently with both
  141. // `background_color_a` and `background_color_b` simultaneously.
  142. GFX_EXPORT SkColor PickGoogleColor(SkColor color,
  143. SkColor background_color_a,
  144. SkColor background_color_b,
  145. float min_contrast);
  146. // Creates an rgba string for an SkColor. For example: 'rgba(255,0,255,0.5)'.
  147. GFX_EXPORT std::string SkColorToRgbaString(SkColor color);
  148. GFX_EXPORT std::string SkColor4fToRgbaString(SkColor4f color);
  149. // Creates an rgb string for an SkColor. For example: '255,0,255'.
  150. GFX_EXPORT std::string SkColorToRgbString(SkColor color);
  151. GFX_EXPORT std::string SkColor4fToRgbString(SkColor4f color);
  152. // Sets the darkest available color to |color|. Returns the previous darkest
  153. // color.
  154. GFX_EXPORT SkColor SetDarkestColorForTesting(SkColor color);
  155. // Returns the luminance of the darkest, midpoint, and lightest colors.
  156. GFX_EXPORT std::tuple<float, float, float> GetLuminancesForTesting();
  157. } // namespace color_utils
  158. #endif // UI_GFX_COLOR_UTILS_H_