Add rotation_angle support to gradient background fill.

GitOrigin-RevId: ebe65367b2cad8777e6e87cf30815a1f9545da9a
This commit is contained in:
levlam 2019-12-22 22:32:01 +03:00
parent b48c465b0d
commit 68a211a368
7 changed files with 94 additions and 38 deletions

View File

@ -2102,7 +2102,8 @@ pushReceiverId id:int64 = PushReceiverId;
backgroundFillSolid color:int32 = BackgroundFill;
//@description Describes a gradient fill of a background @top_color A top color of the background in the RGB24 format @bottom_color A bottom color of the background in the RGB24 format
backgroundFillGradient top_color:int32 bottom_color:int32 = BackgroundFill;
//@rotation_angle Rotation angle of the gradient, in degrees; 0-359. Must be always divisible by 45
backgroundFillGradient top_color:int32 bottom_color:int32 rotation_angle:int32 = BackgroundFill;
//@class BackgroundType @description Describes a type of a background

Binary file not shown.

View File

@ -390,6 +390,10 @@ void BackgroundManager::reload_background(BackgroundId background_id, int64 acce
telegram_api::make_object<telegram_api::inputWallPaper>(background_id.get(), access_hash), std::move(promise));
}
static bool is_background_name_local(Slice name) {
return name.size() <= 6 || name.find('?') <= 13u;
}
BackgroundId BackgroundManager::search_background(const string &name, Promise<Unit> &&promise) {
auto it = name_to_background_id_.find(name);
if (it != name_to_background_id_.end()) {
@ -402,13 +406,22 @@ BackgroundId BackgroundManager::search_background(const string &name, Promise<Un
return BackgroundId();
}
if (name.size() <= 13) {
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);
}
CHECK(fill_colors.size() <= 13u);
bool have_hyphen = false;
size_t hyphen_pos = 0;
for (size_t i = 0; i < name.size(); i++) {
auto c = name[i];
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 < name.size()) {
if (c != '-' || have_hyphen || i > 6 || i + 7 < fill_colors.size()) {
promise.set_error(Status::Error(400, "WALLPAPER_INVALID"));
return BackgroundId();
}
@ -419,11 +432,21 @@ BackgroundId BackgroundManager::search_background(const string &name, Promise<Un
BackgroundFill fill;
if (have_hyphen) {
int32 top_color = static_cast<int32>(hex_to_integer<uint32>(name.substr(0, hyphen_pos)));
int32 bottom_color = static_cast<int32>(hex_to_integer<uint32>(name.substr(hyphen_pos + 1)));
fill = BackgroundFill(top_color, bottom_color);
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>(name));
int32 color = static_cast<int32>(hex_to_integer<uint32>(fill_colors));
fill = BackgroundFill(color);
}
auto background_id = add_fill_background(fill);
@ -459,7 +482,7 @@ void BackgroundManager::on_load_background_from_database(string name, string val
loaded_from_database_backgrounds_.insert(name);
CHECK(name.size() > 13);
CHECK(!is_background_name_local(name));
if (name_to_background_id_.count(name) == 0 && !value.empty()) {
LOG(INFO) << "Successfully loaded background " << name << " of size " << value.size() << " from database";
Background background;
@ -513,11 +536,7 @@ BackgroundId BackgroundManager::add_fill_background(const BackgroundFill &fill)
}
BackgroundId BackgroundManager::add_fill_background(const BackgroundFill &fill, bool is_default, bool is_dark) {
CHECK(0 <= fill.top_color && fill.top_color < 0x1000000);
CHECK(0 <= fill.bottom_color && fill.bottom_color < 0x1000000);
int64 id = fill.is_solid() ? static_cast<int64>(fill.top_color) + 1
: (static_cast<int64>(fill.top_color) << 24) + fill.bottom_color + (1 << 24) + 1;
BackgroundId background_id(id);
BackgroundId background_id(fill.get_id());
Background background;
background.id = background_id;
@ -831,7 +850,7 @@ void BackgroundManager::add_background(const Background &background) {
result->name = background.name;
if (result->name.size() > 13) {
if (!is_background_name_local(result->name)) {
name_to_background_id_.emplace(result->name, result->id);
loaded_from_database_backgrounds_.erase(result->name); // don't needed anymore
}
@ -914,7 +933,7 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
BackgroundFill fill = BackgroundFill(color);
if ((settings->flags_ & telegram_api::wallPaperSettings::SECOND_BACKGROUND_COLOR_MASK) != 0) {
fill = BackgroundFill(color, settings->second_background_color_);
fill = BackgroundFill(color, settings->second_background_color_, settings->rotation_);
}
return add_fill_background(fill, is_default, is_dark);
}
@ -928,7 +947,7 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
if (expected_background_id.is_valid() && id != expected_background_id) {
LOG(ERROR) << "Expected " << expected_background_id << ", but receive " << to_string(wallpaper);
}
if (wallpaper->slug_.size() <= 13 || (0 < wallpaper->id_ && wallpaper->id_ <= 0x1000001000000)) {
if (is_background_name_local(wallpaper->slug_) || BackgroundFill::is_valid_id(wallpaper->id_)) {
LOG(ERROR) << "Receive " << to_string(wallpaper);
return BackgroundId();
}
@ -968,7 +987,7 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
name_to_background_id_.emplace(expected_background_name, id);
}
if (G()->parameters().use_file_db && background.name.size() > 13) {
if (G()->parameters().use_file_db && !is_background_name_local(background.name)) {
LOG(INFO) << "Save " << id << " to database with name " << background.name;
G()->td_db()->get_sqlite_pmc()->set(get_background_name_database_key(background.name),
log_event_store(background).as_slice().str(), Auto());

View File

@ -27,7 +27,7 @@ static BackgroundFill get_background_fill(const td_api::BackgroundFill *fill) {
}
case td_api::backgroundFillGradient::ID: {
auto gradient = static_cast<const td_api::backgroundFillGradient *>(fill);
return BackgroundFill(gradient->top_color_, gradient->bottom_color_);
return BackgroundFill(gradient->top_color_, gradient->bottom_color_, gradient->rotation_angle_);
}
default:
UNREACHABLE();
@ -35,16 +35,43 @@ static BackgroundFill get_background_fill(const td_api::BackgroundFill *fill) {
}
}
static string get_background_fill_color_hex_string(const BackgroundFill &fill) {
static string get_background_fill_color_hex_string(const BackgroundFill &fill, bool is_first) {
if (fill.is_solid()) {
return get_color_hex_string(fill.top_color);
} else {
return PSTRING() << get_color_hex_string(fill.top_color) << '-' << get_color_hex_string(fill.bottom_color);
string colors = PSTRING() << get_color_hex_string(fill.top_color) << '-' << get_color_hex_string(fill.bottom_color);
if (fill.rotation_angle != 0) {
colors += (PSTRING() << (is_first ? '?' : '&') << "rotation=" << fill.rotation_angle);
}
return colors;
}
}
static bool is_valid_color(int32 color) {
return 0 <= color && color <= 0xFFFFFF;
}
static bool is_valid_intensity(int32 intensity) {
return 0 <= intensity && intensity <= 100;
}
int64 BackgroundFill::get_id() const {
CHECK(is_valid_color(top_color));
CHECK(is_valid_color(bottom_color));
CHECK(is_valid_rotation_angle(rotation_angle));
if (is_solid()) {
return static_cast<int64>(top_color) + 1;
}
return (rotation_angle / 45) * 0x1000001000001 + (static_cast<int64>(top_color) << 24) + bottom_color + (1 << 24) + 1;
}
bool BackgroundFill::is_valid_id(int64 id) {
return 0 < id && id < 0x8000008000008;
}
bool operator==(const BackgroundFill &lhs, const BackgroundFill &rhs) {
return lhs.top_color == rhs.top_color && lhs.bottom_color == rhs.bottom_color;
return lhs.top_color == rhs.top_color && lhs.bottom_color == rhs.bottom_color &&
lhs.rotation_angle == rhs.rotation_angle;
}
string BackgroundType::get_link() const {
@ -68,7 +95,7 @@ string BackgroundType::get_link() const {
}
case BackgroundType::Type::Pattern: {
string link = PSTRING() << "intensity=" << intensity
<< "&bg_color=" << get_background_fill_color_hex_string(fill);
<< "&bg_color=" << get_background_fill_color_hex_string(fill, false);
if (!mode.empty()) {
link += "&mode=";
link += mode;
@ -76,7 +103,7 @@ string BackgroundType::get_link() const {
return link;
}
case BackgroundType::Type::Fill:
return get_background_fill_color_hex_string(fill);
return get_background_fill_color_hex_string(fill, true);
default:
UNREACHABLE();
return string();
@ -106,14 +133,6 @@ StringBuilder &operator<<(StringBuilder &string_builder, const BackgroundType &t
return string_builder << "type " << type.type << '[' << type.get_link() << ']';
}
static bool is_valid_color(int32 color) {
return 0 <= color && color <= 0xFFFFFF;
}
static bool is_valid_intensity(int32 intensity) {
return 0 <= intensity && intensity <= 100;
}
Result<BackgroundType> get_background_type(const td_api::BackgroundType *type) {
if (type == nullptr) {
return Status::Error(400, "Type must not be empty");
@ -151,6 +170,9 @@ Result<BackgroundType> get_background_type(const td_api::BackgroundType *type) {
if (!is_valid_color(result.fill.bottom_color)) {
return Status::Error(400, "Wrong bottom color value");
}
if (!BackgroundFill::is_valid_rotation_angle(result.fill.rotation_angle)) {
return Status::Error(400, "Wrong rotation angle value");
}
return result;
}
@ -190,7 +212,7 @@ static td_api::object_ptr<td_api::BackgroundFill> get_background_fill_object(con
if (fill.is_solid()) {
return td_api::make_object<td_api::backgroundFillSolid>(fill.top_color);
}
return td_api::make_object<td_api::backgroundFillGradient>(fill.top_color, fill.bottom_color);
return td_api::make_object<td_api::backgroundFillGradient>(fill.top_color, fill.bottom_color, fill.rotation_angle);
}
td_api::object_ptr<td_api::BackgroundType> get_background_type_object(const BackgroundType &type) {
@ -225,8 +247,9 @@ telegram_api::object_ptr<telegram_api::wallPaperSettings> get_input_wallpaper_se
flags |= telegram_api::wallPaperSettings::INTENSITY_MASK;
}
if (type.is_server()) {
return telegram_api::make_object<telegram_api::wallPaperSettings>(
flags, false /*ignored*/, false /*ignored*/, type.fill.top_color, type.fill.bottom_color, type.intensity, 0);
return telegram_api::make_object<telegram_api::wallPaperSettings>(flags, false /*ignored*/, false /*ignored*/,
type.fill.top_color, type.fill.bottom_color,
type.intensity, type.fill.rotation_angle);
}
UNREACHABLE();

View File

@ -18,16 +18,26 @@ namespace td {
struct BackgroundFill {
int32 top_color = 0;
int32 bottom_color = 0;
int32 rotation_angle = 0;
BackgroundFill() = default;
explicit BackgroundFill(int32 solid_color) : top_color(solid_color), bottom_color(solid_color) {
}
BackgroundFill(int32 top_color, int32 bottom_color) : top_color(top_color), bottom_color(bottom_color) {
BackgroundFill(int32 top_color, int32 bottom_color, int32 rotation_angle)
: top_color(top_color), bottom_color(bottom_color), rotation_angle(rotation_angle) {
}
bool is_solid() const {
return top_color == bottom_color;
}
int64 get_id() const;
static bool is_valid_id(int64 id);
static bool is_valid_rotation_angle(int32 rotation_angle) {
return 0 <= rotation_angle && rotation_angle < 360 && rotation_angle % 45 == 0;
}
};
bool operator==(const BackgroundFill &lhs, const BackgroundFill &rhs);

View File

@ -29,6 +29,7 @@ void store(const BackgroundType &type, StorerT &storer) {
store(type.fill.top_color, storer);
if (is_gradient) {
store(type.fill.bottom_color, storer);
store(type.fill.rotation_angle, storer);
}
}
if (has_intensity) {
@ -53,6 +54,7 @@ void parse(BackgroundType &type, ParserT &parser) {
parse(type.fill.top_color, parser);
if (is_gradient) {
parse(type.fill.bottom_color, parser);
parse(type.fill.rotation_angle, parser);
} else {
type.fill.bottom_color = type.fill.top_color;
}

View File

@ -1277,7 +1277,8 @@ class CliClient final : public Actor {
}
td_api::object_ptr<td_api::backgroundTypeFill> get_gradient_background(int32 top_color, int32 bottom_color) {
auto gradient = td_api::make_object<td_api::backgroundFillGradient>(top_color, bottom_color);
auto gradient =
td_api::make_object<td_api::backgroundFillGradient>(top_color, bottom_color, Random::fast(0, 7) * 45);
return td_api::make_object<td_api::backgroundTypeFill>(std::move(gradient));
}