diff --git a/app/widget/viewer/viewerdisplay.cpp b/app/widget/viewer/viewerdisplay.cpp index 92f9bd119..1357af21a 100644 --- a/app/widget/viewer/viewerdisplay.cpp +++ b/app/widget/viewer/viewerdisplay.cpp @@ -456,84 +456,7 @@ void ViewerDisplayWidget::OnPaint() } // Extraordinarily basic subtitle renderer. Hoping to swap this out with libass at some point. - if (show_subtitles_ && subtitle_tracks_) { - const QVector &subtitle_tracklist = subtitle_tracks_->track_list(Track::kSubtitle)->GetTracks(); - - if (!subtitle_tracklist.empty()) { - 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); - - 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(sub_track->BlockAtTime(time_))) { - // Split into lines - QStringList list = QtUtils::WordWrapString(sub->GetText(), fm, bounding_box.width()); - - for (int i=list.size()-1; i>=0; i--) { - 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)); - } - } - } - } - - 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; - } - } - } + DrawSubtitleTracks(); if (add_band_) { QPainter p(paint_device()); @@ -974,6 +897,93 @@ void ViewerDisplayWidget::EmitColorAtCursor(QMouseEvent *e) } } +void ViewerDisplayWidget::DrawSubtitleTracks() +{ + if (!show_subtitles_ || !subtitle_tracks_) { + return; + } + + const QVector &subtitle_tracklist = subtitle_tracks_->track_list(Track::kSubtitle)->GetTracks(); + if (subtitle_tracklist.empty()) { + return; + } + + // Scale font size by transform + QTransform display_transform = GenerateDisplayTransform(); + qreal font_sz = OLIVE_CONFIG("DefaultSubtitleSize").toInt(); + font_sz *= display_transform.m11(); + if (qIsNaN(font_sz)) { + return; + } + + QPainterPath path; + + QTransform transform = GenerateWorldTransform(); + QRect bounding_box = transform.mapRect(rect()); + + QFont f; + 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); + + 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(sub_track->BlockAtTime(time_))) { + // Split into lines + QStringList list = QtUtils::WordWrapString(sub->GetText(), fm, bounding_box.width()); + + for (int i=list.size()-1; i>=0; i--) { + 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)); + } + } + } + } + + 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; + } +} + void ViewerDisplayWidget::SetShowFPS(bool e) { show_fps_ = e; diff --git a/app/widget/viewer/viewerdisplay.h b/app/widget/viewer/viewerdisplay.h index e88b845a3..430f11b54 100644 --- a/app/widget/viewer/viewerdisplay.h +++ b/app/widget/viewer/viewerdisplay.h @@ -263,6 +263,8 @@ private: void EmitColorAtCursor(QMouseEvent* e); + void DrawSubtitleTracks(); + /** * @brief Internal reference to the OpenGL texture to draw. Set in SetTexture() and used in paintGL(). */