Skip to content

Commit

Permalink
refactor: use raw pixmap filters for paints
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerixyz committed Oct 3, 2024
1 parent 978fb98 commit f504cdd
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 44 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,7 @@ target_link_libraries(${LIBRARY_PROJECT}
PUBLIC
Qt${MAJOR_QT_VERSION}::Core
Qt${MAJOR_QT_VERSION}::Widgets
Qt${MAJOR_QT_VERSION}::WidgetsPrivate # for pixmap filters (paints)
Qt${MAJOR_QT_VERSION}::Gui
Qt${MAJOR_QT_VERSION}::Network
Qt${MAJOR_QT_VERSION}::Svg
Expand Down
3 changes: 2 additions & 1 deletion src/messages/MessageElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,8 @@ void TextElement::addToContainer(MessageLayoutContainer &container,

auto *e = new TextLayoutElement(
*this, text, QSize(width, metrics.height()), color,
this->style_, this->color_.type(), container.getScale());
this->style_, this->color_.type(), container.getScale(),
container.getImageScale() / container.getScale());
e->setTrailingSpace(hasTrailingSpace);
e->setText(text);
e->setWordId(wordId);
Expand Down
11 changes: 5 additions & 6 deletions src/messages/layouts/MessageLayoutElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,12 +421,13 @@ TextLayoutElement::TextLayoutElement(MessageElement &_creator, QString &_text,
const QSize &_size, QColor _color,
FontStyle _style,
MessageColor::Type messageColor,
float _scale)
float _scale, float dpr)
: MessageLayoutElement(_creator, _size)
, color_(_color)
, style_(_style)
, messageColor_(messageColor)
, scale_(_scale)
, dpr_(dpr)
{
this->setText(_text);
}
Expand Down Expand Up @@ -476,11 +477,9 @@ void TextLayoutElement::paint(QPainter &painter,

auto paintPixmap =
paint->getPixmap(this->getText(), font, this->color_,
this->getRect().size(), this->scale_);
this->getRect().size(), this->scale_, this->dpr_);

painter.drawPixmap(QRect(this->getRect().x(), this->getRect().y(),
paintPixmap.width(), paintPixmap.height()),
paintPixmap);
painter.drawPixmap(this->getRect().topLeft(), paintPixmap);
}
else
{
Expand Down Expand Up @@ -516,7 +515,7 @@ bool TextLayoutElement::paintAnimated(QPainter &painter, const int yOffset)

const auto paintPixmap =
paint->getPixmap(this->getText(), font, this->color_,
this->getRect().size(), this->scale_);
this->getRect().size(), this->scale_, this->dpr_);

auto rect = this->getRect();
rect.moveTop(rect.y() + yOffset);
Expand Down
4 changes: 3 additions & 1 deletion src/messages/layouts/MessageLayoutElement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ class TextLayoutElement : public MessageLayoutElement
public:
TextLayoutElement(MessageElement &creator_, QString &text,
const QSize &size, QColor color_, FontStyle style_,
MessageColor::Type messageColor, float scale_);
MessageColor::Type messageColor, float scale_,
float dpr = 1.0F);

protected:
void addCopyTextToString(QString &str, uint32_t from = 0,
Expand All @@ -188,6 +189,7 @@ class TextLayoutElement : public MessageLayoutElement
// space (fits in the padding of `style_`)
MessageColor::Type messageColor_;
float scale_;
float dpr_ = 1.0F; // for 7tv paints
};

// TEXT ICON
Expand Down
60 changes: 31 additions & 29 deletions src/providers/seventv/paints/Paint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "common/Literals.hpp"
#include "singletons/Theme.hpp"

#include <private/qpixmapfilter_p.h>
#include <QLabel>
#include <QPainter>

