blob: a415d2c63165e9bb4f925eca3f16fa9d0b50125f [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/color/color_transform.h"
#include "base/bind.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/color/color_mixer.h"
namespace ui {
ColorTransform::ColorTransform(Callback callback)
: callback_(std::move(callback)) {}
ColorTransform::ColorTransform(SkColor color) {
const auto generator = [](SkColor color, SkColor input_color,
const ColorMixer& mixer) { return color; };
callback_ = base::BindRepeating(generator, color);
}
ColorTransform::ColorTransform(ColorId id) {
DCHECK_COLOR_ID_VALID(id);
const auto generator = [](ColorId id, SkColor input_color,
const ColorMixer& mixer) {
return mixer.GetResultColor(id);
};
callback_ = base::BindRepeating(generator, id);
}
ColorTransform::ColorTransform(const ColorTransform&) = default;
ColorTransform& ColorTransform::operator=(const ColorTransform&) = default;
ColorTransform::~ColorTransform() = default;
SkColor ColorTransform::Run(SkColor input_color,
const ColorMixer& mixer) const {
return callback_.Run(input_color, mixer);
}
ColorTransform AlphaBlend(ColorTransform foreground_transform,
ColorTransform background_transform,
SkAlpha alpha) {
const auto generator = [](ColorTransform foreground_transform,
ColorTransform background_transform, SkAlpha alpha,
SkColor input_color, const ColorMixer& mixer) {
return color_utils::AlphaBlend(foreground_transform.Run(input_color, mixer),
background_transform.Run(input_color, mixer),
alpha);
};
return base::BindRepeating(generator, std::move(foreground_transform),
std::move(background_transform), alpha);
}
ColorTransform BlendForMinContrast(
ColorTransform foreground_transform,
ColorTransform background_transform,
base::Optional<ColorTransform> high_contrast_foreground_transform,
float contrast_ratio) {
const auto generator =
[](ColorTransform foreground_transform,
ColorTransform background_transform,
base::Optional<ColorTransform> high_contrast_foreground_transform,
float contrast_ratio, SkColor input_color, const ColorMixer& mixer) {
const SkColor foreground_color =
foreground_transform.Run(input_color, mixer);
const SkColor background_color =
background_transform.Run(input_color, mixer);
const base::Optional<SkColor> high_contrast_foreground =
high_contrast_foreground_transform.has_value()
? base::make_optional(
high_contrast_foreground_transform.value().Run(
input_color, mixer))
: base::nullopt;
return color_utils::BlendForMinContrast(
foreground_color, background_color, high_contrast_foreground,
contrast_ratio)
.color;
};
return base::BindRepeating(generator, std::move(foreground_transform),
std::move(background_transform),
std::move(high_contrast_foreground_transform),
contrast_ratio);
}
ColorTransform BlendForMinContrastWithSelf(ColorTransform transform,
float contrast_ratio) {
return BlendForMinContrast(transform, transform, base::nullopt,
contrast_ratio);
}
ColorTransform BlendTowardMaxContrast(ColorTransform transform, SkAlpha alpha) {
const auto generator = [](ColorTransform transform, SkAlpha alpha,
SkColor input_color, const ColorMixer& mixer) {
return color_utils::BlendTowardMaxContrast(
transform.Run(input_color, mixer), alpha);
};
return base::BindRepeating(generator, std::move(transform), alpha);
}
ColorTransform ContrastInvert(ColorTransform transform) {
const auto generator = [](ColorTransform transform, SkColor input_color,
const ColorMixer& mixer) {
const SkColor foreground = transform.Run(input_color, mixer);
const SkColor far_endpoint =
color_utils::GetColorWithMaxContrast(foreground);
const SkColor near_endpoint =
color_utils::GetEndpointColorWithMinContrast(foreground);
const float contrast_ratio =
color_utils::GetContrastRatio(foreground, far_endpoint);
return color_utils::BlendForMinContrast(foreground, near_endpoint,
base::nullopt, contrast_ratio)
.color;
};
return base::BindRepeating(generator, std::move(transform));
}
ColorTransform DeriveDefaultIconColor(ColorTransform transform) {
const auto generator = [](ColorTransform transform, SkColor input_color,
const ColorMixer& mixer) {
return color_utils::DeriveDefaultIconColor(
transform.Run(input_color, mixer));
};
return base::BindRepeating(generator, std::move(transform));
}
ColorTransform FromOriginalColorFromSet(ColorId id, ColorSetId set_id) {
DCHECK_COLOR_ID_VALID(id);
DCHECK_COLOR_SET_ID_VALID(set_id);
const auto generator = [](ColorId id, ColorSetId set_id, SkColor input_color,
const ColorMixer& mixer) {
return mixer.GetOriginalColorFromSet(id, set_id);
};
return base::BindRepeating(generator, id, set_id);
}
ColorTransform FromTransformInput() {
const auto generator = [](SkColor input_color, const ColorMixer& mixer) {
return input_color;
};
return base::BindRepeating(generator);
}
ColorTransform GetColorWithMaxContrast(ColorTransform transform) {
const auto generator = [](ColorTransform transform, SkColor input_color,
const ColorMixer& mixer) {
return color_utils::GetColorWithMaxContrast(
transform.Run(input_color, mixer));
};
return base::BindRepeating(generator, std::move(transform));
}
ColorTransform GetResultingPaintColor(ColorTransform foreground_transform,
ColorTransform background_transform) {
const auto generator = [](ColorTransform foreground_transform,
ColorTransform background_transform,
SkColor input_color, const ColorMixer& mixer) {
return color_utils::GetResultingPaintColor(
foreground_transform.Run(input_color, mixer),
background_transform.Run(input_color, mixer));
};
return base::BindRepeating(generator, std::move(foreground_transform),
std::move(background_transform));
}
ColorTransform SelectBasedOnDarkInput(
ColorTransform input_transform,
ColorTransform output_transform_for_dark_input,
ColorTransform output_transform_for_light_input) {
const auto generator = [](ColorTransform input_transform,
ColorTransform output_transform_for_dark_input,
ColorTransform output_transform_for_light_input,
SkColor input_color, const ColorMixer& mixer) {
const SkColor color = input_transform.Run(input_color, mixer);
const auto& output_transform = color_utils::IsDark(color)
? output_transform_for_dark_input
: output_transform_for_light_input;
return output_transform.Run(input_color, mixer);
};
return base::BindRepeating(generator, std::move(input_transform),
std::move(output_transform_for_dark_input),
std::move(output_transform_for_light_input));
}
ColorTransform SetAlpha(ColorTransform transform, SkAlpha alpha) {
const auto generator = [](ColorTransform transform, SkAlpha alpha,
SkColor input_color, const ColorMixer& mixer) {
return SkColorSetA(transform.Run(input_color, mixer), alpha);
};
return base::BindRepeating(generator, std::move(transform), alpha);
}
} // namespace ui