Skip to content

Commit

Permalink
[Refactor] Update font outline code to account for offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
in1tiate authored Aug 31, 2024
1 parent c4d94ce commit cbda03e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 34 deletions.
124 changes: 98 additions & 26 deletions src/aotextboxwidgets.cpp
Original file line number Diff line number Diff line change
@@ -1,57 +1,129 @@
#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)
{}
{
setBrush(QBrush(Qt::white));
setPen(QPen(Qt::black));
}

void AOChatboxLabel::setOutlineColor(QColor color)
void AOChatboxLabel::setIsOutlined(bool outlined)
{
m_outline_color = color;
m_outline = outlined;
}

void AOChatboxLabel::setOutlineWidth(int width)
bool AOChatboxLabel::pointMode()
{
m_outline_width = width;
return m_pointmode;
}

void AOChatboxLabel::setIsOutlined(bool outlined)
void AOChatboxLabel::setPointMode(bool mode)
{
m_outline = outlined;
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;
}

void AOChatboxLabel::setTextColor(QColor color)
QSize AOChatboxLabel::sizeHint()
{
m_text_color = color;
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;

if (indent() == -1)
{
if (frameWidth())
{
l_indent = (metrics.boundingRect("x").width() + w * 2) / 2;
}
else
{
l_indent = w;
}
}
else
{
l_indent = indent();
}

// Set up brush (base text)
brush.setColor(m_text_color);
brush.setStyle(Qt::SolidPattern);
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;
}

// Set up outline
pen.setColor(m_outline_color);
pen.setWidthF(m_outline_width);
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
{
Expand Down
20 changes: 15 additions & 5 deletions src/aotextboxwidgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <QPaintEvent>
#include <QPainter>
#include <QPainterPath>
#include <QStyle>
#include <QTextEdit>

class AOChatboxLabel : public QLabel
Expand All @@ -16,17 +17,26 @@ class AOChatboxLabel : public QLabel
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;
};
6 changes: 3 additions & 3 deletions src/courtroom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit cbda03e

Please sign in to comment.