// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/style/color_util.h"
#include <algorithm>
#include "ash/public/cpp/wallpaper/wallpaper_types.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/wallpaper/wallpaper_controller_impl.h"
#include "chromeos/constants/chromeos_features.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/color_utils.h"
namespace ash {
namespace {
// Alpha value that is used to calculate themed color. Please see function
// GetBackgroundThemedColor() about how the themed color is calculated.
constexpr int kDarkBackgroundBlendKMeansAlpha = 165; // 65%
constexpr int kLightBackgroundBlendKMeansAlpha = 230; // 90%
// Clamp the lightness of input user colors so that there is sufficient contrast
// between shelf and wallpaper.
constexpr double kMaxLightnessLightMode = 0.7;
constexpr double kMinLightnessDarkMode = 0.3;
// The disabled color is always 38% opacity of the enabled color.
constexpr float kDisabledColorOpacity = 0.38f;
// Color of second tone is always 30% opacity of the color of first tone.
constexpr float kSecondToneOpacity = 0.3f;
SkColor ClampLightness(bool use_dark_color, SkColor color) {
color_utils::HSL hsl;
color_utils::SkColorToHSL(color, &hsl);
if (use_dark_color) {
hsl.l = std::clamp(hsl.l, kMinLightnessDarkMode, 1.0);
} else {
hsl.l = std::clamp(hsl.l, 0.0, kMaxLightnessLightMode);
}
return color_utils::HSLToSkColor(hsl, SkColorGetA(color));
}
} // namespace
// static
ui::ColorProviderSource* ColorUtil::GetColorProviderSourceForWindow(
const aura::Window* window) {
DCHECK(window);
auto* root_window = window->GetRootWindow();
if (!root_window)
return nullptr;
return RootWindowController::ForWindow(root_window)->color_provider_source();
}
// static
SkColor ColorUtil::AdjustKMeansColor(SkColor k_means_color,
bool use_dark_color) {
const SkColor clamped_k_means_color =
ClampLightness(use_dark_color, k_means_color);
const SkColor foreground_color =
use_dark_color ? SK_ColorBLACK : SK_ColorWHITE;
const int foreground_alpha = use_dark_color
? kDarkBackgroundBlendKMeansAlpha
: kLightBackgroundBlendKMeansAlpha;
// Put a slightly transparent screen of white/black on top of the user's
// wallpaper color.
return color_utils::GetResultingPaintColor(
SkColorSetA(foreground_color, foreground_alpha), clamped_k_means_color);
}
// static
SkColor ColorUtil::GetDisabledColor(SkColor enabled_color) {
return SkColorSetA(enabled_color, std::round(SkColorGetA(enabled_color) *
kDisabledColorOpacity));
}
// static
SkColor ColorUtil::GetSecondToneColor(SkColor color_of_first_tone) {
return SkColorSetA(
color_of_first_tone,
std::round(SkColorGetA(color_of_first_tone) * kSecondToneOpacity));
}
} // namespace ash