[Refactor] Update font outline code to account for offsets

This commit is contained in:
in1tiate 2024-08-31 08:24:55 -05:00 committed by GitHub
parent c4d94cec42
commit cbda03ed6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 118 additions and 36 deletions

View File

@ -1,17 +1,13 @@
#include "aotextboxwidgets.h"
// Sane outlined QLabel solution ported from PyQt solution on StackOverflow by alec
// https://stackoverflow.com/questions/64290561/qlabel-correct-positioning-for-text-outline
AOChatboxLabel::AOChatboxLabel(QWidget *parent)
: QLabel(parent)
{}
void AOChatboxLabel::setOutlineColor(QColor color)
{
m_outline_color = color;
}
void AOChatboxLabel::setOutlineWidth(int width)
{
m_outline_width = width;
setBrush(QBrush(Qt::white));
setPen(QPen(Qt::black));
}
void AOChatboxLabel::setIsOutlined(bool outlined)
@ -19,39 +15,115 @@ void AOChatboxLabel::setIsOutlined(bool outlined)
m_outline = outlined;
}
void AOChatboxLabel::setTextColor(QColor color)
bool AOChatboxLabel::pointMode()
{
m_text_color = color;
return m_pointmode;
}
void AOChatboxLabel::setPointMode(bool mode)
{
m_pointmode = mode;
}
double AOChatboxLabel::outlineThickness()
{
if (pointMode())
{
return m_outline_width * font().pointSize();
}
else
return m_outline_width;
}
void AOChatboxLabel::setOutlineThickness(double w)
{
m_outline_width = w;
}
void AOChatboxLabel::setBrush(QBrush brush)
{
m_brush = brush;
}
void AOChatboxLabel::setPen(QPen pen)
{
m_pen = pen;
}
QSize AOChatboxLabel::sizeHint()
{
int nrml_w = std::ceil(outlineThickness() * 2);
return QLabel::sizeHint() + QSize(nrml_w, nrml_w);
}
QSize AOChatboxLabel::minimumSizeHint()
{
int nrml_w = std::ceil(outlineThickness() * 2);
return QLabel::minimumSizeHint() + QSize(nrml_w, nrml_w);
}
void AOChatboxLabel::paintEvent(QPaintEvent *event)
{
if (m_outline)
{
QBrush brush;
QPen pen;
QPointF baseline(m_outline_width, fontMetrics().height());
double w = outlineThickness();
QRectF rect = this->rect();
QFontMetrics metrics = QFontMetrics(this->font());
QRect tr = metrics.boundingRect(text()).adjusted(0, 0, w, w);
int l_indent;
int x;
int y;
// Set up brush (base text)
brush.setColor(m_text_color);
brush.setStyle(Qt::SolidPattern);
if (indent() == -1)
{
if (frameWidth())
{
l_indent = (metrics.boundingRect("x").width() + w * 2) / 2;
}
else
{
l_indent = w;
}
}
else
{
l_indent = indent();
}
// Set up outline
pen.setColor(m_outline_color);
pen.setWidthF(m_outline_width);
if (alignment() & Qt::AlignLeft)
{
x = rect.left() + l_indent - std::min(metrics.leftBearing(text()[0]), 0);
}
else if (alignment() & Qt::AlignRight)
{
x = rect.x() + rect.width() - l_indent - tr.width();
}
else
{
x = (rect.width() - tr.width()) / 2;
}
if (alignment() & Qt::AlignTop)
{
y = rect.top() + l_indent + metrics.ascent();
}
else if (alignment() & Qt::AlignBottom)
{
y = rect.y() + rect.height() - l_indent - metrics.descent();
}
else
{
y = (rect.height() + metrics.ascent() - metrics.descent()) / 2;
}
m_pen.setWidth(w * 2);
QPainterPath path;
path.addText(baseline, font(), text());
path.addText(x, y, font(), text());
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// draw outline
painter.setPen(pen);
painter.drawPath(path);
// remove outline pen, then draw text on top
painter.setPen(Qt::NoPen);
painter.setBrush(brush);
painter.drawPath(path);
painter.strokePath(path, m_pen);
if (1 < m_brush.style() && m_brush.style() < 15)
painter.fillPath(path, palette().window());
painter.fillPath(path, m_brush);
}
else
{

View File

@ -6,6 +6,7 @@
#include <QPaintEvent>
#include <QPainter>
#include <QPainterPath>
#include <QStyle>
#include <QTextEdit>
class AOChatboxLabel : public QLabel
@ -16,17 +17,26 @@ public:
AOChatboxLabel(QWidget *parent);
void setIsOutlined(bool outlined);
void setOutlineColor(QColor color);
void setOutlineWidth(int width);
void setTextColor(QColor color);
bool pointMode();
void setPointMode(bool mode);
double outlineThickness();
void setOutlineThickness(double w);
void setBrush(QBrush brush);
void setPen(QPen pen);
QSize sizeHint();
QSize minimumSizeHint();
protected:
void paintEvent(QPaintEvent *event);
private:
bool m_outline = false;
QColor m_outline_color;
bool m_pointmode = false;
int m_outline_width = 1;
QColor m_text_color;
QBrush m_brush;
QPen m_pen;
};

View File

@ -1294,9 +1294,9 @@ void Courtroom::set_qfont(QWidget *widget, QString class_name, QFont font, QColo
if (class_name == "AOChatboxLabel")
{ // Only shownames can be outlined
ui_vp_showname->setIsOutlined(outlined);
ui_vp_showname->setOutlineColor(outline_color);
ui_vp_showname->setTextColor(f_color);
ui_vp_showname->setOutlineWidth(outline_width);
ui_vp_showname->setBrush(QBrush(f_color));
ui_vp_showname->setPen(QPen(outline_color));
ui_vp_showname->setOutlineThickness(outline_width);
}
font.setBold(bold);