diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index e26e65bcb..4bfe73eff 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -111,15 +111,12 @@ namespace { style::font monofont; struct CornersPixmaps { - CornersPixmaps() { - memset(p, 0, sizeof(p)); - } - QPixmap *p[4]; + QPixmap p[4]; }; - CornersPixmaps corners[RoundCornersCount]; + QVector corners; using CornersMap = QMap; CornersMap cornersMap; - QImage *cornersMaskLarge[4] = { nullptr }, *cornersMaskSmall[4] = { nullptr }; + QImage cornersMaskLarge[4], cornersMaskSmall[4]; using EmojiImagesMap = QMap; EmojiImagesMap MainEmojiMap; @@ -2174,6 +2171,7 @@ namespace { } void prepareCorners(RoundCorners index, int32 radius, const QBrush &brush, const style::color *shadow = nullptr, QImage *cors = nullptr) { + Expects(::corners.size() > index); int32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor(); QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4]; { @@ -2198,8 +2196,8 @@ namespace { cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0)); if (index != SmallMaskCorners && index != LargeMaskCorners) { for (int i = 0; i < 4; ++i) { - ::corners[index].p[i] = new QPixmap(pixmapFromImageInPlace(std::move(cors[i]))); - ::corners[index].p[i]->setDevicePixelRatio(cRetinaFactor()); + ::corners[index].p[i] = pixmapFromImageInPlace(std::move(cors[i])); + ::corners[index].p[i].setDevicePixelRatio(cRetinaFactor()); } } } @@ -2221,18 +2219,21 @@ namespace { return MsgRadius; } - void createCorners() { + void createMaskCorners() { QImage mask[4]; - prepareCorners(LargeMaskCorners, msgRadius(), QColor(255, 255, 255), nullptr, mask); - for (int i = 0; i < 4; ++i) { - ::cornersMaskLarge[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied)); - ::cornersMaskLarge[i]->setDevicePixelRatio(cRetinaFactor()); - } prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask); for (int i = 0; i < 4; ++i) { - ::cornersMaskSmall[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied)); - ::cornersMaskSmall[i]->setDevicePixelRatio(cRetinaFactor()); + ::cornersMaskSmall[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied); + ::cornersMaskSmall[i].setDevicePixelRatio(cRetinaFactor()); } + prepareCorners(LargeMaskCorners, msgRadius(), QColor(255, 255, 255), nullptr, mask); + for (int i = 0; i < 4; ++i) { + ::cornersMaskLarge[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied); + ::cornersMaskLarge[i].setDevicePixelRatio(cRetinaFactor()); + } + } + + void createPaletteCorners() { prepareCorners(MenuCorners, st::buttonRadius, st::menuBg); prepareCorners(BoxCorners, st::boxRadius, st::boxBg); prepareCorners(BotKbOverCorners, st::dateRadius, st::msgBotKbOverBgAdd); @@ -2262,19 +2263,14 @@ namespace { prepareCorners(MessageOutSelectedCorners, msgRadius(), st::msgOutBgSelected, &st::msgOutShadowSelected); } + void createCorners() { + ::corners.resize(RoundCornersCount); + createMaskCorners(); + createPaletteCorners(); + } + void clearCorners() { - for (int j = 0; j < 4; ++j) { - for (int i = 0; i < RoundCornersCount; ++i) { - delete ::corners[i].p[j]; ::corners[i].p[j] = nullptr; - } - delete ::cornersMaskSmall[j]; ::cornersMaskSmall[j] = nullptr; - delete ::cornersMaskLarge[j]; ::cornersMaskLarge[j] = nullptr; - } - for (auto i = ::cornersMap.cbegin(), e = ::cornersMap.cend(); i != e; ++i) { - for (int j = 0; j < 4; ++j) { - delete i->p[j]; - } - } + ::corners.clear(); ::cornersMap.clear(); } @@ -2303,18 +2299,13 @@ namespace { using Update = Window::Theme::BackgroundUpdate; static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) { if (update.paletteChanged()) { - clearCorners(); - createCorners(); + createPaletteCorners(); if (App::main()) { App::main()->updateScrollColors(); } HistoryLayout::serviceColorsUpdated(); } else if (update.type == Update::Type::New) { - for (int i = 0; i < 4; ++i) { - delete ::corners[StickerCorners].p[i]; ::corners[StickerCorners].p[i] = nullptr; - delete ::corners[StickerSelectedCorners].p[i]; ::corners[StickerSelectedCorners].p[i] = nullptr; - } prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg); prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected); @@ -2778,7 +2769,7 @@ namespace { roundRect(p, rect, st::msgInBg, MessageInCorners, nullptr, parts); } - QImage **cornersMask(ImageRoundRadius radius) { + QImage *cornersMask(ImageRoundRadius radius) { switch (radius) { case ImageRoundRadius::Large: return ::cornersMaskLarge; case ImageRoundRadius::Small: @@ -2788,8 +2779,8 @@ namespace { } void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) { - auto cornerWidth = corner.p[0]->width() / cIntRetinaFactor(); - auto cornerHeight = corner.p[0]->height() / cIntRetinaFactor(); + auto cornerWidth = corner.p[0].width() / cIntRetinaFactor(); + auto cornerHeight = corner.p[0].height() / cIntRetinaFactor(); if (w < 2 * cornerWidth || h < 2 * cornerHeight) return; if (w > 2 * cornerWidth) { if (parts & RectPart::Top) { @@ -2818,16 +2809,16 @@ namespace { } } if (parts & RectPart::TopLeft) { - p.drawPixmap(x, y, *corner.p[0]); + p.drawPixmap(x, y, corner.p[0]); } if (parts & RectPart::TopRight) { - p.drawPixmap(x + w - cornerWidth, y, *corner.p[1]); + p.drawPixmap(x + w - cornerWidth, y, corner.p[1]); } if (parts & RectPart::BottomLeft) { - p.drawPixmap(x, y + h - cornerHeight, *corner.p[2]); + p.drawPixmap(x, y + h - cornerHeight, corner.p[2]); } if (parts & RectPart::BottomRight) { - p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight, *corner.p[3]); + p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight, corner.p[3]); } } @@ -2837,18 +2828,18 @@ namespace { void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, RoundCorners index, RectParts parts) { auto &corner = ::corners[index]; - auto cornerWidth = corner.p[0]->width() / cIntRetinaFactor(); - auto cornerHeight = corner.p[0]->height() / cIntRetinaFactor(); + auto cornerWidth = corner.p[0].width() / cIntRetinaFactor(); + auto cornerHeight = corner.p[0].height() / cIntRetinaFactor(); if (parts & RectPart::Bottom) { p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, shadow); } if (parts & RectPart::BottomLeft) { p.fillRect(x, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow); - p.drawPixmap(x, y + h - cornerHeight + st::msgShadow, *corner.p[2]); + p.drawPixmap(x, y + h - cornerHeight + st::msgShadow, corner.p[2]); } if (parts & RectPart::BottomRight) { p.fillRect(x + w - cornerWidth, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow); - p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight + st::msgShadow, *corner.p[3]); + p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight + st::msgShadow, corner.p[3]); } } @@ -2865,8 +2856,8 @@ namespace { CornersPixmaps pixmaps; for (int j = 0; j < 4; ++j) { - pixmaps.p[j] = new QPixmap(pixmapFromImageInPlace(std::move(images[j]))); - pixmaps.p[j]->setDevicePixelRatio(cRetinaFactor()); + pixmaps.p[j] = pixmapFromImageInPlace(std::move(images[j])); + pixmaps.p[j].setDevicePixelRatio(cRetinaFactor()); } i = cornersMap.insert(colorKey, pixmaps); } diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 08dee4bf4..9ea201d28 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -283,7 +283,7 @@ namespace App { void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners); void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners); - QImage **cornersMask(ImageRoundRadius radius); + QImage *cornersMask(ImageRoundRadius radius); void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full); inline void roundRect(Painter &p, const QRect &rect, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) { return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts); diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_panel.cpp b/Telegram/SourceFiles/chat_helpers/tabbed_panel.cpp index ad184af2c..a18c2818c 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_panel.cpp +++ b/Telegram/SourceFiles/chat_helpers/tabbed_panel.cpp @@ -265,7 +265,7 @@ void TabbedPanel::startShowAnimation() { auto inner = rect().marginsRemoved(st::emojiPanMargins); _showAnimation->setFinalImage(std::move(image), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor())); auto corners = App::cornersMask(ImageRoundRadius::Small); - _showAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3])); + _showAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]); _showAnimation->start(); } hideChildren(); diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp index 8f4b26c3b..615327c62 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp @@ -653,7 +653,7 @@ void TabbedSelector::switchTab() { auto slidingRect = QRect(_tabsSlider->x() * cIntRetinaFactor(), _scroll->y() * cIntRetinaFactor(), _tabsSlider->width() * cIntRetinaFactor(), (height() - _scroll->y()) * cIntRetinaFactor()); _slideAnimation->setFinalImages(direction, std::move(wasCache), std::move(nowCache), slidingRect, wasSectionIcons); auto corners = App::cornersMask(ImageRoundRadius::Small); - _slideAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3])); + _slideAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]); _slideAnimation->start(); hideForSliding(); diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp index 1e9fcd842..11d5df715 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp @@ -897,7 +897,7 @@ void Widget::startShowAnimation() { auto inner = rect().marginsRemoved(st::emojiPanMargins); _showAnimation->setFinalImage(std::move(image), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor())); auto corners = App::cornersMask(ImageRoundRadius::Small); - _showAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3])); + _showAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]); _showAnimation->start(); } hideChildren(); diff --git a/Telegram/SourceFiles/ui/effects/panel_animation.cpp b/Telegram/SourceFiles/ui/effects/panel_animation.cpp index c152c3e04..761146756 100644 --- a/Telegram/SourceFiles/ui/effects/panel_animation.cpp +++ b/Telegram/SourceFiles/ui/effects/panel_animation.cpp @@ -65,16 +65,16 @@ void RoundShadowAnimation::setShadow(const style::Shadow &st) { } } -void RoundShadowAnimation::setCornerMasks(QImage &&topLeft, QImage &&topRight, QImage &&bottomLeft, QImage &&bottomRight) { - setCornerMask(_topLeft, std::move(topLeft)); - setCornerMask(_topRight, std::move(topRight)); - setCornerMask(_bottomLeft, std::move(bottomLeft)); - setCornerMask(_bottomRight, std::move(bottomRight)); +void RoundShadowAnimation::setCornerMasks(const QImage &topLeft, const QImage &topRight, const QImage &bottomLeft, const QImage &bottomRight) { + setCornerMask(_topLeft, topLeft); + setCornerMask(_topRight, topRight); + setCornerMask(_bottomLeft, bottomLeft); + setCornerMask(_bottomRight, bottomRight); } -void RoundShadowAnimation::setCornerMask(Corner &corner, QImage &&image) { +void RoundShadowAnimation::setCornerMask(Corner &corner, const QImage &image) { t_assert(!started()); - corner.image = std::move(image); + corner.image = image; if (corner.valid()) { corner.width = corner.image.width(); corner.height = corner.image.height(); diff --git a/Telegram/SourceFiles/ui/effects/panel_animation.h b/Telegram/SourceFiles/ui/effects/panel_animation.h index 9d7bbb262..2e35ece14 100644 --- a/Telegram/SourceFiles/ui/effects/panel_animation.h +++ b/Telegram/SourceFiles/ui/effects/panel_animation.h @@ -26,7 +26,7 @@ namespace Ui { class RoundShadowAnimation { public: - void setCornerMasks(QImage &&topLeft, QImage &&topRight, QImage &&bottomLeft, QImage &&bottomRight); + void setCornerMasks(const QImage &topLeft, const QImage &topRight, const QImage &bottomLeft, const QImage &bottomRight); protected: void start(int frameWidth, int frameHeight, float64 devicePixelRatio); @@ -48,7 +48,7 @@ protected: return !image.isNull(); } }; - void setCornerMask(Corner &corner, QImage &&image); + void setCornerMask(Corner &corner, const QImage &image); void paintCorner(Corner &corner, int left, int top); struct Shadow { diff --git a/Telegram/SourceFiles/ui/images.cpp b/Telegram/SourceFiles/ui/images.cpp index 8093a78d8..41eccc43b 100644 --- a/Telegram/SourceFiles/ui/images.cpp +++ b/Telegram/SourceFiles/ui/images.cpp @@ -204,13 +204,13 @@ void prepareRound(QImage &image, ImageRoundRadius radius, ImageRoundCorners corn image = std::move(image).convertToFormat(QImage::Format_ARGB32_Premultiplied); t_assert(!image.isNull()); - QImage **masks = App::cornersMask(radius); + auto masks = App::cornersMask(radius); prepareRound(image, masks, corners); } -void prepareRound(QImage &image, QImage **cornerMasks, ImageRoundCorners corners) { - auto cornerWidth = cornerMasks[0]->width(); - auto cornerHeight = cornerMasks[0]->height(); +void prepareRound(QImage &image, QImage *cornerMasks, ImageRoundCorners corners) { + auto cornerWidth = cornerMasks[0].width(); + auto cornerHeight = cornerMasks[0].height(); auto imageWidth = image.width(); auto imageHeight = image.height(); if (imageWidth < 2 * cornerWidth || imageHeight < 2 * cornerHeight) { @@ -226,15 +226,15 @@ void prepareRound(QImage &image, QImage **cornerMasks, ImageRoundCorners corners auto intsTopRight = ints + imageWidth - cornerWidth; auto intsBottomLeft = ints + (imageHeight - cornerHeight) * imageWidth; auto intsBottomRight = ints + (imageHeight - cornerHeight + 1) * imageWidth - cornerWidth; - auto maskCorner = [imageWidth, imageHeight, imageIntsPerPixel, imageIntsPerLine](uint32 *imageInts, const QImage *mask) { - auto maskWidth = mask->width(); - auto maskHeight = mask->height(); - auto maskBytesPerPixel = (mask->depth() >> 3); - auto maskBytesPerLine = mask->bytesPerLine(); + auto maskCorner = [imageWidth, imageHeight, imageIntsPerPixel, imageIntsPerLine](uint32 *imageInts, const QImage &mask) { + auto maskWidth = mask.width(); + auto maskHeight = mask.height(); + auto maskBytesPerPixel = (mask.depth() >> 3); + auto maskBytesPerLine = mask.bytesPerLine(); auto maskBytesAdded = maskBytesPerLine - maskWidth * maskBytesPerPixel; - auto maskBytes = mask->constBits(); + auto maskBytes = mask.constBits(); t_assert(maskBytesAdded >= 0); - t_assert(mask->depth() == (maskBytesPerPixel << 3)); + t_assert(mask.depth() == (maskBytesPerPixel << 3)); auto imageIntsAdded = imageIntsPerLine - maskWidth * imageIntsPerPixel; t_assert(imageIntsAdded >= 0); for (auto y = 0; y != maskHeight; ++y) { diff --git a/Telegram/SourceFiles/ui/images.h b/Telegram/SourceFiles/ui/images.h index a8349e313..3a6d67875 100644 --- a/Telegram/SourceFiles/ui/images.h +++ b/Telegram/SourceFiles/ui/images.h @@ -180,7 +180,7 @@ namespace Images { QImage prepareBlur(QImage image); void prepareRound(QImage &image, ImageRoundRadius radius, ImageRoundCorners corners = ImageRoundCorner::All); -void prepareRound(QImage &image, QImage **cornerMasks, ImageRoundCorners corners = ImageRoundCorner::All); +void prepareRound(QImage &image, QImage *cornerMasks, ImageRoundCorners corners = ImageRoundCorner::All); void prepareCircle(QImage &image); QImage prepareColored(style::color add, QImage image); QImage prepareOpaque(QImage image); diff --git a/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp b/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp index efe7cba4a..a255b3822 100644 --- a/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp +++ b/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp @@ -254,7 +254,7 @@ void InnerDropdown::startShowAnimation() { auto inner = rect().marginsRemoved(_st.padding); _showAnimation->setFinalImage(std::move(cache), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor())); auto corners = App::cornersMask(ImageRoundRadius::Small); - _showAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3])); + _showAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]); _showAnimation->start(); } hideChildren(); diff --git a/Telegram/SourceFiles/ui/widgets/popup_menu.cpp b/Telegram/SourceFiles/ui/widgets/popup_menu.cpp index 7391b07ce..e30b61292 100644 --- a/Telegram/SourceFiles/ui/widgets/popup_menu.cpp +++ b/Telegram/SourceFiles/ui/widgets/popup_menu.cpp @@ -362,7 +362,7 @@ void PopupMenu::startShowAnimation() { _showAnimation->setFinalImage(std::move(cache), QRect(_inner.topLeft() * cIntRetinaFactor(), _inner.size() * cIntRetinaFactor())); if (_useTransparency) { auto corners = App::cornersMask(ImageRoundRadius::Small); - _showAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3])); + _showAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]); } else { _showAnimation->setSkipShadow(true); }