Add td_api::backgroundFillFreeformGradient.
This commit is contained in:
parent
9662679968
commit
bb957644cf
@ -2619,6 +2619,9 @@ backgroundFillSolid color:int32 = BackgroundFill;
|
||||
//@rotation_angle Clockwise rotation angle of the gradient, in degrees; 0-359. Should be always divisible by 45
|
||||
backgroundFillGradient top_color:int32 bottom_color:int32 rotation_angle:int32 = BackgroundFill;
|
||||
|
||||
//@description Describes a freeform gradient fill of a background @colors A list of 3 or 4 colors of the freeform gradients in the RGB24 format
|
||||
backgroundFillFreeformGradient colors:vector<int32> = BackgroundFill;
|
||||
|
||||
|
||||
//@class BackgroundType @description Describes the type of a background
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "td/db/SqliteKeyValueAsync.h"
|
||||
|
||||
#include "td/utils/algorithm.h"
|
||||
#include "td/utils/base64.h"
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/format.h"
|
||||
@ -393,7 +394,7 @@ void BackgroundManager::reload_background(BackgroundId background_id, int64 acce
|
||||
}
|
||||
|
||||
static bool is_background_name_local(Slice name) {
|
||||
return name.size() <= 6 || name.find('?') <= 13u;
|
||||
return name.size() <= 13u || name.find('?') <= 13u || !is_base64url_characters(name.substr(0, name.find('?')));
|
||||
}
|
||||
|
||||
BackgroundId BackgroundManager::search_background(const string &name, Promise<Unit> &&promise) {
|
||||
@ -409,49 +410,12 @@ BackgroundId BackgroundManager::search_background(const string &name, Promise<Un
|
||||
}
|
||||
|
||||
if (is_background_name_local(name)) {
|
||||
Slice fill_colors = name;
|
||||
Slice parameters;
|
||||
auto parameters_pos = fill_colors.find('?');
|
||||
if (parameters_pos != Slice::npos) {
|
||||
parameters = fill_colors.substr(parameters_pos + 1);
|
||||
fill_colors = fill_colors.substr(0, parameters_pos);
|
||||
auto r_fill = BackgroundFill::get_background_fill(name);
|
||||
if (r_fill.is_error()) {
|
||||
promise.set_error(r_fill.move_as_error());
|
||||
return BackgroundId();
|
||||
}
|
||||
CHECK(fill_colors.size() <= 13u);
|
||||
|
||||
bool have_hyphen = false;
|
||||
size_t hyphen_pos = 0;
|
||||
for (size_t i = 0; i < fill_colors.size(); i++) {
|
||||
auto c = fill_colors[i];
|
||||
if (!is_hex_digit(c)) {
|
||||
if (c != '-' || have_hyphen || i > 6 || i + 7 < fill_colors.size()) {
|
||||
promise.set_error(Status::Error(400, "WALLPAPER_INVALID"));
|
||||
return BackgroundId();
|
||||
}
|
||||
have_hyphen = true;
|
||||
hyphen_pos = i;
|
||||
}
|
||||
}
|
||||
|
||||
BackgroundFill fill;
|
||||
if (have_hyphen) {
|
||||
int32 top_color = static_cast<int32>(hex_to_integer<uint32>(fill_colors.substr(0, hyphen_pos)));
|
||||
int32 bottom_color = static_cast<int32>(hex_to_integer<uint32>(fill_colors.substr(hyphen_pos + 1)));
|
||||
int32 rotation_angle = 0;
|
||||
|
||||
Slice prefix("rotation=");
|
||||
if (begins_with(parameters, prefix)) {
|
||||
rotation_angle = to_integer<int32>(parameters.substr(prefix.size()));
|
||||
if (!BackgroundFill::is_valid_rotation_angle(rotation_angle)) {
|
||||
rotation_angle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fill = BackgroundFill(top_color, bottom_color, rotation_angle);
|
||||
} else {
|
||||
int32 color = static_cast<int32>(hex_to_integer<uint32>(fill_colors));
|
||||
fill = BackgroundFill(color);
|
||||
}
|
||||
auto background_id = add_fill_background(fill);
|
||||
auto background_id = add_fill_background(r_fill.ok());
|
||||
promise.set_value(Unit());
|
||||
return background_id;
|
||||
}
|
||||
@ -538,7 +502,7 @@ Result<FileId> BackgroundManager::prepare_input_file(const tl_object_ptr<td_api:
|
||||
}
|
||||
|
||||
BackgroundId BackgroundManager::add_fill_background(const BackgroundFill &fill) {
|
||||
return add_fill_background(fill, false, (fill.top_color & 0x808080) == 0 && (fill.bottom_color & 0x808080) == 0);
|
||||
return add_fill_background(fill, false, fill.is_dark());
|
||||
}
|
||||
|
||||
BackgroundId BackgroundManager::add_fill_background(const BackgroundFill &fill, bool is_default, bool is_dark) {
|
||||
@ -933,16 +897,10 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
|
||||
return BackgroundId();
|
||||
}
|
||||
|
||||
bool has_color = (settings->flags_ & telegram_api::wallPaperSettings::BACKGROUND_COLOR_MASK) != 0;
|
||||
auto color = has_color ? settings->background_color_ : 0;
|
||||
auto is_default = (wallpaper->flags_ & telegram_api::wallPaperNoFile::DEFAULT_MASK) != 0;
|
||||
auto is_dark = (wallpaper->flags_ & telegram_api::wallPaperNoFile::DARK_MASK) != 0;
|
||||
|
||||
BackgroundFill fill = BackgroundFill(color);
|
||||
if ((settings->flags_ & telegram_api::wallPaperSettings::SECOND_BACKGROUND_COLOR_MASK) != 0) {
|
||||
fill = BackgroundFill(color, settings->second_background_color_, settings->rotation_);
|
||||
}
|
||||
return add_fill_background(fill, is_default, is_dark);
|
||||
return add_fill_background(BackgroundFill(settings.get()), is_default, is_dark);
|
||||
}
|
||||
|
||||
auto wallpaper = move_tl_object_as<telegram_api::wallPaper>(wallpaper_ptr);
|
||||
@ -994,8 +952,9 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
|
||||
name_to_background_id_.emplace(expected_background_name, id);
|
||||
}
|
||||
|
||||
if (G()->parameters().use_file_db && !is_background_name_local(background.name)) {
|
||||
if (G()->parameters().use_file_db) {
|
||||
LOG(INFO) << "Save " << id << " to database with name " << background.name;
|
||||
CHECK(!is_background_name_local(background.name));
|
||||
G()->td_db()->get_sqlite_pmc()->set(get_background_name_database_key(background.name),
|
||||
log_event_store(background).as_slice().str(), Auto());
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "td/telegram/BackgroundType.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
@ -15,7 +16,7 @@ namespace td {
|
||||
static string get_color_hex_string(int32 color) {
|
||||
string result;
|
||||
for (int i = 20; i >= 0; i -= 4) {
|
||||
result += "0123456789abcdef"[(color >> i) & 0xf];
|
||||
result += "0123456789abcdef"[(color >> i) & 0xF];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -24,6 +25,57 @@ static bool is_valid_color(int32 color) {
|
||||
return 0 <= color && color <= 0xFFFFFF;
|
||||
}
|
||||
|
||||
static bool is_valid_rotation_angle(int32 rotation_angle) {
|
||||
return 0 <= rotation_angle && rotation_angle < 360 && rotation_angle % 45 == 0;
|
||||
}
|
||||
|
||||
BackgroundFill::BackgroundFill(const telegram_api::wallPaperSettings *settings) {
|
||||
if (settings == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto flags = settings->flags_;
|
||||
if ((flags & telegram_api::wallPaperSettings::BACKGROUND_COLOR_MASK) != 0) {
|
||||
top_color = settings->background_color_;
|
||||
if (!is_valid_color(top_color)) {
|
||||
LOG(ERROR) << "Receive " << to_string(*settings);
|
||||
top_color = 0;
|
||||
}
|
||||
}
|
||||
if ((flags & telegram_api::wallPaperSettings::FOURTH_BACKGROUND_COLOR_MASK) != 0 ||
|
||||
(flags & telegram_api::wallPaperSettings::THIRD_BACKGROUND_COLOR_MASK) != 0) {
|
||||
bottom_color = settings->second_background_color_;
|
||||
if (!is_valid_color(bottom_color)) {
|
||||
LOG(ERROR) << "Receive " << to_string(*settings);
|
||||
bottom_color = 0;
|
||||
}
|
||||
third_color = settings->third_background_color_;
|
||||
if (!is_valid_color(third_color)) {
|
||||
LOG(ERROR) << "Receive " << to_string(*settings);
|
||||
third_color = 0;
|
||||
}
|
||||
if ((flags & telegram_api::wallPaperSettings::FOURTH_BACKGROUND_COLOR_MASK) != 0) {
|
||||
fourth_color = settings->fourth_background_color_;
|
||||
if (!is_valid_color(fourth_color)) {
|
||||
LOG(ERROR) << "Receive " << to_string(*settings);
|
||||
fourth_color = 0;
|
||||
}
|
||||
}
|
||||
} else if ((flags & telegram_api::wallPaperSettings::SECOND_BACKGROUND_COLOR_MASK) != 0) {
|
||||
bottom_color = settings->second_background_color_;
|
||||
if (!is_valid_color(bottom_color)) {
|
||||
LOG(ERROR) << "Receive " << to_string(*settings);
|
||||
bottom_color = 0;
|
||||
}
|
||||
|
||||
rotation_angle = settings->rotation_;
|
||||
if (!is_valid_rotation_angle(rotation_angle)) {
|
||||
LOG(ERROR) << "Receive " << to_string(*settings);
|
||||
rotation_angle = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Result<BackgroundFill> get_background_fill(const td_api::BackgroundFill *fill) {
|
||||
if (fill == nullptr) {
|
||||
return Status::Error(400, "Background fill info must be non-empty");
|
||||
@ -44,17 +96,85 @@ static Result<BackgroundFill> get_background_fill(const td_api::BackgroundFill *
|
||||
if (!is_valid_color(gradient->bottom_color_)) {
|
||||
return Status::Error(400, "Invalid bottom gradient color value");
|
||||
}
|
||||
if (!BackgroundFill::is_valid_rotation_angle(gradient->rotation_angle_)) {
|
||||
if (!is_valid_rotation_angle(gradient->rotation_angle_)) {
|
||||
return Status::Error(400, "Invalid rotation angle value");
|
||||
}
|
||||
return BackgroundFill(gradient->top_color_, gradient->bottom_color_, gradient->rotation_angle_);
|
||||
}
|
||||
case td_api::backgroundFillFreeformGradient::ID: {
|
||||
auto freeform = static_cast<const td_api::backgroundFillFreeformGradient *>(fill);
|
||||
if (freeform->colors_.size() != 3 && freeform->colors_.size() != 4) {
|
||||
return Status::Error(400, "Wrong number of gradient colors");
|
||||
}
|
||||
for (auto &color : freeform->colors_) {
|
||||
if (!is_valid_color(color)) {
|
||||
return Status::Error(400, "Invalid freeform gradient color value");
|
||||
}
|
||||
}
|
||||
return BackgroundFill(freeform->colors_[0], freeform->colors_[1], freeform->colors_[2],
|
||||
freeform->colors_.size() == 3 ? -1 : freeform->colors_[3]);
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
Result<BackgroundFill> BackgroundFill::get_background_fill(Slice name) {
|
||||
name = name.substr(0, name.find('#'));
|
||||
|
||||
Slice parameters;
|
||||
auto parameters_pos = name.find('?');
|
||||
if (parameters_pos != Slice::npos) {
|
||||
parameters = name.substr(parameters_pos + 1);
|
||||
name = name.substr(0, parameters_pos);
|
||||
}
|
||||
|
||||
auto get_color = [](Slice color_string) -> Result<int32> {
|
||||
auto r_color = hex_to_integer_safe<uint32>(color_string);
|
||||
if (r_color.is_error() || color_string.size() > 6) {
|
||||
return Status::Error(400, "WALLPAPER_INVALID");
|
||||
}
|
||||
return static_cast<int32>(r_color.ok());
|
||||
};
|
||||
|
||||
if (name.find('~') < name.size()) {
|
||||
vector<Slice> color_strings = full_split(name, '~');
|
||||
if (color_strings.size() != 4 && color_strings.size() != 3) {
|
||||
return Status::Error(400, "WALLPAPER_INVALID");
|
||||
}
|
||||
|
||||
TRY_RESULT(first_color, get_color(color_strings[0]));
|
||||
TRY_RESULT(second_color, get_color(color_strings[1]));
|
||||
TRY_RESULT(third_color, get_color(color_strings[2]));
|
||||
int32 fourth_color = -1;
|
||||
if (color_strings.size() == 4) {
|
||||
TRY_RESULT_ASSIGN(fourth_color, get_color(color_strings[3]));
|
||||
}
|
||||
return BackgroundFill(first_color, second_color, third_color, fourth_color);
|
||||
}
|
||||
|
||||
size_t hyphen_pos = name.find('-');
|
||||
if (hyphen_pos < name.size()) {
|
||||
TRY_RESULT(top_color, get_color(name.substr(0, hyphen_pos)));
|
||||
TRY_RESULT(bottom_color, get_color(name.substr(hyphen_pos + 1)));
|
||||
int32 rotation_angle = 0;
|
||||
|
||||
Slice prefix("rotation=");
|
||||
if (begins_with(parameters, prefix)) {
|
||||
rotation_angle = to_integer<int32>(parameters.substr(prefix.size()));
|
||||
if (!is_valid_rotation_angle(rotation_angle)) {
|
||||
rotation_angle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return BackgroundFill(top_color, bottom_color, rotation_angle);
|
||||
}
|
||||
|
||||
TRY_RESULT(color, get_color(name));
|
||||
return BackgroundFill(color);
|
||||
}
|
||||
|
||||
static string get_background_fill_color_hex_string(const BackgroundFill &fill, bool is_first) {
|
||||
switch (fill.get_type()) {
|
||||
case BackgroundFill::Type::Solid:
|
||||
@ -67,6 +187,15 @@ static string get_background_fill_color_hex_string(const BackgroundFill &fill, b
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
case BackgroundFill::Type::FreeformGradient: {
|
||||
SliceBuilder sb;
|
||||
sb << get_color_hex_string(fill.top_color) << '~' << get_color_hex_string(fill.bottom_color) << '~'
|
||||
<< get_color_hex_string(fill.third_color);
|
||||
if (fill.fourth_color != -1) {
|
||||
sb << '~' << get_color_hex_string(fill.fourth_color);
|
||||
}
|
||||
return sb.as_cslice().str();
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return string();
|
||||
@ -80,13 +209,38 @@ static bool is_valid_intensity(int32 intensity) {
|
||||
int64 BackgroundFill::get_id() const {
|
||||
CHECK(is_valid_color(top_color));
|
||||
CHECK(is_valid_color(bottom_color));
|
||||
CHECK(is_valid_rotation_angle(rotation_angle));
|
||||
switch (get_type()) {
|
||||
case Type::Solid:
|
||||
return static_cast<int64>(top_color) + 1;
|
||||
case Type::Gradient:
|
||||
CHECK(is_valid_rotation_angle(rotation_angle));
|
||||
return (rotation_angle / 45) * 0x1000001000001 + (static_cast<int64>(top_color) << 24) + bottom_color +
|
||||
(1 << 24) + 1;
|
||||
case Type::FreeformGradient: {
|
||||
CHECK(is_valid_color(third_color));
|
||||
CHECK(fourth_color == -1 || is_valid_color(fourth_color));
|
||||
const uint64 mul = 123456789;
|
||||
uint64 result = static_cast<uint64>(top_color);
|
||||
result = result * mul + static_cast<uint64>(bottom_color);
|
||||
result = result * mul + static_cast<uint64>(third_color);
|
||||
result = result * mul + static_cast<uint64>(fourth_color);
|
||||
return 0x8000008000008 + static_cast<int64>(result % 0x8000008000008);
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool BackgroundFill::is_dark() const {
|
||||
switch (get_type()) {
|
||||
case Type::Solid:
|
||||
return (top_color & 0x808080) == 0;
|
||||
case Type::Gradient:
|
||||
return (top_color & 0x808080) == 0 && (bottom_color & 0x808080) == 0;
|
||||
case Type::FreeformGradient:
|
||||
return (top_color & 0x808080) == 0 && (bottom_color & 0x808080) == 0 && (third_color & 0x808080) == 0 &&
|
||||
(fourth_color == -1 || (fourth_color & 0x808080) == 0);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
@ -94,12 +248,13 @@ int64 BackgroundFill::get_id() const {
|
||||
}
|
||||
|
||||
bool BackgroundFill::is_valid_id(int64 id) {
|
||||
return 0 < id && id < 0x8000008000008;
|
||||
return 0 < id && id < 0x8000008000008 * 2;
|
||||
}
|
||||
|
||||
bool operator==(const BackgroundFill &lhs, const BackgroundFill &rhs) {
|
||||
return lhs.top_color == rhs.top_color && lhs.bottom_color == rhs.bottom_color &&
|
||||
lhs.rotation_angle == rhs.rotation_angle;
|
||||
lhs.rotation_angle == rhs.rotation_angle && lhs.third_color == rhs.third_color &&
|
||||
lhs.fourth_color == rhs.fourth_color;
|
||||
}
|
||||
|
||||
string BackgroundType::get_link() const {
|
||||
@ -198,39 +353,13 @@ BackgroundType get_background_type(bool is_pattern,
|
||||
telegram_api::object_ptr<telegram_api::wallPaperSettings> settings) {
|
||||
bool is_blurred = false;
|
||||
bool is_moving = false;
|
||||
BackgroundFill fill;
|
||||
BackgroundFill fill(settings.get());
|
||||
int32 intensity = 0;
|
||||
if (settings) {
|
||||
auto flags = settings->flags_;
|
||||
is_blurred = (flags & telegram_api::wallPaperSettings::BLUR_MASK) != 0;
|
||||
is_moving = (flags & telegram_api::wallPaperSettings::MOTION_MASK) != 0;
|
||||
|
||||
int32 color = 0;
|
||||
if ((flags & telegram_api::wallPaperSettings::BACKGROUND_COLOR_MASK) != 0) {
|
||||
color = settings->background_color_;
|
||||
if (!is_valid_color(color)) {
|
||||
LOG(ERROR) << "Receive " << to_string(settings);
|
||||
color = 0;
|
||||
}
|
||||
}
|
||||
if ((flags & telegram_api::wallPaperSettings::SECOND_BACKGROUND_COLOR_MASK) != 0) {
|
||||
int32 second_color = settings->second_background_color_;
|
||||
if (!is_valid_color(second_color)) {
|
||||
LOG(ERROR) << "Receive " << to_string(settings);
|
||||
second_color = 0;
|
||||
}
|
||||
|
||||
int32 rotation_angle = settings->rotation_;
|
||||
if (!BackgroundFill::is_valid_rotation_angle(rotation_angle)) {
|
||||
LOG(ERROR) << "Receive " << to_string(settings);
|
||||
rotation_angle = 0;
|
||||
}
|
||||
|
||||
fill = BackgroundFill(color, second_color, rotation_angle);
|
||||
} else {
|
||||
fill = BackgroundFill(color);
|
||||
}
|
||||
|
||||
if ((flags & telegram_api::wallPaperSettings::INTENSITY_MASK) != 0) {
|
||||
intensity = settings->intensity_;
|
||||
if (!is_valid_intensity(intensity)) {
|
||||
@ -253,6 +382,13 @@ static td_api::object_ptr<td_api::BackgroundFill> get_background_fill_object(con
|
||||
case BackgroundFill::Type::Gradient:
|
||||
return td_api::make_object<td_api::backgroundFillGradient>(fill.top_color, fill.bottom_color,
|
||||
fill.rotation_angle);
|
||||
case BackgroundFill::Type::FreeformGradient: {
|
||||
vector<int32> colors{fill.top_color, fill.bottom_color, fill.third_color, fill.fourth_color};
|
||||
if (colors.back() == -1) {
|
||||
colors.pop_back();
|
||||
}
|
||||
return td_api::make_object<td_api::backgroundFillFreeformGradient>(std::move(colors));
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
@ -285,6 +421,12 @@ telegram_api::object_ptr<telegram_api::wallPaperSettings> get_input_wallpaper_se
|
||||
flags |= telegram_api::wallPaperSettings::MOTION_MASK;
|
||||
}
|
||||
switch (type.fill.get_type()) {
|
||||
case BackgroundFill::Type::FreeformGradient:
|
||||
if (type.fill.fourth_color != -1) {
|
||||
flags |= telegram_api::wallPaperSettings::FOURTH_BACKGROUND_COLOR_MASK;
|
||||
}
|
||||
flags |= telegram_api::wallPaperSettings::THIRD_BACKGROUND_COLOR_MASK;
|
||||
// fallthrough
|
||||
case BackgroundFill::Type::Gradient:
|
||||
flags |= telegram_api::wallPaperSettings::SECOND_BACKGROUND_COLOR_MASK;
|
||||
// fallthrough
|
||||
@ -297,9 +439,9 @@ telegram_api::object_ptr<telegram_api::wallPaperSettings> get_input_wallpaper_se
|
||||
if (type.intensity != 0) {
|
||||
flags |= telegram_api::wallPaperSettings::INTENSITY_MASK;
|
||||
}
|
||||
return telegram_api::make_object<telegram_api::wallPaperSettings>(flags, false /*ignored*/, false /*ignored*/,
|
||||
type.fill.top_color, type.fill.bottom_color, 0, 0,
|
||||
type.intensity, type.fill.rotation_angle);
|
||||
return telegram_api::make_object<telegram_api::wallPaperSettings>(
|
||||
flags, false /*ignored*/, false /*ignored*/, type.fill.top_color, type.fill.bottom_color, type.fill.third_color,
|
||||
type.fill.fourth_color, type.intensity, type.fill.rotation_angle);
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -19,6 +19,8 @@ struct BackgroundFill {
|
||||
int32 top_color = 0;
|
||||
int32 bottom_color = 0;
|
||||
int32 rotation_angle = 0;
|
||||
int32 third_color = -1;
|
||||
int32 fourth_color = -1;
|
||||
|
||||
BackgroundFill() = default;
|
||||
explicit BackgroundFill(int32 solid_color) : top_color(solid_color), bottom_color(solid_color) {
|
||||
@ -26,9 +28,19 @@ struct BackgroundFill {
|
||||
BackgroundFill(int32 top_color, int32 bottom_color, int32 rotation_angle)
|
||||
: top_color(top_color), bottom_color(bottom_color), rotation_angle(rotation_angle) {
|
||||
}
|
||||
BackgroundFill(int32 first_color, int32 second_color, int32 third_color, int32 fourth_color)
|
||||
: top_color(first_color), bottom_color(second_color), third_color(third_color), fourth_color(fourth_color) {
|
||||
}
|
||||
|
||||
enum class Type : int32 { Solid, Gradient };
|
||||
explicit BackgroundFill(const telegram_api::wallPaperSettings *settings);
|
||||
|
||||
static Result<BackgroundFill> get_background_fill(Slice name);
|
||||
|
||||
enum class Type : int32 { Solid, Gradient, FreeformGradient };
|
||||
Type get_type() const {
|
||||
if (third_color != -1) {
|
||||
return Type::FreeformGradient;
|
||||
}
|
||||
if (top_color == bottom_color) {
|
||||
return Type::Solid;
|
||||
}
|
||||
@ -37,11 +49,9 @@ struct BackgroundFill {
|
||||
|
||||
int64 get_id() const;
|
||||
|
||||
static bool is_valid_id(int64 id);
|
||||
bool is_dark() const;
|
||||
|
||||
static bool is_valid_rotation_angle(int32 rotation_angle) {
|
||||
return 0 <= rotation_angle && rotation_angle < 360 && rotation_angle % 45 == 0;
|
||||
}
|
||||
static bool is_valid_id(int64 id);
|
||||
};
|
||||
|
||||
bool operator==(const BackgroundFill &lhs, const BackgroundFill &rhs);
|
||||
|
@ -18,15 +18,22 @@ void store(const BackgroundType &type, StorerT &storer) {
|
||||
bool has_intensity = type.intensity != 0;
|
||||
auto fill_type = type.fill.get_type();
|
||||
bool is_gradient = fill_type == BackgroundFill::Type::Gradient;
|
||||
bool is_freeform_gradient = fill_type == BackgroundFill::Type::FreeformGradient;
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(type.is_blurred);
|
||||
STORE_FLAG(type.is_moving);
|
||||
STORE_FLAG(has_fill);
|
||||
STORE_FLAG(has_intensity);
|
||||
STORE_FLAG(is_gradient);
|
||||
STORE_FLAG(is_freeform_gradient);
|
||||
END_STORE_FLAGS();
|
||||
store(type.type, storer);
|
||||
if (has_fill) {
|
||||
if (is_freeform_gradient) {
|
||||
store(type.fill.top_color, storer);
|
||||
store(type.fill.bottom_color, storer);
|
||||
store(type.fill.third_color, storer);
|
||||
store(type.fill.fourth_color, storer);
|
||||
} else if (has_fill) {
|
||||
store(type.fill.top_color, storer);
|
||||
if (is_gradient) {
|
||||
store(type.fill.bottom_color, storer);
|
||||
@ -43,15 +50,22 @@ void parse(BackgroundType &type, ParserT &parser) {
|
||||
bool has_fill;
|
||||
bool has_intensity;
|
||||
bool is_gradient;
|
||||
bool is_freeform_gradient;
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(type.is_blurred);
|
||||
PARSE_FLAG(type.is_moving);
|
||||
PARSE_FLAG(has_fill);
|
||||
PARSE_FLAG(has_intensity);
|
||||
PARSE_FLAG(is_gradient);
|
||||
PARSE_FLAG(is_freeform_gradient);
|
||||
END_PARSE_FLAGS();
|
||||
parse(type.type, parser);
|
||||
if (has_fill) {
|
||||
if (is_freeform_gradient) {
|
||||
parse(type.fill.top_color, parser);
|
||||
parse(type.fill.bottom_color, parser);
|
||||
parse(type.fill.third_color, parser);
|
||||
parse(type.fill.fourth_color, parser);
|
||||
} else if (has_fill) {
|
||||
parse(type.fill.top_color, parser);
|
||||
if (is_gradient) {
|
||||
parse(type.fill.bottom_color, parser);
|
||||
|
@ -1535,6 +1535,10 @@ class CliClient final : public Actor {
|
||||
return td_api::make_object<td_api::backgroundFillGradient>(top_color, bottom_color, Random::fast(0, 7) * 45);
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::BackgroundFill> get_background_fill(vector<int32> colors) {
|
||||
return td_api::make_object<td_api::backgroundFillFreeformGradient>(std::move(colors));
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::BackgroundType> get_solid_pattern_background(int32 color, int32 intensity,
|
||||
bool is_moving) {
|
||||
return get_gradient_pattern_background(color, color, intensity, is_moving);
|
||||
@ -1546,6 +1550,13 @@ class CliClient final : public Actor {
|
||||
is_moving);
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::BackgroundType> get_freeform_gradient_pattern_background(vector<int32> colors,
|
||||
int32 intensity,
|
||||
bool is_moving) {
|
||||
return td_api::make_object<td_api::backgroundTypePattern>(get_background_fill(std::move(colors)), intensity,
|
||||
is_moving);
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::BackgroundType> get_solid_background(int32 color) {
|
||||
return td_api::make_object<td_api::backgroundTypeFill>(get_background_fill(color));
|
||||
}
|
||||
@ -1554,6 +1565,10 @@ class CliClient final : public Actor {
|
||||
return td_api::make_object<td_api::backgroundTypeFill>(get_background_fill(top_color, bottom_color));
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::BackgroundType> get_freeform_gradient_background(vector<int32> colors) {
|
||||
return td_api::make_object<td_api::backgroundTypeFill>(get_background_fill(std::move(colors)));
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::Object> execute(td_api::object_ptr<td_api::Function> f) {
|
||||
if (combined_log.get_first_verbosity_level() < VERBOSITY_NAME(td_requests)) {
|
||||
LOG(ERROR) << "Execute request: " << to_string(f);
|
||||
@ -2206,12 +2221,19 @@ class CliClient final : public Actor {
|
||||
send_get_background_url(get_gradient_pattern_background(0xFFFFFF, 0, 100, true));
|
||||
send_get_background_url(get_gradient_pattern_background(0xABCDEF, 0xFEDCBA, 49, true));
|
||||
send_get_background_url(get_gradient_pattern_background(0, 0x1000000, 49, true));
|
||||
send_get_background_url(get_freeform_gradient_pattern_background({0xABCDEF, 0xFEDCBA}, 49, true));
|
||||
send_get_background_url(get_freeform_gradient_pattern_background({0xABCDEF, 0x111111, 0x222222}, 49, true));
|
||||
send_get_background_url(
|
||||
get_freeform_gradient_pattern_background({0xABCDEF, 0xFEDCBA, 0x111111, 0x222222}, 49, true));
|
||||
send_get_background_url(get_solid_background(-1));
|
||||
send_get_background_url(get_solid_background(0xABCDEF));
|
||||
send_get_background_url(get_solid_background(0x1000000));
|
||||
send_get_background_url(get_gradient_background(0xABCDEF, 0xFEDCBA));
|
||||
send_get_background_url(get_gradient_background(0, 0));
|
||||
send_get_background_url(get_gradient_background(-1, -1));
|
||||
send_get_background_url(get_freeform_gradient_background({0xFEDCBA, 0x222222}));
|
||||
send_get_background_url(get_freeform_gradient_background({0xFEDCBA, 0x111111, 0x222222}));
|
||||
send_get_background_url(get_freeform_gradient_background({0xABCDEF, 0xFEDCBA, 0x111111, 0x222222}));
|
||||
} else if (op == "sbg") {
|
||||
send_request(td_api::make_object<td_api::searchBackground>(args));
|
||||
} else if (op == "sbgd") {
|
||||
@ -2237,6 +2259,9 @@ class CliClient final : public Actor {
|
||||
get_args(args, top_color, bottom_color);
|
||||
auto background_type = get_gradient_background(top_color, bottom_color);
|
||||
send_request(td_api::make_object<td_api::setBackground>(nullptr, std::move(background_type), op == "sbggd"));
|
||||
} else if (op == "sbgfg" || op == "sbgfgd") {
|
||||
auto background_type = get_freeform_gradient_background(to_integers<int32>(args));
|
||||
send_request(td_api::make_object<td_api::setBackground>(nullptr, std::move(background_type), op == "sbgfgd"));
|
||||
} else if (op == "sbgwid" || op == "sbgwidd") {
|
||||
send_request(td_api::make_object<td_api::setBackground>(
|
||||
td_api::make_object<td_api::inputBackgroundRemote>(to_integer<int64>(args)),
|
||||
|
@ -226,13 +226,16 @@ Result<typename std::enable_if<std::is_unsigned<T>::value, T>::type> hex_to_inte
|
||||
T integer_value = 0;
|
||||
auto begin = str.begin();
|
||||
auto end = str.end();
|
||||
if (begin == end) {
|
||||
return Status::Error("String is empty");
|
||||
}
|
||||
while (begin != end) {
|
||||
T digit = hex_to_int(*begin++);
|
||||
if (digit == 16) {
|
||||
return Status::Error("Not a hex digit");
|
||||
return Status::Error("String contains non-hex digit");
|
||||
}
|
||||
if (integer_value > std::numeric_limits<T>::max() / 16) {
|
||||
return Status::Error("Hex number overflow");
|
||||
return Status::Error("String hex number overflows");
|
||||
}
|
||||
integer_value = integer_value * 16 + digit;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user