diff --git a/ui/style/style_core_palette.cpp b/ui/style/style_core_palette.cpp index 39b036f..336aae7 100644 --- a/ui/style/style_core_palette.cpp +++ b/ui/style/style_core_palette.cpp @@ -10,6 +10,20 @@ namespace style { +struct palette::FinalizeHelper { + not_null with; + base::flat_set ignoreKeys; + base::flat_map< + int, + std::pair> keepContrast; +}; + +palette::palette() = default; + +palette::~palette() { + clear(); +} + int palette::indexOfColor(style::color c) const { auto start = data(0); if (c._data >= start && c._data < start + kCount) { @@ -19,8 +33,9 @@ int palette::indexOfColor(style::color c) const { } color palette::colorAtIndex(int index) const { - Assert(_ready); - Assert(index >= 0 && index < kCount); + Expects(index >= 0 && index < kCount); + Expects(_ready); + return _colors[index]; } @@ -28,8 +43,9 @@ void palette::finalize(const colorizer &with) { if (_ready) return; _ready = true; - _colorizer = with ? &with : nullptr; + _finalizeHelper = PrepareFinalizeHelper(with); palette_data::finalize(*this); + _finalizeHelper = nullptr; } void palette::finalize() { @@ -131,18 +147,18 @@ void palette::compute(int index, int fallbackIndex, TempColorData value) { _status[index] = Status::Loaded; new (data(index)) internal::ColorData(*data(fallbackIndex)); } else { - if (_colorizer && *_colorizer) { - colorize( - //(index - // ? style::main_palette::data()[index - 1].name - // : qstr("transparent")), - value.r, - value.g, - value.b, - *_colorizer); - _status[index] = Status::Loaded; - } else { + if (!_finalizeHelper + || _finalizeHelper->ignoreKeys.contains(index)) { _status[index] = Status::Created; + } else { + const auto &with = *_finalizeHelper->with; + const auto i = _finalizeHelper->keepContrast.find(index); + if (i == end(_finalizeHelper->keepContrast)) { + colorize(value.r, value.g, value.b, with); + } else { + colorize(i->second, value.r, value.g, value.b, with); + } + _status[index] = Status::Loaded; } new (data(index)) internal::ColorData(value.r, value.g, value.b, value.a); } @@ -158,6 +174,28 @@ void palette::setData(int index, const internal::ColorData &value) { _status[index] = Status::Loaded; } +auto palette::PrepareFinalizeHelper(const colorizer &with) +-> std::unique_ptr { + if (!with) { + return nullptr; + } + auto result = std::make_unique(FinalizeHelper{ + .with = &with, + }); + result->ignoreKeys.reserve(with.ignoreKeys.size() + 1); + result->ignoreKeys.emplace(0); + for (const auto &key : with.ignoreKeys) { + if (const auto index = internal::GetPaletteIndex(key); index > 0) { + result->ignoreKeys.emplace(index); + } + } + for (const auto &[key, contrast] : with.keepContrast) { + if (const auto index = internal::GetPaletteIndex(key); index > 0) { + result->keepContrast.emplace(index, contrast); + } + } + return result; +} namespace main_palette { namespace { diff --git a/ui/style/style_core_palette.h b/ui/style/style_core_palette.h index 39c2e1b..757467d 100644 --- a/ui/style/style_core_palette.h +++ b/ui/style/style_core_palette.h @@ -15,12 +15,10 @@ struct colorizer; class palette : public palette_data { public: - palette() = default; + palette(); palette(const palette &other) = delete; palette &operator=(const palette &other); - ~palette() { - clear(); - } + ~palette(); QByteArray save() const; bool load(const QByteArray &cache); @@ -43,14 +41,18 @@ public: color colorAtIndex(int index) const; private: + struct FinalizeHelper; struct TempColorData { uchar r, g, b, a; }; friend class palette_data; + [[nodiscard]] static auto PrepareFinalizeHelper(const colorizer &with) + -> std::unique_ptr; + void clear(); void compute(int index, int fallbackIndex, TempColorData value); void setData(int index, const internal::ColorData &value); - const colorizer *_colorizer = nullptr; + std::unique_ptr _finalizeHelper; bool _ready = false; }; diff --git a/ui/style/style_palette_colorizer.cpp b/ui/style/style_palette_colorizer.cpp index fc7a7bc..ad41a74 100644 --- a/ui/style/style_palette_colorizer.cpp +++ b/ui/style/style_palette_colorizer.cpp @@ -101,9 +101,18 @@ void colorize( const auto i = with.keepContrast.find(name); if (i == end(with.keepContrast)) { colorize(r, g, b, with); - return; + } else { + colorize(i->second, r, g, b, with); } - const auto check = i->second.first; +} + +void colorize( + const std::pair &contrast, + uchar &r, + uchar &g, + uchar &b, + const colorizer &with) { + const auto check = contrast.first; const auto rgb = QColor(int(r), int(g), int(b)); const auto changed = colorize(rgb, with); const auto checked = colorize(check, with).value_or(check); @@ -120,7 +129,7 @@ void colorize( } return; } - const auto replace = i->second.second; + const auto replace = contrast.second; const auto result = colorize(replace, with).value_or(replace); FillColorizeResult( r, diff --git a/ui/style/style_palette_colorizer.h b/ui/style/style_palette_colorizer.h index d1dafe9..1d78c00 100644 --- a/ui/style/style_palette_colorizer.h +++ b/ui/style/style_palette_colorizer.h @@ -40,6 +40,12 @@ void colorize( uchar &g, uchar &b, const colorizer &with); +void colorize( + const std::pair &contrast, + uchar &r, + uchar &g, + uchar &b, + const colorizer &with); void colorize(QImage &image, const colorizer &with); [[nodiscard]] std::optional colorize(