Expand All @@ -12,9 +13,11 @@ namespace chatterino {
using namespace literals;

QPixmap Paint::getPixmap(const QString &text, const QFont &font,
QColor userColor, QSize size, float scale) const
QColor userColor, QSize size, float scale,
float dpr) const
{
QPixmap pixmap(size);
QPixmap pixmap(size * dpr);
pixmap.setDevicePixelRatio(dpr);
pixmap.fill(Qt::transparent);

QPainter pixmapPainter(&pixmap);
Expand Down Expand Up @@ -44,30 +47,29 @@ QPixmap Paint::getPixmap(const QString &text, const QFont &font,
QTextOption(Qt::AlignLeft | Qt::AlignTop));
pixmapPainter.end();

for (const auto &shadow : this->getDropShadows())
if (!this->getDropShadows().empty())
{
if (!shadow.isValid())
QPixmap outMap(size * dpr);
outMap.setDevicePixelRatio(dpr);
for (const auto &shadow : this->getDropShadows())
{
continue;
if (!shadow.isValid())
{
continue;
}
outMap.fill(Qt::transparent);

{
QPainter outPainter(&outMap);
auto scaled = shadow.scaled(
scale / static_cast<float>(outMap.devicePixelRatio()));

QPixmapDropShadowFilter filter;
scaled.apply(filter);
filter.draw(&outPainter, {0, 0}, pixmap);
}
outMap.swap(pixmap);
}

// HACK: create a QLabel from the pixmap to apply drop shadows
QLabel label;

auto scaledShadow = shadow.scaled(
scale / static_cast<float>(label.devicePixelRatioF()));

// NOTE: avoid scaling issues on high DPI displays
pixmap.setDevicePixelRatio(label.devicePixelRatioF());

label.setPixmap(pixmap);

QGraphicsDropShadowEffect dropShadow;
scaledShadow.apply(dropShadow);
label.setGraphicsEffect(&dropShadow);

pixmap = label.grab();
pixmap.setDevicePixelRatio(1);
}

if (drawColon)
Expand All @@ -92,12 +94,12 @@ QColor Paint::overlayColors(QColor background, QColor foreground)
{
auto alpha = foreground.alphaF();

auto r = (1 - alpha) * static_cast<float>(background.red()) +
alpha * static_cast<float>(foreground.red());
auto g = (1 - alpha) * static_cast<float>(background.green()) +
alpha * static_cast<float>(foreground.green());
auto b = (1 - alpha) * static_cast<float>(background.blue()) +
alpha * static_cast<float>(foreground.blue());
auto r = ((1 - alpha) * static_cast<float>(background.red())) +
(alpha * static_cast<float>(foreground.red()));
auto g = ((1 - alpha) * static_cast<float>(background.green())) +
(alpha * static_cast<float>(foreground.green()));
auto b = ((1 - alpha) * static_cast<float>(background.blue())) +
(alpha * static_cast<float>(foreground.blue()));

return {static_cast<int>(r), static_cast<int>(g), static_cast<int>(b)};
}
Expand Down
2 changes: 1 addition & 1 deletion src/providers/seventv/paints/Paint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Paint
virtual bool animated() const = 0;

QPixmap getPixmap(const QString &text, const QFont &font, QColor userColor,
QSize size, float scale) const;
QSize size, float scale, float dpr) const;

Paint(QString id)
: id(std::move(id)){};
Expand Down
8 changes: 4 additions & 4 deletions src/providers/seventv/paints/PaintDropShadow.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "providers/seventv/paints/PaintDropShadow.hpp"

#include <private/qpixmapfilter_p.h>

namespace chatterino {

PaintDropShadow::PaintDropShadow(float xOffset, float yOffset, float radius,
Expand All @@ -22,11 +24,9 @@ PaintDropShadow PaintDropShadow::scaled(float scale) const
this->radius_ * scale, this->color_};
}

void PaintDropShadow::apply(QGraphicsDropShadowEffect &effect) const
void PaintDropShadow::apply(QPixmapDropShadowFilter &effect) const
{
// We can't move here
effect.setXOffset(this->xOffset_);
effect.setYOffset(this->yOffset_);
effect.setOffset({this->xOffset_, this->yOffset_});
effect.setBlurRadius(this->radius_);
effect.setColor(this->color_);
}
Expand Down
4 changes: 2 additions & 2 deletions src/providers/seventv/paints/PaintDropShadow.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <QGraphicsDropShadowEffect>
class QPixmapDropShadowFilter;

namespace chatterino {

Expand All @@ -11,7 +11,7 @@ class PaintDropShadow

bool isValid() const;
PaintDropShadow scaled(float scale) const;
void apply(QGraphicsDropShadowEffect &effect) const;
void apply(QPixmapDropShadowFilter &effect) const;

private:
const float xOffset_;
Expand Down

0 comments on commit f504cdd

Please sign in to comment.