viewer: allow customizing subtitle font

Fixes #1980
This commit is contained in:
itsmattkc
2022-07-23 13:49:02 -07:00
parent 0e6ebee827
commit 3948b77543
4 changed files with 93 additions and 24 deletions
+53 -20
View File
@@ -463,45 +463,78 @@ void ViewerDisplayWidget::OnPaint()
const QVector<Track*> &subtitle_tracklist = subtitle_tracks_->track_list(Track::kSubtitle)->GetTracks();
if (!subtitle_tracklist.empty()) {
QPainter p(paint_device());
QPainterPath path;
QTransform transform = GenerateWorldTransform();
QRect bounding_box = transform.mapRect(rect());
QFont f;
qreal font_sz = OLIVE_CONFIG("DefaultSubtitleSize").toInt();
{
// Scale font size by transform
QTransform display_transform = GenerateDisplayTransform();
font_sz *= display_transform.m11();
}
f.setPointSizeF(font_sz);
QString family = OLIVE_CONFIG("DefaultSubtitleFamily").toString();
if (!family.isEmpty()) {
f.setFamily(family);
}
f.setWeight(OLIVE_CONFIG("DefaultSubtitleWeight").toInt());
bounding_box.adjust(bounding_box.width()/10, bounding_box.height()/10, -bounding_box.width()/10, -bounding_box.height()/10);
QFont f = p.font();
int font_sz = bounding_box.height() / 18;
f.setStyleHint(QFont::SansSerif);
f.setFamily(f.defaultFamily());
f.setPointSize(font_sz);
f.setWeight(QFont::Bold);
p.setFont(f);
p.setPen(Qt::white);
QPainterPath path;
int text_line = 1;
QFontMetrics fm(f);
for (int j=subtitle_tracklist.size()-1; j>=0; j--) {
Track *sub_track = subtitle_tracklist.at(j);
if (!sub_track->IsMuted()) {
if (SubtitleBlock *sub = dynamic_cast<SubtitleBlock*>(sub_track->BlockAtTime(time_))) {
// Split into lines
QStringList list = QtUtils::WordWrapString(sub->GetText(), p.fontMetrics(), bounding_box.width());
QStringList list = QtUtils::WordWrapString(sub->GetText(), fm, bounding_box.width());
for (int i=list.size()-1; i>=0; i--) {
int w = QtUtils::QFontMetricsWidth(p.fontMetrics(), list.at(i));
path.addText(bounding_box.x() + bounding_box.width()/2 - w/2, bounding_box.y() + bounding_box.height() - p.fontMetrics().height() * text_line + p.fontMetrics().ascent(), p.font(), list.at(i));
text_line++;
int w = QtUtils::QFontMetricsWidth(fm, list.at(i));
path.addText(bounding_box.width()/2 - w/2, bounding_box.height() - fm.height() * (list.size() - i) + fm.ascent(), f, list.at(i));
}
}
}
}
p.setPen(QPen(Qt::black, font_sz / 16));
p.setBrush(Qt::white);
p.drawPath(path);
bool antialias = OLIVE_CONFIG("AntialiasSubtitles").toBool();
QPixmap *aa_pixmap;
QPainter *text_painter;
if (antialias) {
// QPainter only supports anti-aliasing in software, so to achieve it, we draw to a
// software buffer first and then draw that onto the hardware
aa_pixmap = new QPixmap(bounding_box.width(), bounding_box.height());
aa_pixmap->fill(Qt::transparent);
text_painter = new QPainter(aa_pixmap);
} else {
// Just draw straight to the hardware
text_painter = new QPainter(paint_device());
// Offset path by however much is necessary
path.translate(bounding_box.x(), bounding_box.y());
}
text_painter->setPen(QPen(Qt::black, f.pointSizeF() / 16));
text_painter->setBrush(Qt::white);
text_painter->setRenderHint(QPainter::Antialiasing);
text_painter->drawPath(path);
delete text_painter;
if (antialias) {
// We just drew to a software buffer, now draw this image onto the hardware device
QPainter p(paint_device());
p.drawPixmap(bounding_box.x(), bounding_box.y(), *aa_pixmap);
delete aa_pixmap;
}
}
}