[Refactor] Update font outline code to account for offsets
This commit is contained in:
parent
c4d94cec42
commit
cbda03ed6c
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user