Skip to content

Commit cbda03e

Browse files
authored
[Refactor] Update font outline code to account for offsets
1 parent c4d94ce commit cbda03e

3 files changed

Lines changed: 116 additions & 34 deletions

File tree

src/aotextboxwidgets.cpp

Lines changed: 98 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,129 @@
11
#include "aotextboxwidgets.h"
22

3+
// Sane outlined QLabel solution ported from PyQt solution on StackOverflow by alec
4+
// https://stackoverflow.com/questions/64290561/qlabel-correct-positioning-for-text-outline
5+
36
AOChatboxLabel::AOChatboxLabel(QWidget *parent)
47
: QLabel(parent)
5-
{}
8+
{
9+
setBrush(QBrush(Qt::white));
10+
setPen(QPen(Qt::black));
11+
}
612

7-
void AOChatboxLabel::setOutlineColor(QColor color)
13+
void AOChatboxLabel::setIsOutlined(bool outlined)
814
{
9-
m_outline_color = color;
15+
m_outline = outlined;
1016
}
1117

12-
void AOChatboxLabel::setOutlineWidth(int width)
18+
bool AOChatboxLabel::pointMode()
1319
{
14-
m_outline_width = width;
20+
return m_pointmode;
1521
}
1622

17-
void AOChatboxLabel::setIsOutlined(bool outlined)
23+
void AOChatboxLabel::setPointMode(bool mode)
1824
{
19-
m_outline = outlined;
25+
m_pointmode = mode;
26+
}
27+
28+
double AOChatboxLabel::outlineThickness()
29+
{
30+
if (pointMode())
31+
{
32+
return m_outline_width * font().pointSize();
33+
}
34+
else
35+
return m_outline_width;
36+
}
37+
38+
void AOChatboxLabel::setOutlineThickness(double w)
39+
{
40+
m_outline_width = w;
41+
}
42+
43+
void AOChatboxLabel::setBrush(QBrush brush)
44+
{
45+
m_brush = brush;
46+
}
47+
void AOChatboxLabel::setPen(QPen pen)
48+
{
49+
m_pen = pen;
2050
}
2151

22-
void AOChatboxLabel::setTextColor(QColor color)
52+
QSize AOChatboxLabel::sizeHint()
2353
{
24-
m_text_color = color;
54+
int nrml_w = std::ceil(outlineThickness() * 2);
55+
return QLabel::sizeHint() + QSize(nrml_w, nrml_w);
56+
}
57+
QSize AOChatboxLabel::minimumSizeHint()
58+
{
59+
int nrml_w = std::ceil(outlineThickness() * 2);
60+
return QLabel::minimumSizeHint() + QSize(nrml_w, nrml_w);
2561
}
2662

2763
void AOChatboxLabel::paintEvent(QPaintEvent *event)
2864
{
2965
if (m_outline)
3066
{
31-
QBrush brush;
32-
QPen pen;
33-
QPointF baseline(m_outline_width, fontMetrics().height());
67+
double w = outlineThickness();
68+
QRectF rect = this->rect();
69+
QFontMetrics metrics = QFontMetrics(this->font());
70+
QRect tr = metrics.boundingRect(text()).adjusted(0, 0, w, w);
71+
int l_indent;
72+
int x;
73+
int y;
74+
75+
if (indent() == -1)
76+
{
77+
if (frameWidth())
78+
{
79+
l_indent = (metrics.boundingRect("x").width() + w * 2) / 2;
80+
}
81+
else
82+
{
83+
l_indent = w;
84+
}
85+
}
86+
else
87+
{
88+
l_indent = indent();
89+
}
3490

35-
// Set up brush (base text)
36-
brush.setColor(m_text_color);
37-
brush.setStyle(Qt::SolidPattern);
91+
if (alignment() & Qt::AlignLeft)
92+
{
93+
x = rect.left() + l_indent - std::min(metrics.leftBearing(text()[0]), 0);
94+
}
95+
else if (alignment() & Qt::AlignRight)
96+
{
97+
x = rect.x() + rect.width() - l_indent - tr.width();
98+
}
99+
else
100+
{
101+
x = (rect.width() - tr.width()) / 2;
102+
}
38103

39-
// Set up outline
40-
pen.setColor(m_outline_color);
41-
pen.setWidthF(m_outline_width);
104+
if (alignment() & Qt::AlignTop)
105+
{
106+
y = rect.top() + l_indent + metrics.ascent();
107+
}
108+
else if (alignment() & Qt::AlignBottom)
109+
{
110+
y = rect.y() + rect.height() - l_indent - metrics.descent();
111+
}
112+
else
113+
{
114+
y = (rect.height() + metrics.ascent() - metrics.descent()) / 2;
115+
}
42116

117+
m_pen.setWidth(w * 2);
43118
QPainterPath path;
44-
path.addText(baseline, font(), text());
119+
path.addText(x, y, font(), text());
45120

46121
QPainter painter(this);
47122
painter.setRenderHint(QPainter::Antialiasing);
48-
// draw outline
49-
painter.setPen(pen);
50-
painter.drawPath(path);
51-
// remove outline pen, then draw text on top
52-
painter.setPen(Qt::NoPen);
53-
painter.setBrush(brush);
54-
painter.drawPath(path);
123+
painter.strokePath(path, m_pen);
124+
if (1 < m_brush.style() && m_brush.style() < 15)
125+
painter.fillPath(path, palette().window());
126+
painter.fillPath(path, m_brush);
55127
}
56128
else
57129
{

src/aotextboxwidgets.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <QPaintEvent>
77
#include <QPainter>
88
#include <QPainterPath>
9+
#include <QStyle>
910
#include <QTextEdit>
1011

1112
class AOChatboxLabel : public QLabel
@@ -16,17 +17,26 @@ class AOChatboxLabel : public QLabel
1617
AOChatboxLabel(QWidget *parent);
1718

1819
void setIsOutlined(bool outlined);
19-
void setOutlineColor(QColor color);
20-
void setOutlineWidth(int width);
2120

22-
void setTextColor(QColor color);
21+
bool pointMode();
22+
void setPointMode(bool mode);
23+
24+
double outlineThickness();
25+
void setOutlineThickness(double w);
26+
27+
void setBrush(QBrush brush);
28+
void setPen(QPen pen);
29+
30+
QSize sizeHint();
31+
QSize minimumSizeHint();
2332

2433
protected:
2534
void paintEvent(QPaintEvent *event);
2635

2736
private:
2837
bool m_outline = false;
29-
QColor m_outline_color;
38+
bool m_pointmode = false;
3039
int m_outline_width = 1;
31-
QColor m_text_color;
40+
QBrush m_brush;
41+
QPen m_pen;
3242
};

src/courtroom.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,9 +1294,9 @@ void Courtroom::set_qfont(QWidget *widget, QString class_name, QFont font, QColo
12941294
if (class_name == "AOChatboxLabel")
12951295
{ // Only shownames can be outlined
12961296
ui_vp_showname->setIsOutlined(outlined);
1297-
ui_vp_showname->setOutlineColor(outline_color);
1298-
ui_vp_showname->setTextColor(f_color);
1299-
ui_vp_showname->setOutlineWidth(outline_width);
1297+
ui_vp_showname->setBrush(QBrush(f_color));
1298+
ui_vp_showname->setPen(QPen(outline_color));
1299+
ui_vp_showname->setOutlineThickness(outline_width);
13001300
}
13011301

13021302
font.setBold(bold);

0 commit comments

Comments
 (0)