blob: f2fee16efbc4715ddce51ea9c5df8e2e24277dfd [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[kColorSysSurfaceNumberedForeground] = {kColorSysPrimary};
// General.
mixer[kColorSysOnSurfaceSecondary] = {dark_mode ? kColorRefSecondary80
: kColorRefSecondary30};
mixer[kColorSysTonalContainer] = {dark_mode ? kColorRefPrimary30
: kColorRefPrimary90};
mixer[kColorSysBaseTonalContainer] = {dark_mode ? kColorRefPrimary10
: 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[kColorSysStateInactiveRing] = {
dark_mode ? SetAlpha({kColorRefPrimary70}, 0x8C)
: SetAlpha({kColorRefPrimary20}, 0x8C)};
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[kColorSysOnSurfacePrimary] = {dark_mode ? kColorRefNeutral90
: kColorRefNeutral10};
mixer[kColorSysDivider] = {dark_mode ? kColorRefNeutral40
: kColorRefNeutral90};
// Chrome surfaces.
mixer[kColorSysHeader] = {dark_mode ? kColorRefNeutral12
: kColorRefNeutral90};
mixer[kColorSysHeaderInactive] = {
dark_mode ? AlphaBlend({kColorSysHeader}, {kColorRefNeutral25}, 0x99)
: AlphaBlend({kColorSysHeader}, {kColorRefNeutral98}, 0x48)};
mixer[kColorSysHeaderContainer] = {dark_mode ? kColorRefNeutral25
: kColorRefNeutral95};
mixer[kColorSysOnHeaderDivider] = {dark_mode ? kColorRefNeutral25
: kColorRefNeutral80};
mixer[kColorSysOnHeaderPrimary] = {dark_mode ? kColorRefNeutral80
: kColorRefNeutral40};
// States.
mixer[kColorSysStateInactiveRing] = {
dark_mode ? SetAlpha({kColorRefNeutral70}, 0x8C)
: SetAlpha({kColorRefNeutral20}, 0x8C)};
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();
// 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};
// 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};
// 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};
// Constant.
mixer[kColorSysBlack] = {kColorRefNeutral0};
mixer[kColorSysWhite] = {kColorRefNeutral100};
// Inverse.
mixer[kColorSysInversePrimary] = {dark_mode ? kColorRefPrimary40
: kColorRefPrimary80};
mixer[kColorSysInverseOnSurface] = {dark_mode ? kColorRefNeutral10
: kColorRefNeutral95};
mixer[kColorSysInverseSurface] = {dark_mode ? kColorRefNeutral90
: kColorRefNeutral20};
mixer[kColorSysInverseSurfacePrimary] = {dark_mode ? kColorRefPrimary95
: kColorRefPrimary20};
// Surfaces.
mixer[kColorSysSurface] = {dark_mode ? kColorRefNeutral10
: kColorRefNeutral100};
mixer[kColorSysSurfaceNumberedForeground] = {
dark_mode ? SkColorSetRGB(0xD1, 0xE1, 0xFF)
: SkColorSetRGB(0x69, 0x91, 0xD6)};
mixer[kColorSysSurface1] = AlphaBlend({kColorSysSurfaceNumberedForeground},
{kColorSysSurface}, 0x0C);
mixer[kColorSysSurface2] = AlphaBlend({kColorSysSurfaceNumberedForeground},
{kColorSysSurface}, 0x14);
mixer[kColorSysSurface3] = AlphaBlend({kColorSysSurfaceNumberedForeground},
{kColorSysSurface}, 0x1C);
mixer[kColorSysSurface4] = AlphaBlend({kColorSysSurfaceNumberedForeground},
{kColorSysSurface}, 0x1E);
mixer[kColorSysSurface5] = AlphaBlend({kColorSysSurfaceNumberedForeground},
{kColorSysSurface}, 0x23);
// 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[kColorSysBaseTonalContainer] = {dark_mode ? kColorRefSecondary10
: kColorRefPrimary90};
mixer[kColorSysOnBaseTonalContainer] = {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
? AlphaBlend({kColorSysHeader}, {kColorRefNeutral25}, 0x99)
: AlphaBlend({kColorSysHeader}, {kColorSysSurfaceVariant}, 0x48)};
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[kColorSysStateFocusRingInverse] = {dark_mode ? kColorRefPrimary40
: kColorRefPrimary80};
mixer[kColorSysStateTextHighlight] = {dark_mode ? kColorRefPrimary80
: kColorRefPrimary40};
mixer[kColorSysStateOnTextHighlight] = {dark_mode ? kColorRefNeutral0
: kColorRefNeutral100};
mixer[kColorSysStateFocusHighlight] = {
dark_mode ? SetAlpha({kColorRefNeutral99}, 0x1A)
: SetAlpha({kColorRefNeutral10}, 0x0F)};
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[kColorSysStateInactiveRing] = {
dark_mode ? SetAlpha({kColorRefNeutral70}, 0x8C)
: SetAlpha({kColorRefPrimary20}, 0x8C)};
mixer[kColorSysStateScrim] = {SetAlpha({kColorRefNeutral0}, 0x99)};
mixer[kColorSysStateOnHeaderHover] = {dark_mode ? kColorRefSecondary90
: kColorRefPrimary20};
mixer[kColorSysStateHeaderHover] = {dark_mode ? kColorRefSecondary30
: kColorRefPrimary80};
mixer[kColorSysStateHeaderHoverInactive] = {kColorSysStateHoverOnSubtle};
mixer[kColorSysStateHeaderSelect] = {SetAlpha({kColorSysBase}, 0x9A)};
// Effects.
mixer[kColorSysShadow] = {kColorRefNeutral0};
mixer[kColorSysGradientPrimary] = {dark_mode ? kColorRefPrimary30
: kColorRefPrimary90};
mixer[kColorSysGradientTertiary] = {dark_mode ? kColorRefTertiary30
: kColorRefTertiary95};
// Illustration.
mixer[kColorSysIlloPrimaryMin] = {dark_mode ? kColorRefPrimary30
: kColorRefPrimary90};
mixer[kColorSysIlloPrimaryLow] = {dark_mode ? kColorRefPrimary40
: kColorRefPrimary80};
mixer[kColorSysIlloPrimaryMid] = {dark_mode ? kColorRefPrimary50
: kColorRefPrimary70};
mixer[kColorSysIlloPrimaryHigh] = {dark_mode ? kColorRefPrimary70
: kColorRefPrimary60};
mixer[kColorSysIlloPrimaryMax] = {dark_mode ? kColorRefPrimary80
: kColorRefPrimary40};
mixer[kColorSysIlloSecondaryMin] = {dark_mode ? kColorRefSecondary30
: kColorRefSecondary90};
mixer[kColorSysIlloSecondaryLow] = {dark_mode ? kColorRefSecondary40
: kColorRefSecondary80};
mixer[kColorSysIlloSecondaryMid] = {dark_mode ? kColorRefSecondary50
: kColorRefSecondary70};
mixer[kColorSysIlloSecondaryHigh] = {dark_mode ? kColorRefSecondary70
: kColorRefSecondary60};
mixer[kColorSysIlloSecondaryMax] = {dark_mode ? kColorRefSecondary80
: kColorRefSecondary40};
mixer[kColorSysIlloTertiaryMin] = {dark_mode ? kColorRefTertiary30
: kColorRefTertiary90};
mixer[kColorSysIlloTertiaryLow] = {dark_mode ? kColorRefTertiary40
: kColorRefTertiary80};
mixer[kColorSysIlloTertiaryMid] = {dark_mode ? kColorRefTertiary50
: kColorRefTertiary70};
mixer[kColorSysIlloTertiaryHigh] = {dark_mode ? kColorRefTertiary70
: kColorRefTertiary60};
mixer[kColorSysIlloTertiaryMax] = {dark_mode ? kColorRefTertiary80
: kColorRefTertiary40};
mixer[kColorSysIlloNeutralMin] = {dark_mode ? kColorRefNeutral0
: kColorRefNeutral100};
mixer[kColorSysIlloNeutralLow] = {dark_mode ? kColorRefNeutral25
: kColorRefNeutral90};
mixer[kColorSysIlloNeutralMid] = {dark_mode ? kColorRefNeutral40
: kColorRefNeutral80};
mixer[kColorSysIlloNeutralHigh] = {dark_mode ? kColorRefNeutral60
: kColorRefNeutral50};
mixer[kColorSysIlloNeutralMax] = {dark_mode ? kColorRefNeutral100
: kColorRefNeutral0};
// ActorUi
mixer[kColorSysActorUiBorder] = {ui::kColorRefPrimary50};
mixer[kColorSysActorUiGradientStart] = {ui::kColorRefPrimary70};
mixer[kColorSysActorUiGradientMiddle] = {ui::kColorRefPrimary40};
mixer[kColorSysActorUiGradientEnd] = {ui::kColorRefPrimary60};
// Glic
mixer[kColorGlicTabUnderline1] = {ui::kColorRefPrimary50};
mixer[kColorGlicTabUnderline2] = {ui::kColorRefPrimary60};
mixer[kColorGlicTabUnderline3] = {ui::kColorRefPrimary70};
// 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.
// TODO(crbug.com/350783235): Remove remaining uses of these deprecated sys
// tokens.
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);
// 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