blob: 42a6ce8330997ac90464bda6829b02d0a332ea98 [file] [log] [blame]
// 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 "ui/color/sys_color_mixer.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/color/color_id.h"
#include "ui/color/color_mixer.h"
#include "ui/color/color_provider.h"
#include "ui/color/color_provider_key.h"
#include "ui/color/color_recipe.h"
#include "ui/color/color_transform.h"
namespace ui {
namespace {
// Sys token overrides for the non-baseline themed case.
void AddThemedSysColorOverrides(ColorMixer& mixer,
const ColorProviderKey& key) {
const bool dark_mode = key.color_mode == ColorProviderKey::ColorMode::kDark;
// Surfaces.
mixer[kColorSysSurface] = {dark_mode ? kColorRefNeutral10
: kColorRefNeutral99};
mixer[kColorSysSurface1] =
dark_mode ? GetResultingPaintColor(SetAlpha({kColorRefPrimary80}, 0x0C),
{kColorRefNeutral10})
: GetResultingPaintColor(SetAlpha({kColorRefPrimary40}, 0x0C),
{kColorRefNeutral99});
mixer[kColorSysSurface2] =
dark_mode ? GetResultingPaintColor(SetAlpha({kColorRefPrimary80}, 0x14),
{kColorRefNeutral10})
: GetResultingPaintColor(SetAlpha({kColorRefPrimary40}, 0x14),
{kColorRefNeutral99});
mixer[kColorSysSurface3] =
dark_mode ? GetResultingPaintColor(SetAlpha({kColorRefPrimary80}, 0x1C),
{kColorRefNeutral10})
: GetResultingPaintColor(SetAlpha({kColorRefPrimary40}, 0x1C),
{kColorRefNeutral99});
mixer[kColorSysSurface4] =
dark_mode ? GetResultingPaintColor(SetAlpha({kColorRefPrimary80}, 0x1E),
{kColorRefNeutral10})
: GetResultingPaintColor(SetAlpha({kColorRefPrimary40}, 0x1E),
{kColorRefNeutral99});
mixer[kColorSysSurface5] =
dark_mode ? GetResultingPaintColor(SetAlpha({kColorRefPrimary80}, 0x23),
{kColorRefNeutral10})
: GetResultingPaintColor(SetAlpha({kColorRefPrimary40}, 0x23),
{kColorRefNeutral99});
// General.
mixer[kColorSysOnSurfaceSecondary] = {dark_mode ? kColorRefSecondary80
: kColorRefSecondary30};
mixer[kColorSysTonalContainer] = {dark_mode ? kColorRefPrimary30
: kColorRefPrimary90};
mixer[kColorSysNeutralContainer] = {dark_mode ? kColorRefNeutralVariant15
: kColorRefNeutral94};
mixer[kColorSysDivider] = {dark_mode ? kColorRefSecondary35
: kColorRefPrimary90};
// Chrome surfaces.
mixer[kColorSysBase] = {dark_mode ? kColorRefSecondary25
: kColorRefNeutral98};
mixer[kColorSysBaseContainer] = {dark_mode ? kColorRefSecondary15
: kColorSysSurface4};
mixer[kColorSysBaseContainerElevated] = {dark_mode ? kColorRefSecondary25
: kColorRefNeutral98};
mixer[kColorSysHeader] = {dark_mode ? kColorRefSecondary12
: kColorRefSecondary90};
mixer[kColorSysHeaderContainer] = {dark_mode ? kColorRefSecondary25
: kColorRefPrimary95};
mixer[kColorSysHeaderContainerInactive] = {dark_mode ? kColorRefNeutral25
: kColorRefNeutral99};
mixer[kColorSysOnHeaderDivider] = {dark_mode ? kColorRefSecondary25
: kColorRefPrimary80};
// States.
mixer[kColorSysStateOnHeaderHover] = {dark_mode ? kColorRefPrimary90
: kColorRefPrimary20};
mixer[kColorSysStateHeaderHover] = {dark_mode ? kColorRefPrimary30
: kColorRefPrimary80};
// Experimentation.
mixer[kColorSysOmniboxContainer] = {dark_mode ? kColorRefSecondary15
: kColorSysSurface4};
}
// Overrides for the grayscale baseline case.
// TODO(tluk): This can probably be migrated to the kMonochrome SchemeVariant
// when available.
void AddGrayscaleSysColorOverrides(ColorMixer& mixer,
const ColorProviderKey& key) {
const bool dark_mode = key.color_mode == ColorProviderKey::ColorMode::kDark;
// General
mixer[kColorSysDivider] = {dark_mode ? kColorRefNeutral40
: kColorRefNeutral90};
// Chrome surfaces.
mixer[kColorSysHeader] = {dark_mode ? kColorRefNeutral12
: kColorRefNeutral90};
mixer[kColorSysHeaderInactive] = {
dark_mode ? GetResultingPaintColor(SetAlpha({kColorSysHeader}, 0x99),
{kColorRefNeutral25})
: GetResultingPaintColor(SetAlpha({kColorSysHeader}, 0x48),
{kColorRefNeutral98})};
mixer[kColorSysHeaderContainer] = {dark_mode ? kColorRefNeutral25
: kColorRefNeutral95};
mixer[kColorSysOnHeaderDivider] = {dark_mode ? kColorRefNeutral25
: kColorRefNeutral80};
mixer[kColorSysOnHeaderPrimary] = {dark_mode ? kColorRefNeutral80
: kColorRefNeutral40};
// States.
mixer[kColorSysStateOnHeaderHover] = {dark_mode ? kColorRefNeutral90
: kColorRefNeutral20};
mixer[kColorSysStateHeaderHover] = {dark_mode ? kColorRefNeutral30
: kColorRefNeutral80};
// Experimentation.
mixer[kColorSysOmniboxContainer] = {dark_mode ? kColorRefNeutral15
: kColorRefNeutral94};
}
} // namespace
void AddSysColorMixer(ColorProvider* provider, const ColorProviderKey& key) {
const bool dark_mode = key.color_mode == ColorProviderKey::ColorMode::kDark;
ColorMixer& mixer = provider->AddMixer();
// TODO(tluk): Current sys token recipes are still in flux. Audit and update
// existing definitions once the color spec is final.
// Primary.
mixer[kColorSysPrimary] = {dark_mode ? kColorRefPrimary80
: kColorRefPrimary40};
mixer[kColorSysOnPrimary] = {dark_mode ? kColorRefPrimary20
: kColorRefPrimary100};
mixer[kColorSysPrimaryContainer] = {dark_mode ? kColorRefPrimary30
: kColorRefPrimary90};
mixer[kColorSysOnPrimaryContainer] = {dark_mode ? kColorRefPrimary90
: kColorRefPrimary10};
mixer[kColorSysGradientPrimary] = {dark_mode ? kColorRefPrimary30
: kColorRefPrimary90};
// Secondary.
mixer[kColorSysSecondary] = {dark_mode ? kColorRefSecondary80
: kColorRefSecondary40};
mixer[kColorSysOnSecondary] = {dark_mode ? kColorRefSecondary20
: kColorRefSecondary100};
mixer[kColorSysSecondaryContainer] = {dark_mode ? kColorRefSecondary30
: kColorRefSecondary90};
mixer[kColorSysOnSecondaryContainer] = {dark_mode ? kColorRefSecondary90
: kColorRefSecondary10};
// Tertiary.
mixer[kColorSysTertiary] = {dark_mode ? kColorRefTertiary80
: kColorRefTertiary40};
mixer[kColorSysOnTertiary] = {dark_mode ? kColorRefTertiary20
: kColorRefTertiary100};
mixer[kColorSysTertiaryContainer] = {dark_mode ? kColorRefTertiary30
: kColorRefTertiary90};
mixer[kColorSysOnTertiaryContainer] = {dark_mode ? kColorRefTertiary90
: kColorRefTertiary10};
mixer[kColorSysGradientTertiary] = {dark_mode ? kColorRefTertiary30
: kColorRefTertiary95};
// Error.
mixer[kColorSysError] = {dark_mode ? kColorRefError80 : kColorRefError40};
mixer[kColorSysOnError] = {dark_mode ? kColorRefError20 : kColorRefError100};
mixer[kColorSysErrorContainer] = {dark_mode ? kColorRefError30
: kColorRefError90};
mixer[kColorSysOnErrorContainer] = {dark_mode ? kColorRefError90
: kColorRefError10};
// Neutral.
mixer[kColorSysOnSurface] = {dark_mode ? kColorRefNeutral90
: kColorRefNeutral10};
mixer[kColorSysOnSurfaceVariant] = {dark_mode ? kColorRefNeutralVariant80
: kColorRefNeutralVariant30};
mixer[kColorSysOutline] = {dark_mode ? kColorRefNeutralVariant60
: kColorRefNeutralVariant50};
mixer[kColorSysSurfaceVariant] = {dark_mode ? kColorRefNeutralVariant30
: kColorRefNeutralVariant90};
// Inverse.
mixer[kColorSysBlack] = {kColorRefNeutral0};
mixer[kColorSysWhite] = {kColorRefNeutral100};
// Inverse.
mixer[kColorSysInversePrimary] = {dark_mode ? kColorRefPrimary40
: kColorRefPrimary80};
mixer[kColorSysInverseSurface] = {dark_mode ? kColorRefNeutral90
: kColorRefNeutral20};
mixer[kColorSysInverseOnSurface] = {dark_mode ? kColorRefNeutral10
: kColorRefNeutral95};
// Surfaces.
mixer[kColorSysSurface] = {dark_mode ? kColorRefNeutral10
: kColorRefNeutral100};
mixer[kColorSysSurface1] =
dark_mode ? GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0xD1, 0xE1, 0xFF)}, 0x0C),
{kColorRefNeutral10})
: GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0x69, 0x91, 0xD6)}, 0x0C),
{kColorRefNeutral99});
mixer[kColorSysSurface2] =
dark_mode ? GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0xD1, 0xE1, 0xFF)}, 0x14),
{kColorRefNeutral10})
: GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0x69, 0x91, 0xD6)}, 0x14),
{kColorRefNeutral99});
mixer[kColorSysSurface3] =
dark_mode ? GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0xD1, 0xE1, 0xFF)}, 0x1C),
{kColorRefNeutral10})
: GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0x69, 0x91, 0xD6)}, 0x1C),
{kColorRefNeutral99});
mixer[kColorSysSurface4] =
dark_mode ? GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0xD1, 0xE1, 0xFF)}, 0x1E),
{kColorRefNeutral10})
: GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0x69, 0x91, 0xD6)}, 0x1E),
{kColorRefNeutral99});
mixer[kColorSysSurface5] =
dark_mode ? GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0xD1, 0xE1, 0xFF)}, 0x23),
{kColorRefNeutral10})
: GetResultingPaintColor(
SetAlpha({SkColorSetRGB(0x69, 0x91, 0xD6)}, 0x23),
{kColorRefNeutral99});
// General.
mixer[kColorSysOnSurfaceSecondary] = {dark_mode ? kColorRefNeutral80
: kColorRefNeutral30};
mixer[kColorSysOnSurfaceSubtle] = {dark_mode ? kColorRefNeutral80
: kColorRefNeutral30};
mixer[kColorSysOnSurfacePrimary] = {dark_mode ? kColorRefPrimary90
: kColorRefPrimary10};
mixer[kColorSysOnSurfacePrimaryInactive] = {dark_mode ? kColorRefNeutral90
: kColorRefNeutral10};
mixer[kColorSysTonalContainer] = {dark_mode ? kColorRefSecondary30
: kColorRefPrimary90};
mixer[kColorSysOnTonalContainer] = {dark_mode ? kColorRefSecondary90
: kColorRefPrimary10};
mixer[kColorSysTonalOutline] = {dark_mode ? kColorRefSecondary50
: kColorRefPrimary80};
mixer[kColorSysNeutralOutline] = {dark_mode ? kColorRefNeutral50
: kColorRefNeutral80};
mixer[kColorSysNeutralContainer] = {dark_mode ? kColorRefNeutral15
: kColorRefNeutral95};
mixer[kColorSysDivider] = {dark_mode ? kColorRefNeutral40
: kColorRefPrimary90};
// Chrome surfaces.
mixer[kColorSysBase] = {dark_mode ? kColorRefNeutral25 : kColorRefNeutral100};
mixer[kColorSysBaseContainer] = {dark_mode ? kColorRefNeutral15
: kColorSysSurface4};
mixer[kColorSysBaseContainerElevated] = {dark_mode ? kColorRefNeutral25
: kColorRefNeutral100};
mixer[kColorSysHeader] = {dark_mode ? kColorRefNeutral12
: kColorRefPrimary90};
mixer[kColorSysHeaderInactive] = {
dark_mode ? GetResultingPaintColor(SetAlpha({kColorSysHeader}, 0x99),
{kColorRefNeutral25})
: GetResultingPaintColor(SetAlpha({kColorSysHeader}, 0x48),
{kColorSysSurfaceVariant})};
mixer[kColorSysHeaderContainer] = {dark_mode ? kColorRefNeutral25
: kColorRefPrimary95};
mixer[kColorSysHeaderContainerInactive] = {dark_mode ? kColorRefNeutral25
: kColorRefNeutral100};
mixer[kColorSysOnHeaderDivider] = {dark_mode ? kColorRefNeutral25
: kColorRefPrimary80};
mixer[kColorSysOnHeaderDividerInactive] = {dark_mode ? kColorRefNeutral25
: kColorRefNeutral80};
mixer[kColorSysOnHeaderPrimary] = {dark_mode ? kColorRefPrimary80
: kColorRefPrimary40};
mixer[kColorSysOnHeaderPrimaryInactive] = {dark_mode ? kColorRefNeutral80
: kColorRefNeutral40};
// States.
mixer[kColorSysStateHoverOnProminent] = {
dark_mode ? SetAlpha({kColorRefNeutral10}, 0x0F)
: SetAlpha({kColorRefNeutral99}, 0x1A)};
mixer[kColorSysStateHoverOnSubtle] = {
dark_mode ? SetAlpha({kColorRefNeutral99}, 0x1A)
: SetAlpha({kColorRefNeutral10}, 0x0F)};
mixer[kColorSysStateRippleNeutralOnProminent] = {
dark_mode ? SetAlpha({kColorRefNeutral10}, 0x1F)
: SetAlpha({kColorRefNeutral99}, 0x29)};
mixer[kColorSysStateRippleNeutralOnSubtle] = {
dark_mode ? SetAlpha({kColorRefNeutral99}, 0x29)
: SetAlpha({kColorRefNeutral10}, 0x14)};
mixer[kColorSysStateRipplePrimary] = {
dark_mode ? SetAlpha({kColorRefPrimary60}, 0x52)
: SetAlpha({kColorRefPrimary70}, 0x52)};
mixer[kColorSysStateFocusRing] = {dark_mode ? kColorRefPrimary80
: kColorRefPrimary40};
mixer[kColorSysStateFocusHighlight] = {
dark_mode ? SetAlpha({kColorRefNeutral99}, 0x1A)
: SetAlpha({kColorRefNeutral10}, 0x0F)};
mixer[kColorSysStateTextHighlight] = {dark_mode ? kColorRefPrimary80
: kColorRefPrimary40};
mixer[kColorSysStateOnTextHighlight] = {dark_mode ? kColorRefNeutral0
: kColorRefNeutral100};
mixer[kColorSysStateDisabled] = dark_mode
? SetAlpha({kColorRefNeutral90}, 0x60)
: SetAlpha({kColorRefNeutral10}, 0x60);
mixer[kColorSysStateDisabledContainer] =
dark_mode ? SetAlpha({kColorRefNeutral90}, 0x1E)
: SetAlpha({kColorRefNeutral10}, 0x1E);
mixer[kColorSysStateHoverDimBlendProtection] = {
dark_mode ? SetAlpha({kColorRefNeutral99}, 0x1A)
: SetAlpha({kColorRefPrimary20}, 0x2E)};
mixer[kColorSysStateHoverBrightBlendProtection] = {
dark_mode ? SetAlpha({kColorRefNeutral99}, 0x29)
: SetAlpha({kColorRefNeutral10}, 0x0F)};
mixer[kColorSysStateOnHeaderHover] = {dark_mode ? kColorRefSecondary90
: kColorRefPrimary20};
mixer[kColorSysStateHeaderHover] = {dark_mode ? kColorRefSecondary30
: kColorRefPrimary80};
mixer[kColorSysStateHeaderHoverInactive] = {kColorSysStateHoverOnSubtle};
mixer[kColorSysStateHeaderSelect] = {SetAlpha({kColorSysBase}, 0x9A)};
// Effects.
mixer[kColorSysShadow] = {kColorRefNeutral0};
// AI.
mixer[kColorSysAiIllustrationShapeSurface1] = {
dark_mode ? ui::kColorRefPrimary40 : ui::kColorRefPrimary70};
mixer[kColorSysAiIllustrationShapeSurface2] = {
dark_mode ? ui::kColorRefPrimary50 : ui::kColorRefPrimary95};
mixer[kColorSysAiIllustrationShapeSurfaceGradientStart] = {
dark_mode ? ui::kColorRefPrimary30 : ui::kColorRefSecondary90};
mixer[kColorSysAiIllustrationShapeSurfaceGradientEnd] = {
dark_mode ? ui::kColorRefPrimary40 : ui::kColorRefPrimary80};
// Experimentation.
mixer[kColorSysOmniboxContainer] = {dark_mode ? kColorRefNeutral15
: kColorSysSurface4};
// Deprecated.
mixer[kColorSysOnBase] = {dark_mode ? kColorRefNeutral90
: kColorRefNeutral10};
mixer[kColorSysOnBaseSecondary] = {dark_mode ? kColorRefNeutral80
: kColorRefNeutral30};
mixer[kColorSysOnBaseBorder] = {dark_mode ? kColorRefNeutral30
: kColorRefPrimary90};
mixer[kColorSysStateHover] = dark_mode ? SetAlpha({kColorRefNeutral90}, 0x14)
: SetAlpha({kColorRefNeutral10}, 0x14);
mixer[kColorSysStateFocus] = dark_mode ? SetAlpha({kColorRefNeutral90}, 0x1E)
: SetAlpha({kColorRefNeutral10}, 0x1E);
mixer[kColorSysStatePressed] = dark_mode
? SetAlpha({kColorRefNeutral90}, 0x1E)
: SetAlpha({kColorRefNeutral10}, 0x1E);
mixer[kColorSysStateDrag] = dark_mode ? SetAlpha({kColorRefNeutral90}, 0x29)
: SetAlpha({kColorRefNeutral10}, 0x29);
mixer[kColorSysStateHoverCutout] = {
dark_mode ? SetAlpha({kColorRefNeutral10}, 0x0F)
: SetAlpha({kColorRefNeutral20}, 0x1F)};
mixer[kColorSysStateHoverInverseCutout] = {
dark_mode ? SetAlpha({kColorRefNeutral10}, 0x29)
: SetAlpha({kColorRefNeutral10}, 0x0F)};
// If grayscale is specified the design intention is to apply the grayscale
// overrides over the baseline palette.
if (key.user_color_source == ColorProviderKey::UserColorSource::kGrayscale) {
AddGrayscaleSysColorOverrides(mixer, key);
} else if (key.user_color_source ==
ColorProviderKey::UserColorSource::kAccent &&
key.user_color.has_value()) {
AddThemedSysColorOverrides(mixer, key);
}
}
} // namespace ui